fix: defer all promises

This commit is contained in:
orion 2023-10-06 11:57:45 -05:00
parent 621f93b314
commit f23f7eed5c
Signed by: orion
GPG Key ID: 6D4165AE4C928719
27 changed files with 342 additions and 346 deletions

View File

@ -13,14 +13,15 @@ export const forPage = p => p.browserContext()
/** @type {(b: Browser) => BrowserContext} */
export const _default = b => b.defaultBrowserContext()
/** @type {(o: object) => (b: Browser) => Promise<BrowserContext>} */
export const _incognito = o => b => b.createIncognitoBrowserContext(o)
/** @type {(o: object) => (b: Browser) => () => Promise<BrowserContext>} */
export const _incognito = o => b => () => b.createIncognitoBrowserContext(o)
/** @type {(origin: string) => (p: Array<import('puppeteer').Permission>) => (b: BrowserContext) => Promise<void>} */
export const _overridePermissions = o => p => c => c.overridePermissions(o, p)
/** @type {(origin: string) => (p: Array<import('puppeteer').Permission>) => (b: BrowserContext) => () => Promise<void>} */
export const _overridePermissions = o => p => c => () =>
c.overridePermissions(o, p)
/** @type {(b: BrowserContext) => Promise<void>} */
export const _clearPermissionOverrides = c => c.clearPermissionOverrides()
/** @type {(b: BrowserContext) => () => Promise<void>} */
export const _clearPermissionOverrides = c => () => c.clearPermissionOverrides()
/** @type {(b: BrowserContext) => Promise<void>} */
export const _close = c => c.close()
/** @type {(b: BrowserContext) => () => Promise<void>} */
export const _close = c => () => c.close()

View File

@ -17,6 +17,7 @@ import Control.Promise as Promise
import Data.Maybe (Maybe(..))
import Data.Set (Set)
import Data.Set as Set
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (BrowserContext) as X
@ -46,13 +47,13 @@ foreign import isIncognito :: BrowserContext -> Boolean
foreign import forPage :: Page -> BrowserContext
foreign import _default :: Browser -> BrowserContext
foreign import _incognito :: Foreign -> Browser -> Promise BrowserContext
foreign import _overridePermissions :: String -> Array Permission -> BrowserContext -> Promise Unit
foreign import _clearPermissionOverrides :: BrowserContext -> Promise Unit
foreign import _close :: BrowserContext -> Promise Unit
foreign import _incognito :: Foreign -> Browser -> Effect (Promise BrowserContext)
foreign import _overridePermissions :: String -> Array Permission -> BrowserContext -> Effect (Promise Unit)
foreign import _clearPermissionOverrides :: BrowserContext -> Effect (Promise Unit)
foreign import _close :: BrowserContext -> Effect (Promise Unit)
incognito :: Create -> Browser -> Aff BrowserContext
incognito c b = Promise.toAff $ _incognito (prepareCreate c) b
incognito c b = Promise.toAffE $ _incognito (prepareCreate c) b
incognito_ :: Browser -> Aff BrowserContext
incognito_ = incognito { proxyBypassList: Nothing, proxyServer: Nothing }
@ -61,10 +62,10 @@ default :: Browser -> BrowserContext
default = _default
overridePermissions :: String -> Set Permission -> BrowserContext -> Aff Unit
overridePermissions origin perms ctx = Promise.toAff $ _overridePermissions origin (Set.toUnfoldable perms) ctx
overridePermissions origin perms ctx = Promise.toAffE $ _overridePermissions origin (Set.toUnfoldable perms) ctx
clearPermissionOverrides :: BrowserContext -> Aff Unit
clearPermissionOverrides = Promise.toAff <<< _clearPermissionOverrides
clearPermissionOverrides = Promise.toAffE <<< _clearPermissionOverrides
close :: BrowserContext -> Aff Unit
close = Promise.toAff <<< _close
close = Promise.toAffE <<< _close

View File

@ -1,8 +1,8 @@
import { BrowserContext } from 'puppeteer'
import { Browser } from 'puppeteer'
/** @type {(b: Browser) => Promise<void>} */
export const _close = b => b.close()
/** @type {(b: Browser) => () => Promise<void>} */
export const _close = b => () => b.close()
/** @type {(b: Browser) => () => void} */
export const disconnect = b => () => b.disconnect()

View File

@ -105,7 +105,7 @@ duplexConnect =
in
duplex into from
foreign import _close :: Browser -> Promise Unit
foreign import _close :: Browser -> Effect (Promise Unit)
foreign import _get :: Foreign -> Effect Browser
foreign import disconnect :: Browser -> Effect Unit
@ -117,4 +117,4 @@ get :: forall b. BrowserAccess b => b -> Effect Browser
get = _get <<< unsafeToForeign
close :: Browser -> Aff Unit
close = Promise.toAff <<< _close
close = Promise.toAffE <<< _close

View File

