mirror of
https://github.com/klntsky/purescript-playwright.git
synced 2024-11-25 21:52:00 +03:00
Merge all forks upstream + latest spago and fix tests (#3)
* Fix compiling errors building with purs/psc-set 0.14.2
* Remove bower and pulp
* Add pacakge-lock.json
* Update playwright minimum version
* evaluation needs to be one expression/statement
* Add connect/connectOverCDP functions
* Convert FFI to more modern JS
* Add bindings for focus, fill, connect among others
* Make ready for 0.15 but drop tests
* Use milliseconds for timeouts
* update spago and esm
* fix tests
* Revert "fix tests"
This reverts commit aec92cb08e
.
* fix effectfulGetter
* add package-lock.json
* update .gitignore
* update CI, aff affCall to context
---------
Co-authored-by: kamoii <>
Co-authored-by: Mark Eibes <mark.eibes@gmail.com>
Co-authored-by: phtz <spamsucks@posteo.de>
This commit is contained in:
parent
3638634ae1
commit
6d0aba0f34
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -16,5 +16,6 @@ jobs:
|
||||
run: |
|
||||
PATH="$PATH:./node_modules/.bin/"
|
||||
npm install
|
||||
npm install spago purescript
|
||||
npm install spago@next purescript
|
||||
npx playwright install --with-deps chromium
|
||||
spago test
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago/
|
||||
/.DS_Store
|
||||
|
17
bower.json
17
bower.json
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "purescript-playwright",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"output"
|
||||
],
|
||||
"dependencies": {
|
||||
"purescript-prelude": "^4.1.1",
|
||||
"purescript-console": "^4.4.0",
|
||||
"purescript-effect": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"purescript-psci-support": "^4.0.0"
|
||||
}
|
||||
}
|
57
package-lock.json
generated
Normal file
57
package-lock.json
generated
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "purescript-playwright",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "purescript-playwright",
|
||||
"version": "0.0.1",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"playwright": "^1.45.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.45.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz",
|
||||
"integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.45.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.45.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz",
|
||||
"integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,11 +7,8 @@
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"bower": "^1.8.8",
|
||||
"playwright": "^1.3.0",
|
||||
"pulp": "^15.0.0"
|
||||
"playwright": "^1.45.1"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "pulp test"
|
||||
},
|
||||
|
@ -1,42 +0,0 @@
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.14.2-20210629/packages.dhall sha256:534c490bb73cae75adb5a39871142fd8db5c2d74c90509797a80b8bb0d5c3f7b
|
||||
|
||||
let overrides =
|
||||
{ untagged-union =
|
||||
{ dependencies =
|
||||
[ "assert"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "foreign"
|
||||
, "foreign-object"
|
||||
, "literals"
|
||||
, "maybe"
|
||||
, "newtype"
|
||||
, "psci-support"
|
||||
, "tuples"
|
||||
, "unsafe-coerce"
|
||||
]
|
||||
, repo = "https://github.com/jvliwanag/purescript-untagged-union.git"
|
||||
, version = "v0.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
let additions =
|
||||
{ literals =
|
||||
{ dependencies =
|
||||
[ "assert"
|
||||
, "effect"
|
||||
, "console"
|
||||
, "integers"
|
||||
, "numbers"
|
||||
, "partial"
|
||||
, "psci-support"
|
||||
, "unsafe-coerce"
|
||||
, "typelevel-prelude"
|
||||
]
|
||||
, repo = "https://github.com/jvliwanag/purescript-literals.git"
|
||||
, version = "7b2ae20f77c67b7e419a92fdd0dc7a09b447b18e"
|
||||
}
|
||||
}
|
||||
|
||||
in upstream ⫽ overrides ⫽ additions
|
29
spago.dhall
29
spago.dhall
@ -1,29 +0,0 @@
|
||||
{ name = "playwright"
|
||||
, dependencies =
|
||||
[ "argonaut-core"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "prelude"
|
||||
, "psci-support"
|
||||
, "aff-promise"
|
||||
, "test-unit"
|
||||
, "untagged-union"
|
||||
, "node-buffer"
|
||||
, "node-fs-aff"
|
||||
, "undefined"
|
||||
, "aff"
|
||||
, "either"
|
||||
, "exceptions"
|
||||
, "foreign"
|
||||
, "foreign-object"
|
||||
, "literals"
|
||||
, "maybe"
|
||||
, "node-streams"
|
||||
, "ordered-collections"
|
||||
, "refs"
|
||||
, "strings"
|
||||
, "transformers"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
1386
spago.lock
Normal file
1386
spago.lock
Normal file
File diff suppressed because it is too large
Load Diff
30
spago.yaml
Normal file
30
spago.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
package:
|
||||
dependencies:
|
||||
- aff
|
||||
- aff-promise
|
||||
- argonaut-core
|
||||
- console
|
||||
- datetime
|
||||
- effect
|
||||
- either
|
||||
- exceptions
|
||||
- foreign
|
||||
- foreign-object
|
||||
- literals
|
||||
- maybe
|
||||
- node-buffer
|
||||
- node-fs
|
||||
- node-streams
|
||||
- ordered-collections
|
||||
- prelude
|
||||
- psci-support
|
||||
- refs
|
||||
- strings
|
||||
- test-unit
|
||||
- transformers
|
||||
- untagged-union
|
||||
- literals
|
||||
name: playwright
|
||||
workspace:
|
||||
packageSet:
|
||||
registry: 53.2.0
|
@ -1,15 +1,21 @@
|
||||
/* global exports */
|
||||
|
||||
exports.exposeBinding_ = function (x) {
|
||||
return function (name) {
|
||||
return function (cb) {
|
||||
return function (opts) {
|
||||
return function () {
|
||||
return x.exposeBinding(name, function (info, arg) {
|
||||
return cb(info)(arg)();
|
||||
}, opts);
|
||||
};
|
||||
};
|
||||
export const exposeBinding_ = x => name => cb => opts => () => {
|
||||
return x.exposeBinding(
|
||||
name,
|
||||
function (info, arg) {
|
||||
return cb(info)(arg)()
|
||||
},
|
||||
opts
|
||||
)
|
||||
}
|
||||
|
||||
export const onResponse = function (page) {
|
||||
return function (cb) {
|
||||
return function () {
|
||||
page.on('response', function (response) {
|
||||
cb(response)();
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,7 +1,10 @@
|
||||
module Playwright
|
||||
( launch
|
||||
, connect
|
||||
, connectOverCDP
|
||||
, close
|
||||
, contexts
|
||||
, context
|
||||
, isConnected
|
||||
, version
|
||||
, newPage
|
||||
@ -9,6 +12,7 @@ module Playwright
|
||||
, goBack
|
||||
, goto
|
||||
, addCookies
|
||||
, cookies
|
||||
, hover
|
||||
, innerHTML
|
||||
, innerText
|
||||
@ -40,25 +44,45 @@ module Playwright
|
||||
, setViewportSize
|
||||
, title
|
||||
, exposeBinding
|
||||
, fill
|
||||
, focus
|
||||
, onResponse
|
||||
, connect
|
||||
, module Playwright.Data
|
||||
, module Playwright.Options
|
||||
)
|
||||
where
|
||||
|
||||
import Playwright.Options
|
||||
|
||||
import Control.Promise (Promise, fromAff, toAffE)
|
||||
import Data.String.Regex (Regex)
|
||||
import Data.Unit (unit)
|
||||
import Effect (Effect)
|
||||
import Effect.Aff (Aff)
|
||||
import Foreign (Foreign, unsafeToForeign)
|
||||
import Literals.Null (Null)
|
||||
import Node.Buffer (Buffer)
|
||||
import Playwright.Data
|
||||
import Playwright.Data (Browser, BrowserContext, BrowserType, ConsoleMessage, Dialog, Download, ElementHandle, ElementState, FileChooser, Frame, JSHandle, Keyboard, Modifier, Mouse, MouseButton, Page, Raf, Request, Response, Route, ScreenshotType, Selector(..), Selectors, URL(..), WaitUntil, Worker, alt, attached, chromium, control, detached, domcontentloaded, firefox, hidden, jpg, left, load, meta, middle, networkidle, png, raf, right, shift, visible, webkit)
|
||||
import Playwright.Internal (effCall, effProp, affCall)
|
||||
import Playwright.Options
|
||||
import Prelude (Unit, ($))
|
||||
import Undefined (undefined)
|
||||
import Untagged.Castable (class Castable)
|
||||
import Untagged.Union (type (|+|), UndefinedOr)
|
||||
import Playwright.Types (Cookie)
|
||||
|
||||
foreign import onResponse :: Page -> (Response -> Effect Unit) -> Effect Unit
|
||||
|
||||
fill
|
||||
:: forall o
|
||||
. Castable o FillOptions
|
||||
=> Page -> Selector -> String -> o -> Aff Unit
|
||||
fill = affCall "fill" \_ -> fill
|
||||
|
||||
focus
|
||||
:: forall o
|
||||
. Castable o FocusOptions
|
||||
=> Page -> Selector -> o -> Aff Unit
|
||||
focus = affCall "focus" \_ -> focus
|
||||
|
||||
launch
|
||||
:: forall o
|
||||
@ -67,6 +91,35 @@ launch
|
||||
launch =
|
||||
affCall "launch" \_ -> launch
|
||||
|
||||
type WebSocketEndpoint = String
|
||||
|
||||
connect
|
||||
:: forall o
|
||||
. Castable o ConnectOptions
|
||||
=> BrowserType
|
||||
-> WebSocketEndpoint
|
||||
-> o
|
||||
-> Aff Browser
|
||||
connect = affCall "connect" \_ -> connect
|
||||
|
||||
type ConnectOptions =
|
||||
{ timeout :: UndefinedOr Number
|
||||
}
|
||||
|
||||
connectOverCDP
|
||||
:: forall o
|
||||
. Castable o ConnectOverCDPOptions
|
||||
=> BrowserType
|
||||
-> String
|
||||
-> o
|
||||
-> Aff Browser
|
||||
connectOverCDP =
|
||||
affCall "connectOverCDP" \_ -> connectOverCDP
|
||||
|
||||
type ConnectOverCDPOptions =
|
||||
{ timeout :: UndefinedOr Number
|
||||
}
|
||||
|
||||
close
|
||||
:: forall x
|
||||
. Castable x (Browser |+| BrowserContext |+| Page)
|
||||
@ -116,12 +169,15 @@ goto
|
||||
goto =
|
||||
affCall "goto" \_ -> goto
|
||||
|
||||
type Cookie =
|
||||
{ name :: String
|
||||
, value :: String
|
||||
, url :: UndefinedOr String
|
||||
}
|
||||
context :: Page -> BrowserContext
|
||||
context = affCall "context" \_ -> context
|
||||
|
||||
cookies
|
||||
:: BrowserContext
|
||||
-> Aff (Array Cookie)
|
||||
cookies =
|
||||
affCall "cookies" \_ -> cookies
|
||||
|
||||
addCookies
|
||||
:: BrowserContext
|
||||
-> Array Cookie
|
||||
@ -320,7 +376,7 @@ waitForFunction
|
||||
-- ^ Function to be evaluated in browser context
|
||||
-> o
|
||||
-> Aff JSHandle
|
||||
waitForFunction x s o = waitForFunction' x s (unsafeToForeign undefined) o
|
||||
waitForFunction x s o = waitForFunction' x s unit o
|
||||
where
|
||||
waitForFunction' = affCall "waitForFunction" \_ -> waitForFunction'
|
||||
|
||||
|
@ -1,31 +1,36 @@
|
||||
/* global require exports */
|
||||
var P = require('playwright');
|
||||
import { chromium as pwChromium, firefox as pwFirefox, webkit as pwWebkit } from 'playwright';
|
||||
|
||||
exports.png = "png";
|
||||
exports.jpg = "jpg";
|
||||
export const png = "png";
|
||||
export const jpg = "jpg";
|
||||
|
||||
exports.chromium = P.chromium;
|
||||
exports.firefox = P.firefox;
|
||||
exports.webkit = P.webkit;
|
||||
export const chromium = pwChromium;
|
||||
export const firefox = pwFirefox;
|
||||
export const webkit = pwWebkit;
|
||||
|
||||
exports.domcontentloaded = "domcontentloaded";
|
||||
exports.load = "load";
|
||||
exports.networkidle = "networkidle";
|
||||
export const domcontentloaded = "domcontentloaded";
|
||||
export const load = "load";
|
||||
export const networkidle = "networkidle";
|
||||
|
||||
exports.alt = "Alt";
|
||||
exports.control = "Control";
|
||||
exports.meta = "Meta";
|
||||
exports.shift = "Shift";
|
||||
export const alt = "Alt";
|
||||
export const control = "Control";
|
||||
export const meta = "Meta";
|
||||
export const shift = "Shift";
|
||||
|
||||
exports.null = null;
|
||||
const _null = null;
|
||||
export { _null as null };
|
||||
|
||||
exports.left = "left";
|
||||
exports.right = "right";
|
||||
exports.middle = "middle";
|
||||
export const left = "left";
|
||||
export const right = "right";
|
||||
export const middle = "middle";
|
||||
|
||||
exports.attached = "attached";
|
||||
exports.detached = "detached";
|
||||
exports.visible = "visible";
|
||||
exports.hidden = "hidden";
|
||||
export const attached = "attached";
|
||||
export const detached = "detached";
|
||||
export const visible = "visible";
|
||||
export const hidden = "hidden";
|
||||
|
||||
exports.raf = "raf";
|
||||
export const raf = "raf";
|
||||
|
||||
export const strict = "Strict";
|
||||
export const lax = "Lax";
|
||||
export const none = "None";
|
||||
|
@ -65,5 +65,10 @@ foreign import detached :: ElementState
|
||||
foreign import visible :: ElementState
|
||||
foreign import hidden :: ElementState
|
||||
|
||||
foreign import data SameSite :: Type
|
||||
foreign import strict :: SameSite
|
||||
foreign import lax :: SameSite
|
||||
foreign import none :: SameSite
|
||||
|
||||
foreign import data Raf :: Type
|
||||
foreign import raf :: Raf
|
||||
|
@ -1,17 +1,10 @@
|
||||
/* global exports */
|
||||
|
||||
exports.createReadStream_ = function (Nothing) {
|
||||
return function (Just) {
|
||||
return function (Download) {
|
||||
return function () {
|
||||
return Download.createReadStream().then(function (result) {
|
||||
if (result === null) {
|
||||
return Nothing;
|
||||
} else {
|
||||
return Just(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export const createReadStream_ = Nothing => Just => Download => () =>
|
||||
Download.createReadStream().then(result => {
|
||||
if (result === null) {
|
||||
return Nothing
|
||||
} else {
|
||||
return Just(result)
|
||||
}
|
||||
})
|
||||
|
@ -1,13 +1,7 @@
|
||||
/* global exports */
|
||||
|
||||
exports.onForeign = function (obj) {
|
||||
return function (eventName) {
|
||||
return function (effCallback) {
|
||||
return function () {
|
||||
obj.on(eventName, function (argument) {
|
||||
effCallback(argument)();
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export const onForeign = (obj) => (eventName) => (effCallback) => () => {
|
||||
obj.on(eventName, (argument) => {
|
||||
effCallback(argument)()
|
||||
})
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* @param {string} property - method to call on object
|
||||
* @param {number} n - number of (curried) arguments
|
||||
* @param {number} argsCount - number of (curried) arguments
|
||||
* @param {effectRunnerWrapper} effectRunnerWrapper - a function to overrride
|
||||
* effect runner with. `toAffE` for `Aff`, `identity` for `Effect`.
|
||||
*
|
||||
@ -19,54 +19,33 @@
|
||||
* effectfulGetter('close', 0, identity);
|
||||
*/
|
||||
function effectfulGetter (property, argsCount, effectRunnerWrapper) {
|
||||
var args = [];
|
||||
return function (object) {
|
||||
function effectRunner () {
|
||||
return object[property].apply(object, args);
|
||||
function consume(arg, args, counter) {
|
||||
const argsNew = [ ...args, arg ];
|
||||
|
||||
if (counter === 0) {
|
||||
const [ object, ...rest ] = argsNew;
|
||||
|
||||
return effectRunnerWrapper(() => object[property].apply(object, rest))
|
||||
} else {
|
||||
return (a) => consume(a, argsNew, counter - 1)
|
||||
}
|
||||
}
|
||||
|
||||
var affectRunner = effectRunnerWrapper(effectRunner);
|
||||
|
||||
function chooseNext () {
|
||||
return argsCount > 0 ? argsConsumer : affectRunner;
|
||||
}
|
||||
|
||||
function argsConsumer (arg) {
|
||||
if (argsCount == 0) {
|
||||
return affectRunner;
|
||||
} else {
|
||||
args.push(arg);
|
||||
argsCount--;
|
||||
return chooseNext();
|
||||
}
|
||||
}
|
||||
|
||||
return chooseNext();
|
||||
};
|
||||
return (object) => consume(object, [], argsCount)
|
||||
}
|
||||
|
||||
function identity (x) {
|
||||
return x;
|
||||
return x;
|
||||
}
|
||||
|
||||
exports.unsafeEffCall = function (method) {
|
||||
return function (argsCount) {
|
||||
return effectfulGetter(method, argsCount, identity);
|
||||
};
|
||||
};
|
||||
|
||||
exports.unsafeAffCall = function (toAffE) {
|
||||
return function (method) {
|
||||
return function (argsCount) {
|
||||
return effectfulGetter(method, argsCount, toAffE);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
exports.effProp = function (prop) {
|
||||
return function (object) {
|
||||
return function () {
|
||||
return object[prop];
|
||||
};
|
||||
};
|
||||
export function unsafeEffCall(method) {
|
||||
return argsCount => effectfulGetter(method, argsCount, identity);
|
||||
}
|
||||
|
||||
export function unsafeAffCall(toAffE) {
|
||||
return method => argsCount => effectfulGetter(method, argsCount, toAffE);
|
||||
}
|
||||
|
||||
export function effProp(prop) {
|
||||
return object => () => object[prop];
|
||||
}
|
@ -1,17 +1,11 @@
|
||||
/* global exports */
|
||||
|
||||
exports.getProperties_ = function (insert) {
|
||||
return function (emptyMap) {
|
||||
return function (jsHandle) {
|
||||
return function () {
|
||||
return jsHandle.getProperties().then(function (props) {
|
||||
var acc = emptyMap;
|
||||
props.entries().forEach(function (pair) {
|
||||
acc = insert(pair[0])(pair[1])(acc);
|
||||
});
|
||||
return acc;
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export function getProperties_(insert) {
|
||||
return emptyMap => jsHandle => () => jsHandle.getProperties().then(props => {
|
||||
let acc = emptyMap;
|
||||
props.entries().forEach(pair => {
|
||||
acc = insert(pair[0])(pair[1])(acc);
|
||||
});
|
||||
return acc;
|
||||
});
|
||||
}
|
||||
|
@ -3,13 +3,27 @@ module Playwright.Options where
|
||||
import Playwright.Data
|
||||
|
||||
import Data.String.Regex (Regex)
|
||||
import Data.Time.Duration (Milliseconds(..))
|
||||
import Foreign (Foreign)
|
||||
import Foreign.Object (Object)
|
||||
import Literals.Null (Null)
|
||||
import Untagged.Union (UndefinedOr, type (|+|))
|
||||
import Playwright.Types (Cookie)
|
||||
|
||||
type Opt a = UndefinedOr a
|
||||
|
||||
type FocusOptions =
|
||||
{ strict :: Opt Boolean
|
||||
, timeout :: Opt Number
|
||||
}
|
||||
|
||||
type FillOptions =
|
||||
{ force :: Opt Boolean
|
||||
, noWaitAfter :: Opt Boolean
|
||||
, strict :: Opt Boolean
|
||||
, timeout :: Opt Number
|
||||
}
|
||||
|
||||
type LaunchOptions =
|
||||
{ headless :: Opt Boolean
|
||||
, executablePath :: Opt String
|
||||
@ -22,10 +36,17 @@ type LaunchOptions =
|
||||
, handleSIGINT :: Opt Boolean
|
||||
, handleSIGTERM :: Opt Boolean
|
||||
, handleSIGHUP :: Opt Boolean
|
||||
, timeout :: Opt Number
|
||||
, timeout :: Opt Milliseconds
|
||||
, env :: Opt (Object String)
|
||||
, devtools :: Opt Boolean
|
||||
, slowMo :: Opt Number
|
||||
, storageState :: Opt { cookies :: Array Cookie }
|
||||
}
|
||||
|
||||
type ConnectOptions =
|
||||
{ headers :: Opt (Object String)
|
||||
, slowMo :: Opt Number
|
||||
, timeout :: Opt Number
|
||||
}
|
||||
|
||||
type ProxyOptions =
|
||||
@ -40,11 +61,11 @@ type ScreenshotOptions =
|
||||
, "type" :: Opt ScreenshotType
|
||||
, quality :: Opt Number
|
||||
, omitBackground :: Opt Boolean
|
||||
, timeout :: Opt Number
|
||||
, timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type GotoOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
, waitUntil :: Opt WaitUntil
|
||||
, referer :: Opt String
|
||||
}
|
||||
@ -57,7 +78,7 @@ type NewpageOptions =
|
||||
}
|
||||
|
||||
type GoOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
, waitUntil :: Opt WaitUntil
|
||||
}
|
||||
|
||||
@ -68,11 +89,11 @@ type HoverOptions =
|
||||
}
|
||||
|
||||
type InnerHTMLOptions =
|
||||
{ timeout :: Opt Number
|
||||
{ timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type InnerTextOptions =
|
||||
{ timeout :: Opt Number
|
||||
{ timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type KeyboardPressOptions =
|
||||
@ -92,7 +113,7 @@ type ClickOptions =
|
||||
, modifiers :: Opt (Array Modifier)
|
||||
, force :: Opt Boolean
|
||||
, noWaitAfter :: Opt Boolean
|
||||
, timeout :: Opt Int
|
||||
, timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type MouseClickOptions =
|
||||
@ -116,31 +137,31 @@ type MouseMoveOptions =
|
||||
}
|
||||
|
||||
type WaitForNavigationOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
, url :: Opt (String |+| Regex |+| URL -> Boolean)
|
||||
, waitUntil :: Opt WaitUntil
|
||||
}
|
||||
|
||||
type WaitForRequestOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type WaitForResponseOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type WaitForSelectorOptions =
|
||||
{ state :: Opt ElementState
|
||||
, timeout :: Opt Int
|
||||
, timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type WaitForFunctionOptions =
|
||||
{ polling :: Opt (Int |+| Raf)
|
||||
, timeout :: Opt Int
|
||||
, timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type WaitForLoadStateOptions =
|
||||
{ timeout :: Opt Int
|
||||
{ timeout :: Opt Milliseconds
|
||||
}
|
||||
|
||||
type Margin =
|
||||
@ -168,5 +189,5 @@ type PdfOptions =
|
||||
|
||||
type SetFilesOptions =
|
||||
{ noWaitAfter :: Opt Boolean
|
||||
, timeout :: Opt Int
|
||||
, timeout :: Opt Milliseconds
|
||||
}
|
||||
|
@ -1,17 +1,10 @@
|
||||
/* global exports */
|
||||
|
||||
exports.finished_ = function (Nothing) {
|
||||
return function (Just) {
|
||||
return function (Response) {
|
||||
return function () {
|
||||
return Response.finished().then(function (result) {
|
||||
if (result === null) {
|
||||
return Nothing;
|
||||
} else {
|
||||
return Just(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export const finished_ = Nothing => Just => Response => () =>
|
||||
Response.finished().then((result) => {
|
||||
if (result === null) {
|
||||
return Nothing
|
||||
} else {
|
||||
return Just(result)
|
||||
}
|
||||
})
|
||||
|
14
src/Playwright/Types.purs
Normal file
14
src/Playwright/Types.purs
Normal file
@ -0,0 +1,14 @@
|
||||
module Playwright.Types where
|
||||
|
||||
import Playwright.Data (SameSite)
|
||||
|
||||
type Cookie =
|
||||
{ name :: String
|
||||
, value :: String
|
||||
, domain :: String
|
||||
, path :: String
|
||||
, expires :: Number
|
||||
, httpOnly :: Boolean
|
||||
, secure :: Boolean
|
||||
, sameSite :: SameSite
|
||||
}
|
@ -3,6 +3,7 @@ module Test.Main where
|
||||
import Control.Monad.Except (runExcept)
|
||||
import Data.Either (isLeft)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Time.Duration (Milliseconds(..))
|
||||
import Effect (Effect)
|
||||
import Effect.Aff (launchAff_, try)
|
||||
import Effect.Class (liftEffect)
|
||||
@ -13,6 +14,7 @@ import Node.Encoding as Encoding
|
||||
import Node.FS.Aff as FS
|
||||
import Node.Stream as Stream
|
||||
import Playwright
|
||||
import Node.EventEmitter (on_)
|
||||
import Playwright.ConsoleMessage as ConsoleMessage
|
||||
import Playwright.Dialog as Dialog
|
||||
import Playwright.Download as Download
|
||||
@ -78,7 +80,7 @@ main = runTest do
|
||||
withBrowserPage hello
|
||||
\page -> do
|
||||
void $ waitForSelector page (Selector "body") {}
|
||||
res <- try $ waitForSelector page (Selector "nonexistent") { timeout: 100 }
|
||||
res <- try $ waitForSelector page (Selector "nonexistent") { timeout: Milliseconds 100.0 }
|
||||
Assert.assert "waitForSelector fails when no element" $
|
||||
isLeft res
|
||||
test "waitForFunction" do
|
||||
@ -89,7 +91,7 @@ main = runTest do
|
||||
void $ waitForFunction
|
||||
page
|
||||
"document.body.textContent.includes('uniqstring')"
|
||||
{ timeout: 5000, polling: 100 }
|
||||
{ timeout: Milliseconds 5000.0, polling: 100 }
|
||||
suite "FFI" do
|
||||
test "exposeBinding" do
|
||||
withBrowserPage hello \page -> do
|
||||
@ -151,19 +153,22 @@ main = runTest do
|
||||
case mbStream of
|
||||
Nothing -> Assert.assert "Unable to get stream" false
|
||||
Just stream -> do
|
||||
liftEffect $ Stream.onDataString stream Encoding.UTF8 $ \string -> do
|
||||
liftEffect $ Stream.setEncoding stream Encoding.UTF8
|
||||
liftEffect $ stream # on_ Stream.dataHStr \string -> do
|
||||
Ref.write (Just string) downloadRef
|
||||
void $ evaluate page
|
||||
"""
|
||||
function download(filename, text) {
|
||||
var element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
||||
element.setAttribute('download', filename);
|
||||
document.body.appendChild(element);
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
{
|
||||
function download(filename, text) {
|
||||
var element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
||||
element.setAttribute('download', filename);
|
||||
document.body.appendChild(element);
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
}
|
||||
download("hello.txt","hiiii");
|
||||
}
|
||||
download("hello.txt","hiiii");
|
||||
"""
|
||||
waitForTimeout page 100
|
||||
downloadContent <- liftEffect $ Ref.read downloadRef
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* global exports __dirname */
|
||||
|
||||
exports.cwd = process.cwd();
|
||||
export const cwd = process.cwd();
|
||||
|
||||
exports.isNull = function (sth) { return sth === null; };
|
||||
export const isNull = sth => sth === null;
|
||||
|
Loading…
Reference in New Issue
Block a user