【问题标题】:How to combine WebDriver and Scotty monads如何结合 WebDriver 和 Scotty monads
【发布时间】:2017-02-02 20:15:59
【问题描述】:

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

我有以下代码:

{-# 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: 以下是错误:

  • 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)

【问题讨论】:

    标签: selenium haskell selenium-webdriver scotty


    【解决方案1】:

    好心人ForTheFunctionGod reddit answered it,这里是:

    这是你的问题:

    lift $ scottyT 3000 _ routes
    

    由于scottyT的返回类型是

    MonadIO n => n
    

    您无需解除它 - 它可以适合任何可以执行 IO 操作的 monad。 WD 就是这样一个单子——注意它的 MonadIO 实例。如果scottyT 的返回类型是简单的IO,您只需要解除它。

    MonadIOMonadState 等类型的类主要消除了手动提升计算的需要。如果要将函数嵌入到StateT s IO Int 中,则需要提升函数以键入IO Int,而无需提升MonadIO m =&gt; m a 类型的函数,因为StateT s IO 已经是@ 的实例987654336@,所以m可以被实例化为它。

    关于孔:它必须是类型

    WD Response -> IO Response
    

    完成这项工作的唯一方法是使用runSession 或其朋友之一。我不太了解 Selenium,但是,大概,您可以重新使用您已经打开的会话的 id:

    runWD :: WDSession -> WD a -> IO a
    
    startServer = startMyBrowser $ do
       sessionID <- getSession
       scottyT 3000 (runWD sessionID) routes
       stopMyBrowser
    

    我还没有尝试过,但类型应该检查出来。希望对你有帮助!


    它确实做到了:)。

    【讨论】:

      猜你喜欢
      • 2018-01-27
      • 2017-11-13
      • 2015-01-29
      • 2018-11-15
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多