@ -1,9 +1,9 @@
import { Page, JSHandle } from 'puppeteer'
/**
* @type {(_: string) => (_: Page | JSHandle<unknown>) => (_: Array<unknown>) => Promise<unknown>}
* @type {(_: string) => (_: Page | JSHandle<unknown>) => (_: Array<unknown>) => () => Promise<unknown>}
*/
export const _run = s => h => a => {
export const _run = s => h => a => () => {
/** @type {any} */
const f = new Function(`return (${s})(...arguments)`)
/** @type {(_s: () => void, ...as: Array<unknown>) => Promise<unknown>} */
@ -12,9 +12,9 @@ export const _run = s => h => a => {
}
/**
* @type {(_: string) => (_: Page | JSHandle<unknown>) => (_: Array<unknown>) => Promise<JSHandle<unknown>>}
* @type {(_: string) => (_: Page | JSHandle<unknown>) => (_: Array<unknown>) => () => Promise<JSHandle<unknown>>}
*/
export const _runh = s => h => a => {
export const _runh = s => h => a => () => {
/** @type {any} */
const f = new Function(`return (${s})(...arguments)`)
/** @type {(_s: () => void, ...as: Array<unknown>) => Promise<JSHandle<unknown>>} */

View File

@ -13,33 +13,34 @@ import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign, unsafeToForeign)
import Puppeteer.Base (class EvalTarget, Handle)
foreign import _run :: forall @r. String -> Foreign -> Array Foreign -> Promise r
foreign import _runh :: forall @r. String -> Foreign -> Array Foreign -> Promise (Handle r)
foreign import _run :: forall @r. String -> Foreign -> Array Foreign -> Effect (Promise r)
foreign import _runh :: forall @r. String -> Foreign -> Array Foreign -> Effect (Promise (Handle r))
unsafeRunJs0 :: forall e @r. EvalTarget e => String -> e -> Aff r
unsafeRunJs0 js h = Promise.toAff $ _run js (unsafeToForeign h) []
unsafeRunJs0 js h = Promise.toAffE $ _run js (unsafeToForeign h) []
unsafeRunJsHandle0 :: forall e @r. EvalTarget e => String -> e -> Aff (Handle r)
unsafeRunJsHandle0 js h = Promise.toAff $ _runh js (unsafeToForeign h) []
unsafeRunJsHandle0 js h = Promise.toAffE $ _runh js (unsafeToForeign h) []
unsafeRunJs1 :: forall a e @r. EvalTarget e => String -> a -> e -> Aff r
unsafeRunJs1 js a h = Promise.toAff $ _run js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJs1 js a h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJsHandle1 :: forall a e @r. EvalTarget e => String -> a -> e -> Aff (Handle r)
unsafeRunJsHandle1 js a h = Promise.toAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJsHandle1 js a h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJs2 :: forall a b e @r. EvalTarget e => String -> a -> b -> e -> Aff r
unsafeRunJs2 js a b h = Promise.toAff $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJs2 js a b h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJsHandle2 :: forall a b e @r. EvalTarget e => String -> a -> b -> e -> Aff (Handle r)
unsafeRunJsHandle2 js a b h = Promise.toAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJsHandle2 js a b h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJs3 :: forall a b c e @r. EvalTarget e => String -> a -> b -> c -> e -> Aff r
unsafeRunJs3 js a b c h = Promise.toAff $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJs3 js a b c h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJsHandle3 :: forall a b c e @r. EvalTarget e => String -> a -> b -> c -> e -> Aff (Handle r)
unsafeRunJsHandle3 js a b c h = Promise.toAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJsHandle3 js a b c h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]

View File

@ -3,56 +3,57 @@
import { ElementHandle } from 'puppeteer'
import { JSHandle } from 'puppeteer'
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => Promise<Array<ElementHandle<Node>>>} */
export const _find = s => h => h.$$(s)
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => () => Promise<Array<ElementHandle<Node>>>} */
export const _find = s => h => () => h.$$(s)
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _click = h => h.click()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _click = h => () => h.click()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<unknown>} */
export const _boundingBox = h => h.boundingBox()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<unknown>} */
export const _boundingBox = h => () => h.boundingBox()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<unknown>} */
export const _boxModel = h => h.boxModel()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<unknown>} */
export const _boxModel = h => () => h.boxModel()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _hover = h => h.hover()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _hover = h => () => h.hover()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<boolean>} */
export const _isHidden = h => h.isHidden()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<boolean>} */
export const _isHidden = h => () => h.isHidden()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<boolean>} */
export const _isVisible = h => h.isVisible()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<boolean>} */
export const _isVisible = h => () => h.isVisible()
/** @type {(_: ElementHandle<HTMLElement>) => Promise<boolean>} */
export const _isIntersectingViewport = h => h.isIntersectingViewport()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<boolean>} */
export const _isIntersectingViewport = h => () => h.isIntersectingViewport()
/** @type {(_: ElementHandle<HTMLElement>) => (_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _drop = from => to => to.drop(from)
/** @type {(_: ElementHandle<HTMLElement>) => (_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _drop = from => to => () => to.drop(from)
/** @type {(_: import('puppeteer').ScreenshotOptions) => (_: ElementHandle<HTMLElement>) => Promise<Buffer>} */
export const _screenshot = o => h => h.screenshot(o).then(bs => Buffer.from(bs))
/** @type {(_: import('puppeteer').ScreenshotOptions) => (_: ElementHandle<HTMLElement>) => () => Promise<Buffer>} */
export const _screenshot = o => h => () =>
h.screenshot(o).then(bs => Buffer.from(bs))
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _scrollIntoView = h => h.scrollIntoView()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _scrollIntoView = h => () => h.scrollIntoView()
/** @type {(_: Array<string>) => (_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _select = o => h => h.select(...o).then(() => {})
/** @type {(_: Array<string>) => (_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _select = o => h => () => h.select(...o).then(() => {})
/** @type {(_: ElementHandle<HTMLElement>) => Promise<void>} */
export const _tap = h => h.tap()
/** @type {(_: ElementHandle<HTMLElement>) => () => Promise<void>} */
export const _tap = h => () => h.tap()
/** @type {(_: Array<string>) => (_: ElementHandle<HTMLInputElement>) => Promise<void>} */
export const _uploadFile = ps => h => h.uploadFile(...ps)
/** @type {(_: Array<string>) => (_: ElementHandle<HTMLInputElement>) => () => Promise<void>} */
export const _uploadFile = ps => h => () => h.uploadFile(...ps)
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => Promise<ElementHandle<Element> | null>} */
export const _waitForSelector = s => h => h.waitForSelector(s)
/** @type {(_: string) => (_: ElementHandle<HTMLElement>) => () => Promise<ElementHandle<Element> | null>} */
export const _waitForSelector = s => h => () => h.waitForSelector(s)
/** @type {(_: JSHandle<unknown>) => Promise<Array<{k: string, v: JSHandle<unknown>}>>} */
export const _getProperties = async h => {
/** @type {(_: JSHandle<unknown>) => () => Promise<Array<{k: string, v: JSHandle<unknown>}>>} */
export const _getProperties = h => async () => {
const ps = await h.getProperties()
return Array.from(ps.entries()).map(([k, v]) => ({ k, v }))
}
/** @type {<T>(h: JSHandle<T>) => Promise<T>} */
export const _clone = h => h.jsonValue()
/** @type {<T>(h: JSHandle<T>) => () => Promise<T>} */
export const _clone = h => () => h.jsonValue()

View File

@ -31,6 +31,7 @@ import Data.Map (Map)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Data.Nullable as Nullable
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Node.Buffer (Buffer)
@ -47,26 +48,26 @@ import Unsafe.Coerce (unsafeCoerce)
import Web.HTML (HTMLElement)
import Web.HTML as HTML
foreign import _find :: forall a b. String -> Handle a -> Promise (Array (Handle b))
foreign import _click :: forall a. Handle a -> Promise Unit
foreign import _boundingBox :: forall a. Handle a -> Promise (Nullable Foreign)
foreign import _boxModel :: forall a. Handle a -> Promise (Nullable Foreign)
foreign import _hover :: forall a. Handle a -> Promise Unit
foreign import _isHidden :: 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 _drop :: forall a b. Handle a -> Handle b -> Promise Unit
foreign import _screenshot :: forall a. Foreign -> Handle a -> Promise Buffer
foreign import _scrollIntoView :: forall a. Handle a -> Promise Unit
foreign import _select :: forall a. Array String -> Handle a -> Promise Unit
foreign import _tap :: forall a. Handle a -> Promise Unit
foreign import _uploadFile :: forall a. Array FilePath -> Handle a -> Promise Unit
foreign import _waitForSelector :: forall a b. String -> Handle a -> Promise (Handle b)
foreign import _clone :: forall a. Handle a -> Promise a
foreign import _getProperties :: forall a. Handle a -> Promise (Array { k :: String, v :: (Handle Foreign) })
foreign import _find :: forall a b. String -> Handle a -> Effect (Promise (Array (Handle b)))
foreign import _click :: forall a. Handle a -> Effect (Promise Unit)
foreign import _boundingBox :: forall a. Handle a -> Effect (Promise (Nullable Foreign))
foreign import _boxModel :: forall a. Handle a -> Effect (Promise (Nullable Foreign))
foreign import _hover :: forall a. Handle a -> Effect (Promise Unit)
foreign import _isHidden :: forall a. Handle a -> Effect (Promise Boolean)
foreign import _isVisible :: forall a. Handle a -> Effect (Promise Boolean)
foreign import _isIntersectingViewport :: forall a. Handle a -> Effect (Promise Boolean)
foreign import _drop :: forall a b. Handle a -> Handle b -> Effect (Promise Unit)
foreign import _screenshot :: forall a. Foreign -> Handle a -> Effect (Promise Buffer)
foreign import _scrollIntoView :: forall a. Handle a -> Effect (Promise Unit)
foreign import _select :: forall a. Array String -> Handle a -> Effect (Promise Unit)
foreign import _tap :: forall a. Handle a -> Effect (Promise Unit)
foreign import _uploadFile :: forall a. Array FilePath -> Handle a -> Effect (Promise Unit)
foreign import _waitForSelector :: forall a b. String -> Handle a -> Effect (Promise (Handle b))
foreign import _clone :: forall a. Handle a -> Effect (Promise a)
foreign import _getProperties :: forall a. Handle a -> Effect (Promise (Array { k :: String, v :: (Handle Foreign) }))
clone :: forall a. WriteForeign a => ReadForeign a => Handle a -> Aff a
clone = Promise.toAff <<< _clone
clone = Promise.toAffE <<< _clone
findFirst :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Maybe (Handle b))
findFirst q h = do
@ -74,52 +75,52 @@ findFirst q h = do
pure $ head els
findAll :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Array (Handle b))
findAll q h = Promise.toAff $ _find (Selector.toCSS q) h
findAll q h = Promise.toAffE $ _find (Selector.toCSS q) h
click :: forall a. IsElement a => Handle a -> Aff Unit
click h = Promise.toAff $ _click h
click h = Promise.toAffE $ _click h
boundingBox :: forall a. IsElement a => Handle a -> Aff (Maybe Foreign)
boundingBox = map Nullable.toMaybe <<< Promise.toAff <<< _boundingBox
boundingBox = map Nullable.toMaybe <<< Promise.toAffE <<< _boundingBox
boxModel :: forall a. IsElement a => Handle a -> Aff (Maybe Foreign)
boxModel = map Nullable.toMaybe <<< Promise.toAff <<< _boxModel
boxModel = map Nullable.toMaybe <<< Promise.toAffE <<< _boxModel
hover :: forall a. IsElement a => Handle a -> Aff Unit
hover = Promise.toAff <<< _hover
hover = Promise.toAffE <<< _hover
isHidden :: forall a. IsElement a => Handle a -> Aff Boolean
isHidden = Promise.toAff <<< _isHidden
isHidden = Promise.toAffE <<< _isHidden
isVisible :: forall a. IsElement a => Handle a -> Aff Boolean
isVisible = Promise.toAff <<< _isVisible
isVisible = Promise.toAffE <<< _isVisible
isIntersectingViewport :: forall a. IsElement a => Handle a -> Aff Boolean
isIntersectingViewport = Promise.toAff <<< _isIntersectingViewport
isIntersectingViewport = Promise.toAffE <<< _isIntersectingViewport
drop :: forall a b. IsElement a => IsElement b => Handle a -> Handle b -> Aff Unit
drop a = Promise.toAff <<< _drop a
drop a = Promise.toAffE <<< _drop a
screenshot :: forall a. IsElement a => ScreenshotOptions -> Handle a -> Aff Buffer
screenshot o = Promise.toAff <<< _screenshot (prepareScreenshotOptions o)
screenshot o = Promise.toAffE <<< _screenshot (prepareScreenshotOptions o)
scrollIntoView :: forall a. IsElement a => Handle a -> Aff Unit
scrollIntoView = Promise.toAff <<< _scrollIntoView
scrollIntoView = Promise.toAffE <<< _scrollIntoView
select :: forall a. IsElement a => Array String -> Handle a -> Aff Unit
select a = Promise.toAff <<< _select a
select a = Promise.toAffE <<< _select a
tap :: forall a. IsElement a => Handle a -> Aff Unit
tap = Promise.toAff <<< _tap
tap = Promise.toAffE <<< _tap
uploadFile :: Array FilePath -> Handle HTML.HTMLInputElement -> Aff Unit
uploadFile a = Promise.toAff <<< _uploadFile a
uploadFile a = Promise.toAffE <<< _uploadFile a
waitForSelector :: forall a b s. Selector s b => IsElement a => s -> Handle a -> Aff (Handle b)
waitForSelector s = Promise.toAff <<< _waitForSelector (Selector.toCSS s)
waitForSelector s = Promise.toAffE <<< _waitForSelector (Selector.toCSS s)
getProperties :: forall a. Handle a -> Aff (Map String (Handle Foreign))
getProperties = map FFI.makeMap <<< Promise.toAff <<< _getProperties
getProperties = map FFI.makeMap <<< Promise.toAffE <<< _getProperties
toHTML :: forall a. Handle a -> Aff (Maybe (Handle HTMLElement))
toHTML h = do

