test: finish Puppeteer.Handle.Spec
This commit is contained in:
parent
7528e0d121
commit
e3eb4924d0
@ -3,19 +3,6 @@
|
|||||||
import { ElementHandle } from 'puppeteer'
|
import { ElementHandle } from 'puppeteer'
|
||||||
import { JSHandle } from 'puppeteer'
|
import { JSHandle } from 'puppeteer'
|
||||||
|
|
||||||
/** @type {<T>(_: { remoteObject: (_0: string) => T, primitive: (_0: unknown) => T }) => (_: JSHandle<unknown>) => () => T} */
|
|
||||||
export const _id =
|
|
||||||
({ remoteObject, primitive }) =>
|
|
||||||
h =>
|
|
||||||
() => {
|
|
||||||
const oid = h.remoteObject().objectId
|
|
||||||
if (oid) {
|
|
||||||
return remoteObject(oid)
|
|
||||||
} else {
|
|
||||||
return primitive(h.remoteObject().value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => Promise<Array<ElementHandle<Node>>>} */
|
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => Promise<Array<ElementHandle<Node>>>} */
|
||||||
export const _find = s => h => h.$$(s)
|
export const _find = s => h => h.$$(s)
|
||||||
|
|
||||||
@ -28,9 +15,6 @@ export const _boundingBox = h => h.boundingBox()
|
|||||||
/** @type {(_: ElementHandle<HTMLElement>) => Promise<unknown>} */
|
/** @type {(_: ElementHandle<HTMLElement>) => Promise<unknown>} */
|
||||||
export const _boxModel = h => h.boxModel()
|
export const _boxModel = h => h.boxModel()
|
||||||
|
|
||||||
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
|
|
||||||
export const _focus = h => h.focus()
|
|
||||||
|
|
||||||
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
|
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
|
||||||
export const _hover = h => h.hover()
|
export const _hover = h => h.hover()
|
||||||
|
|
||||||
@ -43,9 +27,6 @@ export const _isVisible = h => h.isVisible()
|
|||||||
/** @type {(_: ElementHandle<HTMLElement>) => Promise<boolean>} */
|
/** @type {(_: ElementHandle<HTMLElement>) => Promise<boolean>} */
|
||||||
export const _isIntersectingViewport = h => h.isIntersectingViewport()
|
export const _isIntersectingViewport = h => h.isIntersectingViewport()
|
||||||
|
|
||||||
/** @type {(_: ElementHandle<HTMLElement> | {x: number, y: number}) => (_: ElementHandle<HTMLElement>) => Promise<void>} */
|
|
||||||
export const _drag = c => h => h.drag(c).then(() => {})
|
|
||||||
|
|
||||||
/** @type {(_: ElementHandle<HTMLElement>) => (_: ElementHandle<HTMLElement>) => Promise<void>} */
|
/** @type {(_: ElementHandle<HTMLElement>) => (_: ElementHandle<HTMLElement>) => Promise<void>} */
|
||||||
export const _drop = from => to => to.drop(from)
|
export const _drop = from => to => to.drop(from)
|
||||||
|
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
module Puppeteer.Handle
|
module Puppeteer.Handle
|
||||||
( module X
|
( module X
|
||||||
, id
|
, findFirst
|
||||||
, HandleId(..)
|
|
||||||
, findOne
|
|
||||||
, findAll
|
, findAll
|
||||||
, click
|
, click
|
||||||
, clone
|
, clone
|
||||||
, boundingBox
|
, boundingBox
|
||||||
, boxModel
|
, boxModel
|
||||||
, focus
|
|
||||||
, hover
|
, hover
|
||||||
, isHidden
|
, isHidden
|
||||||
, isVisible
|
, isVisible
|
||||||
, isIntersectingViewport
|
, isIntersectingViewport
|
||||||
, dragToElement
|
|
||||||
, dragToPoint
|
|
||||||
, drop
|
, drop
|
||||||
, screenshot
|
, screenshot
|
||||||
, scrollIntoView
|
, scrollIntoView
|
||||||
@ -34,24 +29,19 @@ import Control.Promise as Promise
|
|||||||
import Data.Array (head)
|
import Data.Array (head)
|
||||||
import Data.Map (Map)
|
import Data.Map (Map)
|
||||||
import Data.Maybe (Maybe(..))
|
import Data.Maybe (Maybe(..))
|
||||||
import Data.Maybe as Maybe
|
|
||||||
import Data.Nullable (Nullable)
|
import Data.Nullable (Nullable)
|
||||||
import Data.Nullable as Nullable
|
import Data.Nullable as Nullable
|
||||||
import Data.Time (Millisecond)
|
|
||||||
import Effect (Effect)
|
import Effect (Effect)
|
||||||
import Effect.Aff (Aff)
|
import Effect.Aff (Aff)
|
||||||
import Foreign (Foreign, unsafeToForeign)
|
import Foreign (Foreign, unsafeToForeign)
|
||||||
import Node.Buffer (Buffer)
|
import Node.Buffer (Buffer)
|
||||||
import Node.Path (FilePath)
|
import Node.Path (FilePath)
|
||||||
import Partial.Unsafe (unsafePartial)
|
|
||||||
import Puppeteer.Base (Handle) as X
|
import Puppeteer.Base (Handle) as X
|
||||||
import Puppeteer.Base (class IsElement, Handle)
|
import Puppeteer.Base (class IsElement, Handle)
|
||||||
import Puppeteer.Cartesian (Coord, BoxModel, BoundingBox)
|
import Puppeteer.Cartesian (Coord)
|
||||||
import Puppeteer.Eval as Eval
|
import Puppeteer.Eval as Eval
|
||||||
import Puppeteer.FFI as FFI
|
import Puppeteer.FFI as FFI
|
||||||
import Puppeteer.Keyboard (Key)
|
|
||||||
import Puppeteer.Screenshot (ScreenshotOptions, prepareScreenshotOptions)
|
import Puppeteer.Screenshot (ScreenshotOptions, prepareScreenshotOptions)
|
||||||
import Puppeteer.Screenshot as Screenshot
|
|
||||||
import Puppeteer.Selector (class Selector)
|
import Puppeteer.Selector (class Selector)
|
||||||
import Puppeteer.Selector as Selector
|
import Puppeteer.Selector as Selector
|
||||||
import Simple.JSON (class ReadForeign, class WriteForeign, writeJSON)
|
import Simple.JSON (class ReadForeign, class WriteForeign, writeJSON)
|
||||||
@ -59,33 +49,14 @@ import Unsafe.Coerce (unsafeCoerce)
|
|||||||
import Web.HTML (HTMLElement)
|
import Web.HTML (HTMLElement)
|
||||||
import Web.HTML as HTML
|
import Web.HTML as HTML
|
||||||
|
|
||||||
id :: forall a. Handle a -> Effect HandleId
|
|
||||||
id = _id { remoteObject: HandleObject, primitive: HandlePrimitive }
|
|
||||||
|
|
||||||
data HandleId
|
|
||||||
= HandleObject String
|
|
||||||
| HandlePrimitive Foreign
|
|
||||||
|
|
||||||
instance eqHandleId :: Eq HandleId where
|
|
||||||
eq (HandleObject ida) (HandleObject idb) = ida == idb
|
|
||||||
eq (HandlePrimitive va) (HandlePrimitive vb) = writeJSON va == writeJSON vb
|
|
||||||
eq _ _ = false
|
|
||||||
|
|
||||||
instance showHandleId :: Show HandleId where
|
|
||||||
show (HandleObject ida) = "HandleObject " <> show ida
|
|
||||||
show (HandlePrimitive va) = "HandlePrimitive " <> (show $ writeJSON va)
|
|
||||||
|
|
||||||
foreign import _id :: forall a. { remoteObject :: String -> HandleId, primitive :: Foreign -> HandleId } -> Handle a -> Effect HandleId
|
|
||||||
foreign import _find :: forall a b. String -> Handle a -> Promise (Array (Handle b))
|
foreign import _find :: forall a b. String -> Handle a -> Promise (Array (Handle b))
|
||||||
foreign import _click :: forall a. Handle a -> Promise Unit
|
foreign import _click :: forall a. Handle a -> Promise Unit
|
||||||
foreign import _boundingBox :: forall a. Handle a -> Promise (Nullable Foreign)
|
foreign import _boundingBox :: forall a. Handle a -> Promise (Nullable Foreign)
|
||||||
foreign import _boxModel :: forall a. Handle a -> Promise (Nullable Foreign)
|
foreign import _boxModel :: forall a. Handle a -> Promise (Nullable Foreign)
|
||||||
foreign import _focus :: forall a. Handle a -> Promise Unit
|
|
||||||
foreign import _hover :: forall a. Handle a -> Promise Unit
|
foreign import _hover :: forall a. Handle a -> Promise Unit
|
||||||
foreign import _isHidden :: forall a. Handle a -> Promise Boolean
|
foreign import _isHidden :: forall a. Handle a -> Promise Boolean
|
||||||
foreign import _isVisible :: forall a. Handle a -> Promise Boolean
|
foreign import _isVisible :: forall a. Handle a -> Promise Boolean
|
||||||
foreign import _isIntersectingViewport :: forall a. Handle a -> Promise Boolean
|
foreign import _isIntersectingViewport :: forall a. Handle a -> Promise Boolean
|
||||||
foreign import _drag :: forall a. Foreign -> Handle a -> Promise Unit
|
|
||||||
foreign import _drop :: forall a b. Handle a -> Handle b -> Promise Unit
|
foreign import _drop :: forall a b. Handle a -> Handle b -> Promise Unit
|
||||||
foreign import _screenshot :: forall a. Foreign -> Handle a -> Promise Buffer
|
foreign import _screenshot :: forall a. Foreign -> Handle a -> Promise Buffer
|
||||||
foreign import _scrollIntoView :: forall a. Handle a -> Promise Unit
|
foreign import _scrollIntoView :: forall a. Handle a -> Promise Unit
|
||||||
@ -99,8 +70,8 @@ foreign import _getProperties :: forall a. Handle a -> Promise (Array { k :: Str
|
|||||||
clone :: forall a. WriteForeign a => ReadForeign a => Handle a -> Aff a
|
clone :: forall a. WriteForeign a => ReadForeign a => Handle a -> Aff a
|
||||||
clone = Promise.toAff <<< _clone
|
clone = Promise.toAff <<< _clone
|
||||||
|
|
||||||
findOne :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Maybe (Handle b))
|
findFirst :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Maybe (Handle b))
|
||||||
findOne q h = do
|
findFirst q h = do
|
||||||
els <- findAll q h
|
els <- findAll q h
|
||||||
pure $ head els
|
pure $ head els
|
||||||
|
|
||||||
@ -116,9 +87,6 @@ boundingBox = map Nullable.toMaybe <<< Promise.toAff <<< _boundingBox
|
|||||||
boxModel :: forall a. IsElement a => Handle a -> Aff (Maybe Foreign)
|
boxModel :: forall a. IsElement a => Handle a -> Aff (Maybe Foreign)
|
||||||
boxModel = map Nullable.toMaybe <<< Promise.toAff <<< _boxModel
|
boxModel = map Nullable.toMaybe <<< Promise.toAff <<< _boxModel
|
||||||
|
|
||||||
focus :: forall a. IsElement a => Handle a -> Aff Unit
|
|
||||||
focus = Promise.toAff <<< _focus
|
|
||||||
|
|
||||||
hover :: forall a. IsElement a => Handle a -> Aff Unit
|
hover :: forall a. IsElement a => Handle a -> Aff Unit
|
||||||
hover = Promise.toAff <<< _hover
|
hover = Promise.toAff <<< _hover
|
||||||
|
|
||||||
@ -131,12 +99,6 @@ isVisible = Promise.toAff <<< _isVisible
|
|||||||
isIntersectingViewport :: forall a. IsElement a => Handle a -> Aff Boolean
|
isIntersectingViewport :: forall a. IsElement a => Handle a -> Aff Boolean
|
||||||
isIntersectingViewport = Promise.toAff <<< _isIntersectingViewport
|
isIntersectingViewport = Promise.toAff <<< _isIntersectingViewport
|
||||||
|
|
||||||
dragToPoint :: forall a. IsElement a => Coord -> Handle a -> Aff Unit
|
|
||||||
dragToPoint c = Promise.toAff <<< _drag (unsafeToForeign $ c)
|
|
||||||
|
|
||||||
dragToElement :: forall a b. IsElement a => IsElement b => Handle a -> Handle b -> Aff Unit
|
|
||||||
dragToElement from to = Promise.toAff $ _drag (unsafeToForeign from) to
|
|
||||||
|
|
||||||
drop :: forall a b. IsElement a => IsElement b => Handle a -> Handle b -> Aff Unit
|
drop :: forall a b. IsElement a => IsElement b => Handle a -> Handle b -> Aff Unit
|
||||||
drop a = Promise.toAff <<< _drop a
|
drop a = Promise.toAff <<< _drop a
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
module Puppeteer.Screenshot (ScreenshotFormat(..), ScreenshotOptions, prepareScreenshotOptions) where
|
module Puppeteer.Screenshot
|
||||||
|
( ScreenshotFormat(..)
|
||||||
|
, ScreenshotOptions
|
||||||
|
, prepareScreenshotOptions
|
||||||
|
, defaultScreenshot
|
||||||
|
) where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
import Data.Maybe (Maybe)
|
import Data.Maybe (Maybe(..))
|
||||||
import Foreign (Foreign)
|
import Foreign (Foreign)
|
||||||
import Puppeteer.FFI as FFI
|
import Puppeteer.FFI as FFI
|
||||||
import Simple.JSON (writeImpl)
|
import Simple.JSON (writeImpl)
|
||||||
@ -30,6 +35,16 @@ type ScreenshotOptions =
|
|||||||
, format :: Maybe ScreenshotFormat
|
, format :: Maybe ScreenshotFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultScreenshot :: ScreenshotOptions
|
||||||
|
defaultScreenshot =
|
||||||
|
{ captureBeyondViewport: Nothing
|
||||||
|
, fullPage: Nothing
|
||||||
|
, omitBackground: Nothing
|
||||||
|
, optimizeForSpeed: Nothing
|
||||||
|
, quality: Nothing
|
||||||
|
, format: Nothing
|
||||||
|
}
|
||||||
|
|
||||||
prepareScreenshotOptions :: ScreenshotOptions -> Foreign
|
prepareScreenshotOptions :: ScreenshotOptions -> Foreign
|
||||||
prepareScreenshotOptions
|
prepareScreenshotOptions
|
||||||
{ captureBeyondViewport
|
{ captureBeyondViewport
|
||||||
|
@ -19,14 +19,14 @@ instance selectorArraySel :: Selector s e => Selector (Array s) e where
|
|||||||
toCSS = map toCSS >>> String.joinWith ", "
|
toCSS = map toCSS >>> String.joinWith ", "
|
||||||
|
|
||||||
instance selectorHas :: Selector s e => Selector (Has s) e where
|
instance selectorHas :: Selector s e => Selector (Has s) e where
|
||||||
toCSS (HasId s id) = toCSS s <> "#" <> id
|
toCSS (HasId s' id) = toCSS s' <> "#" <> id
|
||||||
toCSS (HasClass s cls) = toCSS s <> "." <> cls
|
toCSS (HasClass s' cls) = toCSS s' <> "." <> cls
|
||||||
toCSS (HasAttrEqualTo s k v) = toCSS s <> "[" <> show k <> "=" <> show v <> "]"
|
toCSS (HasAttrEqualTo s' k v) = toCSS s' <> "[" <> k <> " = " <> show v <> "]"
|
||||||
toCSS (HasAttrListContaining s k v) = toCSS s <> "[" <> show k <> "~=" <> show v <> "]"
|
toCSS (HasAttrListContaining s' k v) = toCSS s' <> "[" <> k <> " ~= " <> show v <> "]"
|
||||||
toCSS (HasAttrStartsWith s k v) = toCSS s <> "[" <> show k <> "^=" <> show v <> "]"
|
toCSS (HasAttrStartsWith s' k v) = toCSS s' <> "[" <> k <> " ^= " <> show v <> "]"
|
||||||
toCSS (HasAttrEndsWith s k v) = toCSS s <> "[" <> show k <> "$=" <> show v <> "]"
|
toCSS (HasAttrEndsWith s' k v) = toCSS s' <> "[" <> k <> " $= " <> show v <> "]"
|
||||||
toCSS (HasAttrContaining s k v) = toCSS s <> "[" <> show k <> "*=" <> show v <> "]"
|
toCSS (HasAttrContaining s' k v) = toCSS s' <> "[" <> k <> " *= " <> show v <> "]"
|
||||||
toCSS (HasAttr s k) = toCSS s <> "[" <> show k <> "]"
|
toCSS (HasAttr s' k) = toCSS s' <> "[" <> k <> "]"
|
||||||
|
|
||||||
instance selectorSelectorRefine :: Selector s e => Selector (SelectorRefine s) e where
|
instance selectorSelectorRefine :: Selector s e => Selector (SelectorRefine s) e where
|
||||||
toCSS (SelectorActive a) = toCSS a <> ":active"
|
toCSS (SelectorActive a) = toCSS a <> ":active"
|
||||||
@ -263,9 +263,9 @@ instance selectorTagH6 :: Selector TagH6 HTMLHeadingElement where
|
|||||||
toCSS _ = "h6"
|
toCSS _ = "h6"
|
||||||
|
|
||||||
--| HTMLHtmlElement
|
--| HTMLHtmlElement
|
||||||
data TagHtml = TagHtml
|
data TagHtmlRoot = TagHtmlRoot
|
||||||
|
|
||||||
instance selectorTagHtml :: Selector TagHtml HTMLHtmlElement where
|
instance selectorTagHtmlRoot :: Selector TagHtmlRoot HTMLHtmlElement where
|
||||||
toCSS _ = "html"
|
toCSS _ = "html"
|
||||||
|
|
||||||
--| HTMLIFrameElement
|
--| HTMLIFrameElement
|
||||||
@ -502,12 +502,32 @@ data TagVideo = TagVideo
|
|||||||
instance selectorTagVideo :: Selector TagVideo HTMLVideoElement where
|
instance selectorTagVideo :: Selector TagVideo HTMLVideoElement where
|
||||||
toCSS _ = "video"
|
toCSS _ = "video"
|
||||||
|
|
||||||
|
--| HTMLElement
|
||||||
|
data TagHtml
|
||||||
|
= TagI
|
||||||
|
| TagB
|
||||||
|
| TagS
|
||||||
|
|
||||||
|
instance selectorTagHtml :: Selector TagHtml HTMLElement where
|
||||||
|
toCSS TagI = "i"
|
||||||
|
toCSS TagB = "b"
|
||||||
|
toCSS TagS = "s"
|
||||||
|
|
||||||
wild :: TagWild
|
wild :: TagWild
|
||||||
wild = TagWild
|
wild = TagWild
|
||||||
|
|
||||||
none :: TagNone
|
none :: TagNone
|
||||||
none = TagNone
|
none = TagNone
|
||||||
|
|
||||||
|
i :: TagHtml
|
||||||
|
i = TagI
|
||||||
|
|
||||||
|
b :: TagHtml
|
||||||
|
b = TagB
|
||||||
|
|
||||||
|
s :: TagHtml
|
||||||
|
s = TagS
|
||||||
|
|
||||||
anchor :: TagAnchor
|
anchor :: TagAnchor
|
||||||
anchor = TagAnchor
|
anchor = TagAnchor
|
||||||
|
|
||||||
@ -571,8 +591,8 @@ h5 = TagH5
|
|||||||
h6 :: TagH6
|
h6 :: TagH6
|
||||||
h6 = TagH6
|
h6 = TagH6
|
||||||
|
|
||||||
html :: TagHtml
|
html :: TagHtmlRoot
|
||||||
html = TagHtml
|
html = TagHtmlRoot
|
||||||
|
|
||||||
iframe :: TagIFrame
|
iframe :: TagIFrame
|
||||||
iframe = TagIFrame
|
iframe = TagIFrame
|
||||||
|
@ -24,7 +24,8 @@ import Effect.Aff (Aff)
|
|||||||
import Effect.Unsafe (unsafePerformEffect)
|
import Effect.Unsafe (unsafePerformEffect)
|
||||||
import Foreign (Foreign)
|
import Foreign (Foreign)
|
||||||
import Puppeteer.Base (Puppeteer)
|
import Puppeteer.Base (Puppeteer)
|
||||||
import Puppeteer.Base (class BrowserAccess, class IsElement, class PageProducer, class Plugin, Browser, BrowserContext, Context(..), Frame, Handle, Keyboard, LifecycleEvent(..), Page, Puppeteer, Request, Response, URL, Viewport, closeContext, prepareLifecycleEvent, timeout, use) as X
|
import Puppeteer.Base as X
|
||||||
|
import Puppeteer.Screenshot as X
|
||||||
import Puppeteer.Browser (Browser)
|
import Puppeteer.Browser (Browser)
|
||||||
import Puppeteer.Browser as Browser
|
import Puppeteer.Browser as Browser
|
||||||
import Puppeteer.FFI as FFI
|
import Puppeteer.FFI as FFI
|
||||||
|
216
test/Puppeteer.Handle.Spec.purs
Normal file
216
test/Puppeteer.Handle.Spec.purs
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
module Puppeteer.Handle.Spec where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Control.Monad.Error.Class (liftMaybe)
|
||||||
|
import Control.Monad.Rec.Class (Step(..), tailRecM)
|
||||||
|
import Data.Array as Array
|
||||||
|
import Data.Map as Map
|
||||||
|
import Data.Set as Set
|
||||||
|
import Data.Maybe (isJust)
|
||||||
|
import Data.Newtype (wrap)
|
||||||
|
import Data.Tuple.Nested ((/\))
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Aff (Aff, forkAff, joinFiber)
|
||||||
|
import Effect.Class (liftEffect)
|
||||||
|
import Effect.Exception (error)
|
||||||
|
import Node.Buffer as Buffer
|
||||||
|
import Puppeteer as Pup
|
||||||
|
import Puppeteer.Base (timeoutThrow)
|
||||||
|
import Puppeteer.Browser as Pup.Browser
|
||||||
|
import Puppeteer.Eval as Pup.Eval
|
||||||
|
import Puppeteer.Handle as Pup.Handle
|
||||||
|
import Puppeteer.Handle.HTML as Pup.Handle.HTML
|
||||||
|
import Puppeteer.Page as Pup.Page
|
||||||
|
import Puppeteer.Page.Event as Pup.Page.Event
|
||||||
|
import Puppeteer.Page.Event.ConsoleMessage as ConsoleMessage
|
||||||
|
import Puppeteer.Selector as S
|
||||||
|
import Test.Spec (SpecT, aroundWith, describe)
|
||||||
|
import Test.Spec.Assertions (shouldEqual)
|
||||||
|
import Test.Util (failOnPageError, test)
|
||||||
|
|
||||||
|
html :: String
|
||||||
|
html =
|
||||||
|
"""
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Handle test</title>
|
||||||
|
<script>
|
||||||
|
document.addEventListener(
|
||||||
|
'DOMContentLoaded',
|
||||||
|
() => {
|
||||||
|
const selectme = document.querySelector('#selectme')
|
||||||
|
const clickme = document.querySelector('#clickme')
|
||||||
|
const dragme = document.querySelector('#dragme')
|
||||||
|
const dropme = document.querySelector('#dropme')
|
||||||
|
|
||||||
|
selectme.addEventListener('change', e => {
|
||||||
|
console.log('select(' + e.target.value + ')')
|
||||||
|
})
|
||||||
|
|
||||||
|
clickme.addEventListener('click', () => {
|
||||||
|
console.log('clicked!')
|
||||||
|
})
|
||||||
|
|
||||||
|
dragme.addEventListener('drag', () => {
|
||||||
|
console.log('drag')
|
||||||
|
})
|
||||||
|
|
||||||
|
dragme.addEventListener('dragend', () => {
|
||||||
|
console.log('dragend')
|
||||||
|
})
|
||||||
|
|
||||||
|
dropme.addEventListener('dragenter', e => {
|
||||||
|
e.preventDefault()
|
||||||
|
console.log('dragenter')
|
||||||
|
})
|
||||||
|
|
||||||
|
dropme.addEventListener('dragover', e => {
|
||||||
|
e.preventDefault()
|
||||||
|
console.log('dragover')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="foo">
|
||||||
|
<input type="text" id="input-a"></input>
|
||||||
|
<input type="text" id="input-b"></input>
|
||||||
|
<input type="file" id="input-c"></input>
|
||||||
|
<select id="selectme">
|
||||||
|
<option value="foo">foo</option>
|
||||||
|
<option value="bar">bar</option>
|
||||||
|
<option value="baz">baz</option>
|
||||||
|
</select>
|
||||||
|
<button id="clickme">click me!</button>
|
||||||
|
<div id="bar">
|
||||||
|
<span class="text">Hello, world!</span>
|
||||||
|
<i style="visibility: hidden;" id="111abc222" name="frankie hobarth" cheeses="muenster cheddar brie"></i>
|
||||||
|
</div>
|
||||||
|
<div style="height: 100px; width: 100px; border: black solid 1px;" id="dragme" draggable="true"></div>
|
||||||
|
<div style="height: 100px; width: 100px; border: red solid 1px;" id="dropme"></div>
|
||||||
|
<div id="gone" style="position: fixed; top: 0; left: -100px; width: 10px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
withPage :: SpecT Aff Pup.Page Effect Unit -> SpecT Aff Unit Effect Unit
|
||||||
|
withPage =
|
||||||
|
let
|
||||||
|
withPage' spec' _ = do
|
||||||
|
pup <- Pup.puppeteer unit
|
||||||
|
b <- Pup.launch_ pup
|
||||||
|
page <- Pup.Page.new b
|
||||||
|
failOnPageError page do
|
||||||
|
-- Pup.Page.Event.connectPageConsole page
|
||||||
|
Pup.Page.setContent html Pup.Load page
|
||||||
|
spec' page
|
||||||
|
Pup.Browser.close b
|
||||||
|
in
|
||||||
|
aroundWith withPage'
|
||||||
|
|
||||||
|
spec :: SpecT Aff Unit Effect Unit
|
||||||
|
spec = withPage $ describe "Handle" do
|
||||||
|
test "findAll" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
divs <- Pup.Handle.findAll S.div body
|
||||||
|
Array.length divs `shouldEqual` 5
|
||||||
|
|
||||||
|
let
|
||||||
|
findFirstOrHtmlEquals p = do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
foo <- liftMaybe (error "div#foo not found!") =<< Pup.Handle.findFirst (S.div `S.hasId` "foo") body
|
||||||
|
firstDiv <- liftMaybe (error "no divs not found!") =<< Pup.Handle.findFirst S.div body
|
||||||
|
shouldEqual true =<< Pup.Handle.HTML.equals foo firstDiv
|
||||||
|
let
|
||||||
|
i =
|
||||||
|
S.i
|
||||||
|
`S.hasAttrStartsWith` ("id" /\ "111")
|
||||||
|
`S.hasAttrEndsWith` ("id" /\ "222")
|
||||||
|
`S.hasAttrContaining` ("id" /\ "abc")
|
||||||
|
`S.hasAttrListContaining` ("cheeses" /\ "muenster")
|
||||||
|
void $ liftMaybe (error "i not found!") =<< Pup.Handle.findFirst i body
|
||||||
|
|
||||||
|
test "findFirst" findFirstOrHtmlEquals
|
||||||
|
|
||||||
|
let
|
||||||
|
clickOrTap f p =
|
||||||
|
do
|
||||||
|
log <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Console p
|
||||||
|
button <- liftMaybe (error "button#clickme not found!") =<< Pup.Page.findFirst (S.button `S.hasId` "clickme") p
|
||||||
|
f button
|
||||||
|
log' <- timeoutThrow (wrap 100.0) $ joinFiber log
|
||||||
|
ConsoleMessage.text log' `shouldEqual` "clicked!"
|
||||||
|
|
||||||
|
test "click" $ clickOrTap Pup.Handle.click
|
||||||
|
test "tap" $ clickOrTap Pup.Handle.tap
|
||||||
|
|
||||||
|
test "clone" \p -> do
|
||||||
|
aHandle <- Pup.Eval.unsafeRunJsHandle0 "() => ({a: 1, b: 'foo', c: ['a']})" p
|
||||||
|
a <- Pup.Handle.clone aHandle
|
||||||
|
a `shouldEqual` { a: 1, b: "foo", c: [ "a" ] }
|
||||||
|
|
||||||
|
test "hover" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
shouldEqual false <=< map isJust <<< Pup.Handle.findFirst (S.hover S.button) $ body
|
||||||
|
btn <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst S.button body
|
||||||
|
Pup.Handle.hover btn
|
||||||
|
shouldEqual true <=< map isJust <<< Pup.Handle.findFirst (S.hover S.button) $ body
|
||||||
|
|
||||||
|
test "isHidden" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
shouldEqual false <=< map isJust <<< Pup.Handle.findFirst (S.hover S.button) $ body
|
||||||
|
i <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst S.i body
|
||||||
|
shouldEqual true =<< Pup.Handle.isHidden i
|
||||||
|
|
||||||
|
test "isVisible" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
shouldEqual false <=< map isJust <<< Pup.Handle.findFirst (S.hover S.button) $ body
|
||||||
|
i <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst S.i body
|
||||||
|
div <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst S.div body
|
||||||
|
shouldEqual false =<< Pup.Handle.isVisible i
|
||||||
|
shouldEqual true =<< Pup.Handle.isVisible div
|
||||||
|
|
||||||
|
test "isIntersectingViewport" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
shouldEqual false <=< map isJust <<< Pup.Handle.findFirst (S.hover S.button) $ body
|
||||||
|
foo <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst (S.div `S.hasId` "foo") body
|
||||||
|
gone <- liftMaybe (error "input not found!") =<< Pup.Handle.findFirst (S.div `S.hasId` "gone") body
|
||||||
|
shouldEqual true =<< Pup.Handle.isIntersectingViewport foo
|
||||||
|
shouldEqual false =<< Pup.Handle.isIntersectingViewport gone
|
||||||
|
|
||||||
|
test "dragToElement" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
dragme <- liftMaybe (error "dragme not found!") =<< Pup.Handle.findFirst (S.div `S.hasId` "dragme") body
|
||||||
|
dropme <- liftMaybe (error "dropme not found!") =<< Pup.Handle.findFirst (S.div `S.hasId` "dropme") body
|
||||||
|
let
|
||||||
|
collectLogs as = do
|
||||||
|
log <- Pup.Page.Event.once Pup.Page.Event.Console p
|
||||||
|
let as' = as <> [ log ]
|
||||||
|
pure $ if Array.length as' == 4 then Done as' else Loop as'
|
||||||
|
logs <- forkAff $ tailRecM collectLogs []
|
||||||
|
Pup.Handle.drop dragme dropme
|
||||||
|
logs' <- timeoutThrow (wrap 1000.0) $ joinFiber logs
|
||||||
|
(ConsoleMessage.text <$> logs') `shouldEqual` [ "drag", "dragenter", "dragover", "dragend" ]
|
||||||
|
|
||||||
|
test "screenshot" \p -> do
|
||||||
|
body <- liftMaybe (error "body not found!") =<< Pup.Page.findFirst S.body p
|
||||||
|
buf <- Pup.Handle.screenshot Pup.defaultScreenshot body
|
||||||
|
void $ liftEffect $ Buffer.size buf
|
||||||
|
|
||||||
|
test "select" \p -> do
|
||||||
|
sel <- liftMaybe (error "select not found!") =<< Pup.Page.findFirst S.select p
|
||||||
|
log <- forkAff $ Pup.Page.Event.once Pup.Page.Event.Console p
|
||||||
|
Pup.Handle.select [ "foo" ] sel
|
||||||
|
log' <- timeoutThrow (wrap 1000.0) $ joinFiber log
|
||||||
|
ConsoleMessage.text log' `shouldEqual` "select(foo)"
|
||||||
|
|
||||||
|
test "getProperties" \p -> do
|
||||||
|
o <- Pup.Eval.unsafeRunJsHandle0 "() => ({foo: 'foo', bar: 'bar', baz: 'baz'})" p
|
||||||
|
props <- Pup.Handle.getProperties o
|
||||||
|
Map.keys props `shouldEqual` Set.fromFoldable [ "foo", "bar", "baz" ]
|
||||||
|
|
||||||
|
describe "HTML" do
|
||||||
|
test "equals" findFirstOrHtmlEquals
|
@ -19,7 +19,8 @@ spec = describe "Selector" do
|
|||||||
let
|
let
|
||||||
s = S.toCSS
|
s = S.toCSS
|
||||||
$ isButton
|
$ isButton
|
||||||
$ S.button
|
$
|
||||||
|
S.button
|
||||||
`S.hasId` "foo"
|
`S.hasId` "foo"
|
||||||
`S.hasClass` "bar"
|
`S.hasClass` "bar"
|
||||||
`S.hasAttr` "disabled"
|
`S.hasAttr` "disabled"
|
||||||
@ -29,10 +30,24 @@ spec = describe "Selector" do
|
|||||||
`S.hasAttrEndsWith` ("name" /\ "johnson")
|
`S.hasAttrEndsWith` ("name" /\ "johnson")
|
||||||
`S.isDescendantOf` S.body
|
`S.isDescendantOf` S.body
|
||||||
`S.isChildOf` S.html
|
`S.isChildOf` S.html
|
||||||
|
`S.not` (S.enabled S.none)
|
||||||
|
`S.has` (S.div `S.isChildOf` S.none)
|
||||||
|
# S.focus
|
||||||
|
# S.disabled
|
||||||
|
# S.active
|
||||||
let
|
let
|
||||||
expected = fold
|
expected = fold
|
||||||
[ "html > body button"
|
[ "html > body button"
|
||||||
, "#foo.bar"
|
, "#foo.bar"
|
||||||
, """["disabled"]["ident"*="abc"]["feet"~="left_foot"]["name"^="frank"]["name"$="johnson"]"""
|
, """[disabled]"""
|
||||||
|
, """[ident *= "abc"]"""
|
||||||
|
, """[feet ~= "left_foot"]"""
|
||||||
|
, """[name ^= "frank"]"""
|
||||||
|
, """[name $= "johnson"]"""
|
||||||
|
, ":not(:enabled)"
|
||||||
|
, ":has( > div)"
|
||||||
|
, ":focus"
|
||||||
|
, ":disabled"
|
||||||
|
, ":active"
|
||||||
]
|
]
|
||||||
s `shouldEqual` expected
|
s `shouldEqual` expected
|
@ -9,6 +9,7 @@ import Effect.Class (liftEffect)
|
|||||||
import Puppeteer as Pup
|
import Puppeteer as Pup
|
||||||
import Puppeteer.Browser as Pup.Browser
|
import Puppeteer.Browser as Pup.Browser
|
||||||
import Puppeteer.Browser.Spec as Spec.Browser
|
import Puppeteer.Browser.Spec as Spec.Browser
|
||||||
|
import Puppeteer.Handle.Spec as Spec.Handle
|
||||||
import Puppeteer.Page.Spec as Spec.Page
|
import Puppeteer.Page.Spec as Spec.Page
|
||||||
import Puppeteer.Selector.Spec as Spec.Selector
|
import Puppeteer.Selector.Spec as Spec.Selector
|
||||||
import Test.Spec (SpecT, describe, mapSpecTree, parallel)
|
import Test.Spec (SpecT, describe, mapSpecTree, parallel)
|
||||||
@ -37,4 +38,5 @@ spec = describe "Puppeteer" do
|
|||||||
|
|
||||||
Spec.Browser.spec
|
Spec.Browser.spec
|
||||||
Spec.Page.spec
|
Spec.Page.spec
|
||||||
|
Spec.Handle.spec
|
||||||
mapSpecTree (pure <<< unwrap) identity Spec.Selector.spec
|
mapSpecTree (pure <<< unwrap) identity Spec.Selector.spec
|
||||||
|
@ -4,22 +4,17 @@ import Prelude
|
|||||||
|
|
||||||
import Data.Array as Array
|
import Data.Array as Array
|
||||||
import Data.Filterable (filterMap)
|
import Data.Filterable (filterMap)
|
||||||
import Data.Foldable (findMap, fold, foldl)
|
import Data.Foldable (foldl)
|
||||||
import Data.Maybe (Maybe(..), fromMaybe)
|
import Data.Maybe (Maybe(..), fromMaybe)
|
||||||
import Data.Traversable (traverse)
|
|
||||||
import Effect (Effect, foreachE)
|
import Effect (Effect, foreachE)
|
||||||
import Effect.Aff (Aff, launchAff_)
|
import Effect.Aff (Aff, launchAff_)
|
||||||
import Effect.Class (liftEffect)
|
import Effect.Class (liftEffect)
|
||||||
import Effect.Console as Console
|
|
||||||
import Effect.Exception (Error)
|
import Effect.Exception (Error)
|
||||||
import Effect.Exception as Error
|
import Effect.Exception as Error
|
||||||
import Node.Encoding (Encoding(..))
|
import Node.Encoding (Encoding(..))
|
||||||
import Node.Process as Process
|
import Node.Process as Process
|
||||||
import Node.Stream as Writable
|
import Node.Stream as Writable
|
||||||
import Puppeteer.Browser.Spec as Spec.Browser
|
|
||||||
import Puppeteer.Page.Spec as Spec.Page
|
|
||||||
import Puppeteer.Spec as Spec
|
import Puppeteer.Spec as Spec
|
||||||
import Test.Spec (SpecT)
|
|
||||||
import Test.Spec.Config (defaultConfig)
|
import Test.Spec.Config (defaultConfig)
|
||||||
import Test.Spec.Reporter (consoleReporter)
|
import Test.Spec.Reporter (consoleReporter)
|
||||||
import Test.Spec.Result (Result(..))
|
import Test.Spec.Result (Result(..))
|
||||||
|
Loading…
Reference in New Issue
Block a user