如何结合 WebDriver 和 Scotty monad
How to combine WebDriver and Scotty monads
我是初学者,请多多包涵
我有以下代码:
{-# 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
),启动一个网络服务器(scottyT
部分)并在 web 之后服务器停止它应该结束 Selenium 会话 (stopMyBrowser
)。
在摆弄类型之后,我得到了上面的代码,似乎我只漏掉了一个部分——那个洞。
如果你让它工作,请尝试解释你的解决方案and/or添加一些指向更多材料的链接。我很想了解那些该死的变形金刚。
编辑 1:
以下是错误:
• 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)
好心人ForTheFunctionGod on reddit answered it,这里是:
你的问题是:
lift $ scottyT 3000 _ routes
因为 scottyT
的 return 类型是
MonadIO n => n
你不需要解除它 - 它可以适合任何可以执行 IO 操作的 monad。 WD
就是这样一个 monad - 注意它的 MonadIO
实例。如果 return 类型是简单的 IO
.
,则您只需要提升 scottyT
键入 类,如 MonadIO
、MonadState
等,大部分都避免了手动提升计算的需要。如果你想将它嵌入到 StateT s IO Int
中,你需要提升一个函数来键入 IO Int
,你不需要提升一个类型为 MonadIO m => m a
的函数,因为 [=24] =] 已经是 MonadIO
的一个实例,所以 m
可以实例化它。
至于孔:必须是
类型
WD Response -> IO Response
完成这项工作的唯一方法是使用 runSession
或其朋友之一。我不太了解 Selenium,但是,据推测,您可以 re-use 您已经打开的会话的 ID:
runWD :: WDSession -> WD a -> IO a
startServer = startMyBrowser $ do
sessionID <- getSession
scottyT 3000 (runWD sessionID) routes
stopMyBrowser
我还没有试过,但类型应该检查一下。希望对您有所帮助!
确实如此 :)。
我是初学者,请多多包涵
我有以下代码:
{-# 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
),启动一个网络服务器(scottyT
部分)并在 web 之后服务器停止它应该结束 Selenium 会话 (stopMyBrowser
)。
在摆弄类型之后,我得到了上面的代码,似乎我只漏掉了一个部分——那个洞。
如果你让它工作,请尝试解释你的解决方案and/or添加一些指向更多材料的链接。我很想了解那些该死的变形金刚。
编辑 1: 以下是错误:
• 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)
好心人ForTheFunctionGod on reddit answered it,这里是:
你的问题是:
lift $ scottyT 3000 _ routes
因为 scottyT
的 return 类型是
MonadIO n => n
你不需要解除它 - 它可以适合任何可以执行 IO 操作的 monad。 WD
就是这样一个 monad - 注意它的 MonadIO
实例。如果 return 类型是简单的 IO
.
scottyT
键入 类,如 MonadIO
、MonadState
等,大部分都避免了手动提升计算的需要。如果你想将它嵌入到 StateT s IO Int
中,你需要提升一个函数来键入 IO Int
,你不需要提升一个类型为 MonadIO m => m a
的函数,因为 [=24] =] 已经是 MonadIO
的一个实例,所以 m
可以实例化它。
至于孔:必须是
类型WD Response -> IO Response
完成这项工作的唯一方法是使用 runSession
或其朋友之一。我不太了解 Selenium,但是,据推测,您可以 re-use 您已经打开的会话的 ID:
runWD :: WDSession -> WD a -> IO a
startServer = startMyBrowser $ do
sessionID <- getSession
scottyT 3000 (runWD sessionID) routes
stopMyBrowser
我还没有试过,但类型应该检查一下。希望对您有所帮助!
确实如此 :)。