View File

@ -2,24 +2,26 @@ import { Keyboard } from 'puppeteer'
/**
* `foreign import _up :: Foreign -> Keyboard -> Promise Unit`
* @type {(_1: import("puppeteer").KeyInput) => (_2: Keyboard) => Promise<void>}
* @type {(_1: import("puppeteer").KeyInput) => (_2: Keyboard) => () => Promise<void>}
*/
export const _up = k => kb => kb.up(k)
export const _up = k => kb => () => kb.up(k)
/**
* `foreign import _down :: Foreign -> Keyboard -> Promise Unit`
* @type {(_1: import("puppeteer").KeyInput) => (_2: Keyboard) => Promise<void>}
* @type {(_1: import("puppeteer").KeyInput) => (_2: Keyboard) => () => Promise<void>}
*/
export const _down = k => kb => kb.down(k)
export const _down = k => kb => () => kb.down(k)
/**
* foreign import _press :: Foreign -> Nullable Int -> Keyboard -> Promise Unit
* @type {(_1: import('puppeteer').KeyInput) => (_2: number | null) => (_3: Keyboard) => Promise<void>}
* @type {(_1: import('puppeteer').KeyInput) => (_2: number | null) => (_3: Keyboard) => () => Promise<void>}
*/
export const _press = k => ms => kb => kb.press(k, { delay: ms || undefined })
export const _press = k => ms => kb => () =>
kb.press(k, { delay: ms || undefined })
/**
* foreign import _type :: String -> Nullable Int -> Keyboard -> Promise Unit
* @type {(_1: string) => (_2: number | null) => (_3: Keyboard) => Promise<void>}
* @type {(_1: string) => (_2: number | null) => (_3: Keyboard) => () => Promise<void>}
*/
export const _type = k => ms => kb => kb.type(k, { delay: ms || undefined })
export const _type = k => ms => kb => () =>
kb.type(k, { delay: ms || undefined })

View File

@ -11,6 +11,7 @@ import Data.Nullable as Nullable
import Data.Ord.Generic (genericCompare)
import Data.String as String
import Data.String.CodePoints as CodePoint
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Keyboard)
@ -20,24 +21,24 @@ import Simple.JSON (writeImpl)
type DownHint :: Symbol
type DownHint = "Key is being held. Invoking `Puppeteer.closeContext` will release this key"
foreign import _up :: Foreign -> Keyboard -> Promise Unit
foreign import _down :: Foreign -> Keyboard -> Promise Unit
foreign import _press :: Foreign -> Nullable Int -> Keyboard -> Promise Unit
foreign import _type :: String -> Nullable Int -> Keyboard -> Promise Unit
foreign import _up :: Foreign -> Keyboard -> Effect (Promise Unit)
foreign import _down :: Foreign -> Keyboard -> Effect (Promise Unit)
foreign import _press :: Foreign -> Nullable Int -> Keyboard -> Effect (Promise Unit)
foreign import _type :: String -> Nullable Int -> Keyboard -> Effect (Promise Unit)
up :: Key -> Keyboard -> Aff Unit
up k kb = Promise.toAff $ _up (prepareKey k) kb
up k kb = Promise.toAffE $ _up (prepareKey k) kb
down :: Key -> Keyboard -> Aff (Context DownHint)
down k kb = do
Promise.toAff $ _down (prepareKey k) kb
Promise.toAffE $ _down (prepareKey k) kb
pure $ Context (\_ -> up k kb)
press :: Key -> Keyboard -> Aff Unit
press k kb = Promise.toAff $ _press (prepareKey k) Nullable.null kb
press k kb = Promise.toAffE $ _press (prepareKey k) Nullable.null kb
doType :: String -> Keyboard -> Aff Unit
doType s kb = Promise.toAff $ _type s Nullable.null kb
doType s kb = Promise.toAffE $ _type s Nullable.null kb
data KeyMod
= KeyModMetaLeft

View File

@ -2,18 +2,18 @@ import { Page } from 'puppeteer'
/**
* `foreign import _list :: Array String -> Page -> Promise (Array CookieRaw)`
* @type {(_0: Array<string>) => (_1: Page) => Promise<Array<import('devtools-protocol').Protocol.Network.Cookie>>}
* @type {(_0: Array<string>) => (_1: Page) => () => Promise<Array<import('devtools-protocol').Protocol.Network.Cookie>>}
*/
export const _list = cs => page => page.cookies(...cs)
export const _list = cs => page => () => page.cookies(...cs)
/**
* `foreign import _delete :: Foreign -> Page -> Promise Unit`
* @type {(_0: import('devtools-protocol').Protocol.Network.DeleteCookiesRequest) => (_1: Page) => Promise<void>}
* @type {(_0: import('devtools-protocol').Protocol.Network.DeleteCookiesRequest) => (_1: Page) => () => Promise<void>}
*/
export const _delete = dc => p => p.deleteCookie(dc)
export const _delete = dc => p => () => p.deleteCookie(dc)
/**
* `foreign import _set :: Foreign -> Page -> Promise Unit`
* @type {(_0: import('devtools-protocol').Protocol.Network.CookieParam) => (_1: Page) => Promise<void>}
* @type {(_0: import('devtools-protocol').Protocol.Network.CookieParam) => (_1: Page) => () => Promise<void>}
*/
export const _set = c => p => p.setCookie(c)
export const _set = c => p => () => p.setCookie(c)

View File

