使用Haskell和Webdriver重用现有的Selenium会话

3

我正在尝试在REPL会话中使用Haskell的Selenium(使用webdriver包)。为了开始,我运行了以下命令:

startup :: IO ()
startup = do
  runSession chromeConfig $ do
    openPage "http://www.google.com"

新的 Chrome 浏览器打开后,导航到 Google 页面,并保持打开状态(就像我需要的那样)。现在,我想编写简单的脚本与 Google 页面交互,并从 REPL 运行它们。如何重用已经打开的会话/Chrome 浏览器呢?如果再次使用 runSession,它会打开一个新的浏览器(正如文档中所说)。如果我尝试使用 runWD,它需要一个会话作为第一个参数,但我还没有会话。有一个叫做 sessions 的值:sessions :: WebDriver wd => wd [(SessionId, Capabilities)],但要使用它,我必须在 runWD 中,并且那需要一个会话!而且,它返回一个 SessionID,我看不到任何将其转换为 WDSession 的函数。我一直在打转,任何帮助都将不胜感激。我不确定为什么会这么复杂,是因为 Selenium 还是 Haskell?
2个回答

4
WD单子是MonadIO的一个实例,这意味着你可以使用liftIO交错WebDriver操作和IO操作。这允许你读写控制台。想法是在单个runSession调用中完成所有操作。
main = runSession chromeConfig $ do
    openPage "http://www.google.com"

    liftIO $ putStrLn "Enter your search term"
    searchTerm <- liftIO getLine

    input <- findElem "#lst-ib"

    sendKeys input searchTerm
    submit input

谢谢您的回答,但我明确要寻找一种不需要在一个runSession块中编写所有代码的解决方案。 - klozovin

2

我之前从未听说过这个库,但是现在仔细研究后,我发现runSession似乎会根据给定的配置创建一个新的会话并运行WD操作。

因此,可能可以尝试以下代码:

do
  session <- runSession defaultConfig getSession
  runWD session (return ())

getSession 应该可以工作,因为 WDWDSessionState 的一个实例。 runSession 明确表示会话不会自动关闭,因此希望它可以被重复使用。


1
我确实尝试过这样的东西,但它无法在 GHCi 重新加载时生效。 - klozovin
1
@kmelva 你可以使用 "foreign-store" http://hackage.haskell.org/package/foreign-store 来使得会话在 GHCi 重新加载后仍然保持。但也许最简单的方法是从预定的文件路径读取会话(也许有一个指向该文件的环境变量,以增加一些灵活性)。 - danidiaz
@kmelva 你为什么想要/需要在重新加载后保持它的持久性?这是为了开发方便,还是目标工作流程的基本部分?看着 WDSession,我认为唯一可能难以序列化的部分是 Manager。我不熟悉 @danidiaz 提到的 foreign-store - 也许这是一个简单易行的方法来让某些东西工作。 - ryachza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接