关于selenium:如何结合使用WebDriver和Scotty monads

How to combine WebDriver and Scotty monads

我是初学者,所以请多包涵。

我有以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{-# LANGUAGE OverloadedStrings #-}

module Lib where

import           Control.Monad.IO.Class
import           Control.Monad.Trans.Class
import           Data.Monoid               ((<>))
import qualified Data.Text                 as T
import qualified Data.Text.Lazy            as TL
import           Test.WebDriver
--import           Web.Scotty
import           Web.Scotty.Trans

firefoxConfig :: WDConfig
firefoxConfig = defaultConfig

startMyBrowser :: WD a -> IO a
startMyBrowser = runSession firefoxConfig

stopMyBrowser = closeSession

someFunc :: WD String
someFunc = do
  openPage"http://maslo.cz"
  captionElem <- findElem (ByCSS"h2")
  text <- getText captionElem
  return $ T.unpack text

helloAction :: ActionT TL.Text WD ()
helloAction = do
  a <- lift someFunc
  text $"got this for you:" <> TL.pack a

routes :: ScottyT TL.Text WD ()
routes = get"/hello" helloAction

startServer = startMyBrowser $ do
  lift $ scottyT 3000 _ routes
  stopMyBrowser

我不确定那些填充部分是否正确-应该启动Selenium会话(startMyBrowser),启动Web服务器(scottyT部分),然后在Web服务器停止运行后结束selenium会话(stopMyBrowser)。

摆弄类型后,我到达了上面的代码,似乎我只错过了一个-洞。

请,如果您可以使用它,请尝试解释您的解决方案和/或添加一些指向更多材料的链接。我很想了解那些该死的变压器。

编辑1:
错误如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  ? Couldn't match type ‘t0 m0’ with ‘WD’
    Expected type: WD ()
      Actual type: t0 m0 ()
  ? In a stmt of a 'do' block: lift $ scottyT 3000 _ routes
    In the second argument of($)’, namely
      ‘do { lift $ scottyT 3000 _ routes;
            stopMyBrowser }
    In the expression:
      startMyBrowser
      $ do { lift $ scottyT 3000 _ routes;
             stopMyBrowser }


  ? Found hole:
      _ :: WD wai-3.2.1.1:Network.Wai.Internal.Response
           -> IO wai-3.2.1.1:Network.Wai.Internal.Response
  ? In the second argument of ‘scottyT’, namely ‘_’
    In the second argument of($)’, namely ‘scottyT 3000 _ routes’
    In a stmt of a 'do' block: lift $ scottyT 3000 _ routes
  ? Relevant bindings include
      startServer :: IO () (bound at src/Lib.hs:37:1)

reddit上的好心人ForTheFunctionGod回答了它,这是:

您的问题是:

1
lift $ scottyT 3000 _ routes

由于scottyT的返回类型为

1
MonadIO n => n

您不需要抬起它-它可以放入可以执行IO操作的任何monad中。 WD是一个单子-请注意其MonadIO实例。如果返回类型为简单的IO,则只需提升scottyT

类型类,例如MonadIOMonadState等,大多数不需要手动进行计算。如果要将其嵌入到StateT s IO Int中,则需要提升一个函数来键入IO Int,而您不需要提升MonadIO m => m a类型的函数,因为StateT s IO已经是一个实例MonadIO的值,因此可以将m实例化为它。

关于孔:它必须是

类型

1
WD Response -> IO Response

进行此工作的唯一方法是使用runSession或其朋友之一。我不太了解Selenium,但是大概可以重新使用已经打开的会话的ID:

1
2
3
4
5
6
runWD :: WDSession -> WD a -> IO a

startServer = startMyBrowser $ do
   sessionID <- getSession
   scottyT 3000 (runWD sessionID) routes
   stopMyBrowser

我还没有尝试过,但是类型应该签出。希望对您有所帮助!

它确实做到了:)。