@ -14,22 +14,23 @@ import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Array.NonEmpty (NonEmptyArray)
import Data.Array as Array
import Data.Array.NonEmpty (NonEmptyArray)
import Data.Array.NonEmpty as Array.NonEmpty
import Data.DateTime.Instant (Instant)
import Data.DateTime.Instant as Instant
import Data.Maybe (Maybe(..))
import Data.Newtype (unwrap, wrap)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Page, URL)
import Puppeteer.FFI as FFI
import Simple.JSON (writeImpl)
foreign import _list :: Array String -> Page -> Promise (Array CookieRaw)
foreign import _delete :: Foreign -> Page -> Promise Unit
foreign import _set :: Foreign -> Page -> Promise Unit
foreign import _list :: Array String -> Page -> Effect (Promise (Array CookieRaw))
foreign import _delete :: Foreign -> Page -> Effect (Promise Unit)
foreign import _set :: Foreign -> Page -> Effect (Promise Unit)
data CookieSameSite = Strict | Lax | None
@ -92,23 +93,23 @@ set { name, value, url, domain, path, secure, sameSite, expires } p =
, expires: map (unwrap <<< Instant.unInstant) expires
}
in
Promise.toAff $ _set o p
Promise.toAffE $ _set o p
delete :: CookieDelete -> Page -> Aff Unit
delete { name, url, domain, path } p =
let
o = writeImpl { name, url: FFI.maybeToUndefined url, domain: FFI.maybeToUndefined domain, path: FFI.maybeToUndefined path }
in
Promise.toAff $ _delete o p
Promise.toAffE $ _delete o p
listForCurrentPage :: Page -> Aff (Array Cookie)
listForCurrentPage = map (Array.catMaybes <<< map cookieRaw) <<< Promise.toAff <<< _list []
listForCurrentPage = map (Array.catMaybes <<< map cookieRaw) <<< Promise.toAffE <<< _list []
listForUrl :: URL -> Page -> Aff (Array Cookie)
listForUrl = listForUrls <<< pure
listForUrls :: NonEmptyArray URL -> Page -> Aff (Array Cookie)
listForUrls urls p = map (Array.catMaybes <<< map cookieRaw) $ Promise.toAff $ _list (Array.NonEmpty.toArray urls) p
listForUrls urls p = map (Array.catMaybes <<< map cookieRaw) $ Promise.toAffE $ _list (Array.NonEmpty.toArray urls) p
cookieRaw :: CookieRaw -> Maybe Cookie
cookieRaw { domain, expires, path, url, name, value, sameSite, secure } = do

View File

@ -5,57 +5,58 @@ import Cdp from 'devtools-protocol'
/** @type {(_0: keyof KnownDevices) => import('puppeteer').Device} */
export const _knownDevice = k => KnownDevices[k]
/** @type {(_0: import('puppeteer').Device) => (_1: Page) => Promise<void>} */
export const _emulate = d => p => p.emulate(d)
/** @type {(_0: import('puppeteer').Device) => (_1: Page) => () => Promise<void>} */
export const _emulate = d => p => () => p.emulate(d)
/** @type {(_0: number) => (_1: Page) => Promise<void>} */
export const _cpuThrottling = f => p => p.emulateCPUThrottling(f)
/** @type {(_0: number) => (_1: Page) => () => Promise<void>} */
export const _cpuThrottling = f => p => () => p.emulateCPUThrottling(f)
/** @type {(_0: { isUserActive: boolean, isScreenUnlocked: boolean } | undefined) => (_1: Page) => Promise<void>} */
export const _idle = o => p => p.emulateIdleState(o)
/** @type {(_0: { isUserActive: boolean, isScreenUnlocked: boolean } | undefined) => (_1: Page) => () => Promise<void>} */
export const _idle = o => p => () => p.emulateIdleState(o)
/** @type {(_1: Page) => Promise<void>} */
export const _emulatePrint = p => p.emulateMediaType('print')
/** @type {(_1: Page) => () => Promise<void>} */
export const _emulatePrint = p => () => p.emulateMediaType('print')
/** @type {(_1: Page) => Promise<void>} */
export const _unemulatePrint = p => p.emulateMediaType(undefined)
/** @type {(_1: Page) => () => Promise<void>} */
export const _unemulatePrint = p => () => p.emulateMediaType(undefined)
/** @type {(_0: import('puppeteer').NetworkConditions) => (_1: Page) => Promise<void>} */
export const _emulateNetwork = c => p => p.emulateNetworkConditions(c)
/** @type {(_0: import('puppeteer').NetworkConditions) => (_1: Page) => () => Promise<void>} */
export const _emulateNetwork = c => p => () => p.emulateNetworkConditions(c)
/** @type {(_1: Page) => Promise<void>} */
export const _unemulateNetwork = p => p.emulateNetworkConditions(null)
/** @type {(_1: Page) => () => Promise<void>} */
export const _unemulateNetwork = p => () => p.emulateNetworkConditions(null)
/** @type {(_0: string) => (_1: Page) => Promise<void>} */
export const _emulateTimezone = c => p => p.emulateTimezone(c)
/** @type {(_0: string) => (_1: Page) => () => Promise<void>} */
export const _emulateTimezone = c => p => () => p.emulateTimezone(c)
/** @type {(_1: Page) => Promise<void>} */
export const _unemulateTimezone = p => p.emulateTimezone(undefined)
/** @type {(_1: Page) => () => Promise<void>} */
export const _unemulateTimezone = p => () => p.emulateTimezone(undefined)
/** @type {(_0: import('devtools-protocol').Protocol.Emulation.SetEmulatedVisionDeficiencyRequest['type']) => (_1: Page) => Promise<void>} */
export const _emulateVisionDeficiency = c => p => p.emulateVisionDeficiency(c)
/** @type {(_0: import('devtools-protocol').Protocol.Emulation.SetEmulatedVisionDeficiencyRequest['type']) => (_1: Page) => () => Promise<void>} */
export const _emulateVisionDeficiency = c => p => () =>
p.emulateVisionDeficiency(c)
/** @type {(_1: Page) => Promise<void>} */
export const _unemulateVisionDeficiency = p =>
/** @type {(_1: Page) => () => Promise<void>} */
export const _unemulateVisionDeficiency = p => () =>
p.emulateVisionDeficiency(undefined)
/** @type {(_0: import('puppeteer').GeolocationOptions) => (_1: Page) => Promise<void>} */
export const _setGeolocation = g => p => p.setGeolocation(g)
/** @type {(_0: Page) => Promise<void>} */
export const _unsetGeolocation = p =>
/** @type {(_0: import('puppeteer').GeolocationOptions) => (_1: Page) => () => Promise<void>} */
export const _setGeolocation = g => p => () => p.setGeolocation(g)
/** @type {(_0: Page) => () => Promise<void>} */
export const _unsetGeolocation = p => () =>
p
.createCDPSession()
.then(cdp => cdp.send('Emulation.clearGeolocationOverride'))
/** @type {(_0: Page) => Promise<void>} */
export const _setJavascriptDisabled = p => p.setJavaScriptEnabled(false)
/** @type {(_0: Page) => Promise<void>} */
export const _unsetJavascriptDisabled = p => p.setJavaScriptEnabled(true)
/** @type {(_0: Page) => () => Promise<void>} */
export const _setJavascriptDisabled = p => () => p.setJavaScriptEnabled(false)
/** @type {(_0: Page) => () => Promise<void>} */
export const _unsetJavascriptDisabled = p => () => p.setJavaScriptEnabled(true)
/** @type {(_0: Page) => Promise<void>} */
export const _setOffline = p => p.setOfflineMode(true)
/** @type {(_0: Page) => Promise<void>} */
export const _unsetOffline = p => p.setOfflineMode(false)
/** @type {(_0: Page) => () => Promise<void>} */
export const _setOffline = p => () => p.setOfflineMode(true)
/** @type {(_0: Page) => () => Promise<void>} */
export const _unsetOffline = p => () => p.setOfflineMode(false)
/** @type {(_0: String) => (_1: Page) => Promise<void>} */
export const _setUserAgent = ua => p => p.setUserAgent(ua)
/** @type {(_0: String) => (_1: Page) => () => Promise<void>} */
export const _setUserAgent = ua => p => () => p.setUserAgent(ua)

View File

