packages feed

sandwich-webdriver 0.1.2.0 → 0.2.0.0

raw patch · 5 files changed

+68/−32 lines, 5 filesdep +unliftioPVP ok

version bump matches the API change (PVP)

Dependencies added: unliftio

API changes (from Hackage documentation)

- Test.Sandwich.WebDriver.Config: obtainChromeDriver :: (MonadIO m, MonadLogger m, MonadBaseControl IO m) => FilePath -> ChromeDriverToUse -> m (Either Text FilePath)
+ Test.Sandwich.WebDriver.Config: obtainChromeDriver :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadMask m) => FilePath -> ChromeDriverToUse -> m (Either Text FilePath)
- Test.Sandwich.WebDriver.Internal.Binaries: obtainChromeDriver :: (MonadIO m, MonadLogger m, MonadBaseControl IO m) => FilePath -> ChromeDriverToUse -> m (Either Text FilePath)
+ Test.Sandwich.WebDriver.Internal.Binaries: obtainChromeDriver :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadMask m) => FilePath -> ChromeDriverToUse -> m (Either Text FilePath)

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for sandwich-webdriver +# 0.2.0.0++* Fix the obtainChromeDriver function now that the zip files contain multiple files. This added a MonadMask constraint to the function so it's a major version bump.+ # 0.1.2.0  * Be able to control download directory.
LICENSE view
@@ -1,4 +1,4 @@-Copyright Tom McLaughlin (c) 2022+Copyright Tom McLaughlin (c) 2023  All rights reserved. 
sandwich-webdriver.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.0.+-- This file has been generated from package.yaml by hpack version 0.35.1. -- -- see: https://github.com/sol/hpack  name:           sandwich-webdriver-version:        0.1.2.0+version:        0.2.0.0 synopsis:       Sandwich integration with Selenium WebDriver description:    Please see the <https://codedownio.github.io/sandwich/docs/extensions/sandwich-webdriver documentation>. category:       Testing@@ -13,7 +13,7 @@ bug-reports:    https://github.com/codedownio/sandwich/issues author:         Tom McLaughlin maintainer:     tom@codedown.io-copyright:      2022 Tom McLaughlin+copyright:      2023 Tom McLaughlin license:        BSD3 license-file:   LICENSE build-type:     Simple@@ -226,11 +226,13 @@     , safe     , safe-exceptions     , sandwich >=0.1.0.3+    , sandwich-webdriver     , string-interpolate     , temporary     , text     , time     , transformers+    , unliftio     , unordered-containers     , vector     , webdriver
src/Test/Sandwich/WebDriver/Internal/Binaries.hs view
@@ -1,5 +1,9 @@ {-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP, QuasiQuotes, ScopedTypeVariables, NamedFieldPuns, Rank2Types #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE Rank2Types #-}  module Test.Sandwich.WebDriver.Internal.Binaries (   obtainSelenium@@ -9,7 +13,9 @@   , downloadChromeDriverIfNecessary   ) where +import Control.Exception import Control.Monad+import Control.Monad.Catch import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Control (MonadBaseControl)@@ -19,17 +25,25 @@ import GHC.Stack import System.Directory import System.FilePath+import System.IO.Temp import System.Process import Test.Sandwich.Logging import Test.Sandwich.WebDriver.Internal.Binaries.Util import Test.Sandwich.WebDriver.Internal.Types import Test.Sandwich.WebDriver.Internal.Util -type Constraints m = (HasCallStack, MonadLogger m, MonadIO m, MonadBaseControl IO m) +type Constraints m = (+  HasCallStack+  , MonadLogger m+  , MonadIO m+  , MonadBaseControl IO m+  , MonadMask m+  )+ -- * Obtaining binaries -  -- TODO: remove curl dependencies here+-- TODO: remove curl dependencies here  -- | 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.@@ -46,14 +60,15 @@   unlessM (liftIO $ doesFileExist seleniumPath) $     void $ liftIO $ readCreateProcess (shell [i|curl https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar -o #{seleniumPath}|]) ""   return $ Right seleniumPath-obtainSelenium _ (UseSeleniumAt path) =-  (liftIO $ doesFileExist path) >>= \case-    False -> return $ Left [i|Path '#{path}' didn't exist|]-    True -> return $ Right path+obtainSelenium _ (UseSeleniumAt path) = liftIO (doesFileExist path) >>= \case+  False -> return $ Left [i|Path '#{path}' didn't exist|]+  True -> return $ Right path  -- | Manually obtain a chromedriver binary, according to the 'ChromeDriverToUse' policy, -- storing it under the provided 'FilePath' if necessary and returning the exact path.-obtainChromeDriver :: (MonadIO m, MonadLogger m, MonadBaseControl IO m) => FilePath -> ChromeDriverToUse -> m (Either T.Text FilePath)+obtainChromeDriver :: (+  MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadMask m+  ) => FilePath -> ChromeDriverToUse -> m (Either T.Text FilePath) obtainChromeDriver toolsDir (DownloadChromeDriverFrom url) = do   let path = [i|#{toolsDir}/#{chromeDriverExecutable}|]   liftIO $ createDirectoryIfMissing True (takeDirectory path)@@ -71,10 +86,9 @@ obtainChromeDriver toolsDir (DownloadChromeDriverAutodetect maybeChromePath) = runExceptT $ do   version <- ExceptT $ liftIO $ getChromeDriverVersion maybeChromePath   ExceptT $ obtainChromeDriver toolsDir (DownloadChromeDriverVersion version)-obtainChromeDriver _ (UseChromeDriverAt path) =-  (liftIO $ doesFileExist path) >>= \case-    False -> return $ Left [i|Path '#{path}' didn't exist|]-    True -> return $ Right path+obtainChromeDriver _ (UseChromeDriverAt path) = liftIO (doesFileExist path) >>= \case+  False -> return $ Left [i|Path '#{path}' didn't exist|]+  True -> return $ Right path  -- | Manually obtain a geckodriver binary, according to the 'GeckoDriverToUse' policy, -- storing it under the provided 'FilePath' if necessary and returning the exact path.@@ -96,10 +110,9 @@ obtainGeckoDriver toolsDir (DownloadGeckoDriverAutodetect maybeFirefoxPath) = runExceptT $ do   version <- ExceptT $ liftIO $ getGeckoDriverVersion maybeFirefoxPath   ExceptT $ obtainGeckoDriver toolsDir (DownloadGeckoDriverVersion version)-obtainGeckoDriver _ (UseGeckoDriverAt path) =-  (liftIO $ doesFileExist path) >>= \case-    False -> return $ Left [i|Path '#{path}' didn't exist|]-    True -> return $ Right path+obtainGeckoDriver _ (UseGeckoDriverAt path) = liftIO (doesFileExist path) >>= \case+  False -> return $ Left [i|Path '#{path}' didn't exist|]+  True -> return $ Right path  -- * Lower level helpers @@ -107,7 +120,7 @@ downloadSeleniumIfNecessary :: Constraints 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))+  liftIO (doesFileExist seleniumPath) >>= flip unless (downloadSelenium seleniumPath)   return seleniumPath  downloadSelenium :: Constraints m => FilePath -> m ()@@ -147,11 +160,19 @@   Windows -> "geckodriver.exe"   _ -> "geckodriver" -downloadAndUnzipToPath :: (MonadIO m, MonadBaseControl IO m, MonadLogger m) => T.Text -> FilePath -> m (Either T.Text ())+downloadAndUnzipToPath :: (MonadIO m, MonadBaseControl IO m, MonadLogger m, MonadMask m) => T.Text -> FilePath -> m (Either T.Text ()) downloadAndUnzipToPath downloadPath localPath = leftOnException' $ do   info [i|Downloading #{downloadPath} to #{localPath}|]   liftIO $ createDirectoryIfMissing True (takeDirectory localPath)-  liftIO $ void $ readCreateProcess (shell [i|wget -nc -O - #{downloadPath} | gunzip - > #{localPath}|]) ""+  withSystemTempDirectory "sandwich-webdriver-tool-download" $ \dir -> liftIO $ do+    void $ readCreateProcess ((proc "curl" [T.unpack downloadPath, "-o", "temp.zip"]) { cwd = Just dir }) ""+    void $ readCreateProcess ((proc "unzip" ["temp.zip"]) { cwd = Just dir }) ""++    liftIO (listDirectory dir >>= filterM (\f -> executable <$> getPermissions (dir </> f))) >>= \case+      [] -> throwIO $ userError [i|No executable found in file downloaded from #{downloadPath}|]+      [x] -> renameFile (dir </> x) localPath+      xs -> throwIO $ userError [i|Found multiple executable found in file downloaded from #{downloadPath}: #{xs}|]+   liftIO $ void $ readCreateProcess (shell [i|chmod u+x #{localPath}|]) ""  downloadAndUntarballToPath :: (MonadIO m, MonadBaseControl IO m, MonadLogger m) => T.Text -> FilePath -> m (Either T.Text ())
test/Spec.hs view
@@ -1,20 +1,29 @@  import Test.Sandwich+import Test.Sandwich.WebDriver.Config+import Data.Text as T+import UnliftIO.Temporary import Data.Time.Clock-import Test.Sandwich.Formatters.Print+import Data.String.Interpolate -data Foo = Foo { fooInt :: Int, fooString :: String, fooBar :: Bar } deriving (Show, Eq)-data Bar = Bar { barInt :: Int, barString :: String } deriving (Show, Eq)-data Baz = Baz Int String Bar deriving (Show, Eq)-data Simple = Simple { simpleInt :: Int } deriving (Show, Eq) +spec :: TopSpec+spec = do+  it "successfully runs obtainChromeDriver" $ do+    withSystemTempDirectory "test-download" $ \dir -> do+      obtainChromeDriver dir (DownloadChromeDriverAutodetect Nothing) >>= \case+        Right x -> info [i|Got chromedriver: #{x}|]+        Left err -> expectationFailure (T.unpack err) -verySimple :: TopSpec-verySimple = do-  it "succeeds" (return ())+  it "successfully runs obtainGeckoDriver" $ do+    withSystemTempDirectory "test-download" $ \dir -> do+      obtainGeckoDriver dir (DownloadGeckoDriverAutodetect Nothing) >>= \case+        Right x -> info [i|Got geckoDriver: #{x}|]+        Left err -> expectationFailure (T.unpack err) + main :: IO ()-main = runSandwich options verySimple+main = runSandwich options spec   where     options = defaultOptions {       optionsTestArtifactsDirectory = TestArtifactsGeneratedDirectory "test_runs" (show <$> getCurrentTime)