purescript-puppeteer/test/Puppeteer.Page.Event.Spec.purs

144 lines
5.7 KiB
Haskell
Raw Normal View History

2023-09-29 18:23:27 +00:00
module Puppeteer.Page.Event.Spec where
import Prelude
import Control.Monad.Rec.Class (untilJust)
import Control.Monad.ST.Class (liftST)
import Control.Monad.ST.Ref as ST.Ref
import Data.Array as Array
2023-09-29 22:32:24 +00:00
import Data.Either (Either(..))
import Data.Maybe (Maybe(..), isJust)
2023-09-29 18:23:27 +00:00
import Data.Newtype (wrap)
import Effect (Effect)
2023-09-29 22:32:24 +00:00
import Effect.Aff (Aff, delay, forkAff, joinFiber)
2023-09-29 18:23:27 +00:00
import Effect.Exception as Error
2023-09-29 22:32:24 +00:00
import Puppeteer (timeout)
2023-09-29 18:23:27 +00:00
import Puppeteer as Pup
import Puppeteer.Base (timeoutThrow)
2023-09-29 22:32:24 +00:00
import Puppeteer.Browser as Pup.Browser
import Puppeteer.HTTP.Request as Pup.HTTP.Request
2023-09-29 18:23:27 +00:00
import Puppeteer.Page as Pup.Page
import Puppeteer.Page.Event as Pup.Page.Event
import Puppeteer.Page.Event.ConsoleMessage as ConsoleMessage
2023-09-29 22:32:24 +00:00
import Puppeteer.Page.Event.Dialog as Dialog
import Puppeteer.Page.HTTP as Pup.Page.HTTP
import Test.Spec (SpecT, afterAll, aroundWith, beforeAll, describe)
2023-09-29 18:23:27 +00:00
import Test.Spec.Assertions (shouldEqual)
import Test.Util (failOnPageError, test)
scriptError :: String
scriptError = "throw new Error('eek!')"
2023-09-29 22:32:24 +00:00
pageRequestsJs :: String
pageRequestsJs =
"""
<html>
<head>
<script defer src="http://remote.org/index.js"></script>
</head>
<body></body>
</html>
"""
scriptUnblocks :: String
scriptUnblocks = "window.unblock = true"
scriptDialog :: String
scriptDialog = "alert('wow!')"
2023-09-29 18:23:27 +00:00
scriptLog :: String
scriptLog = "console.log('beak')"
2023-09-29 22:32:24 +00:00
withPage :: SpecT Aff Pup.Page Effect Unit -> SpecT Aff Pup.Browser Effect Unit
withPage =
2023-09-29 18:23:27 +00:00
let
2023-09-29 22:32:24 +00:00
withPage' spec' b = do
page <- Pup.Page.new b
spec' page
Pup.Page.close page
in
aroundWith withPage'
2023-09-29 18:23:27 +00:00
spec :: SpecT Aff Unit Effect Unit
spec =
2023-10-03 21:25:12 +00:00
beforeAll (Pup.launch_ =<< Pup.new)
2023-09-29 22:32:24 +00:00
$ afterAll Pup.Browser.close
$ do
describe "Event" do
withPage $ test "listen PageError" \p -> do
errorsST <- liftST $ ST.Ref.new []
let handle = void <<< liftST <<< flip ST.Ref.modify errorsST <<< Array.cons
listening <- Pup.Page.Event.listen Pup.Page.Event.PageError handle p
void $ Pup.Page.addScriptTag (Pup.Page.AddScriptInline scriptError) p
err <- timeoutThrow (wrap 1000.0) $ untilJust (liftST $ Array.head <$> ST.Ref.read errorsST)
Error.message err `shouldEqual` "eek!"
Pup.closeContext listening
withPage $ test "once" \p -> do
errF <- forkAff $ Pup.Page.Event.once Pup.Page.Event.PageError p
_ <- Pup.Page.addScriptTag (Pup.Page.AddScriptInline scriptError) p
err <- joinFiber errF
Error.message err `shouldEqual` "eek!"
withPage $ test "Console" \p -> failOnPageError p do
logF <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Console p
_ <- Pup.Page.addScriptTag (Pup.Page.AddScriptInline scriptLog) p
log <- joinFiber logF
ConsoleMessage.text log `shouldEqual` "beak"
ConsoleMessage.messageType log `shouldEqual` ConsoleMessage.Log
withPage $ test "Dialog" \p -> failOnPageError p do
dialogF <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Dialog p
script <- forkAff $ Pup.Page.addScriptTag (Pup.Page.AddScriptInline scriptDialog) p
dialog <- timeoutThrow (wrap 3000.0) $ joinFiber dialogF
Dialog.dismiss dialog
void $ joinFiber script
withPage $ test "Request" \p -> failOnPageError p do
let
rep = Pup.HTTP.Request.defaultRespond
{ body = Just (Left "console.log('hi')")
, contentType = Just "text/javascript"
}
let onrequest c = Pup.HTTP.Request.respond c rep
requestIntercepted <- forkAff $ Pup.Page.HTTP.interceptNextRequest onrequest p
log <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Console p
loadEvent <- forkAff $ Pup.Page.setContent pageRequestsJs Pup.Load p
timeoutThrow (wrap 1000.0) $ joinFiber requestIntercepted
timeoutThrow (wrap 1000.0) $ joinFiber loadEvent
log' <- timeoutThrow (wrap 1000.0) $ joinFiber log
ConsoleMessage.text log' `shouldEqual` "hi"
2023-09-29 18:23:27 +00:00
2023-09-29 22:32:24 +00:00
withPage $ test "DomContentLoaded, Load" \p -> failOnPageError p do
continueST <- liftST $ ST.Ref.new false
let
rep = Pup.HTTP.Request.defaultRespond
{ body = Just (Left "console.log('hi')")
, contentType = Just "text/javascript"
}
let
onrequest c r = do
untilJust do
continue <- liftST $ ST.Ref.read continueST
if not continue then delay $ wrap 100.0 else pure unit
pure $ if continue then Just unit else Nothing
Pup.HTTP.Request.respond c rep r
requestIntercepted <- forkAff $ Pup.Page.HTTP.interceptNextRequest onrequest p
f <- forkAff $ Pup.Page.setContent pageRequestsJs Pup.Load p
domContentLoaded <- forkAff $ Pup.Page.Event.once Pup.Page.Event.DomContentLoaded p
loaded <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Load p
let loaded' = timeout (wrap 100.0) $ joinFiber domContentLoaded <$ joinFiber loaded
let shouldBeLoaded yn = shouldEqual yn =<< map isJust loaded'
shouldBeLoaded false
_ <- liftST $ ST.Ref.write true continueST
timeoutThrow (wrap 100.0) $ joinFiber requestIntercepted
timeoutThrow (wrap 100.0) $ joinFiber f
shouldBeLoaded true
2023-09-29 18:23:27 +00:00
2023-09-29 22:32:24 +00:00
test "Close" \b -> do
p <- Pup.Page.new b
failOnPageError p do
closeF <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Close p
Pup.Page.close p
joinFiber closeF