@ -19,6 +19,7 @@ import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype, unwrap)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Handle, Page)
@ -45,33 +46,33 @@ derive instance ntthrottlefactor :: Newtype ThrottleFactor _
noThrottling :: ThrottleFactor
noThrottling = ThrottleFactor 1.0
foreign import _idle :: Foreign -> Page -> Promise Unit
foreign import _idle :: Foreign -> Page -> Effect (Promise Unit)
foreign import _knownDevice :: String -> Foreign
foreign import _emulate :: Foreign -> Page -> Promise Unit
foreign import _cpuThrottling :: Number -> Page -> Promise Unit
foreign import _emulate :: Foreign -> Page -> Effect (Promise Unit)
foreign import _cpuThrottling :: Number -> Page -> Effect (Promise Unit)
foreign import _emulatePrint :: Page -> Promise Unit
foreign import _unemulatePrint :: Page -> Promise Unit
foreign import _emulatePrint :: Page -> Effect (Promise Unit)
foreign import _unemulatePrint :: Page -> Effect (Promise Unit)
foreign import _emulateNetwork :: NetworkConditions -> Page -> Promise Unit
foreign import _unemulateNetwork :: Page -> Promise Unit
foreign import _emulateNetwork :: NetworkConditions -> Page -> Effect (Promise Unit)
foreign import _unemulateNetwork :: Page -> Effect (Promise Unit)
foreign import _emulateTimezone :: String -> Page -> Promise Unit
foreign import _unemulateTimezone :: Page -> Promise Unit
foreign import _emulateTimezone :: String -> Page -> Effect (Promise Unit)
foreign import _unemulateTimezone :: Page -> Effect (Promise Unit)
foreign import _emulateVisionDeficiency :: String -> Page -> Promise Unit
foreign import _unemulateVisionDeficiency :: Page -> Promise Unit
foreign import _emulateVisionDeficiency :: String -> Page -> Effect (Promise Unit)
foreign import _unemulateVisionDeficiency :: Page -> Effect (Promise Unit)
foreign import _setGeolocation :: Geolocation -> Page -> Promise Unit
foreign import _unsetGeolocation :: Page -> Promise Unit
foreign import _setGeolocation :: Geolocation -> Page -> Effect (Promise Unit)
foreign import _unsetGeolocation :: Page -> Effect (Promise Unit)
foreign import _setJavascriptDisabled :: Page -> Promise Unit
foreign import _unsetJavascriptDisabled :: Page -> Promise Unit
foreign import _setJavascriptDisabled :: Page -> Effect (Promise Unit)
foreign import _unsetJavascriptDisabled :: Page -> Effect (Promise Unit)
foreign import _setOffline :: Page -> Promise Unit
foreign import _unsetOffline :: Page -> Promise Unit
foreign import _setOffline :: Page -> Effect (Promise Unit)
foreign import _unsetOffline :: Page -> Effect (Promise Unit)
foreign import _setUserAgent :: String -> Page -> Promise Unit
foreign import _setUserAgent :: String -> Page -> Effect (Promise Unit)
type PrintHint :: Symbol
type PrintHint = "Print mode is being emulated. Invoking `Puppeteer.closeContext` will undo this emulation."
@ -92,41 +93,41 @@ type IdleHint :: Symbol
type IdleHint = "User idling is being emulated. Invoking `Puppeteer.closeContext` will undo this emulation."
device :: Device -> Page -> Aff Unit
device d p = Promise.toAff $ _emulate (_knownDevice <<< knownDeviceString $ d) p
device d p = Promise.toAffE $ _emulate (_knownDevice <<< knownDeviceString $ d) p
cpuThrottling :: ThrottleFactor -> Page -> Aff (Context CpuThrottleHint)
cpuThrottling t p = do
Promise.toAff $ _cpuThrottling (unwrap t) p
pure $ Context (\_ -> Promise.toAff $ _cpuThrottling 1.0 p)
Promise.toAffE $ _cpuThrottling (unwrap t) p
pure $ Context (\_ -> Promise.toAffE $ _cpuThrottling 1.0 p)
idle :: Idle -> Page -> Aff (Context IdleHint)
idle UserInactive p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAff <<< _idle (writeImpl { isUserActive: false, isScreenUnlocked: true }) $ p
idle ScreenLocked p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAff <<< _idle (writeImpl { isScreenUnlocked: false, isUserActive: false }) $ p
idle UserInactive p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAffE <<< _idle (writeImpl { isUserActive: false, isScreenUnlocked: true }) $ p
idle ScreenLocked p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAffE <<< _idle (writeImpl { isScreenUnlocked: false, isUserActive: false }) $ p
idle NotIdle p = map (const mempty) $ unidle p
unidle :: Page -> Aff Unit
unidle = void <<< Promise.toAff <<< _idle undefined
unidle = void <<< Promise.toAffE <<< _idle undefined
print :: Page -> Aff (Context PrintHint)
print p = do
Promise.toAff $ _emulatePrint p
pure $ Context (\_ -> Promise.toAff $ _unemulatePrint p)
Promise.toAffE $ _emulatePrint p
pure $ Context (\_ -> Promise.toAffE $ _unemulatePrint p)
network :: NetworkConditions -> Page -> Aff (Context NetworkHint)
network n p = do
Promise.toAff $ _emulateNetwork n p
pure $ Context (\_ -> Promise.toAff $ _unemulateNetwork p)
Promise.toAffE $ _emulateNetwork n p
pure $ Context (\_ -> Promise.toAffE $ _unemulateNetwork p)
--| https://pptr.dev/api/puppeteer.page.emulatetimezone
timezone :: String -> Page -> Aff (Context TimezoneHint)
timezone tz p = do
Promise.toAff $ _emulateTimezone tz p
pure $ Context (\_ -> Promise.toAff $ _unemulateTimezone p)
Promise.toAffE $ _emulateTimezone tz p
pure $ Context (\_ -> Promise.toAffE $ _unemulateTimezone p)
visionDeficiency :: VisionDeficiency -> Page -> Aff (Context VisionDeficiencyHint)
visionDeficiency d p = do
Promise.toAff $ _emulateVisionDeficiency (visionDeficiencyString d) p
pure $ Context (\_ -> Promise.toAff $ _unemulateVisionDeficiency p)
Promise.toAffE $ _emulateVisionDeficiency (visionDeficiencyString d) p
pure $ Context (\_ -> Promise.toAffE $ _unemulateVisionDeficiency p)
data VisionDeficiency
= BlurredVision

View File

@ -1,9 +1,3 @@
// foreign import defaultValue :: Dialog -> String
// foreign import message :: Dialog -> String
// foreign import _dismiss :: Dialog -> Promise Unit
// foreign import _accept :: Foreign -> Dialog -> Promise Unit
// foreign import _type :: Dialog -> String
import { Dialog } from 'puppeteer'
/** @type {(d: Dialog) => string} */
@ -12,11 +6,11 @@ export const defaultValue = d => d.defaultValue()
/** @type {(d: Dialog) => string} */
export const message = d => d.message()
/** @type {(d: Dialog) => Promise<void>} */
export const _dismiss = d => d.dismiss()
/** @type {(d: Dialog) => () => Promise<void>} */
export const _dismiss = d => () => d.dismiss()
/** @type {(s: string | undefined) => (d: Dialog) => Promise<void>} */
export const _accept = s => d => d.accept(s)
/** @type {(s: string | undefined) => (d: Dialog) => () => Promise<void>} */
export const _accept = s => d => () => d.accept(s)
/** @type {(d: Dialog) => string} */
export const _type = d => d.type()

View File

@ -13,6 +13,7 @@ import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign, unsafeFromForeign)
import Puppeteer.FFI as FFI
@ -43,15 +44,15 @@ instance dialogForeign :: ReadForeign Dialog where
foreign import defaultValue :: Dialog -> String
foreign import message :: Dialog -> String
foreign import _dismiss :: Dialog -> Promise Unit
foreign import _accept :: Foreign -> Dialog -> Promise Unit
foreign import _dismiss :: Dialog -> Effect (Promise Unit)
foreign import _accept :: Foreign -> Dialog -> Effect (Promise Unit)
foreign import _type :: Dialog -> String
dismiss :: Dialog -> Aff Unit
dismiss = Promise.toAff <<< _dismiss
dismiss = Promise.toAffE <<< _dismiss
accept :: Maybe String -> Dialog -> Aff Unit
accept s = Promise.toAff <<< _accept (FFI.maybeToUndefined s)
accept s = Promise.toAffE <<< _accept (FFI.maybeToUndefined s)
dialogType :: Dialog -> DialogType
dialogType = dialogTypeOfString <<< _type

View File

@ -5,6 +5,7 @@ import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Node.Buffer (Buffer)
@ -97,11 +98,11 @@ preparePdfOptions
, margin: FFI.maybeToUndefined $ map margin' margin
}
foreign import _screenshot :: Foreign -> Page -> Promise Buffer
foreign import _pdf :: Foreign -> Page -> Promise Buffer
foreign import _screenshot :: Foreign -> Page -> Effect (Promise Buffer)
foreign import _pdf :: Foreign -> Page -> Effect (Promise Buffer)
screenshot :: ScreenshotOptions -> Page -> Aff Buffer
screenshot o = Promise.toAff <<< _screenshot (prepareScreenshotOptions o)
screenshot o = Promise.toAffE <<< _screenshot (prepareScreenshotOptions o)
pdf :: PdfOptions -> Page -> Aff Buffer
pdf o = Promise.toAff <<< _pdf (preparePdfOptions o)
pdf o = Promise.toAffE <<< _pdf (preparePdfOptions o)

