Skip to content

Commit 2169a42

Browse files
committed
sandwich-webdriver: use latest process logging and managed asyncs
1 parent e6a45b2 commit 2169a42

8 files changed

Lines changed: 48 additions & 36 deletions

File tree

sandwich-webdriver/src/Test/Sandwich/WebDriver/Internal/Binaries/Chrome.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ import Test.Sandwich.WebDriver.Internal.Binaries.DetectPlatform
3232
import UnliftIO.Directory
3333

3434

35-
type Constraints m = (
35+
type Constraints context m = (
3636
HasCallStack
3737
, MonadLogger m
3838
, MonadUnliftIO m
39+
, HasBaseContextMonad context m
3940
)
4041

4142
-- | Manually obtain a chrome binary, according to the 'ChromeToUse' policy,
@@ -108,7 +109,7 @@ obtainChromeDriver (UseChromeDriverFromNixpkgs nixContext) = do
108109
debug [i|Built chromedriver: #{ret}|]
109110
return $ Right ret
110111

111-
downloadChromeDriverIfNecessary' :: Constraints m => FilePath -> ChromeDriverVersion -> m (Either T.Text FilePath)
112+
downloadChromeDriverIfNecessary' :: Constraints context m => FilePath -> ChromeDriverVersion -> m (Either T.Text FilePath)
112113
downloadChromeDriverIfNecessary' toolsDir chromeDriverVersion = runExceptT $ do
113114
let chromeDriverPath = getChromeDriverPath toolsDir chromeDriverVersion
114115

@@ -118,7 +119,7 @@ downloadChromeDriverIfNecessary' toolsDir chromeDriverVersion = runExceptT $ do
118119

119120
return chromeDriverPath
120121

121-
downloadChromeDriverIfNecessary :: Constraints m => FilePath -> FilePath -> m (Either T.Text FilePath)
122+
downloadChromeDriverIfNecessary :: Constraints context m => FilePath -> FilePath -> m (Either T.Text FilePath)
122123
downloadChromeDriverIfNecessary chromePath toolsDir = runExceptT $ do
123124
chromeDriverVersion <- ExceptT $ liftIO $ getChromeDriverVersion chromePath
124125
ExceptT $ downloadChromeDriverIfNecessary' toolsDir chromeDriverVersion
Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,65 @@
11

22
module Test.Sandwich.WebDriver.Internal.Binaries.Common where
33

4-
import Control.Exception
54
import Control.Monad
65
import Control.Monad.IO.Class
76
import Control.Monad.IO.Unlift
87
import Control.Monad.Logger
98
import Data.String.Interpolate
109
import qualified Data.Text as T
11-
import System.Directory
1210
import System.Exit
1311
import System.FilePath
14-
import System.Process
1512
import Test.Sandwich.Expectations
1613
import Test.Sandwich.Logging
14+
import Test.Sandwich.Misc (HasBaseContextMonad)
1715
import Test.Sandwich.WebDriver.Internal.Util
16+
import UnliftIO.Async
17+
import UnliftIO.Directory
18+
import UnliftIO.Exception
19+
import UnliftIO.Process
1820
import UnliftIO.Temporary
1921

2022

21-
downloadAndUnzipToPath :: (MonadUnliftIO m, MonadLogger m) => T.Text -> FilePath -> m (Either T.Text ())
23+
downloadAndUnzipToPath :: (MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m) => T.Text -> FilePath -> m (Either T.Text ())
2224
downloadAndUnzipToPath downloadPath localPath = leftOnException' $ do
2325
info [i|Downloading #{downloadPath} to #{localPath}|]
24-
liftIO $ createDirectoryIfMissing True (takeDirectory localPath)
26+
createDirectoryIfMissing True (takeDirectory localPath)
2527
withSystemTempDirectory "sandwich-webdriver-tool-download" $ \dir -> do
2628
curlDownloadToPath (T.unpack downloadPath) (dir </> "temp.zip")
2729

2830
createProcessWithLogging ((proc "unzip" ["temp.zip", "-d", "unzipped"]) { cwd = Just dir })
29-
>>= liftIO . waitForProcess >>= (`shouldBe` ExitSuccess)
31+
>>= \(ps, asy) -> finally (waitForProcess ps >>= (`shouldBe` ExitSuccess))
32+
(cancel asy)
3033
let unzipped = dir </> "unzipped"
3134

3235
executables <- (filter (/= "") . T.splitOn "\n" . T.pack) <$> readCreateProcessWithLogging (proc "find" [unzipped, "-executable", "-type", "f"]) ""
3336
case executables of
34-
[] -> liftIO $ throwIO $ userError [i|No executable found in file downloaded from #{downloadPath}|]
37+
[] -> throwIO $ userError [i|No executable found in file downloaded from #{downloadPath}|]
3538
[x] -> do
36-
liftIO $ copyFile (T.unpack x) localPath
39+
copyFile (T.unpack x) localPath
3740
createProcessWithLogging (shell [i|chmod u+x #{localPath}|])
38-
>>= liftIO . waitForProcess >>= (`shouldBe` ExitSuccess)
39-
xs -> liftIO $ throwIO $ userError [i|Found multiple executable found in file downloaded from #{downloadPath}: #{xs}|]
41+
>>= \(ps, asy) -> finally (waitForProcess ps >>= (`shouldBe` ExitSuccess))
42+
(cancel asy)
43+
xs -> throwIO $ userError [i|Found multiple executable found in file downloaded from #{downloadPath}: #{xs}|]
4044

41-
downloadAndUntarballToPath :: (MonadUnliftIO m, MonadLogger m) => T.Text -> FilePath -> m (Either T.Text ())
45+
downloadAndUntarballToPath :: (MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m) => T.Text -> FilePath -> m (Either T.Text ())
4246
downloadAndUntarballToPath downloadPath localPath = leftOnException' $ do
4347
info [i|Downloading #{downloadPath} to #{localPath}|]
44-
liftIO $ createDirectoryIfMissing True (takeDirectory localPath)
48+
createDirectoryIfMissing True (takeDirectory localPath)
4549
createProcessWithLogging (shell [i|wget -qO- #{downloadPath} | tar xvz -C #{takeDirectory localPath}|])
46-
>>= liftIO . waitForProcess >>= (`shouldBe` ExitSuccess)
50+
>>= \(ps, asy) -> finally (liftIO $ waitForProcess ps >>= (`shouldBe` ExitSuccess))
51+
(cancel asy)
4752
createProcessWithLogging (shell [i|chmod u+x #{localPath}|])
48-
>>= liftIO . waitForProcess >>= (`shouldBe` ExitSuccess)
53+
>>= \(ps, asy) -> finally (liftIO $ waitForProcess ps >>= (`shouldBe` ExitSuccess))
54+
(cancel asy)
4955

50-
curlDownloadToPath :: (MonadUnliftIO m, MonadLogger m) => String -> FilePath -> m ()
56+
curlDownloadToPath :: (MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m) => String -> FilePath -> m ()
5157
curlDownloadToPath downloadPath localPath = do
5258
info [i|Downloading #{downloadPath} to #{localPath}|]
53-
liftIO $ createDirectoryIfMissing True (takeDirectory localPath)
54-
p <- createProcessWithLogging (proc "curl" [downloadPath, "-o", localPath, "-s"])
55-
liftIO (waitForProcess p) >>= (`shouldBe` ExitSuccess)
59+
createDirectoryIfMissing True (takeDirectory localPath)
60+
(p, asy) <- createProcessWithLogging (proc "curl" [downloadPath, "-o", localPath, "-s"])
61+
finally (liftIO (waitForProcess p) >>= (`shouldBe` ExitSuccess))
62+
(cancel asy)
5663

5764
unlessM :: Monad m => m Bool -> m () -> m ()
5865
unlessM b s = b >>= (\t -> unless t s)

sandwich-webdriver/src/Test/Sandwich/WebDriver/Internal/Binaries/Selenium.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ import Test.Sandwich.WebDriver.Internal.Util
2424
import UnliftIO.Directory
2525

2626

27-
type Constraints m = (
27+
type Constraints context m = (
2828
HasCallStack
2929
, MonadLogger m
3030
, MonadUnliftIO m
31+
, HasBaseContextMonad context m
3132
)
3233

3334
-- * Obtaining binaries
@@ -76,13 +77,13 @@ obtainSelenium (UseSeleniumFromNixpkgs nc) = do
7677

7778
-- * Lower level helpers
7879

79-
downloadSeleniumIfNecessary :: Constraints m => FilePath -> m (Either T.Text FilePath)
80+
downloadSeleniumIfNecessary :: Constraints context m => FilePath -> m (Either T.Text FilePath)
8081
downloadSeleniumIfNecessary toolsDir = leftOnException' $ do
8182
let seleniumPath = [i|#{toolsDir}/selenium-server.jar|]
8283
liftIO (doesFileExist seleniumPath) >>= flip unless (downloadSelenium seleniumPath)
8384
return seleniumPath
8485
where
85-
downloadSelenium :: Constraints m => FilePath -> m ()
86+
downloadSelenium :: Constraints context m => FilePath -> m ()
8687
downloadSelenium seleniumPath = void $ do
8788
info [i|Downloading selenium-server.jar to #{seleniumPath}|]
8889
curlDownloadToPath defaultSeleniumJarUrl seleniumPath

sandwich-webdriver/src/Test/Sandwich/WebDriver/Internal/OnDemand.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ import Data.String.Interpolate
77
import Data.Text as T
88
import Test.Sandwich
99
import Test.Sandwich.WebDriver.Internal.Types
10-
import UnliftIO.Async
10+
import UnliftIO.Async (wait)
1111
import UnliftIO.Exception
1212
import UnliftIO.MVar
1313

1414

15-
getOnDemand :: forall m a. (
16-
MonadUnliftIO m, MonadLogger m
15+
getOnDemand :: forall context m a. (
16+
MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m
1717
) => MVar (OnDemand a) -> m (Either Text a) -> m a
1818
getOnDemand onDemandVar doObtain = do
1919
result <- modifyMVar onDemandVar $ \case
2020
OnDemandErrored msg -> expectationFailure (T.unpack msg)
2121
OnDemandNotStarted -> do
22-
asy <- async $ do
22+
asy <- managedAsync "webdriver-on-demand" $ do
2323
let handler :: SomeException -> m a
2424
handler e = do
2525
modifyMVar_ onDemandVar (const $ return $ OnDemandErrored [i|Got exception: #{e}|])

sandwich-webdriver/src/Test/Sandwich/WebDriver/Internal/StartWebDriver.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ import GHC.Stack
1717
import Test.Sandwich.WebDriver.Internal.Types
1818
import qualified Test.WebDriver as W
1919

20-
#ifndef mingw32_HOST_OS
21-
import Test.Sandwich.WebDriver.Internal.StartWebDriver.Xvfb
22-
#endif
20+
-- #ifndef mingw32_HOST_OS
21+
-- import Test.Sandwich.WebDriver.Internal.StartWebDriver.Xvfb
22+
-- #endif
2323

2424

2525
type Constraints m = (

sandwich-webdriver/src/Test/Sandwich/WebDriver/Video.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import Test.Sandwich.WebDriver.Video.Internal
4848
import Test.Sandwich.WebDriver.Video.Types
4949
import Test.Sandwich.WebDriver.Windows
5050
import Test.WebDriver
51+
import UnliftIO.Async
5152
import UnliftIO.Directory
5253
import UnliftIO.Exception
5354

@@ -61,6 +62,7 @@ type BaseVideoConstraints context m = (
6162
data VideoProcess = VideoProcess {
6263
-- | The process handle
6364
videoProcessProcess :: ProcessHandle
65+
, videoProcessAsync :: Async ()
6466
, videoProcessCreatedFiles :: [FilePath]
6567
}
6668
-- defaultVideoProcess :: ProcessHandle -> VideoProcess
@@ -122,15 +124,16 @@ startVideoRecording path (width, height, x, y) vs = do
122124

123125
case logToDisk vs of
124126
False -> do
125-
p <- createProcessWithLogging cp
126-
return $ VideoProcess p [videoPath]
127+
(p, asy) <- createProcessWithLogging cp
128+
return $ VideoProcess p asy [videoPath]
127129
True -> do
128130
let stdoutPath = path <.> "stdout" <.> "log"
129131
let stderrPath = path <.> "stderr" <.> "log"
130132
liftIO $ bracket (openFile stdoutPath AppendMode) hClose $ \hout ->
131133
bracket (openFile stderrPath AppendMode) hClose $ \herr -> do
132134
(_, _, _, p) <- createProcess (cp { std_out = UseHandle hout, std_err = UseHandle herr })
133-
return $ VideoProcess p [videoPath, stdoutPath, stderrPath]
135+
asy <- async $ return ()
136+
return $ VideoProcess p asy [videoPath, stdoutPath, stderrPath]
134137

135138
-- | Gracefully stop the 'ProcessHandle' returned by 'startVideoRecording'.
136139
endVideoRecording :: (

sandwich-webdriver/src/Test/Sandwich/WebDriver/Windows.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ getScreenResolution :: (MonadIO m) => TestWebDriverContext -> m (Int, Int, Int,
6969
-- getScreenResolution (TestWebDriverContext {wdWebDriver=(_, maybeXvfbSession)}) = case maybeXvfbSession of
7070
-- Nothing -> liftIO getResolution
7171
-- Just (XvfbSession {..}) -> liftIO $ getResolutionForDisplay xvfbDisplayNum
72-
getScreenResolution twdc = liftIO getResolution
72+
getScreenResolution _twdc = liftIO getResolution
7373

7474
getScreenPixelDimensions :: (WebDriver m) => Int -> Int -> m (Double, Double)
7575
getScreenPixelDimensions width height = do

sandwich-webdriver/unix-src/Test/Sandwich/WebDriver/Internal/StartWebDriver/Xvfb.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ createXvfbSession webdriverRoot w h (Fd fd) xvfbToUse xvfbOnDemand = do
101101

102102
-- Start the Xvfb session
103103
authFile <- liftIO $ writeTempFile webdriverRoot ".Xauthority" ""
104-
p <- createProcessWithLogging $ (
104+
p <- createProcessWithFileLogging $ (
105105
proc xvfb [":" <> show serverNum
106106
, "-screen", "0", [i|#{w}x#{h}x24|]
107107
, "-displayfd", [i|#{fd}|]

0 commit comments

Comments
 (0)