module Puppeteer.Page.Spec where import Prelude import Control.Monad.Error.Class (liftMaybe) import Data.Array as Array import Data.Map as Map import Data.Maybe (Maybe(..)) import Data.Time.Duration (Milliseconds(..)) import Effect (Effect) import Effect.Aff (Aff) import Effect.Class (liftEffect) import Effect.Exception (error) import Puppeteer as Pup import Puppeteer.Base (timeout') import Puppeteer.Handle as Pup.Handle import Puppeteer.Handle.HTML as Pup.Handle.HTML import Puppeteer.Keyboard as Pup.Keyboard import Puppeteer.Page as Pup.Page import Puppeteer.Browser as Pup.Browser import Puppeteer.Page.Event (connectPageConsole) import Puppeteer.Page.Event.Spec as Spec.Page.Event import Puppeteer.Page.WaitFor as Pup.Page.WaitFor import Test.Spec (SpecT, afterAll, beforeAll, beforeWith, describe) import Test.Spec.Assertions (shouldEqual) import Test.Util (failOnPageError, test) styleFoo :: String styleFoo = """ #foo { width: 200px; } """ scriptAddBar :: String scriptAddBar = """ const bar = document.createElement('div') bar.id = 'bar' document.body.append(bar) """ simplePage :: String simplePage = """ Simple Page

Foo

Bar

Baz

""" inputPage :: String inputPage = """ Input Page """ spec :: SpecT Aff Unit Effect Unit spec = beforeAll (Pup.launch_ =<< Pup.new) $ afterAll Pup.Browser.close $ describe "Page" do test "new, close, isClosed" \b -> do p <- Pup.Page.new b let shouldBeClosed b' = shouldEqual b' <=< liftEffect <<< Pup.Page.isClosed $ p shouldBeClosed false Pup.Page.close p shouldBeClosed true test "all" \b -> do let pageCountShouldBe n = shouldEqual n <=< map Array.length <<< Pup.Page.all $ b pageCountShouldBe 1 p <- Pup.Page.new b pageCountShouldBe 2 Pup.Page.close p pageCountShouldBe 1 test "bringToFront" \b -> do p <- Pup.Page.new b Pup.Page.bringToFront p Pup.Page.close p test "setContent, content" \b -> do p <- Pup.Page.new b let html = "" Pup.Page.setContent html Pup.Load p c <- Pup.Page.content p c `shouldEqual` html Pup.Page.close p test "setViewport, viewport" \b -> do p <- Pup.Page.new b let vp = { deviceScaleFactor: Nothing , hasTouch: Nothing , height: 1200 , width: 800 , isLandscape: Nothing , isMobile: Nothing } Pup.Page.setViewport vp p vp' <- liftMaybe (error "no viewport!") $ Pup.Page.viewport p vp' `shouldEqual` vp test "title" \b -> do p <- Pup.Page.new b Pup.Page.setContent simplePage Pup.Load p shouldEqual "Simple Page" =<< Pup.Page.title p test "url" \b -> do p <- Pup.Page.new b url <- liftEffect $ Pup.Page.url p url `shouldEqual` "about:blank" test "findAll" \b -> do p <- Pup.Page.new b Pup.Page.setContent simplePage Pup.Load p let selectorCountShouldBe s n = shouldEqual n =<< Array.length <$> Pup.Page.findAll s p selectorCountShouldBe "div" 2 selectorCountShouldBe "div#foo" 1 test "findFirst" \b -> do p <- Pup.Page.new b Pup.Page.setContent simplePage Pup.Load p let maybeNoDivs = liftMaybe (error "no divs!") div <- maybeNoDivs =<< Array.head <$> Pup.Page.findAll "div" p divFF <- maybeNoDivs =<< Pup.Page.findFirst "div" p isEq <- Pup.Handle.HTML.equals div divFF shouldEqual isEq true test "addStyleTag" \b -> do p <- Pup.Page.new b liftEffect $ connectPageConsole p failOnPageError p do Pup.Page.setContent simplePage Pup.Load p _ <- Pup.Page.addStyleTag (Pup.Page.AddStyleInline styleFoo) p foo <- liftMaybe (error "#foo not found") =<< Pup.Page.findFirst "div#foo" p style <- Pup.Handle.HTML.computedStyle foo width <- liftMaybe (error "#foo doesn't have width") $ Map.lookup "width" style width `shouldEqual` "200px" Pup.Page.close p test "addScriptTag" \b -> do p <- Pup.Page.new b liftEffect $ connectPageConsole p failOnPageError p do Pup.Page.setContent simplePage Pup.Load p _ <- Pup.Page.addScriptTag (Pup.Page.AddScriptInline scriptAddBar) p _ <- timeout' (Milliseconds 5000.0) $ Pup.Page.WaitFor.selector "div#bar" p Pup.Page.close p test "keyboard" \b -> do p <- Pup.Page.new b liftEffect $ connectPageConsole p failOnPageError p do Pup.Page.setContent inputPage Pup.Load p input <- liftMaybe (error "no inputs!") =<< Pup.Page.findFirst "input" p input' <- liftMaybe (error "not an input!") =<< Pup.Handle.HTML.toHTMLInputElement input shouldEqual "" =<< Pup.Handle.HTML.value input' Pup.Handle.click input kb <- liftEffect $ Pup.Page.keyboard p Pup.Keyboard.doType "foo bar bingus bat" kb shouldEqual "foo bar bingus bat" =<< Pup.Handle.HTML.value input' Pup.Page.close p beforeWith (const $ pure unit) Spec.Page.Event.spec