View File

@ -9,21 +9,21 @@ export const request = r => () => r.request()
/**
* `foreign import _bodyBuffer :: Response -> Promise Buffer`
* @type {(_0: HTTPResponse) => Promise<Buffer>}
* @type {(_0: HTTPResponse) => () => Promise<Buffer>}
*/
export const _bodyBuffer = r => r.buffer()
export const _bodyBuffer = r => () => r.buffer()
/**
* `foreign import _bodyJson :: Response -> Promise Foreign`
* @type {(_0: HTTPResponse) => Promise<unknown>}
* @type {(_0: HTTPResponse) => () => Promise<unknown>}
*/
export const _bodyJson = r => r.json()
export const _bodyJson = r => () => r.json()
/**
* `foreign import _bodyText :: Response -> Promise String`
* @type {(_0: HTTPResponse) => Promise<string>}
* @type {(_0: HTTPResponse) => () => Promise<string>}
*/
export const _bodyText = r => r.text()
export const _bodyText = r => () => r.text()
/**
* `foreign import _url :: Response -> Effect String`

View File

@ -19,21 +19,21 @@ foreign import url :: Response -> Effect String
foreign import status :: Response -> Effect Int
foreign import statusText :: Response -> Effect String
foreign import _bodyBuffer :: Response -> Promise Buffer
foreign import _bodyJson :: Response -> Promise Foreign
foreign import _bodyText :: Response -> Promise String
foreign import _bodyBuffer :: Response -> Effect (Promise Buffer)
foreign import _bodyJson :: Response -> Effect (Promise Foreign)
foreign import _bodyText :: Response -> Effect (Promise String)
foreign import _remoteAddressIp :: Response -> Effect Foreign
foreign import _remoteAddressPort :: Response -> Effect Foreign
bodyBuffer :: Response -> Aff Buffer
bodyBuffer = Promise.toAff <<< _bodyBuffer
bodyBuffer = Promise.toAffE <<< _bodyBuffer
bodyJson :: Response -> Aff Foreign
bodyJson = Promise.toAff <<< _bodyJson
bodyJson = Promise.toAffE <<< _bodyJson
bodyText :: Response -> Aff String
bodyText = Promise.toAff <<< _bodyText
bodyText = Promise.toAffE <<< _bodyText
remoteAddressIp :: Response -> Effect (Maybe String)
remoteAddressIp = map (hush <<< runExcept) <<< map readImpl <<< _remoteAddressIp

View File

@ -2,42 +2,42 @@ import { Page } from 'puppeteer'
/**
* `foreign import _bypassCsp :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _bypassCsp = p => p.setBypassCSP(true)
export const _bypassCsp = p => () => p.setBypassCSP(true)
/**
* `foreign import _unbypassCsp :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _unbypassCsp = p => p.setBypassCSP(false)
export const _unbypassCsp = p => () => p.setBypassCSP(false)
/**
* `foreign import _enableCache :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _enableCache = p => p.setCacheEnabled(true)
export const _enableCache = p => () => p.setCacheEnabled(true)
/**
* `foreign import _disableCache :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _disableCache = p => p.setCacheEnabled(false)
export const _disableCache = p => () => p.setCacheEnabled(false)
/**
* `foreign import _interceptRequests :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _interceptRequests = p => p.setRequestInterception(true)
export const _interceptRequests = p => () => p.setRequestInterception(true)
/**
* `foreign import _uninterceptRequests :: Page -> Promise Unit`
* @type {(_p: Page) => Promise<void>}
* @type {(_p: Page) => () => Promise<void>}
*/
export const _uninterceptRequests = p => p.setRequestInterception(false)
export const _uninterceptRequests = p => () => p.setRequestInterception(false)
/**
* `foreign import _sendExtraHeaders :: Map String String -> Page -> Promise Unit`
* @type {(_0: Record<string, string>) => (_1: Page) => Promise<void>}
* @type {(_0: Record<string, string>) => (_1: Page) => () => Promise<void>}
*/
export const _sendExtraHeaders = h => p => p.setExtraHTTPHeaders(h)
export const _sendExtraHeaders = h => p => () => p.setExtraHTTPHeaders(h)

View File

@ -14,6 +14,7 @@ import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Map (Map)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Page, closeContext)
@ -21,16 +22,16 @@ import Puppeteer.FFI as FFI
import Puppeteer.HTTP (Request)
import Puppeteer.Page.Event as Event
foreign import _bypassCsp :: Page -> Promise Unit
foreign import _unbypassCsp :: Page -> Promise Unit
foreign import _bypassCsp :: Page -> Effect (Promise Unit)
foreign import _unbypassCsp :: Page -> Effect (Promise Unit)
foreign import _enableCache :: Page -> Promise Unit
foreign import _disableCache :: Page -> Promise Unit
foreign import _enableCache :: Page -> Effect (Promise Unit)
foreign import _disableCache :: Page -> Effect (Promise Unit)
foreign import _interceptRequests :: Page -> Promise Unit
foreign import _uninterceptRequests :: Page -> Promise Unit
foreign import _interceptRequests :: Page -> Effect (Promise Unit)
foreign import _uninterceptRequests :: Page -> Effect (Promise Unit)
foreign import _sendExtraHeaders :: Foreign -> Page -> Promise Unit
foreign import _sendExtraHeaders :: Foreign -> Page -> Effect (Promise Unit)
type BypassCSPHint :: Symbol
type BypassCSPHint = "CSP is being bypassed. Invoking `Puppeteer.closeContext` will restore default CSP behavior."
@ -43,18 +44,18 @@ type InterceptRequestsHint = "Requests are being intercepted. Invoking `Puppetee
bypassCsp :: Page -> Aff (Context BypassCSPHint)
bypassCsp p = do
Promise.toAff $ _bypassCsp p
pure $ Context (\_ -> Promise.toAff $ _unbypassCsp p)
Promise.toAffE $ _bypassCsp p
pure $ Context (\_ -> Promise.toAffE $ _unbypassCsp p)
disableCache :: Page -> Aff (Context DisableCacheHint)
disableCache p = do
Promise.toAff $ _disableCache p
pure $ Context (\_ -> Promise.toAff $ _enableCache p)
Promise.toAffE $ _disableCache p
pure $ Context (\_ -> Promise.toAffE $ _enableCache p)
interceptRequests :: Page -> Aff (Context InterceptRequestsHint)
interceptRequests p = do
Promise.toAff $ _interceptRequests p
pure (Context $ \_ -> Promise.toAff $ _uninterceptRequests p)
Promise.toAffE $ _interceptRequests p
pure (Context $ \_ -> Promise.toAffE $ _uninterceptRequests p)
interceptNextRequest :: (Context InterceptRequestsHint -> Request -> Aff Unit) -> Page -> Aff Unit
interceptNextRequest cb p = do
@ -65,4 +66,4 @@ interceptNextRequest cb p = do
pure unit
sendExtraHeaders :: Map String String -> Page -> Aff Unit
sendExtraHeaders h = Promise.toAff <<< _sendExtraHeaders (FFI.mapToRecord h)
sendExtraHeaders h = Promise.toAffE <<< _sendExtraHeaders (FFI.mapToRecord h)

View File

