一个haskell" withSubprocess"围绕一个阻止

时间:2016-12-08 05:13:53

标签: selenium haskell

我正在使用Haskell WebDriver selenium软件包进行测试,here

我有这个例子:

import Test.WebDriver

firefoxConfig :: WDConfig
firefoxConfig = defaultConfig

main :: IO ()
main = runSession firefoxConfig $ do                      
  openPage "http://google.com"                            
  searchInput <- findElem ( ByCSS "input[type='text']" )  
  sendKeys "Hello, World!" searchInput                    
  submit searchInput                                      
  closeSession                                            

getting started section表明selenium客户端需要selenium服务器与

进行通信
java -jar selenium-server-standalone-*.jar

如果没有它运行,你会得到这个:

ghci    λ> main
*** Exception: FailedConnectionException2 "127.0.0.1" 4444 False connect: does not exist (Connection refused)

我希望将我的整个测试脚本包装在一个函数中,该函数初始化selenium-server,记录其pid,并在运行会话后kill(pid)。也就是说,在我现有的main的持续时间内,我想调用java selenium-server,但我希望它在调用完成后立即停止存在。

在python中我通过定义__enter__()__exit__()以及其他拆解内容subprocess.Popen,记录id,杀死它,然后执行此操作调用

with Browser() as b:
  do_stuff

我理解runSession实体是我需要复制以包装启动和拆卸这样的事情,因为它将firefoxConfig $ do块作为参数并且我想这样做,太

但是,我无法理解来自询问runSession的类型,如何做出这样的事情:

ghci    λ> :t runSession
runSession
  :: Test.WebDriver.Config.WebDriverConfig conf =>
     conf -> WD a -> IO a

我想我正在寻找某种withMonad我可以应用于do。我认为语法会是某种......

import Test.WebDriver
import System.Process

firefoxConfig :: WDConfig
firefoxConfig = defaultConfig

withBrowser :: Monad a -> Monad a -- maybe this type?
withBrowser = do
  r <- createProcess (proc "java -jar selenium-server-standalone-*.jar" [])
  -- other magic here?

main :: IO ()
main = withBrowser $ runSession firefoxConfig $ do                      
  openPage "http://google.com"                            
  searchInput <- findElem ( ByCSS "input[type='text']" )  
  sendKeys "Hello, World!" searchInput                    
  submit searchInput                                      
  closeSession                                            

我将如何实现这一目标? monad是否正确?是否有更多的Haskell习惯用法或策略?

1 个答案:

答案 0 :(得分:1)

你基本上只想要来自https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Exception.html#v:bracketbracket

它允许您指定设置和拆卸IO操作以围绕第三个操作运行。它会自动处理将设置动作的输出输入主动作和拆卸动作,你的设置动作应该只给出PID的结果,这样拆解动作就会被告知要杀死什么PID。

类似的东西:

withBrowser browserAction
  = bracket startSelenium killSelenium (const browserAction)

(我假设您不希望主要操作必须为pid采用参数,因此我使用const忽略它)