sandwich-webdriver-0.5.0.0: src/Test/Sandwich/WebDriver/Internal/Binaries/Selenium.hs
{-# LANGUAGE ConstraintKinds #-}
module Test.Sandwich.WebDriver.Internal.Binaries.Selenium (
obtainSelenium
, downloadSeleniumIfNecessary
, SeleniumToUse(..)
) where
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift
import Control.Monad.Logger
import Control.Monad.Reader
import qualified Data.List as L
import Data.String.Interpolate
import qualified Data.Text as T
import GHC.Stack
import Test.Sandwich
import Test.Sandwich.Contexts.Files
import Test.Sandwich.Contexts.Nix
import Test.Sandwich.WebDriver.Internal.Binaries.Common
import Test.Sandwich.WebDriver.Internal.Binaries.Selenium.Types
import Test.Sandwich.WebDriver.Internal.Util
import UnliftIO.Directory
type Constraints context m = (
HasCallStack
, MonadLogger m
, MonadUnliftIO m
, HasBaseContextMonad context m
)
-- * Obtaining binaries
defaultSeleniumJarUrl :: String
defaultSeleniumJarUrl = "https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar"
-- | Manually obtain a Selenium server JAR file, according to the 'SeleniumToUse' policy,
-- storing it under the provided 'FilePath' if necessary and returning the exact path.
obtainSelenium :: (
MonadReader context m, HasBaseContext context
, MonadUnliftIO m, MonadLogger m
)
-- | How to obtain Selenium
=> SeleniumToUse
-> m FilePath
obtainSelenium (DownloadSeleniumFrom toolsDir url) = do
let path = [i|#{toolsDir}/selenium-server-standalone.jar|]
doesFileExist path >>= \case
True -> do
debug [i|Selenium already existed at #{path}|]
False -> do
debug [i|Downloading Selenium from #{url} to #{path}|]
curlDownloadToPath url path
return path
obtainSelenium (DownloadSeleniumDefault toolsDir) = do
let path = [i|#{toolsDir}/selenium-server-standalone-3.141.59.jar|]
doesFileExist path >>= \case
True -> do
debug [i|Selenium already existed at #{path}|]
False -> do
debug [i|Downloading Selenium from #{defaultSeleniumJarUrl} to #{path}|]
curlDownloadToPath defaultSeleniumJarUrl path
return path
obtainSelenium (UseSeleniumAt path) = liftIO (doesFileExist path) >>= \case
False -> expectationFailure [i|Path '#{path}' didn't exist|]
True -> do
debug [i|Found Selenium at #{path}|]
return path
obtainSelenium (UseSeleniumFromNixpkgs nc) = do
debug [i|Building selenium-server-standalone with Nix...|]
ret <- buildNixSymlinkJoin' nc ["selenium-server-standalone"] >>=
liftIO . findFirstFile (return . (".jar" `L.isSuffixOf`))
debug [i|Got Selenium: #{ret}|]
return ret
-- * Lower level helpers
downloadSeleniumIfNecessary :: Constraints context m => FilePath -> m (Either T.Text FilePath)
downloadSeleniumIfNecessary toolsDir = leftOnException' $ do
let seleniumPath = [i|#{toolsDir}/selenium-server.jar|]
liftIO (doesFileExist seleniumPath) >>= flip unless (downloadSelenium seleniumPath)
return seleniumPath
where
downloadSelenium :: Constraints context m => FilePath -> m ()
downloadSelenium seleniumPath = void $ do
info [i|Downloading selenium-server.jar to #{seleniumPath}|]
curlDownloadToPath defaultSeleniumJarUrl seleniumPath