@ -10,28 +10,28 @@ export const _navigation = ev => p => () =>
/**
* `foreign import _networkIdle :: Number -> Foreign -> Page -> Promise Unit`
* @type {(_1: number) => (_2: Page) => Promise<void>}
* @type {(_1: number) => (_2: Page) => () => Promise<void>}
*/
export const _networkIdle = idleTime => p =>
export const _networkIdle = idleTime => p => () =>
p.waitForNetworkIdle({ idleTime, timeout: 0 })
/**
* `foreign import _selector :: forall a. String -> Number -> Page -> Promise (Handle a)`
* @type {(_0: string) => (_2: Page) => Promise<ElementHandle<Element> | null>}
* @type {(_0: string) => (_2: Page) => () => Promise<ElementHandle<Element> | null>}
*/
export const _selectorToExist = sel => p =>
export const _selectorToExist = sel => p => () =>
p.waitForSelector(sel, { timeout: 0 })
/**
* `foreign import _selector :: forall a. String -> Number -> Page -> Promise (Handle a)`
* @type {(_0: string) => (_2: Page) => Promise<ElementHandle<Element> | null>}
* @type {(_0: string) => (_2: Page) => () => Promise<ElementHandle<Element> | null>}
*/
export const _selector = sel => p =>
export const _selector = sel => p => () =>
p.waitForSelector(sel, { visible: true, timeout: 0 })
/**
* `foreign import _selector :: forall a. String -> Number -> Page -> Promise (Handle a)`
* @type {(_0: string) => (_2: Page) => Promise<void>}
* @type {(_0: string) => (_2: Page) => () => Promise<void>}
*/
export const _selectorToBeHidden = sel => p =>
export const _selectorToBeHidden = sel => p => () =>
p.waitForSelector(sel, { hidden: true, timeout: 0 }).then(() => {})

View File

@ -28,10 +28,10 @@ type WaitingForNavigationHint :: Symbol
type WaitingForNavigationHint = "`Puppeteer.Page.WaitFor.navigation` was initiated, waiting for your code to trigger the navigation. Invoke `Puppeteer.closeContext` to block once the navigation has been initiated."
foreign import _navigation :: Foreign -> Page -> Effect (Promise Unit)
foreign import _networkIdle :: Number -> Page -> Promise Unit
foreign import _selector :: forall a. String -> Page -> Promise (Handle a)
foreign import _selectorToExist :: forall a. String -> Page -> Promise (Handle a)
foreign import _selectorToBeHidden :: String -> Page -> Promise Unit
foreign import _networkIdle :: Number -> Page -> Effect (Promise Unit)
foreign import _selector :: forall a. String -> Page -> Effect (Promise (Handle a))
foreign import _selectorToExist :: forall a. String -> Page -> Effect (Promise (Handle a))
foreign import _selectorToBeHidden :: String -> Page -> Effect (Promise Unit)
navigation :: LifecycleEvent -> Page -> Effect (Context WaitingForNavigationHint)
navigation ev p = do
@ -39,13 +39,13 @@ navigation ev p = do
pure $ Context (\_ -> Promise.toAff $ promise)
networkIdle :: NetworkIdleFor -> Page -> Aff Unit
networkIdle i = Promise.toAff <<< _networkIdle (unwrap $ unwrap i)
networkIdle i = Promise.toAffE <<< _networkIdle (unwrap $ unwrap i)
selector :: forall s e. Selector s e => s -> Page -> Aff (Handle e)
selector s = Promise.toAff <<< _selectorToExist (toCSS s)
selector s = Promise.toAffE <<< _selectorToExist (toCSS s)
selectorToBeVisible :: forall s e. Selector s e => s -> Page -> Aff (Handle e)
selectorToBeVisible s = Promise.toAff <<< _selector (toCSS s)
selectorToBeVisible s = Promise.toAffE <<< _selector (toCSS s)
selectorToBeHidden :: forall s e. Selector s e => s -> Page -> Aff Unit
selectorToBeHidden s = Promise.toAff <<< _selectorToBeHidden (toCSS s)
selectorToBeHidden s = Promise.toAffE <<< _selectorToBeHidden (toCSS s)

View File

@ -15,81 +15,69 @@ export const mouse = p => () => p.mouse
/** @type {(_: Page) => () => Touchscreen} */
export const touchscreen = p => () => p.touchscreen
/** @type {(_: Browser | BrowserContext) => Promise<Page>} */
export const _newPage = b => b.newPage()
/** @type {(_: Browser | BrowserContext) => () => Promise<Page>} */
export const _newPage = b => () => b.newPage()
/** @type {(_: Browser | BrowserContext) => Promise<Array<Page>>} */
export const _all = b => b.pages()
/** @type {(_: Browser | BrowserContext) => () => Promise<Array<Page>>} */
export const _all = b => () => b.pages()
/**
* `foreign import _findAll :: String -> Page -> Promise (Array (Handle HTMLElement))`
* @type {(_1: string) => (_2: Page) => Promise<Array<ElementHandle<any>>>}
* @type {(_1: string) => (_2: Page) => () => Promise<Array<ElementHandle<any>>>}
*/
export const _findAll = s => p => p.$$(s)
export const _findAll = s => p => () => p.$$(s)
/**
* `foreign import _addScriptTag :: Foreign -> Page -> Promise (Handle HTMLScriptElement)`
* @type {(_1: import("puppeteer").FrameAddScriptTagOptions) => (_2: Page) => Promise<ElementHandle<any>>}
* @type {(_1: import("puppeteer").FrameAddScriptTagOptions) => (_2: Page) => () => Promise<ElementHandle<any>>}
*/
export const _addScriptTag = o => p => p.addScriptTag(o)
export const _addScriptTag = o => p => () => p.addScriptTag(o)
/**
* `foreign import _addStyleTag :: Foreign -> Page -> Promise (Handle Foreign)`
* @type {(_1: import("puppeteer").FrameAddStyleTagOptions) => (_2: Page) => Promise<ElementHandle<any>>}
* @type {(_1: import("puppeteer").FrameAddStyleTagOptions) => (_2: Page) => () => Promise<ElementHandle<any>>}
*/
export const _addStyleTag = o => p => p.addStyleTag(o)
export const _addStyleTag = o => p => () => p.addStyleTag(o)
/**
* `foreign import _bringToFront :: Page -> Promise Unit`
* @type {(_1: Page) => Promise<void>}
* @type {(_1: Page) => () => Promise<void>}
*/
export const _bringToFront = p => p.bringToFront()
export const _bringToFront = p => () => p.bringToFront()
/**
* `foreign import _close :: forall r. Page -> Promise Unit`
* @type {(_0: Page) => Promise<void>}
* @type {(_0: Page) => () => Promise<void>}
*/
export const _close = p => p.close()
export const _close = p => () => p.close()
/**
* `foreign import _isClosed :: forall r. Page -> Effect Boolean`
* @type {(_0: Page) => () => boolean}
*/
export const isClosed = p => () => p.isClosed()
/**
* `foreign import _content :: Page -> Promise String`
* @type {(_0: Page) => Promise<string>}
* @type {(_0: Page) => () => Promise<string>}
*/
export const _content = p => p.content()
export const _content = p => () => p.content()
/**
* `foreign import _setContent :: String -> Foreign -> Page -> Promise Unit`
* @type {(_0: string) => (_2: import("puppeteer").PuppeteerLifeCycleEvent) => (_4: Page) => Promise<void>}
* @type {(_0: string) => (_2: import("puppeteer").PuppeteerLifeCycleEvent) => (_4: Page) => () => Promise<void>}
*/
export const _setContent = html => ev => p =>
export const _setContent = html => ev => p => () =>
p.setContent(html, { timeout: 0, waitUntil: ev })
/**
* `foreign import _setViewport :: Viewport -> Page -> Promise Unit`
* @type {(_0: import("puppeteer").Viewport) => (_4: Page) => Promise<void>}
* @type {(_0: import("puppeteer").Viewport) => (_4: Page) => () => Promise<void>}
*/
export const _setViewport = v => p => p.setViewport(v)
export const _setViewport = v => p => () => p.setViewport(v)
/**
* `foreign import _title :: Page -> Promise String`
* @type {(_4: Page) => Promise<string>}
* @type {(_4: Page) => () => Promise<string>}
*/
export const _title = p => p.title()
export const _title = p => () => p.title()
/**
* `foreign import _url :: Page -> Effect URL`
* @type {(_4: Page) => () => string}
*/
export const url = p => () => p.url()
/**
* `foreign import _viewport :: Page -> Nullable Viewport`
* @type {(_0: Page) => import("puppeteer").Viewport | null}
*/
export const _viewport = p => p.viewport()

View File

@ -102,56 +102,56 @@ foreign import mouse :: Page -> Effect Unit
foreign import touchscreen :: Page -> Effect Unit
foreign import isClosed :: Page -> Effect Boolean
foreign import _newPage :: Foreign -> Promise Page
foreign import _all :: Foreign -> Promise (Array Page)
foreign import _findAll :: forall a. String -> Page -> Promise (Array (Handle a))
foreign import _addScriptTag :: Foreign -> Page -> Promise (Handle HTMLScriptElement)
foreign import _addStyleTag :: Foreign -> Page -> Promise (Handle Foreign)
foreign import _bringToFront :: Page -> Promise Unit
foreign import _close :: Page -> Promise Unit
foreign import _content :: Page -> Promise String
foreign import _setContent :: String -> Foreign -> Page -> Promise Unit
foreign import _setViewport :: Foreign -> Page -> Promise Unit
foreign import _title :: Page -> Promise String
foreign import _newPage :: Foreign -> Effect (Promise Page)
foreign import _all :: Foreign -> Effect (Promise (Array Page))
foreign import _findAll :: forall a. String -> Page -> Effect (Promise (Array (Handle a)))
foreign import _addScriptTag :: Foreign -> Page -> Effect (Promise (Handle HTMLScriptElement))
foreign import _addStyleTag :: Foreign -> Page -> Effect (Promise (Handle Foreign))
foreign import _bringToFront :: Page -> Effect (Promise Unit)
foreign import _close :: Page -> Effect (Promise Unit)
foreign import _content :: Page -> Effect (Promise String)
foreign import _setContent :: String -> Foreign -> Page -> Effect (Promise Unit)
foreign import _setViewport :: Foreign -> Page -> Effect (Promise Unit)
foreign import _title :: Page -> Effect (Promise String)
foreign import _viewport :: Page -> Foreign
new :: forall b. PageProducer b => b -> Aff Page
new = Promise.toAff <<< _newPage <<< unsafeToForeign
new = Promise.toAffE <<< _newPage <<< unsafeToForeign
all :: forall b. PageProducer b => b -> Aff (Array Page)
all = Promise.toAff <<< _all <<< unsafeToForeign
all = Promise.toAffE <<< _all <<< unsafeToForeign
findAll :: forall s e. Selector s e => s -> Page -> Aff (Array (Handle e))
findAll s = Promise.toAff <<< _findAll (toCSS s)
findAll s = Promise.toAffE <<< _findAll (toCSS s)
findFirst :: forall s e. Selector s e => s -> Page -> Aff (Maybe (Handle e))
findFirst s = map Array.head <<< findAll s
addScriptTag :: AddScript -> Page -> Aff (Handle HTMLScriptElement)
addScriptTag a = Promise.toAff <<< _addScriptTag (prepareAddScript a)
addScriptTag a = Promise.toAffE <<< _addScriptTag (prepareAddScript a)
addStyleTag :: forall s e. AddStyle s e => s -> Page -> Aff (Handle e)
addStyleTag a h = do
t <- Promise.toAff $ _addStyleTag (prepareAddStyle a) h
t <- Promise.toAffE $ _addStyleTag (prepareAddStyle a) h
pure $ unsafeCoerceHandle t
bringToFront :: Page -> Aff Unit
bringToFront = Promise.toAff <<< _bringToFront
bringToFront = Promise.toAffE <<< _bringToFront
close :: Page -> Aff Unit
close = Promise.toAff <<< _close
close = Promise.toAffE <<< _close
content :: Page -> Aff String
content = Promise.toAff <<< _content
content = Promise.toAffE <<< _content
setContent :: String -> LifecycleEvent -> Page -> Aff Unit
setContent s ev = Promise.toAff <<< _setContent s (duplexWrite duplexLifecycleEvent ev)
setContent s ev = Promise.toAffE <<< _setContent s (duplexWrite duplexLifecycleEvent ev)
setViewport :: Viewport -> Page -> Aff Unit
setViewport vp = Promise.toAff <<< _setViewport (duplexWrite duplexViewport vp)
setViewport vp = Promise.toAffE <<< _setViewport (duplexWrite duplexViewport vp)
title :: Page -> Aff String
title = Promise.toAff <<< _title
title = Promise.toAffE <<< _title
viewport :: Page -> Maybe Viewport
viewport = hush <<< runExcept <<< readImpl <<< _viewport

View File

@ -10,14 +10,14 @@ import Captcha from 'puppeteer-extra-plugin-recaptcha'
/** @type {(_: PluginOptions) => (_: PuppeteerExtra) => () => PuppeteerExtra} */
export const _captcha = o => p => () => p.use(Captcha(o))
/** @type {(_: Page) => Promise<{captchas: CaptchaInfo[], filtered: unknown[]}>} */
export const _findCaptchas = p => p.findRecaptchas()
/** @type {(_: Page) => () => Promise<{captchas: CaptchaInfo[], filtered: unknown[]}>} */
export const _findCaptchas = p => () => p.findRecaptchas()
/** @type {(_: Page) => (_: CaptchaInfo[]) => Promise<{solutions: CaptchaSolution[]}>} */
export const _getSolutions = p => cs => p.getRecaptchaSolutions(cs)
/** @type {(_: Page) => (_: CaptchaInfo[]) => () => Promise<{solutions: CaptchaSolution[]}>} */
export const _getSolutions = p => cs => () => p.getRecaptchaSolutions(cs)
/** @type {(_: Page) => (_: CaptchaSolution[]) => Promise<{solved: CaptchaSolved[]}>} */
export const _enterSolutions = p => cs => p.enterRecaptchaSolutions(cs)
/** @type {(_: Page) => (_: CaptchaSolution[]) => () => Promise<{solved: CaptchaSolved[]}>} */
export const _enterSolutions = p => cs => () => p.enterRecaptchaSolutions(cs)
/** @type {(_: Page) => Promise<{captchas: CaptchaInfo[], filtered: unknown[], solutions: CaptchaSolution[], solved: CaptchaSolved[]}>} */
export const _solveCaptchas = p => p.solveRecaptchas()
/** @type {(_: Page) => () => Promise<{captchas: CaptchaInfo[], filtered: unknown[], solutions: CaptchaSolution[], solved: CaptchaSolved[]}>} */
export const _solveCaptchas = p => () => p.solveRecaptchas()

View File

@ -256,10 +256,10 @@ duplexInfo =
foreign import data CaptchaPlugin :: Type
foreign import _captcha :: forall (r :: Row Type). Foreign -> Puppeteer r -> Effect (Puppeteer (captcha :: CaptchaPlugin | r))
foreign import _findCaptchas :: Page -> Promise Foreign
foreign import _getSolutions :: Page -> Foreign -> Promise Foreign
foreign import _enterSolutions :: Page -> Foreign -> Promise Foreign
foreign import _solveCaptchas :: Page -> Promise Foreign
foreign import _findCaptchas :: Page -> Effect (Promise Foreign)
foreign import _getSolutions :: Page -> Foreign -> Effect (Promise Foreign)
foreign import _enterSolutions :: Page -> Foreign -> Effect (Promise Foreign)
foreign import _solveCaptchas :: Page -> Effect (Promise Foreign)
read :: forall @a. ReadForeign a => Foreign -> Either Error a
read = lmap (error <<< show) <<< runExcept <<< readImpl
@ -282,24 +282,24 @@ infos f = do
findCaptchas :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Aff (Array CaptchaInfoMaybeFiltered)
findCaptchas _ p = do
f <- Promise.toAff $ _findCaptchas p
f <- Promise.toAffE $ _findCaptchas p
liftEither $ infos f
getSolutions :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Array CaptchaInfo -> Aff (Array CaptchaSolution)
getSolutions _ p is = do
f <- Promise.toAff $ _getSolutions p (writeImpl $ duplexWrite duplexInfo <$> is)
f <- Promise.toAffE $ _getSolutions p (writeImpl $ duplexWrite duplexInfo <$> is)
{ solutions } <- liftEither $ read @({ solutions :: Array Foreign }) f
liftEither $ for solutions $ duplexRead duplexSoln
enterSolutions :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Array CaptchaSolution -> Aff (Array CaptchaSolved)
enterSolutions _ p sols = do
f <- Promise.toAff $ _enterSolutions p (writeImpl $ duplexWrite duplexSoln <$> sols)
f <- Promise.toAffE $ _enterSolutions p (writeImpl $ duplexWrite duplexSoln <$> sols)
{ solved } <- liftEither $ read @({ solved :: Array Foreign }) f
liftEither $ for solved $ duplexRead duplexSolved
solveCaptchas :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Aff SolveResult
solveCaptchas _ p = do
f <- Promise.toAff $ _solveCaptchas p
f <- Promise.toAffE $ _solveCaptchas p
{ solved, solutions } <- liftEither $ read @({ solved :: Array Foreign, solutions :: Array Foreign }) f
captchas <- liftEither $ infos f
liftEither do