git.iko.soy/rowtype-yoga/purescript-lunapark
on main help sign in
.github/workflows/ci.ymlnew file+37
since splitsnapshots
unifiedsplit
@@ -0,0 +1,37 @@
1+name: CI
2+
3+on:
4+ push:
5+ branches: [master, main]
6+ pull_request:
7+ branches: [master, main]
8+
9+jobs:
10+ build:
11+ runs-on: ubuntu-latest
12+ steps:
13+ - uses: actions/checkout@v4
14+
15+ - name: Set up a PureScript toolchain
16+ uses: purescript-contrib/setup-purescript@main
17+ with:
18+ purescript: "latest"
19+ purs-tidy: "latest"
20+ spago: "unstable"
21+
22+ - name: Cache PureScript dependencies
23+ uses: actions/cache@v4
24+ with:
25+ key: ${{ runner.os }}-spago-${{ hashFiles('**/spago.lock') }}
26+ path: |
27+ .spago
28+ output
29+
30+ - name: Build source
31+ run: spago build --censor-stats --strict --pedantic-packages
32+
33+ - name: Run tests
34+ run: spago test --offline --censor-stats --strict --pedantic-packages -- --censor-codes=UserDefinedWarning
35+
36+ - name: Verify formatting
37+ run: purs-tidy check src test
.gitignore+1−2
@@ -1,8 +1,7 @@
1/.*
1/.*
2!/.gitignore
2!/.gitignore
3−!/.travis.yml
3+!/.github
4/bower_components/
4/bower_components/
5/node_modules/
5/node_modules/
6/output/
6/output/
7−/example/dist/test.js
8package-lock.json
7package-lock.json
.travis.ymldeleted−15
@@ -1,15 +0,0 @@
1−language: node_js
2−dist: trusty
3−sudo: required
4−node_js: stable
5−install:
6− - npm install
7− - npm install -g bower
8− - bower install --production
9−script:
10− - npm run -s build
11−after_success:
12−- >-
13− test $TRAVIS_TAG &&
14− echo $GITHUB_TOKEN | pulp login &&
15− echo y | pulp publish --no-push
README.md+23−21
@@ -1,12 +1,13 @@
1# purescript-lunapark
1# purescript-lunapark
2
2
3[![Latest release](http://img.shields.io/github/release/slamdata/purescript-lunapark.svg)](https://github.com/slamdata/purescript-lunapark/releases)
3[![Latest release](http://img.shields.io/github/release/slamdata/purescript-lunapark.svg)](https://github.com/slamdata/purescript-lunapark/releases)
4−[![Build status](https://travis-ci.org/slamdata/purescript-lunapark.svg?branch=master)](https://travis-ci.org/slamdata/purescript-lunapark)
4+![Build Status](https://github.com/slamdata/purescript-lunapark/actions/workflows/ci.yml/badge.svg)
5
5
6## Disclaimer
6## Disclaimer
7
7
8+Webdriver/JsonWire bindings for PureScript
9+
8−+ This is WIP: some things weren't implemented, some might have bugs. Filling issues and prs are welcomed!
10+- This is WIP: some things weren't implemented, some might have bugs. Filling issues and prs are welcomed!
9−+ All files in `vendor` folders: three drivers and selenium jar -- are subjects of appropriate copyrights.
10
11
11## Purescript W3C webdriver protocol bindings
12## Purescript W3C webdriver protocol bindings
12
13
@@ -15,20 +16,20 @@ won't involve any JavaScript dependencies.
15
16
16## Architecture
17## Architecture
17
18
18−+ There is a module that encodes any possible error returned by Selenium.
19+- There is a module that encodes any possible error returned by Selenium.
19−+ Low-level API uses `purescript-argonaut`'s `Json` type and `purescript-affjax`s helper functions (`get`, `post` etc)
20+- Low-level API uses `purescript-argonaut`'s `Json` type and `purescript-affjax`s helper functions (`get`, `post` etc)
20−+ Endpoints are constructed using `Endpoint@Lunapark.Endpoint` type. This module also provides helper functions
21+- Endpoints are constructed using `Endpoint@Lunapark.Endpoint` type. This module also provides helper functions
21−returning `Aff _ (Either Error Json)`
22+ returning `Aff (Either Error Json)`
22−+ Types of requests and resposes live in `Lunapark.Types` module.
23+- Types of requests and resposes live in `Lunapark.Types` module.
23−+ High-level API uses `purescript-run`. There are several functors, but the main two are: `LunaparkF` and `ActionF`.
24+- High-level API uses `purescript-run`. There are several functors, but the main two are: `LunaparkF` and `ActionF`.
24−This functor embed in `Run` encode almost all posible interactions with w3c/selenium server.
25+ This functor embed in `Run` encode almost all posible interactions with w3c/selenium server.
25−+ At first `ActionF` functor (that is a functor that encodes all posible actions like click, hover) is interpreted to
26+- At first `ActionF` functor (that is a functor that encodes all posible actions like click, hover) is interpreted to
26−`LunaparkF`, then `LunaparkF` is interpreted into `Run` with `EXCEPT` and `AFF|EFF` effects.
27+ `LunaparkF`, then `LunaparkF` is interpreted into `Run` with `EXCEPT` and `AFF|EFF` effects.
27−+ `Lunapark` is facade library on top of api, functors and error.
28+- `Lunapark` is facade library on top of api, functors and error.
28−+ Capabilities are represented via gradually typed datastructure `Array Capability`. `init` function takes a record
29+- Capabilities are represented via gradually typed datastructure `Array Capability`. `init` function takes a record
29−`{ alwaysMatch: Array Capability, firstMatch: Array (Array Capability) }`. `firstMatch` must have at least on array.
30+ `{ alwaysMatch: Array Capability, firstMatch: Array (Array Capability) }`. `firstMatch` must have at least on array.
30−+ To construct interpreter you need call `init@Lunapark.API`. The result would be `Aff _ (Either Error Interpreter)`,
31+- To construct interpreter you need call `init@Lunapark.API`. The result would be `Aff (Either Error Interpreter)`,
31−where `Interpreter` is function taking `Lunapark` monad and unwrapping it into `Run` with `EXCEPT` and `AFF|EFF`. E.g.
32+ where `Interpreter` is function taking `Lunapark` monad and unwrapping it into `Run` with `EXCEPT` and `AFF|EFF`. E.g.
32
33
33```purescript
34```purescript
34main = launchAff do
35main = launchAff do
@@ -48,7 +49,8 @@ main = launchAff do
48 sendKeys "secret"
49 sendKeys "secret"
49 sendKeys "\\xE007"
50 sendKeys "\\xE007"
50```
51```
52+
51−+ The interpreter takes care about implemented and non-implemented features of particular driver. E.g. if driver supports
53+- The interpreter takes care about implemented and non-implemented features of particular driver. E.g. if driver supports
52−`GET@/session/:sessionId/timeouts` via W3C standard it will use it otherwise the interpreter makes it a chain call of
54+ `GET@/session/:sessionId/timeouts` via W3C standard it will use it otherwise the interpreter makes it a chain call of
53−JsonWire commands. The same works for actions: they are interpreted into either `POST@/session/:sessionId/action` or
55+ JsonWire commands. The same works for actions: they are interpreted into either `POST@/session/:sessionId/action` or
54−chains of JsonWire commands.
56+ chains of JsonWire commands.
bower.jsondeleted−35
@@ -1,35 +0,0 @@
1−{
2− "name": "purescript-lunapark",
3− "homepage": "https://github.com/slamdata/purescript-lunapark",
4− "authors": [
5− "Maxim Zimaliev <zimaliev@gmail.com>"
6− ],
7− "description": "Webdriver/JsonWire bindings for PureScript",
8− "license": "Apache-2.0",
9− "keywords": [
10− "purescript",
11− "selenium",
12− "webdriver",
13− "jsonwire"
14− ],
15− "repository": {
16− "type": "git",
17− "url": "git://github.com/slamdata/purescript-lunapark.git"
18− },
19− "ignore": [
20− "**/*.",
21− "node_modules",
22− "bower_components",
23− "output",
24− "test"
25− ],
26− "dependencies": {
27− "purescript-xpath": "cryogenian/purescript-xpath#compiler/0.12",
28− "purescript-argonaut-core": "^4.0.0",
29− "purescript-argonaut-codecs": "^4.0.0",
30− "purescript-affjax": "^7.0.0",
31− "purescript-css": "^4.0.0",
32− "purescript-node-fs-aff": "^6.0.0",
33− "purescript-run": "cryogenian/purescript-run#compiler/0.12"
34− }
35−}
package.jsondeleted−17
@@ -1,17 +0,0 @@
1−{
2− "name": "purescript-lunapark",
3− "private": true,
4− "scripts": {
5− "build": "pulp build -- --strict --stash",
6− "build:non-strict": "pulp build",
7− "ide": "purs ide server"
8− },
9− "license": "Apache-2.0",
10− "dependencies": {
11− "chromedriver": "^2.37.0",
12− "pulp": "^12.2.0",
13− "purescript": "slamdata/node-purescript#0.12",
14− "purescript-psa": "^0.6.0",
15− "xhr2": "^0.1.4"
16− }
17−}
spago.locknew file+1712
@@ -0,0 +1,1712 @@
1+{
2+ "workspace": {
3+ "packages": {
4+ "lunapark": {
5+ "path": "./",
6+ "core": {
7+ "dependencies": [
8+ "aff",
9+ "affjax",
10+ "affjax-node",
11+ "argonaut-codecs",
12+ "argonaut-core",
13+ "arrays",
14+ "bifunctors",
15+ "control",
16+ "css",
17+ "datetime",
18+ "effect",
19+ "either",
20+ "foldable-traversable",
21+ "foreign-object",
22+ "lists",
23+ "maybe",
24+ "newtype",
25+ "node-buffer",
26+ "node-fs",
27+ "node-path",
28+ "ordered-collections",
29+ "prelude",
30+ "refs",
31+ "run",
32+ "strings",
33+ "tailrec",
34+ "tuples",
35+ "typelevel-prelude",
36+ "unsafe-coerce",
37+ "variant"
38+ ],
39+ "build_plan": [
40+ "aff",
41+ "affjax",
42+ "affjax-node",
43+ "argonaut-codecs",
44+ "argonaut-core",
45+ "arraybuffer-types",
46+ "arrays",
47+ "bifunctors",
48+ "catenable-lists",
49+ "colors",
50+ "console",
51+ "const",
52+ "contravariant",
53+ "control",
54+ "css",
55+ "datetime",
56+ "distributive",
57+ "effect",
58+ "either",
59+ "enums",
60+ "exceptions",
61+ "exists",
62+ "foldable-traversable",
63+ "foreign",
64+ "foreign-object",
65+ "form-urlencoded",
66+ "free",
67+ "functions",
68+ "functors",
69+ "gen",
70+ "http-methods",
71+ "identity",
72+ "integers",
73+ "invariant",
74+ "js-date",
75+ "js-uri",
76+ "lazy",
77+ "lcg",
78+ "lists",
79+ "maybe",
80+ "media-types",
81+ "newtype",
82+ "node-buffer",
83+ "node-event-emitter",
84+ "node-fs",
85+ "node-path",
86+ "node-streams",
87+ "nonempty",
88+ "now",
89+ "nullable",
90+ "numbers",
91+ "ordered-collections",
92+ "orders",
93+ "parallel",
94+ "partial",
95+ "prelude",
96+ "profunctor",
97+ "quickcheck",
98+ "quickcheck-laws",
99+ "random",
100+ "record",
101+ "refs",
102+ "run",
103+ "safe-coerce",
104+ "st",
105+ "strings",
106+ "tailrec",
107+ "these",
108+ "transformers",
109+ "tuples",
110+ "type-equality",
111+ "typelevel-prelude",
112+ "unfoldable",
113+ "unsafe-coerce",
114+ "variant",
115+ "web-dom",
116+ "web-events",
117+ "web-file",
118+ "web-html",
119+ "web-storage",
120+ "web-xhr"
121+ ]
122+ },
123+ "test": {
124+ "dependencies": [
125+ "console"
126+ ],
127+ "build_plan": [
128+ "console",
129+ "effect",
130+ "prelude"
131+ ]
132+ }
133+ }
134+ },
135+ "package_set": {
136+ "address": {
137+ "registry": "60.4.0"
138+ },
139+ "compiler": ">=0.15.15 <0.16.0",
140+ "content": {
141+ "abc-parser": "2.0.1",
142+ "ace": "9.1.0",
143+ "address-rfc2821": "0.1.1",
144+ "aff": "8.0.0",
145+ "aff-bus": "6.0.0",
146+ "aff-coroutines": "9.0.0",
147+ "aff-promise": "4.0.0",
148+ "aff-retry": "2.0.0",
149+ "affjax": "13.0.0",
150+ "affjax-node": "1.0.0",
151+ "affjax-web": "1.0.0",
152+ "ansi": "7.0.0",
153+ "apexcharts": "0.5.0",
154+ "applicative-phases": "1.0.0",
155+ "argonaut": "9.0.0",
156+ "argonaut-aeson-generic": "0.4.1",
157+ "argonaut-codecs": "9.1.0",
158+ "argonaut-core": "7.0.0",
159+ "argonaut-generic": "8.0.0",
160+ "argonaut-traversals": "10.0.0",
161+ "argparse-basic": "2.0.0",
162+ "array-builder": "0.1.2",
163+ "array-search": "0.6.0",
164+ "arraybuffer": "13.2.0",
165+ "arraybuffer-builder": "3.1.0",
166+ "arraybuffer-types": "3.0.2",
167+ "arrays": "7.3.0",
168+ "arrays-extra": "0.6.1",
169+ "arrays-zipper": "2.0.1",
170+ "ask": "1.0.0",
171+ "assert": "6.0.0",
172+ "assert-multiple": "0.4.0",
173+ "avar": "5.0.0",
174+ "b64": "0.0.8",
175+ "barbies": "1.0.1",
176+ "barlow-lens": "0.9.0",
177+ "bifunctors": "6.0.0",
178+ "bigints": "7.0.1",
179+ "bolson": "0.3.9",
180+ "bookhound": "0.1.7",
181+ "bower-json": "3.0.0",
182+ "call-by-name": "4.0.1",
183+ "canvas": "6.0.0",
184+ "canvas-action": "9.0.0",
185+ "cartesian": "1.0.6",
186+ "catenable-lists": "7.0.0",
187+ "cbor-stream": "1.3.0",
188+ "chameleon": "1.0.0",
189+ "chameleon-halogen": "1.0.3",
190+ "chameleon-react-basic": "1.1.0",
191+ "chameleon-styled": "2.5.0",
192+ "chameleon-transformers": "1.0.0",
193+ "channel": "1.0.0",
194+ "checked-exceptions": "3.1.1",
195+ "choku": "1.0.1",
196+ "classless": "0.1.1",
197+ "classless-arbitrary": "0.1.1",
198+ "classless-decode-json": "0.1.1",
199+ "classless-encode-json": "0.1.3",
200+ "classnames": "2.0.0",
201+ "codec": "6.1.0",
202+ "codec-argonaut": "10.0.0",
203+ "codec-json": "2.0.0",
204+ "colors": "7.0.1",
205+ "concur-core": "0.5.0",
206+ "concur-react": "0.5.0",
207+ "concurrent-queues": "3.0.0",
208+ "console": "6.1.0",
209+ "const": "6.0.0",
210+ "contravariant": "6.0.0",
211+ "control": "6.0.0",
212+ "convertable-options": "1.0.0",
213+ "coroutines": "7.0.0",
214+ "css": "6.0.0",
215+ "css-frameworks": "1.0.1",
216+ "csv-stream": "2.3.0",
217+ "data-mvc": "0.0.2",
218+ "datetime": "6.1.0",
219+ "datetime-parsing": "0.2.0",
220+ "debounce": "0.1.0",
221+ "debug": "6.0.2",
222+ "decimals": "7.1.0",
223+ "default-values": "1.0.1",
224+ "deku": "0.9.23",
225+ "deno": "0.0.5",
226+ "dissect": "1.0.0",
227+ "distributive": "6.0.0",
228+ "dom-filereader": "7.0.0",
229+ "dom-indexed": "12.0.0",
230+ "dom-simple": "0.4.0",
231+ "dotenv": "4.0.3",
232+ "droplet": "0.6.0",
233+ "dts": "1.0.0",
234+ "dual-numbers": "1.0.3",
235+ "dynamic-buffer": "3.0.1",
236+ "echarts-simple": "0.0.1",
237+ "effect": "4.0.0",
238+ "either": "6.1.0",
239+ "elmish": "0.13.0",
240+ "elmish-enzyme": "0.1.1",
241+ "elmish-hooks": "0.10.3",
242+ "elmish-html": "0.9.0",
243+ "elmish-testing-library": "0.3.2",
244+ "email-validate": "7.0.0",
245+ "encoding": "0.0.9",
246+ "enums": "6.0.1",
247+ "env-names": "0.4.0",
248+ "error": "2.0.0",
249+ "eta-conversion": "0.3.2",
250+ "exceptions": "6.1.0",
251+ "exists": "6.0.0",
252+ "exitcodes": "4.0.0",
253+ "expect-inferred": "3.0.0",
254+ "ezfetch": "1.0.0",
255+ "fahrtwind": "2.0.0",
256+ "fallback": "0.1.0",
257+ "fast-vect": "1.2.0",
258+ "fetch": "4.1.0",
259+ "fetch-argonaut": "1.0.1",
260+ "fetch-core": "5.1.0",
261+ "fetch-yoga-json": "1.1.0",
262+ "ffi-simple": "0.5.1",
263+ "fft-js": "0.1.0",
264+ "filterable": "5.0.0",
265+ "fix-functor": "0.1.0",
266+ "fixed-points": "7.0.0",
267+ "fixed-precision": "5.0.0",
268+ "flame": "1.3.0",
269+ "float32": "2.0.0",
270+ "fmt": "0.2.1",
271+ "foldable-traversable": "6.0.0",
272+ "foldable-traversable-extra": "0.0.6",
273+ "foreign": "7.0.0",
274+ "foreign-object": "4.1.0",
275+ "foreign-readwrite": "3.4.0",
276+ "forgetmenot": "0.1.0",
277+ "fork": "6.0.0",
278+ "form-urlencoded": "7.0.0",
279+ "formatters": "7.0.0",
280+ "framer-motion": "1.0.1",
281+ "free": "7.1.0",
282+ "freeap": "7.0.0",
283+ "freer-free": "0.0.1",
284+ "freet": "7.0.0",
285+ "functions": "6.0.0",
286+ "functor1": "3.0.0",
287+ "functors": "5.0.0",
288+ "fuzzy": "0.4.0",
289+ "gen": "4.0.0",
290+ "generate-values": "1.0.1",
291+ "generic-router": "0.0.1",
292+ "geojson": "0.0.5",
293+ "geometria": "2.2.0",
294+ "gojs": "0.1.1",
295+ "grain": "3.0.0",
296+ "grain-router": "3.0.0",
297+ "grain-virtualized": "3.0.0",
298+ "graphs": "8.1.0",
299+ "group": "4.1.1",
300+ "halogen": "7.0.0",
301+ "halogen-bootstrap5": "5.3.2",
302+ "halogen-canvas": "1.0.0",
303+ "halogen-css": "10.0.0",
304+ "halogen-echarts-simple": "0.0.4",
305+ "halogen-formless": "4.0.3",
306+ "halogen-helix": "1.0.1",
307+ "halogen-hooks": "0.6.3",
308+ "halogen-hooks-extra": "0.9.0",
309+ "halogen-infinite-scroll": "1.1.0",
310+ "halogen-store": "0.5.4",
311+ "halogen-storybook": "2.0.0",
312+ "halogen-subscriptions": "2.0.0",
313+ "halogen-svg-elems": "8.0.0",
314+ "halogen-typewriter": "1.0.4",
315+ "halogen-vdom": "8.0.0",
316+ "halogen-vdom-string-renderer": "0.5.0",
317+ "halogen-xterm": "2.0.0",
318+ "heckin": "2.0.1",
319+ "heterogeneous": "0.6.0",
320+ "homogeneous": "0.4.0",
321+ "http-methods": "6.0.0",
322+ "httpurple": "4.0.0",
323+ "huffman": "0.4.0",
324+ "humdrum": "0.0.1",
325+ "hyrule": "2.3.8",
326+ "identity": "6.0.0",
327+ "identy": "4.0.1",
328+ "indexed-db": "1.0.0",
329+ "indexed-monad": "3.0.0",
330+ "int64": "3.0.0",
331+ "integers": "6.0.0",
332+ "interpolate": "5.0.2",
333+ "intersection-observer": "1.0.1",
334+ "invariant": "6.0.0",
335+ "jarilo": "1.0.1",
336+ "jelly": "0.10.0",
337+ "jelly-router": "0.3.0",
338+ "jelly-signal": "0.4.0",
339+ "jest": "1.0.0",
340+ "js-abort-controller": "1.0.0",
341+ "js-bigints": "2.2.1",
342+ "js-date": "8.0.0",
343+ "js-fetch": "0.2.1",
344+ "js-fileio": "3.0.0",
345+ "js-intl": "1.0.4",
346+ "js-iterators": "0.1.1",
347+ "js-maps": "0.1.2",
348+ "js-promise": "1.0.0",
349+ "js-promise-aff": "1.0.0",
350+ "js-timers": "6.1.0",
351+ "js-uri": "3.1.0",
352+ "json": "1.1.0",
353+ "json-codecs": "5.0.0",
354+ "justifill": "0.5.0",
355+ "jwt": "0.0.9",
356+ "labeled-data": "0.2.0",
357+ "language-cst-parser": "0.14.0",
358+ "lazy": "6.0.0",
359+ "lazy-joe": "1.0.0",
360+ "lcg": "4.0.0",
361+ "leibniz": "5.0.0",
362+ "leveldb": "1.0.1",
363+ "liminal": "1.0.1",
364+ "linalg": "6.0.0",
365+ "lists": "7.0.0",
366+ "literals": "1.0.2",
367+ "logging": "3.0.0",
368+ "logging-journald": "0.4.0",
369+ "lumi-components": "18.0.0",
370+ "machines": "7.0.0",
371+ "maps-eager": "0.5.0",
372+ "marionette": "1.0.0",
373+ "marionette-react-basic-hooks": "0.1.1",
374+ "marked": "0.1.0",
375+ "matrices": "5.0.1",
376+ "matryoshka": "1.0.0",
377+ "maybe": "6.0.0",
378+ "media-types": "6.0.0",
379+ "meowclient": "1.0.0",
380+ "midi": "4.0.0",
381+ "milkis": "9.0.0",
382+ "minibench": "4.0.1",
383+ "mmorph": "7.0.0",
384+ "monad-control": "5.0.0",
385+ "monad-logger": "1.3.1",
386+ "monad-loops": "0.5.0",
387+ "monad-unlift": "1.0.1",
388+ "monoid-extras": "0.0.1",
389+ "monoidal": "0.16.0",
390+ "morello": "0.4.0",
391+ "mote": "3.0.0",
392+ "motsunabe": "2.0.0",
393+ "mvc": "0.0.1",
394+ "mysql": "6.0.1",
395+ "n3": "0.1.0",
396+ "nano-id": "1.1.0",
397+ "nanoid": "0.1.0",
398+ "naturals": "3.0.0",
399+ "nested-functor": "0.2.1",
400+ "newtype": "5.0.0",
401+ "nextjs": "0.1.1",
402+ "nextui": "0.2.0",
403+ "node-buffer": "9.0.0",
404+ "node-child-process": "11.1.0",
405+ "node-event-emitter": "3.0.0",
406+ "node-execa": "5.0.0",
407+ "node-fs": "9.2.0",
408+ "node-glob-basic": "1.3.0",
409+ "node-http": "9.1.0",
410+ "node-http2": "1.1.1",
411+ "node-human-signals": "1.0.0",
412+ "node-net": "5.1.0",
413+ "node-os": "5.1.0",
414+ "node-path": "5.0.0",
415+ "node-process": "11.2.0",
416+ "node-readline": "8.1.1",
417+ "node-sqlite3": "8.0.0",
418+ "node-stream-pipes": "2.1.6",
419+ "node-streams": "9.0.0",
420+ "node-tls": "0.3.1",
421+ "node-url": "7.0.1",
422+ "node-zlib": "0.4.0",
423+ "nonempty": "7.0.0",
424+ "now": "6.0.0",
425+ "npm-package-json": "2.0.0",
426+ "nullable": "6.0.0",
427+ "numberfield": "0.2.2",
428+ "numbers": "9.0.1",
429+ "oak": "3.1.1",
430+ "oak-debug": "1.2.2",
431+ "object-maps": "0.3.0",
432+ "ocarina": "1.5.4",
433+ "oooooooooorrrrrrrmm-lib": "0.0.1",
434+ "open-colors-scales-and-schemes": "1.0.0",
435+ "open-folds": "6.4.0",
436+ "open-foreign-generic": "11.0.3",
437+ "open-memoize": "6.2.0",
438+ "open-mkdirp-aff": "1.2.0",
439+ "open-pairing": "6.2.0",
440+ "open-smolder": "12.0.2",
441+ "options": "7.0.0",
442+ "optparse": "5.0.1",
443+ "ordered-collections": "3.2.0",
444+ "ordered-set": "0.4.0",
445+ "orders": "6.0.0",
446+ "owoify": "1.2.0",
447+ "pairs": "9.0.1",
448+ "parallel": "7.0.0",
449+ "parsing": "10.2.0",
450+ "parsing-dataview": "3.2.4",
451+ "partial": "4.0.0",
452+ "pathy": "9.0.0",
453+ "pha": "0.13.0",
454+ "phaser": "0.7.0",
455+ "phylio": "1.1.2",
456+ "pipes": "8.0.0",
457+ "pirates-charm": "0.0.1",
458+ "pmock": "0.9.0",
459+ "point-free": "1.0.0",
460+ "pointed-list": "0.5.1",
461+ "polymorphic-vectors": "4.0.0",
462+ "posix-types": "6.0.0",
463+ "postgresql": "2.0.19",
464+ "precise": "6.0.0",
465+ "precise-datetime": "7.0.0",
466+ "prelude": "6.0.1",
467+ "prettier-printer": "3.0.0",
468+ "priority-queue": "0.1.2",
469+ "profunctor": "6.0.1",
470+ "profunctor-lenses": "8.0.0",
471+ "protobuf": "4.3.0",
472+ "psa-utils": "8.0.0",
473+ "psci-support": "6.0.0",
474+ "punycode": "1.0.0",
475+ "qualified-do": "2.2.0",
476+ "quantities": "12.2.0",
477+ "quickcheck": "8.0.1",
478+ "quickcheck-combinators": "0.1.3",
479+ "quickcheck-laws": "7.0.0",
480+ "quickcheck-utf8": "0.0.0",
481+ "random": "6.0.0",
482+ "rationals": "6.0.0",
483+ "rdf": "0.1.0",
484+ "react": "11.0.0",
485+ "react-aria": "0.2.0",
486+ "react-basic": "17.0.0",
487+ "react-basic-classic": "3.0.0",
488+ "react-basic-dnd": "10.1.0",
489+ "react-basic-dom": "6.1.0",
490+ "react-basic-dom-beta": "0.1.1",
491+ "react-basic-emotion": "7.1.0",
492+ "react-basic-hooks": "8.2.0",
493+ "react-basic-storybook": "2.0.0",
494+ "react-dom": "8.0.0",
495+ "react-halo": "3.0.0",
496+ "react-icons": "1.1.5",
497+ "react-markdown": "0.1.0",
498+ "react-testing-library": "4.0.1",
499+ "react-virtuoso": "1.0.0",
500+ "reactix": "0.6.1",
501+ "read": "1.0.1",
502+ "recharts": "1.1.0",
503+ "record": "4.0.0",
504+ "record-extra": "5.0.1",
505+ "record-ptional-fields": "0.1.2",
506+ "record-studio": "1.0.4",
507+ "refs": "6.0.0",
508+ "remotedata": "5.0.1",
509+ "repr": "0.5.0",
510+ "resize-observer": "1.0.0",
511+ "resource": "2.0.1",
512+ "resourcet": "1.0.0",
513+ "result": "1.0.3",
514+ "return": "0.2.0",
515+ "ring-modules": "5.0.1",
516+ "rito": "0.3.4",
517+ "roman": "0.4.0",
518+ "rough-notation": "1.0.2",
519+ "routing": "11.0.0",
520+ "routing-duplex": "0.7.0",
521+ "run": "5.0.0",
522+ "safe-coerce": "2.0.0",
523+ "safely": "4.0.1",
524+ "school-of-music": "1.3.0",
525+ "selection-foldable": "0.2.0",
526+ "selective-functors": "1.0.1",
527+ "semirings": "7.0.0",
528+ "signal": "13.0.0",
529+ "simple-emitter": "3.0.1",
530+ "simple-i18n": "2.0.1",
531+ "simple-json": "9.0.0",
532+ "simple-json-generics": "0.2.1",
533+ "simple-ulid": "3.0.0",
534+ "sized-matrices": "1.0.0",
535+ "sized-vectors": "5.0.2",
536+ "slug": "3.1.0",
537+ "small-ffi": "4.0.1",
538+ "soundfonts": "4.1.0",
539+ "sparse-matrices": "2.0.1",
540+ "sparse-polynomials": "3.0.1",
541+ "spec": "8.1.0",
542+ "spec-discovery": "8.4.0",
543+ "spec-mocha": "5.1.1",
544+ "spec-node": "0.0.2",
545+ "spec-quickcheck": "5.0.2",
546+ "spec-reporter-xunit": "0.7.1",
547+ "splitmix": "2.1.0",
548+ "ssrs": "1.0.0",
549+ "st": "6.2.0",
550+ "statistics": "0.3.2",
551+ "strictlypositiveint": "1.0.1",
552+ "string-parsers": "8.0.0",
553+ "strings": "6.0.1",
554+ "strings-extra": "4.0.0",
555+ "stringutils": "0.0.12",
556+ "substitute": "0.2.3",
557+ "supply": "0.2.0",
558+ "svg-parser": "3.0.0",
559+ "systemd-journald": "0.3.0",
560+ "tagged": "4.0.2",
561+ "tailrec": "6.1.0",
562+ "tecton": "0.2.1",
563+ "tecton-halogen": "0.2.0",
564+ "test-unit": "17.0.0",
565+ "thermite": "6.3.1",
566+ "thermite-dom": "0.3.1",
567+ "these": "6.0.0",
568+ "threading": "0.0.3",
569+ "tldr": "0.0.0",
570+ "toestand": "0.9.0",
571+ "transformation-matrix": "1.0.1",
572+ "transformers": "6.1.0",
573+ "tree-rose": "4.0.2",
574+ "ts-bridge": "4.0.0",
575+ "tuples": "7.0.0",
576+ "two-or-more": "1.0.0",
577+ "type-equality": "4.0.1",
578+ "typedenv": "2.0.1",
579+ "typelevel": "6.0.0",
580+ "typelevel-lists": "2.1.0",
581+ "typelevel-peano": "1.0.1",
582+ "typelevel-prelude": "7.0.0",
583+ "typelevel-regex": "0.0.3",
584+ "typelevel-rows": "0.1.0",
585+ "typisch": "0.4.0",
586+ "uint": "7.0.0",
587+ "ulid": "3.0.1",
588+ "uncurried-transformers": "1.1.0",
589+ "undefined": "2.0.0",
590+ "undefined-is-not-a-problem": "1.1.0",
591+ "unfoldable": "6.0.0",
592+ "unicode": "6.0.0",
593+ "unique": "0.6.1",
594+ "unlift": "1.0.1",
595+ "unordered-collections": "3.1.0",
596+ "unsafe-coerce": "6.0.0",
597+ "unsafe-reference": "5.0.0",
598+ "untagged-to-tagged": "0.1.4",
599+ "untagged-union": "1.0.0",
600+ "uri": "9.0.0",
601+ "url-immutable": "1.0.0",
602+ "uuid": "9.0.0",
603+ "uuidv4": "1.0.0",
604+ "validation": "6.0.0",
605+ "variant": "8.0.0",
606+ "variant-encodings": "2.0.0",
607+ "vectorfield": "1.0.1",
608+ "vectors": "2.1.0",
609+ "versions": "7.0.0",
610+ "visx": "0.0.2",
611+ "web-clipboard": "6.0.0",
612+ "web-cssom": "2.0.0",
613+ "web-cssom-view": "0.1.0",
614+ "web-dom": "6.0.0",
615+ "web-dom-parser": "8.0.0",
616+ "web-dom-xpath": "3.0.0",
617+ "web-encoding": "3.0.0",
618+ "web-events": "4.0.0",
619+ "web-fetch": "4.0.1",
620+ "web-file": "4.0.0",
621+ "web-geometry": "0.1.0",
622+ "web-html": "4.1.0",
623+ "web-pointerevents": "2.0.0",
624+ "web-proletarian": "1.0.0",
625+ "web-promise": "3.2.0",
626+ "web-resize-observer": "2.1.0",
627+ "web-router": "1.0.0",
628+ "web-socket": "4.0.0",
629+ "web-storage": "5.0.0",
630+ "web-streams": "4.0.0",
631+ "web-touchevents": "4.0.0",
632+ "web-uievents": "5.0.0",
633+ "web-url": "2.0.0",
634+ "web-workers": "1.1.0",
635+ "web-xhr": "5.0.1",
636+ "webextension-polyfill": "0.1.0",
637+ "webgpu": "0.0.1",
638+ "which": "2.0.0",
639+ "xterm": "1.0.0",
640+ "yoga-fetch": "1.0.1",
641+ "yoga-json": "5.1.0",
642+ "yoga-om": "0.1.0",
643+ "yoga-postgres": "6.0.0",
644+ "yoga-tree": "1.0.0",
645+ "z3": "0.0.2",
646+ "zipperarray": "2.0.0"
647+ }
648+ },
649+ "extra_packages": {}
650+ },
651+ "packages": {
652+ "aff": {
653+ "type": "registry",
654+ "version": "8.0.0",
655+ "integrity": "sha256-5MmdI4+0RHBtSBy+YlU3/Cq4R5W2ih3OaRedJIrVHdk=",
656+ "dependencies": [
657+ "bifunctors",
658+ "control",
659+ "datetime",
660+ "effect",
661+ "either",
662+ "exceptions",
663+ "foldable-traversable",
664+ "functions",
665+ "maybe",
666+ "newtype",
667+ "parallel",
668+ "prelude",
669+ "refs",
670+ "tailrec",
671+ "transformers",
672+ "unsafe-coerce"
673+ ]
674+ },
675+ "affjax": {
676+ "type": "registry",
677+ "version": "13.0.0",
678+ "integrity": "sha256-blYfaoW4FYIrIdvmT4sB7nN7BathFaEfZuiVLPmHJOo=",
679+ "dependencies": [
680+ "aff",
681+ "argonaut-core",
682+ "arraybuffer-types",
683+ "foreign",
684+ "form-urlencoded",
685+ "http-methods",
686+ "integers",
687+ "media-types",
688+ "nullable",
689+ "refs",
690+ "unsafe-coerce",
691+ "web-xhr"
692+ ]
693+ },
694+ "affjax-node": {
695+ "type": "registry",
696+ "version": "1.0.0",
697+ "integrity": "sha256-NcmRTXJxJzgHuKoLh+36yA8UejkfouYcX3uevT+Trjc=",
698+ "dependencies": [
699+ "aff",
700+ "affjax",
701+ "either",
702+ "maybe",
703+ "prelude"
704+ ]
705+ },
706+ "argonaut-codecs": {
707+ "type": "registry",
708+ "version": "9.1.0",
709+ "integrity": "sha256-N6efXByUeg848ompEqJfVvZuZPfdRYDGlTDFn0G0Oh8=",
710+ "dependencies": [
711+ "argonaut-core",
712+ "arrays",
713+ "effect",
714+ "foreign-object",
715+ "identity",
716+ "integers",
717+ "maybe",
718+ "nonempty",
719+ "ordered-collections",
720+ "prelude",
721+ "record"
722+ ]
723+ },
724+ "argonaut-core": {
725+ "type": "registry",
726+ "version": "7.0.0",
727+ "integrity": "sha256-RC82GfAjItydxrO24cdX373KHVZiLqybu19b5X8u7B4=",
728+ "dependencies": [
729+ "arrays",
730+ "control",
731+ "either",
732+ "foreign-object",
733+ "functions",
734+ "gen",
735+ "maybe",
736+ "nonempty",
737+ "prelude",
738+ "strings",
739+ "tailrec"
740+ ]
741+ },
742+ "arraybuffer-types": {
743+ "type": "registry",
744+ "version": "3.0.2",
745+ "integrity": "sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA=",
746+ "dependencies": []
747+ },
748+ "arrays": {
749+ "type": "registry",
750+ "version": "7.3.0",
751+ "integrity": "sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc=",
752+ "dependencies": [
753+ "bifunctors",
754+ "control",
755+ "foldable-traversable",
756+ "functions",
757+ "maybe",
758+ "nonempty",
759+ "partial",
760+ "prelude",
761+ "safe-coerce",
762+ "st",
763+ "tailrec",
764+ "tuples",
765+ "unfoldable",
766+ "unsafe-coerce"
767+ ]
768+ },
769+ "bifunctors": {
770+ "type": "registry",
771+ "version": "6.0.0",
772+ "integrity": "sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw=",
773+ "dependencies": [
774+ "const",
775+ "either",
776+ "newtype",
777+ "prelude",
778+ "tuples"
779+ ]
780+ },
781+ "catenable-lists": {
782+ "type": "registry",
783+ "version": "7.0.0",
784+ "integrity": "sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA=",
785+ "dependencies": [
786+ "control",
787+ "foldable-traversable",
788+ "lists",
789+ "maybe",
790+ "prelude",
791+ "tuples",
792+ "unfoldable"
793+ ]
794+ },
795+ "colors": {
796+ "type": "registry",
797+ "version": "7.0.1",
798+ "integrity": "sha256-udlg/y2PFsHYli8Tgz8BQGGrOjyGo0BcJj36IfgYADs=",
799+ "dependencies": [
800+ "arrays",
801+ "integers",
802+ "lists",
803+ "numbers",
804+ "partial",
805+ "strings"
806+ ]
807+ },
808+ "console": {
809+ "type": "registry",
810+ "version": "6.1.0",
811+ "integrity": "sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM=",
812+ "dependencies": [
813+ "effect",
814+ "prelude"
815+ ]
816+ },
817+ "const": {
818+ "type": "registry",
819+ "version": "6.0.0",
820+ "integrity": "sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=",
821+ "dependencies": [
822+ "invariant",
823+ "newtype",
824+ "prelude"
825+ ]
826+ },
827+ "contravariant": {
828+ "type": "registry",
829+ "version": "6.0.0",
830+ "integrity": "sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=",
831+ "dependencies": [
832+ "const",
833+ "either",
834+ "newtype",
835+ "prelude",
836+ "tuples"
837+ ]
838+ },
839+ "control": {
840+ "type": "registry",
841+ "version": "6.0.0",
842+ "integrity": "sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk=",
843+ "dependencies": [
844+ "newtype",
845+ "prelude"
846+ ]
847+ },
848+ "css": {
849+ "type": "registry",
850+ "version": "6.0.0",
851+ "integrity": "sha256-zfSHxgiU4rSWuVxMjSKKh+s7j433wxmsr+CqI6hm9s4=",
852+ "dependencies": [
853+ "colors",
854+ "console",
855+ "effect",
856+ "nonempty",
857+ "profunctor",
858+ "strings",
859+ "these",
860+ "transformers"
861+ ]
862+ },
863+ "datetime": {
864+ "type": "registry",
865+ "version": "6.1.0",
866+ "integrity": "sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI=",
867+ "dependencies": [
868+ "bifunctors",
869+ "control",
870+ "either",
871+ "enums",
872+ "foldable-traversable",
873+ "functions",
874+ "gen",
875+ "integers",
876+ "lists",
877+ "maybe",
878+ "newtype",
879+ "numbers",
880+ "ordered-collections",
881+ "partial",
882+ "prelude",
883+ "tuples"
884+ ]
885+ },
886+ "distributive": {
887+ "type": "registry",
888+ "version": "6.0.0",
889+ "integrity": "sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=",
890+ "dependencies": [
891+ "identity",
892+ "newtype",
893+ "prelude",
894+ "tuples",
895+ "type-equality"
896+ ]
897+ },
898+ "effect": {
899+ "type": "registry",
900+ "version": "4.0.0",
901+ "integrity": "sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M=",
902+ "dependencies": [
903+ "prelude"
904+ ]
905+ },
906+ "either": {
907+ "type": "registry",
908+ "version": "6.1.0",
909+ "integrity": "sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=",
910+ "dependencies": [
911+ "control",
912+ "invariant",
913+ "maybe",
914+ "prelude"
915+ ]
916+ },
917+ "enums": {
918+ "type": "registry",
919+ "version": "6.0.1",
920+ "integrity": "sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8=",
921+ "dependencies": [
922+ "control",
923+ "either",
924+ "gen",
925+ "maybe",
926+ "newtype",
927+ "nonempty",
928+ "partial",
929+ "prelude",
930+ "tuples",
931+ "unfoldable"
932+ ]
933+ },
934+ "exceptions": {
935+ "type": "registry",
936+ "version": "6.1.0",
937+ "integrity": "sha256-K0T89IHtF3vBY7eSAO7eDOqSb2J9kZGAcDN5+IKsF8E=",
938+ "dependencies": [
939+ "effect",
940+ "either",
941+ "maybe",
942+ "prelude"
943+ ]
944+ },
945+ "exists": {
946+ "type": "registry",
947+ "version": "6.0.0",
948+ "integrity": "sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=",
949+ "dependencies": [
950+ "unsafe-coerce"
951+ ]
952+ },
953+ "foldable-traversable": {
954+ "type": "registry",
955+ "version": "6.0.0",
956+ "integrity": "sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM=",
957+ "dependencies": [
958+ "bifunctors",
959+ "const",
960+ "control",
961+ "either",
962+ "functors",
963+ "identity",
964+ "maybe",
965+ "newtype",
966+ "orders",
967+ "prelude",
968+ "tuples"
969+ ]
970+ },
971+ "foreign": {
972+ "type": "registry",
973+ "version": "7.0.0",
974+ "integrity": "sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA=",
975+ "dependencies": [
976+ "either",
977+ "functions",
978+ "identity",
979+ "integers",
980+ "lists",
981+ "maybe",
982+ "prelude",
983+ "strings",
984+ "transformers"
985+ ]
986+ },
987+ "foreign-object": {
988+ "type": "registry",
989+ "version": "4.1.0",
990+ "integrity": "sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo=",
991+ "dependencies": [
992+ "arrays",
993+ "foldable-traversable",
994+ "functions",
995+ "gen",
996+ "lists",
997+ "maybe",
998+ "prelude",
999+ "st",
1000+ "tailrec",
1001+ "tuples",
1002+ "typelevel-prelude",
1003+ "unfoldable"
1004+ ]
1005+ },
1006+ "form-urlencoded": {
1007+ "type": "registry",
1008+ "version": "7.0.0",
1009+ "integrity": "sha256-WUzk8DTjrbPVHKZ5w7XpPBO6ci6xFhvYguHp6RvX+18=",
1010+ "dependencies": [
1011+ "foldable-traversable",
1012+ "js-uri",
1013+ "maybe",
1014+ "newtype",
1015+ "prelude",
1016+ "strings",
1017+ "tuples"
1018+ ]
1019+ },
1020+ "free": {
1021+ "type": "registry",
1022+ "version": "7.1.0",
1023+ "integrity": "sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k=",
1024+ "dependencies": [
1025+ "catenable-lists",
1026+ "control",
1027+ "distributive",
1028+ "either",
1029+ "exists",
1030+ "foldable-traversable",
1031+ "invariant",
1032+ "lazy",
1033+ "maybe",
1034+ "prelude",
1035+ "tailrec",
1036+ "transformers",
1037+ "tuples",
1038+ "unsafe-coerce"
1039+ ]
1040+ },
1041+ "functions": {
1042+ "type": "registry",
1043+ "version": "6.0.0",
1044+ "integrity": "sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI=",
1045+ "dependencies": [
1046+ "prelude"
1047+ ]
1048+ },
1049+ "functors": {
1050+ "type": "registry",
1051+ "version": "5.0.0",
1052+ "integrity": "sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=",
1053+ "dependencies": [
1054+ "bifunctors",
1055+ "const",
1056+ "contravariant",
1057+ "control",
1058+ "distributive",
1059+ "either",
1060+ "invariant",
1061+ "maybe",
1062+ "newtype",
1063+ "prelude",
1064+ "profunctor",
1065+ "tuples",
1066+ "unsafe-coerce"
1067+ ]
1068+ },
1069+ "gen": {
1070+ "type": "registry",
1071+ "version": "4.0.0",
1072+ "integrity": "sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=",
1073+ "dependencies": [
1074+ "either",
1075+ "foldable-traversable",
1076+ "identity",
1077+ "maybe",
1078+ "newtype",
1079+ "nonempty",
1080+ "prelude",
1081+ "tailrec",
1082+ "tuples",
1083+ "unfoldable"
1084+ ]
1085+ },
1086+ "http-methods": {
1087+ "type": "registry",
1088+ "version": "6.0.0",
1089+ "integrity": "sha256-Orr7rbDGcp7qoqmUMXPRMjBx+C4jqOQcFe9+gE3nMgU=",
1090+ "dependencies": [
1091+ "either",
1092+ "prelude",
1093+ "strings"
1094+ ]
1095+ },
1096+ "identity": {
1097+ "type": "registry",
1098+ "version": "6.0.0",
1099+ "integrity": "sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=",
1100+ "dependencies": [
1101+ "control",
1102+ "invariant",
1103+ "newtype",
1104+ "prelude"
1105+ ]
1106+ },
1107+ "integers": {
1108+ "type": "registry",
1109+ "version": "6.0.0",
1110+ "integrity": "sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158=",
1111+ "dependencies": [
1112+ "maybe",
1113+ "numbers",
1114+ "prelude"
1115+ ]
1116+ },
1117+ "invariant": {
1118+ "type": "registry",
1119+ "version": "6.0.0",
1120+ "integrity": "sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=",
1121+ "dependencies": [
1122+ "control",
1123+ "prelude"
1124+ ]
1125+ },
1126+ "js-date": {
1127+ "type": "registry",
1128+ "version": "8.0.0",
1129+ "integrity": "sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo=",
1130+ "dependencies": [
1131+ "datetime",
1132+ "effect",
1133+ "exceptions",
1134+ "foreign",
1135+ "integers",
1136+ "now"
1137+ ]
1138+ },
1139+ "js-uri": {
1140+ "type": "registry",
1141+ "version": "3.1.0",
1142+ "integrity": "sha256-3p0ynHveCJmC2CXze+eMBdW/2l5e953Q8XMAKz+jxUo=",
1143+ "dependencies": [
1144+ "functions",
1145+ "maybe"
1146+ ]
1147+ },
1148+ "lazy": {
1149+ "type": "registry",
1150+ "version": "6.0.0",
1151+ "integrity": "sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU=",
1152+ "dependencies": [
1153+ "control",
1154+ "foldable-traversable",
1155+ "invariant",
1156+ "prelude"
1157+ ]
1158+ },
1159+ "lcg": {
1160+ "type": "registry",
1161+ "version": "4.0.0",
1162+ "integrity": "sha256-h7ME5cthLfbgJOJdsZcSfFpwXsx4rf8YmhebU+3iSYg=",
1163+ "dependencies": [
1164+ "effect",
1165+ "integers",
1166+ "maybe",
1167+ "partial",
1168+ "prelude",
1169+ "random"
1170+ ]
1171+ },
1172+ "lists": {
1173+ "type": "registry",
1174+ "version": "7.0.0",
1175+ "integrity": "sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI=",
1176+ "dependencies": [
1177+ "bifunctors",
1178+ "control",
1179+ "foldable-traversable",
1180+ "lazy",
1181+ "maybe",
1182+ "newtype",
1183+ "nonempty",
1184+ "partial",
1185+ "prelude",
1186+ "tailrec",
1187+ "tuples",
1188+ "unfoldable"
1189+ ]
1190+ },
1191+ "maybe": {
1192+ "type": "registry",
1193+ "version": "6.0.0",
1194+ "integrity": "sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=",
1195+ "dependencies": [
1196+ "control",
1197+ "invariant",
1198+ "newtype",
1199+ "prelude"
1200+ ]
1201+ },
1202+ "media-types": {
1203+ "type": "registry",
1204+ "version": "6.0.0",
1205+ "integrity": "sha256-n/4FoGBasbVSYscGVRSyBunQ6CZbL3jsYL+Lp01mc9k=",
1206+ "dependencies": [
1207+ "newtype",
1208+ "prelude"
1209+ ]
1210+ },
1211+ "newtype": {
1212+ "type": "registry",
1213+ "version": "5.0.0",
1214+ "integrity": "sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=",
1215+ "dependencies": [
1216+ "prelude",
1217+ "safe-coerce"
1218+ ]
1219+ },
1220+ "node-buffer": {
1221+ "type": "registry",
1222+ "version": "9.0.0",
1223+ "integrity": "sha256-PWE2DJ5ruBLCmeA/fUiuySEFmUJ/VuRfyrnCuVZBlu4=",
1224+ "dependencies": [
1225+ "arraybuffer-types",
1226+ "effect",
1227+ "maybe",
1228+ "nullable",
1229+ "st",
1230+ "unsafe-coerce"
1231+ ]
1232+ },
1233+ "node-event-emitter": {
1234+ "type": "registry",
1235+ "version": "3.0.0",
1236+ "integrity": "sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w=",
1237+ "dependencies": [
1238+ "effect",
1239+ "either",
1240+ "functions",
1241+ "maybe",
1242+ "nullable",
1243+ "prelude",
1244+ "unsafe-coerce"
1245+ ]
1246+ },
1247+ "node-fs": {
1248+ "type": "registry",
1249+ "version": "9.2.0",
1250+ "integrity": "sha256-Sg0vkXycEzkEerX6hLccz21Ygd9w1+QSk1thotRZPGI=",
1251+ "dependencies": [
1252+ "datetime",
1253+ "effect",
1254+ "either",
1255+ "enums",
1256+ "exceptions",
1257+ "functions",
1258+ "integers",
1259+ "js-date",
1260+ "maybe",
1261+ "node-buffer",
1262+ "node-path",
1263+ "node-streams",
1264+ "nullable",
1265+ "partial",
1266+ "prelude",
1267+ "strings",
1268+ "unsafe-coerce"
1269+ ]
1270+ },
1271+ "node-path": {
1272+ "type": "registry",
1273+ "version": "5.0.0",
1274+ "integrity": "sha256-pd82nQ+2l5UThzaxPdKttgDt7xlsgIDLpPG0yxDEdyE=",
1275+ "dependencies": [
1276+ "effect"
1277+ ]
1278+ },
1279+ "node-streams": {
1280+ "type": "registry",
1281+ "version": "9.0.0",
1282+ "integrity": "sha256-2n6dq7YWleTDmD1Kur/ul7Cn08IvWrScgPf+0PgX2TQ=",
1283+ "dependencies": [
1284+ "aff",
1285+ "effect",
1286+ "either",
1287+ "exceptions",
1288+ "node-buffer",
1289+ "node-event-emitter",
1290+ "nullable",
1291+ "prelude"
1292+ ]
1293+ },
1294+ "nonempty": {
1295+ "type": "registry",
1296+ "version": "7.0.0",
1297+ "integrity": "sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=",
1298+ "dependencies": [
1299+ "control",
1300+ "foldable-traversable",
1301+ "maybe",
1302+ "prelude",
1303+ "tuples",
1304+ "unfoldable"
1305+ ]
1306+ },
1307+ "now": {
1308+ "type": "registry",
1309+ "version": "6.0.0",
1310+ "integrity": "sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY=",
1311+ "dependencies": [
1312+ "datetime",
1313+ "effect"
1314+ ]
1315+ },
1316+ "nullable": {
1317+ "type": "registry",
1318+ "version": "6.0.0",
1319+ "integrity": "sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o=",
1320+ "dependencies": [
1321+ "effect",
1322+ "functions",
1323+ "maybe"
1324+ ]
1325+ },
1326+ "numbers": {
1327+ "type": "registry",
1328+ "version": "9.0.1",
1329+ "integrity": "sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk=",
1330+ "dependencies": [
1331+ "functions",
1332+ "maybe"
1333+ ]
1334+ },
1335+ "ordered-collections": {
1336+ "type": "registry",
1337+ "version": "3.2.0",
1338+ "integrity": "sha256-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM=",
1339+ "dependencies": [
1340+ "arrays",
1341+ "foldable-traversable",
1342+ "gen",
1343+ "lists",
1344+ "maybe",
1345+ "partial",
1346+ "prelude",
1347+ "st",
1348+ "tailrec",
1349+ "tuples",
1350+ "unfoldable"
1351+ ]
1352+ },
1353+ "orders": {
1354+ "type": "registry",
1355+ "version": "6.0.0",
1356+ "integrity": "sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=",
1357+ "dependencies": [
1358+ "newtype",
1359+ "prelude"
1360+ ]
1361+ },
1362+ "parallel": {
1363+ "type": "registry",
1364+ "version": "7.0.0",
1365+ "integrity": "sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o=",
1366+ "dependencies": [
1367+ "control",
1368+ "effect",
1369+ "either",
1370+ "foldable-traversable",
1371+ "functors",
1372+ "maybe",
1373+ "newtype",
1374+ "prelude",
1375+ "profunctor",
1376+ "refs",
1377+ "transformers"
1378+ ]
1379+ },
1380+ "partial": {
1381+ "type": "registry",
1382+ "version": "4.0.0",
1383+ "integrity": "sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4=",
1384+ "dependencies": []
1385+ },
1386+ "prelude": {
1387+ "type": "registry",
1388+ "version": "6.0.1",
1389+ "integrity": "sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0=",
1390+ "dependencies": []
1391+ },
1392+ "profunctor": {
1393+ "type": "registry",
1394+ "version": "6.0.1",
1395+ "integrity": "sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk=",
1396+ "dependencies": [
1397+ "control",
1398+ "distributive",
1399+ "either",
1400+ "exists",
1401+ "invariant",
1402+ "newtype",
1403+ "prelude",
1404+ "tuples"
1405+ ]
1406+ },
1407+ "quickcheck": {
1408+ "type": "registry",
1409+ "version": "8.0.1",
1410+ "integrity": "sha256-ZvpccKQCvgslTXZCNmpYW4bUsFzhZd/kQUr2WmxFTGY=",
1411+ "dependencies": [
1412+ "arrays",
1413+ "console",
1414+ "control",
1415+ "effect",
1416+ "either",
1417+ "enums",
1418+ "exceptions",
1419+ "foldable-traversable",
1420+ "gen",
1421+ "identity",
1422+ "integers",
1423+ "lazy",
1424+ "lcg",
1425+ "lists",
1426+ "maybe",
1427+ "newtype",
1428+ "nonempty",
1429+ "numbers",
1430+ "partial",
1431+ "prelude",
1432+ "record",
1433+ "st",
1434+ "strings",
1435+ "tailrec",
1436+ "transformers",
1437+ "tuples",
1438+ "unfoldable"
1439+ ]
1440+ },
1441+ "quickcheck-laws": {
1442+ "type": "registry",
1443+ "version": "7.0.0",
1444+ "integrity": "sha256-rnzVTiDnymzYkvnhI8EvPwrmO8LgcTnrMTuiI172Tkc=",
1445+ "dependencies": [
1446+ "enums",
1447+ "quickcheck"
1448+ ]
1449+ },
1450+ "random": {
1451+ "type": "registry",
1452+ "version": "6.0.0",
1453+ "integrity": "sha256-CJ611a35MPCE7XQMp0rdC6MCn76znlhisiCRgboAG+Q=",
1454+ "dependencies": [
1455+ "effect",
1456+ "integers"
1457+ ]
1458+ },
1459+ "record": {
1460+ "type": "registry",
1461+ "version": "4.0.0",
1462+ "integrity": "sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg=",
1463+ "dependencies": [
1464+ "functions",
1465+ "prelude",
1466+ "unsafe-coerce"
1467+ ]
1468+ },
1469+ "refs": {
1470+ "type": "registry",
1471+ "version": "6.0.0",
1472+ "integrity": "sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s=",
1473+ "dependencies": [
1474+ "effect",
1475+ "prelude"
1476+ ]
1477+ },
1478+ "run": {
1479+ "type": "registry",
1480+ "version": "5.0.0",
1481+ "integrity": "sha256-uCCGBqPXOSTnQoVzQUoCcEYyGvi+dWZp+lLsxtNG6+U=",
1482+ "dependencies": [
1483+ "aff",
1484+ "effect",
1485+ "either",
1486+ "free",
1487+ "maybe",
1488+ "newtype",
1489+ "prelude",
1490+ "profunctor",
1491+ "tailrec",
1492+ "tuples",
1493+ "type-equality",
1494+ "typelevel-prelude",
1495+ "unsafe-coerce",
1496+ "variant"
1497+ ]
1498+ },
1499+ "safe-coerce": {
1500+ "type": "registry",
1501+ "version": "2.0.0",
1502+ "integrity": "sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=",
1503+ "dependencies": [
1504+ "unsafe-coerce"
1505+ ]
1506+ },
1507+ "st": {
1508+ "type": "registry",
1509+ "version": "6.2.0",
1510+ "integrity": "sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY=",
1511+ "dependencies": [
1512+ "partial",
1513+ "prelude",
1514+ "tailrec",
1515+ "unsafe-coerce"
1516+ ]
1517+ },
1518+ "strings": {
1519+ "type": "registry",
1520+ "version": "6.0.1",
1521+ "integrity": "sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k=",
1522+ "dependencies": [
1523+ "arrays",
1524+ "control",
1525+ "either",
1526+ "enums",
1527+ "foldable-traversable",
1528+ "gen",
1529+ "integers",
1530+ "maybe",
1531+ "newtype",
1532+ "nonempty",
1533+ "partial",
1534+ "prelude",
1535+ "tailrec",
1536+ "tuples",
1537+ "unfoldable",
1538+ "unsafe-coerce"
1539+ ]
1540+ },
1541+ "tailrec": {
1542+ "type": "registry",
1543+ "version": "6.1.0",
1544+ "integrity": "sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=",
1545+ "dependencies": [
1546+ "bifunctors",
1547+ "effect",
1548+ "either",
1549+ "identity",
1550+ "maybe",
1551+ "partial",
1552+ "prelude",
1553+ "refs"
1554+ ]
1555+ },
1556+ "these": {
1557+ "type": "registry",
1558+ "version": "6.0.0",
1559+ "integrity": "sha256-6poQvFzGw7Ir9mTDEbFV9N6+cUeSHe0FdzTR2ZK1o6g=",
1560+ "dependencies": [
1561+ "arrays",
1562+ "gen",
1563+ "lists",
1564+ "quickcheck",
1565+ "quickcheck-laws",
1566+ "tuples"
1567+ ]
1568+ },
1569+ "transformers": {
1570+ "type": "registry",
1571+ "version": "6.1.0",
1572+ "integrity": "sha256-3Bm+Z6tsC/paG888XkywDngJ2JMos+JfOhRlkVfb7gI=",
1573+ "dependencies": [
1574+ "control",
1575+ "distributive",
1576+ "effect",
1577+ "either",
1578+ "exceptions",
1579+ "foldable-traversable",
1580+ "identity",
1581+ "lazy",
1582+ "maybe",
1583+ "newtype",
1584+ "prelude",
1585+ "st",
1586+ "tailrec",
1587+ "tuples",
1588+ "unfoldable"
1589+ ]
1590+ },
1591+ "tuples": {
1592+ "type": "registry",
1593+ "version": "7.0.0",
1594+ "integrity": "sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=",
1595+ "dependencies": [
1596+ "control",
1597+ "invariant",
1598+ "prelude"
1599+ ]
1600+ },
1601+ "type-equality": {
1602+ "type": "registry",
1603+ "version": "4.0.1",
1604+ "integrity": "sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=",
1605+ "dependencies": []
1606+ },
1607+ "typelevel-prelude": {
1608+ "type": "registry",
1609+ "version": "7.0.0",
1610+ "integrity": "sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM=",
1611+ "dependencies": [
1612+ "prelude",
1613+ "type-equality"
1614+ ]
1615+ },
1616+ "unfoldable": {
1617+ "type": "registry",
1618+ "version": "6.0.0",
1619+ "integrity": "sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg=",
1620+ "dependencies": [
1621+ "foldable-traversable",
1622+ "maybe",
1623+ "partial",
1624+ "prelude",
1625+ "tuples"
1626+ ]
1627+ },
1628+ "unsafe-coerce": {
1629+ "type": "registry",
1630+ "version": "6.0.0",
1631+ "integrity": "sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=",
1632+ "dependencies": []
1633+ },
1634+ "variant": {
1635+ "type": "registry",
1636+ "version": "8.0.0",
1637+ "integrity": "sha256-SR//zQDg2dnbB8ZHslcxieUkCeNlbMToapvmh9onTtw=",
1638+ "dependencies": [
1639+ "enums",
1640+ "lists",
1641+ "maybe",
1642+ "partial",
1643+ "prelude",
1644+ "record",
1645+ "tuples",
1646+ "unsafe-coerce"
1647+ ]
1648+ },
1649+ "web-dom": {
1650+ "type": "registry",
1651+ "version": "6.0.0",
1652+ "integrity": "sha256-1kSKWFDI4LupdmpjK01b1MMxDFW7jvatEgPgVmCmSBQ=",
1653+ "dependencies": [
1654+ "web-events"
1655+ ]
1656+ },
1657+ "web-events": {
1658+ "type": "registry",
1659+ "version": "4.0.0",
1660+ "integrity": "sha256-YDt8b6u1tzGtnWyNRodne57iO8FNSGPaTCVzBUyUn4k=",
1661+ "dependencies": [
1662+ "datetime",
1663+ "enums",
1664+ "foreign",
1665+ "nullable"
1666+ ]
1667+ },
1668+ "web-file": {
1669+ "type": "registry",
1670+ "version": "4.0.0",
1671+ "integrity": "sha256-1h5jPBkvjY71jLEdwVadXCx86/2inNoMBO//Rd3eCSU=",
1672+ "dependencies": [
1673+ "foreign",
1674+ "media-types",
1675+ "web-dom"
1676+ ]
1677+ },
1678+ "web-html": {
1679+ "type": "registry",
1680+ "version": "4.1.0",
1681+ "integrity": "sha256-ByqS/h1/yG+hjCOnOQp7L1QpIWzQENNKB1kaHtpEhlE=",
1682+ "dependencies": [
1683+ "js-date",
1684+ "web-dom",
1685+ "web-file",
1686+ "web-storage"
1687+ ]
1688+ },
1689+ "web-storage": {
1690+ "type": "registry",
1691+ "version": "5.0.0",
1692+ "integrity": "sha256-q+6lxcnfWxus0/nDeFVtF1V+tLehZvvXQ0cduYPLksY=",
1693+ "dependencies": [
1694+ "nullable",
1695+ "web-events"
1696+ ]
1697+ },
1698+ "web-xhr": {
1699+ "type": "registry",
1700+ "version": "5.0.1",
1701+ "integrity": "sha256-3dbIPVG66S+hPrgEVnpD78hrGjE7qlBbsReWOz89Ios=",
1702+ "dependencies": [
1703+ "arraybuffer-types",
1704+ "datetime",
1705+ "http-methods",
1706+ "web-dom",
1707+ "web-file",
1708+ "web-html"
1709+ ]
1710+ }
1711+ }
1712+}
spago.yamlnew file+41
@@ -0,0 +1,41 @@
1+package:
2+ name: lunapark
3+ dependencies:
4+ - aff: ">=8.0.0 <9.0.0"
5+ - affjax: ">=13.0.0 <14.0.0"
6+ - affjax-node: ">=1.0.0 <2.0.0"
7+ - argonaut-codecs: ">=9.1.0 <10.0.0"
8+ - argonaut-core: ">=7.0.0 <8.0.0"
9+ - arrays: ">=7.3.0 <8.0.0"
10+ - bifunctors: ">=6.0.0 <7.0.0"
11+ - control: ">=6.0.0 <7.0.0"
12+ - css: ">=6.0.0 <7.0.0"
13+ - datetime: ">=6.1.0 <7.0.0"
14+ - effect: ">=4.0.0 <5.0.0"
15+ - either: ">=6.1.0 <7.0.0"
16+ - foldable-traversable: ">=6.0.0 <7.0.0"
17+ - foreign-object: ">=4.1.0 <5.0.0"
18+ - lists: ">=7.0.0 <8.0.0"
19+ - maybe: ">=6.0.0 <7.0.0"
20+ - newtype: ">=5.0.0 <6.0.0"
21+ - node-buffer: ">=9.0.0 <10.0.0"
22+ - node-fs: ">=9.2.0 <10.0.0"
23+ - node-path: ">=5.0.0 <6.0.0"
24+ - ordered-collections: ">=3.2.0 <4.0.0"
25+ - prelude: ">=6.0.1 <7.0.0"
26+ - refs: ">=6.0.0 <7.0.0"
27+ - run: ">=5.0.0 <6.0.0"
28+ - strings: ">=6.0.1 <7.0.0"
29+ - tailrec: ">=6.1.0 <7.0.0"
30+ - tuples: ">=7.0.0 <8.0.0"
31+ - typelevel-prelude: ">=7.0.0 <8.0.0"
32+ - unsafe-coerce: ">=6.0.0 <7.0.0"
33+ - variant: ">=8.0.0 <9.0.0"
34+ test:
35+ main: Test.Main
36+ dependencies:
37+ - console
38+workspace:
39+ packageSet:
40+ registry: 60.4.0
41+ extraPackages: {}
src/Lunapark.purs+8−5
@@ -3,10 +3,13 @@ module Lunapark
3 , module Lunapark.Error
3 , module Lunapark.Error
4 , module Lunapark.ActionF
4 , module Lunapark.ActionF
5 , module Lunapark.LunaparkF
5 , module Lunapark.LunaparkF
6+ , module Lunapark.WebDriverError
7+ , module Lunapark.Types
6 ) where
8 ) where
7
9
8−
9−import Lunapark.API (BaseRun, HandleLunaparkInput, Lunapark, handleLunapark, init, interpret, interpretW3CActions, jsonWireActions, runLunapark, runLunaparkActions, w3cActions)
10+import Lunapark.API (Lunapark, Interpreter(..), runInterpreter, BASE_EFFECTS, HandleLunaparkInput, handleLunapark, init, interpret, interpretW3CActions, jsonWireActions, runLunapark, runLunaparkActions, w3cActions)
10−import Lunapark.Error (Error, ErrorType(..), fromJson, fromStringCode, toStringCode, unknownError)
11+import Lunapark.Error (Error(..), CachingError(..), printError)
11−import Lunapark.ActionF (ActionF(..), LUNAPARK_ACTIONS, TouchF(..), WithAction, _lunaparkActions, buttonDown, buttonUp, click, doubleClick, doubleTap, flick, liftAction, longTap, moveTo, pause, scroll, sendKeys, tap, touchDown, touchUp)
12+import Lunapark.ActionF (ActionF(..), LUNAPARK_ACTIONS, TouchF(..), _lunaparkActions, buttonDown, buttonUp, click, doubleClick, doubleTap, flick, liftAction, longTap, moveTo, pause, scroll, sendKeys, tap, touchDown, touchUp)
12−import Lunapark.LunaparkF (ElementF(..), LUNAPARK, LunaparkF(..), WithLunapark, _lunapark, acceptAlert, addCookie, back, childElement, childElements, clearElement, clickElement, closeWindow, deleteAllCookies, deleteCookie, dismissAlert, elementScreenshot, executeScript, executeScriptAsync, findElement, findElements, forward, fullscreenWindow, getAlertText, getAllCookies, getAttribute, getCookie, getCss, getProperty, getRectangle, getTagName, getText, getTimeouts, getTitle, getUrl, getWindowHandle, getWindowHandles, getWindowRectangle, go, isDisplayed, isEnabled, isSelected, liftLunapark, maximizeWindow, minimizeWindow, performActions, quit, refresh, releaseActions, screenshot, sendAlertText, sendKeysElement, setTimeouts, setWindowRectangle, status, submitElement, switchToFrame, switchToParentFrame, switchToWindow)
13+import Lunapark.LunaparkF (ElementF(..), LUNAPARK, LunaparkF(..), _lunapark, acceptAlert, addCookie, back, childElement, childElements, clearElement, clickElement, closeWindow, deleteAllCookies, deleteCookie, dismissAlert, elementScreenshot, executeScript, executeScriptAsync, findElement, findElements, forward, fullscreenWindow, getAlertText, getAllCookies, getAttribute, getCookie, getCss, getProperty, getRectangle, getTagName, getText, getTimeouts, getTitle, getUrl, getWindowHandle, getWindowHandles, getWindowRectangle, go, isDisplayed, isEnabled, isSelected, liftLunapark, maximizeWindow, minimizeWindow, performActions, quit, refresh, releaseActions, screenshot, sendAlertText, sendKeysElement, setTimeouts, setWindowRectangle, status, submitElement, switchToFrame, switchToParentFrame, switchToWindow)
14+import Lunapark.WebDriverError (WebDriverError, WebDriverErrorType(..), fromJson, fromStringCode, toStringCode)
15+import Lunapark.Types (SessionId(..), WindowHandle(..), FrameId(..), Element(..), CreateSessionResponse, ServerStatus, Timeouts, Rectangle, RawLocator, Locator(..), Script, Cookie, Screenshot, Button(..), PointerMoveOrigin(..), PointerMove, Action, PointerType(..), ActionSequence(..), ActionRequest, BrowserType(..), DriverPaths, PageLoad(..), UnhandledPrompt(..), Platform(..), Capability(..), CapabilitiesRequest, MoveToRequest)
src/Lunapark/API.purs+238−181
@@ -22,24 +22,34 @@ import Effect.Aff.Class (class MonadAff, liftAff)
22import Effect.Class (liftEffect)
22import Effect.Class (liftEffect)
23import Effect.Ref as Ref
23import Effect.Ref as Ref
24import Foreign.Object as FO
24import Foreign.Object as FO
25−import Lunapark.ActionF (_lunaparkActions, LUNAPARK_ACTIONS, ActionF(..), TouchF(..))
25+import Lunapark.ActionF (_lunaparkActions, ActionF(..), TouchF(..), LUNAPARK_ACTIONS)
26import Lunapark.Endpoint as LP
26import Lunapark.Endpoint as LP
27import Lunapark.Error as LE
27import Lunapark.Error as LE
28−import Lunapark.LunaparkF (_lunapark, LUNAPARK, ElementF(..), LunaparkF(..), performActions, findElement)
28+import Lunapark.LunaparkF (_lunapark, ElementF(..), LunaparkF(..), LUNAPARK, performActions, findElement)
29import Lunapark.Types as LT
29import Lunapark.Types as LT
30−import Lunapark.Utils (liftAndRethrow, throwLeft, catch)
30+import Lunapark.Utils (liftAndRethrow, rethrowAsJsonDecodeError, catch)
31import Node.Buffer as B
31import Node.Buffer as B
32import Node.FS.Aff as FS
32import Node.FS.Aff as FS
33+import Run (Run)
33import Run as R
34import Run as R
34import Run.Except (EXCEPT)
35import Run.Except (EXCEPT)
36+import Type.Row (type (+))
37+import Run.Except as RE
38+
39+type Lunapark r a = Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r) a
40+
41+newtype Interpreter r = Interpreter (Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r) ~> Run (BASE_EFFECTS r))
42+
43+runInterpreter ∷ ∀ r. Interpreter r → Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r) ~> Run (BASE_EFFECTS r)
44+runInterpreter (Interpreter f) = f
35
45
36init
46init
37− ∷ ∀ m r a
47+ ∷ ∀ m r
38 . MonadAff m
48 . MonadAff m
39 ⇒ MonadRec m
49 ⇒ MonadRec m
40 ⇒ String
50 ⇒ String
41 → LT.CapabilitiesRequest
51 → LT.CapabilitiesRequest
42− → m (Either LE.Error (Lunapark r a → BaseRun r a))
52+ → m (Either LE.Error (Interpreter r))
43init uri caps = do
53init uri caps = do
44 res ←
54 res ←
45 liftAff
55 liftAff
@@ -49,7 +59,7 @@ init uri caps = do
49 let
59 let
50 sessionResponse = do
60 sessionResponse = do
51 sessObj ← res
61 sessObj ← res
52− lmap LE.unknownError $ LT.decodeCreateSessionResponse sessObj
62+ lmap LE.JsonDecodeError $ LT.decodeCreateSessionResponse sessObj
53
63
54 T.for sessionResponse \{ session, capabilities } → do
64 T.for sessionResponse \{ session, capabilities } → do
55 timeoutsRef ←
65 timeoutsRef ←
@@ -64,8 +74,9 @@ init uri caps = do
64 actionsEnabled ←
74 actionsEnabled ←
65 map isRight
75 map isRight
66 $ liftAff
76 $ liftAff
67− $ LP.post uri (LP.InSession session : LP.Actions : Nil)
77+ $ LP.post uri (LP.InSession session : LP.Actions : Nil)
68− $ LT.encodeActionRequest $ FO.singleton "action-test"
78+ $ LT.encodeActionRequest
79+ $ FO.singleton "action-test"
69 $ LT.NoSource [ LT.pause $ Milliseconds 0.0 ]
80 $ LT.NoSource [ LT.pause $ Milliseconds 0.0 ]
70
81
71 let
82 let
@@ -78,29 +89,26 @@ init uri caps = do
78 , actionsEnabled
89 , actionsEnabled
79 }
90 }
80
91
81− pure $ interpret input
92+ pure $ Interpreter (interpret input)
82
93
83interpret
94interpret
84 ∷ ∀ r
95 ∷ ∀ r
85 . HandleLunaparkInput
96 . HandleLunaparkInput
86− → Lunapark r
97+ → Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r)
87− ~> BaseRun r
98+ ~> Run (BASE_EFFECTS r)
88interpret input = runLunapark input <<< runLunaparkActions input
99interpret input = runLunapark input <<< runLunaparkActions input
89
100
101+type BASE_EFFECTS r = EXCEPT LE.Error + R.AFF + R.EFFECT + r
90
102
91−type Lunapark r = BaseRun (lunapark ∷ LUNAPARK, lunaparkActions ∷ LUNAPARK_ACTIONS|r)
92−
93−type BaseRun r = R.Run
94− ( except ∷ EXCEPT LE.Error
95− , aff ∷ R.AFF
96− , effect ∷ R.EFFECT
97− | r)
98−
99−runLunapark ∷ ∀ r. HandleLunaparkInput → BaseRun (lunapark ∷ LUNAPARK|r) ~> BaseRun r
103+runLunapark ∷ ∀ r. HandleLunaparkInput → Run (BASE_EFFECTS + LUNAPARK + r) ~> Run (BASE_EFFECTS r)
100runLunapark input = do
104runLunapark input = do
101 R.interpretRec (R.on _lunapark (handleLunapark input) R.send)
105 R.interpretRec (R.on _lunapark (handleLunapark input) R.send)
102
106
107+runLunaparkActions
108+ ∷ ∀ r
103−runLunaparkActions ∷ ∀ r. HandleLunaparkInput → Lunapark r ~> BaseRun (lunapark ∷ LUNAPARK|r)
109+ . HandleLunaparkInput
110+ → Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r)
111+ ~> Run (BASE_EFFECTS + LUNAPARK + r)
104runLunaparkActions input
112runLunaparkActions input
105 | input.actionsEnabled = interpretW3CActions Nil
113 | input.actionsEnabled = interpretW3CActions Nil
106 | otherwise = R.interpretRec (R.on _lunaparkActions (jsonWireActions input) R.send)
114 | otherwise = R.interpretRec (R.on _lunaparkActions (jsonWireActions input) R.send)
@@ -108,8 +116,8 @@ runLunaparkActions input
108interpretW3CActions
116interpretW3CActions
109 ∷ ∀ r
117 ∷ ∀ r
110 . List LT.ActionSequence
118 . List LT.ActionSequence
111− → Lunapark r
119+ → Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r)
112− ~> BaseRun (lunapark ∷ LUNAPARK|r)
120+ ~> Run (BASE_EFFECTS + LUNAPARK + r)
113interpretW3CActions acc as = case R.peel as of
121interpretW3CActions acc as = case R.peel as of
114 Left la → case tag la of
122 Left la → case tag la of
115 Left a → w3cActions acc interpretW3CActions a
123 Left a → w3cActions acc interpretW3CActions a
@@ -125,55 +133,83 @@ w3cActions
125 ∷ ∀ r a
133 ∷ ∀ r a
126 . List LT.ActionSequence
134 . List LT.ActionSequence
127 → ( List LT.ActionSequence
135 → ( List LT.ActionSequence
128− → Lunapark r
136+ → Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r)
129− ~> BaseRun (lunapark ∷ LUNAPARK|r)
137+ ~> Run (BASE_EFFECTS + LUNAPARK + r)
130 )
138 )
131− → ActionF (Lunapark r a)
139+ → ActionF (Run (BASE_EFFECTS + LUNAPARK + LUNAPARK_ACTIONS + r) a)
132− → BaseRun (lunapark ∷ LUNAPARK|r) a
140+ → Run (BASE_EFFECTS + LUNAPARK + r) a
133w3cActions acc loop = case _ of
141w3cActions acc loop = case _ of
134 Click btn next →
142 Click btn next →
143+ let
135− let seq = [ LT.pointerDown btn, LT.pointerUp btn ]
144+ seq = [ LT.pointerDown btn, LT.pointerUp btn ]
145+ in
136− in loop (inMouse seq) next
146+ loop (inMouse seq) next
137 ButtonDown btn next →
147 ButtonDown btn next →
148+ let
138− let seq = [ LT.pointerDown btn ]
149+ seq = [ LT.pointerDown btn ]
150+ in
139− in loop (inMouse seq) next
151+ loop (inMouse seq) next
140 ButtonUp btn next →
152 ButtonUp btn next →
153+ let
141− let seq = [ LT.pointerUp btn ]
154+ seq = [ LT.pointerUp btn ]
155+ in
142− in loop (inMouse seq) next
156+ loop (inMouse seq) next
143 DoubleClick btn next →
157 DoubleClick btn next →
158+ let
144− let seq = [ LT.pointerDown btn, LT.pointerUp btn, LT.pointerDown btn, LT.pointerUp btn ]
159+ seq = [ LT.pointerDown btn, LT.pointerUp btn, LT.pointerDown btn, LT.pointerUp btn ]
160+ in
145− in loop (inMouse seq) next
161+ loop (inMouse seq) next
146 MoveTo move next →
162 MoveTo move next →
163+ let
147− let seq = [ LT.pointerMove move ]
164+ seq = [ LT.pointerMove move ]
165+ in
148− in loop (inPointer seq) next
166+ loop (inPointer seq) next
149 SendKeys txt next →
167 SendKeys txt next →
168+ let
150− let seq = T.foldMap (\ch → [ LT.keyDown ch, LT.keyUp ch ]) $ Str.toCharArray txt
169+ seq = T.foldMap (\ch → [ LT.keyDown ch, LT.keyUp ch ]) $ Str.toCharArray txt
170+ in
151− in loop (inKeys seq) next
171+ loop (inKeys seq) next
152 Pause ms next →
172 Pause ms next →
173+ let
153− let seq = [ LT.pause ms ]
174+ seq = [ LT.pause ms ]
175+ in
154− in loop (anywhere seq) next
176+ loop (anywhere seq) next
155 InTouch tch → case tch of
177 InTouch tch → case tch of
156 Tap next →
178 Tap next →
179+ let
157− let seq = [ LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn ]
180+ seq = [ LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn ]
181+ in
158− in loop (inTouch seq) next
182+ loop (inTouch seq) next
159 TouchDown next →
183 TouchDown next →
184+ let
160− let seq = [ LT.pointerDown LT.LeftBtn ]
185+ seq = [ LT.pointerDown LT.LeftBtn ]
186+ in
161− in loop (inTouch seq) next
187+ loop (inTouch seq) next
162 TouchUp next →
188 TouchUp next →
189+ let
163− let seq = [ LT.pointerUp LT.LeftBtn ]
190+ seq = [ LT.pointerUp LT.LeftBtn ]
191+ in
164− in loop (inTouch seq) next
192+ loop (inTouch seq) next
165 LongClick next →
193 LongClick next →
194+ let
166− let seq = [ LT.pointerDown LT.LeftBtn, LT.pause (Milliseconds 3000.0), LT.pointerUp LT.LeftBtn ]
195+ seq = [ LT.pointerDown LT.LeftBtn, LT.pause (Milliseconds 3000.0), LT.pointerUp LT.LeftBtn ]
196+ in
167− in loop (inTouch seq) next
197+ loop (inTouch seq) next
168 Flick move next →
198 Flick move next →
199+ let
169− let seq = [ LT.pointerMove move ]
200+ seq = [ LT.pointerMove move ]
201+ in
170− in loop (inTouch seq) next
202+ loop (inTouch seq) next
171 Scroll move next →
203 Scroll move next →
204+ let
172− let seq = [ LT.pointerMove move ]
205+ seq = [ LT.pointerMove move ]
206+ in
173− in loop (inTouch seq) next
207+ loop (inTouch seq) next
174 DoubleTap next →
208 DoubleTap next →
209+ let
175− let seq = [ LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn, LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn ]
210+ seq = [ LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn, LT.pointerDown LT.LeftBtn, LT.pointerUp LT.LeftBtn ]
211+ in
176− in loop (inTouch seq) next
212+ loop (inTouch seq) next
177 where
213 where
178 unconsed = L.uncons acc
214 unconsed = L.uncons acc
179
215
@@ -214,7 +250,7 @@ type HandleLunaparkInput =
214 , actionsEnabled ∷ Boolean
250 , actionsEnabled ∷ Boolean
215 }
251 }
216
252
217−jsonWireActions ∷ ∀ r. HandleLunaparkInput → ActionF ~> BaseRun (lunapark ∷ LUNAPARK|r)
253+jsonWireActions ∷ ∀ r. HandleLunaparkInput → ActionF ~> Run (BASE_EFFECTS + LUNAPARK + r)
218jsonWireActions inp = case _ of
254jsonWireActions inp = case _ of
219 Click btn next → do
255 Click btn next → do
220 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
256 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
@@ -227,8 +263,8 @@ jsonWireActions inp = case _ of
227 pure next
263 pure next
228 DoubleClick btn next → do
264 DoubleClick btn next → do
229 _ ← case btn of
265 _ ← case btn of
230− LT.LeftBtn → post_ (LP.DoubleClick : Nil)
266+ LT.LeftBtn → post' (LP.DoubleClick : Nil)
231− other → do
267+ _ → do
232 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
268 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
233 post (LP.Click : Nil) (LT.encodeButton btn)
269 post (LP.Click : Nil) (LT.encodeButton btn)
234 pure next
270 pure next
@@ -248,16 +284,16 @@ jsonWireActions inp = case _ of
248 pure next
284 pure next
249 InTouch tch → case tch of
285 InTouch tch → case tch of
250 Tap next → do
286 Tap next → do
251− _ ← post_ (LP.Touch : LP.Click : Nil)
287+ _ ← post' (LP.Touch : LP.Click : Nil)
252 pure next
288 pure next
253 TouchDown next → do
289 TouchDown next → do
254− _ ← post_ (LP.Touch : LP.Down : Nil)
290+ _ ← post' (LP.Touch : LP.Down : Nil)
255 pure next
291 pure next
256 TouchUp next → do
292 TouchUp next → do
257− _ ← post_ (LP.Touch : LP.Up : Nil)
293+ _ ← post' (LP.Touch : LP.Up : Nil)
258 pure next
294 pure next
259 LongClick next → do
295 LongClick next → do
260− _ ← post_ (LP.Touch : LP.LongClick : Nil)
296+ _ ← post' (LP.Touch : LP.LongClick : Nil)
261 pure next
297 pure next
262 Flick move next → do
298 Flick move next → do
263 element ← case move.origin of
299 element ← case move.origin of
@@ -276,23 +312,23 @@ jsonWireActions inp = case _ of
276 _ ← post (LP.Touch : LP.Scroll : Nil) (LT.encodeMoveToRequest req)
312 _ ← post (LP.Touch : LP.Scroll : Nil) (LT.encodeMoveToRequest req)
277 pure next
313 pure next
278 DoubleTap next → do
314 DoubleTap next → do
279− _ ← post_ (LP.Touch : LP.DoubleClick : Nil)
315+ _ ← post' (LP.Touch : LP.DoubleClick : Nil)
280 pure next
316 pure next
281 where
317 where
282 post a b = liftAndRethrow $ LP.post inp.uri (inSession : a) b
318 post a b = liftAndRethrow $ LP.post inp.uri (inSession : a) b
283− post_ a = liftAndRethrow $ LP.post_ inp.uri (inSession : a)
319+ post' a = liftAndRethrow $ LP.post' inp.uri (inSession : a)
284
320
285 inSession ∷ LP.EndpointPart
321 inSession ∷ LP.EndpointPart
286 inSession = LP.InSession inp.session
322 inSession = LP.InSession inp.session
287
323
288−handleLunapark ∷ ∀ r. HandleLunaparkInput → LunaparkF ~> BaseRun r
324+handleLunapark ∷ ∀ r. HandleLunaparkInput → LunaparkF ~> Run (BASE_EFFECTS r)
289handleLunapark inp = case _ of
325handleLunapark inp = case _ of
290 Quit next → do
326 Quit next → do
291 _ ← delete $ inSession : Nil
327 _ ← delete $ inSession : Nil
292 pure next
328 pure next
293 Status cont → do
329 Status cont → do
294 res ← get $ LP.Status : Nil
330 res ← get $ LP.Status : Nil
295− ss ← throwLeft $ LT.decodeServerStatus res
331+ ss ← rethrowAsJsonDecodeError $ LT.decodeServerStatus res
296 pure $ cont ss
332 pure $ cont ss
297 GetTimeouts cont → do
333 GetTimeouts cont → do
298 res ← R.liftEffect $ Ref.read inp.timeoutsRef
334 res ← R.liftEffect $ Ref.read inp.timeoutsRef
@@ -301,8 +337,7 @@ handleLunapark inp = case _ of
301 R.liftEffect $ Ref.write ts inp.timeoutsRef
337 R.liftEffect $ Ref.write ts inp.timeoutsRef
302 tryAndCache "set timeouts"
338 tryAndCache "set timeouts"
303 [ void $ post (inSession : LP.Timeouts : Nil) (LT.encodeTimeouts ts)
339 [ void $ post (inSession : LP.Timeouts : Nil) (LT.encodeTimeouts ts)
304− , do T.for_ (LT.encodeLegacyTimeouts ts) \j →
340+ , T.for_ (LT.encodeLegacyTimeouts ts) (post (inSession : LP.Timeouts : Nil))
305− void $ post (inSession : LP.Timeouts : Nil) j
306 ]
341 ]
307 pure next
342 pure next
308 GoTo uri next → do
343 GoTo uri next → do
@@ -310,31 +345,31 @@ handleLunapark inp = case _ of
310 pure next
345 pure next
311 GetUrl cont → do
346 GetUrl cont → do
312 res ← get $ inSession : LP.Url : Nil
347 res ← get $ inSession : LP.Url : Nil
313− map cont $ throwLeft $ J.decodeJson res
348+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
314 Back next → do
349 Back next → do
315− _ ← post_ (inSession : LP.Back : Nil)
350+ _ ← post' (inSession : LP.Back : Nil)
316 pure next
351 pure next
317 Forward next → do
352 Forward next → do
318− _ ← post_ (inSession : LP.Forward : Nil)
353+ _ ← post' (inSession : LP.Forward : Nil)
319 pure next
354 pure next
320 Refresh next → do
355 Refresh next → do
321− _ ← post_ (inSession : LP.Refresh : Nil)
356+ _ ← post' (inSession : LP.Refresh : Nil)
322 pure next
357 pure next
323 GetTitle cont → do
358 GetTitle cont → do
324 res ← get (inSession : LP.Title : Nil)
359 res ← get (inSession : LP.Title : Nil)
325− map cont $ throwLeft $ J.decodeJson res
360+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
326 GetWindowHandle cont → do
361 GetWindowHandle cont → do
327 res ← tryAndCache "get window handle"
362 res ← tryAndCache "get window handle"
328 [ get (inSession : LP.Window : Nil)
363 [ get (inSession : LP.Window : Nil)
329 , get (inSession : LP.WindowHandle : Nil)
364 , get (inSession : LP.WindowHandle : Nil)
330 ]
365 ]
331− map cont $ throwLeft $ LT.decodeWindowHandle res
366+ map cont $ rethrowAsJsonDecodeError $ LT.decodeWindowHandle res
332 GetWindowHandles cont → do
367 GetWindowHandles cont → do
333 res ← tryAndCache "get window handles"
368 res ← tryAndCache "get window handles"
334 [ get (inSession : LP.Window : LP.Handles : Nil)
369 [ get (inSession : LP.Window : LP.Handles : Nil)
335 , get (inSession : LP.WindowHandles : Nil)
370 , get (inSession : LP.WindowHandles : Nil)
336 ]
371 ]
337− map cont $ throwLeft $ T.traverse LT.decodeWindowHandle =<< J.decodeJson res
372+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeWindowHandle =<< J.decodeJson res
338 CloseWindow next → do
373 CloseWindow next → do
339 _ ← delete (inSession : LP.Window : Nil)
374 _ ← delete (inSession : LP.Window : Nil)
340 pure next
375 pure next
@@ -345,33 +380,36 @@ handleLunapark inp = case _ of
345 _ ← post (inSession : LP.Frame : Nil) (LT.encodeFrameId fid)
380 _ ← post (inSession : LP.Frame : Nil) (LT.encodeFrameId fid)
346 pure next
381 pure next
347 SwitchToParentFrame next → do
382 SwitchToParentFrame next → do
348− _ ← post_ (inSession : LP.Frame : LP.Parent : Nil)
383+ _ ← post' (inSession : LP.Frame : LP.Parent : Nil)
349 pure next
384 pure next
350 GetWindowRectangle cont → do
385 GetWindowRectangle cont → do
351 res ← tryAndCache "get window rectangle"
386 res ← tryAndCache "get window rectangle"
387+ [ do
352− [ do res ← get (inSession : LP.Window : LP.Rect : Nil)
388+ res ← get (inSession : LP.Window : LP.Rect : Nil)
353− throwLeft $ LT.decodeRectangle res
389+ rethrowAsJsonDecodeError $ LT.decodeRectangle res
390+ , do
354− , do position ← get (inSession : LP.Window : LP.Position : Nil)
391+ position ← get (inSession : LP.Window : LP.Position : Nil)
355− size ← get (inSession : LP.Window : LP.Size : Nil)
392+ size ← get (inSession : LP.Window : LP.Size : Nil)
356− throwLeft $ LT.decodeRectangleLegacy { position, size }
393+ rethrowAsJsonDecodeError $ LT.decodeRectangleLegacy { position, size }
357 ]
394 ]
358 pure $ cont res
395 pure $ cont res
359 SetWindowRectangle r next → do
396 SetWindowRectangle r next → do
360 tryAndCache "set window rectangle"
397 tryAndCache "set window rectangle"
361 [ void $ post (inSession : LP.Window : LP.Rect : Nil) (LT.encodeRectangle r)
398 [ void $ post (inSession : LP.Window : LP.Rect : Nil) (LT.encodeRectangle r)
399+ , do
362− , do let js = LT.encodeRectangleLegacy r
400+ let js = LT.encodeRectangleLegacy r
363− _ ← post (inSession : LP.Window : LP.Size : Nil) js.size
401+ _ ← post (inSession : LP.Window : LP.Size : Nil) js.size
364− void $ post (inSession : LP.Window : LP.Position : Nil) js.position
402+ void $ post (inSession : LP.Window : LP.Position : Nil) js.position
365 ]
403 ]
366 pure next
404 pure next
367 MaximizeWindow next → do
405 MaximizeWindow next → do
368− _ ← post_ (inSession : LP.Window : LP.Maximize : Nil)
406+ _ ← post' (inSession : LP.Window : LP.Maximize : Nil)
369 pure next
407 pure next
370 MinimizeWindow next → do
408 MinimizeWindow next → do
371− _ ← post_ (inSession : LP.Window : LP.Minimize : Nil)
409+ _ ← post' (inSession : LP.Window : LP.Minimize : Nil)
372 pure next
410 pure next
373 FullscreenWindow next → do
411 FullscreenWindow next → do
374− _ ← post_ (inSession : LP.Window : LP.Fullscreen : Nil)
412+ _ ← post' (inSession : LP.Window : LP.Fullscreen : Nil)
375 pure next
413 pure next
376 ExecuteScript script cont → do
414 ExecuteScript script cont → do
377 map cont $ tryAndCache "execute script"
415 map cont $ tryAndCache "execute script"
@@ -385,10 +423,10 @@ handleLunapark inp = case _ of
385 ]
423 ]
386 GetAllCookies cont → do
424 GetAllCookies cont → do
387 res ← get (inSession : LP.Cookies : Nil)
425 res ← get (inSession : LP.Cookies : Nil)
388− map cont $ throwLeft $ T.traverse LT.decodeCookie =<< J.decodeJson res
426+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeCookie =<< J.decodeJson res
389 GetCookie name cont → do
427 GetCookie name cont → do
390 res ← get (inSession : LP.Cookie name : Nil)
428 res ← get (inSession : LP.Cookie name : Nil)
391− map cont $ throwLeft $ LT.decodeCookie res
429+ map cont $ rethrowAsJsonDecodeError $ LT.decodeCookie res
392 DeleteAllCookies next → do
430 DeleteAllCookies next → do
393 _ ← delete (inSession : LP.Cookies : Nil)
431 _ ← delete (inSession : LP.Cookies : Nil)
394 pure next
432 pure next
@@ -400,14 +438,14 @@ handleLunapark inp = case _ of
400 pure next
438 pure next
401 DismissAlert next → do
439 DismissAlert next → do
402 _ ← tryAndCache "dismiss alert"
440 _ ← tryAndCache "dismiss alert"
403− [ post_ (inSession : LP.Alert : LP.Dismiss : Nil)
441+ [ post' (inSession : LP.Alert : LP.Dismiss : Nil)
404− , post_ (inSession : LP.DismissAlert : Nil)
442+ , post' (inSession : LP.DismissAlert : Nil)
405 ]
443 ]
406 pure next
444 pure next
407 AcceptAlert next → do
445 AcceptAlert next → do
408 _ ← tryAndCache "accept alert"
446 _ ← tryAndCache "accept alert"
409− [ post_ (inSession : LP.Alert : LP.Accept : Nil)
447+ [ post' (inSession : LP.Alert : LP.Accept : Nil)
410− , post_ (inSession : LP.AcceptAlert : Nil)
448+ , post' (inSession : LP.AcceptAlert : Nil)
411 ]
449 ]
412 pure next
450 pure next
413 GetAlertText cont → do
451 GetAlertText cont → do
@@ -415,7 +453,7 @@ handleLunapark inp = case _ of
415 [ get (inSession : LP.Alert : LP.Text : Nil)
453 [ get (inSession : LP.Alert : LP.Text : Nil)
416 , get (inSession : LP.AlertText : Nil)
454 , get (inSession : LP.AlertText : Nil)
417 ]
455 ]
418− map cont $ throwLeft $ J.decodeJson res
456+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
419 SendAlertText str next → do
457 SendAlertText str next → do
420 _ ← tryAndCache "send alert text"
458 _ ← tryAndCache "send alert text"
421 [ post (inSession : LP.Alert : LP.Text : Nil) (LT.encodeSendKeysRequest str)
459 [ post (inSession : LP.Alert : LP.Text : Nil) (LT.encodeSendKeysRequest str)
@@ -424,124 +462,143 @@ handleLunapark inp = case _ of
424 pure next
462 pure next
425 Screenshot fp next → do
463 Screenshot fp next → do
426 res ← get (inSession : LP.Screenshot : Nil)
464 res ← get (inSession : LP.Screenshot : Nil)
427− screenshotPack ← throwLeft $ LT.decodeScreenshot res
465+ screenshotPack ← rethrowAsJsonDecodeError $ LT.decodeScreenshot res
428 buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
466 buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
429 R.liftAff $ FS.writeFile fp buffer
467 R.liftAff $ FS.writeFile fp buffer
430 pure next
468 pure next
431 FindElement loc cont → do
469 FindElement loc cont → do
432 res ← post (inSession : LP.Element : Nil) (LT.encodeLocator loc)
470 res ← post (inSession : LP.Element : Nil) (LT.encodeLocator loc)
433− map cont $ throwLeft $ LT.decodeElement res
471+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
434 FindElements loc cont → do
472 FindElements loc cont → do
435 res ← post (inSession : LP.Elements : Nil) (LT.encodeLocator loc)
473 res ← post (inSession : LP.Elements : Nil) (LT.encodeLocator loc)
436− map cont $ throwLeft $ T.traverse LT.decodeElement =<< J.decodeJson res
474+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeElement =<< J.decodeJson res
437 GetActiveElement cont → do
475 GetActiveElement cont → do
438 res ← get (inSession : LP.Element : LP.Active : Nil)
476 res ← get (inSession : LP.Element : LP.Active : Nil)
439− map cont $ throwLeft $ LT.decodeElement res
477+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
440 PerformActions req next → do
478 PerformActions req next → do
441 when inp.actionsEnabled
479 when inp.actionsEnabled
442− $ void $ post
480+ $ void
481+ $ post
443− (inSession : LP.Actions : Nil)
482+ (inSession : LP.Actions : Nil)
444− (LT.encodeActionRequest req)
483+ (LT.encodeActionRequest req)
445 pure next
484 pure next
446 ReleaseActions next → do
485 ReleaseActions next → do
447 when inp.actionsEnabled $ void $ delete (inSession : LP.Actions : Nil)
486 when inp.actionsEnabled $ void $ delete (inSession : LP.Actions : Nil)
448 pure next
487 pure next
449 OnElement el elF →
488 OnElement el elF →
489+ let
450− let inElement = LP.InElement el
490+ inElement = LP.InElement el
491+ in
451− in case elF of
492+ case elF of
452− ChildElement loc cont → do
493+ ChildElement loc cont → do
453− res ← post (inSession : inElement : LP.Element : Nil) (LT.encodeLocator loc)
494+ res ← post (inSession : inElement : LP.Element : Nil) (LT.encodeLocator loc)
454− map cont $ throwLeft $ LT.decodeElement res
495+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
455− ChildElements loc cont → do
496+ ChildElements loc cont → do
456− res ← post (inSession : inElement : LP.Elements : Nil) (LT.encodeLocator loc)
497+ res ← post (inSession : inElement : LP.Elements : Nil) (LT.encodeLocator loc)
457− map cont $ throwLeft $ T.traverse LT.decodeElement =<< J.decodeJson res
498+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeElement =<< J.decodeJson res
458− ScreenshotEl fp next → do
499+ ScreenshotEl fp next → do
459− res ← get (inSession : inElement : LP.Screenshot : Nil)
500+ res ← get (inSession : inElement : LP.Screenshot : Nil)
460− screenshotPack ← throwLeft $ LT.decodeScreenshot res
501+ screenshotPack ← rethrowAsJsonDecodeError $ LT.decodeScreenshot res
461− buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
502+ buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
462− R.liftAff $ FS.writeFile fp buffer
503+ R.liftAff $ FS.writeFile fp buffer
463− pure next
504+ pure next
464− IsSelected cont → do
505+ IsSelected cont → do
465− res ← get (inSession : inElement : LP.Selected : Nil)
506+ res ← get (inSession : inElement : LP.Selected : Nil)
466− map cont $ throwLeft $ J.decodeJson res
507+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
467− GetAttribute attr cont → do
508+ GetAttribute attr cont → do
468− res ← get (inSession : inElement : LP.Attribute attr : Nil)
509+ res ← get (inSession : inElement : LP.Attribute attr : Nil)
469− map cont $ throwLeft $ J.decodeJson res
510+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
470− GetProperty prop cont → do
511+ GetProperty prop cont → do
471− map cont $ get (inSession : inElement : LP.Property prop : Nil)
512+ map cont $ get (inSession : inElement : LP.Property prop : Nil)
472− GetCss css cont → do
513+ GetCss css cont → do
473− res ← get (inSession : inElement : LP.CssValue css : Nil)
514+ res ← get (inSession : inElement : LP.CssValue css : Nil)
474− map cont $ throwLeft $ J.decodeJson res
515+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
475− GetText cont → do
516+ GetText cont → do
476− res ← get (inSession : inElement : LP.Text : Nil)
517+ res ← get (inSession : inElement : LP.Text : Nil)
477− map cont $ throwLeft $ J.decodeJson res
518+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
478− GetTagName cont → do
519+ GetTagName cont → do
479− res ← get (inSession : inElement : LP.Name : Nil)
520+ res ← get (inSession : inElement : LP.Name : Nil)
480− map cont $ throwLeft $ J.decodeJson res
521+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
481− GetRectangle cont →
522+ GetRectangle cont →
482− map cont $ tryAndCache "get element rectangle"
523+ map cont $ tryAndCache "get element rectangle"
524+ [ do
483− [ do res ← get (inSession : inElement : LP.Rect : Nil)
525+ res ← get (inSession : inElement : LP.Rect : Nil)
484− throwLeft $ LT.decodeRectangle res
526+ rethrowAsJsonDecodeError $ LT.decodeRectangle res
527+ , do
485− , do position ← get (inSession : inElement : LP.Position : Nil)
528+ position ← get (inSession : inElement : LP.Position : Nil)
486− size ← get (inSession : inElement : LP.Size : Nil)
529+ size ← get (inSession : inElement : LP.Size : Nil)
487− throwLeft $ LT.decodeRectangleLegacy { position, size }
530+ rethrowAsJsonDecodeError $ LT.decodeRectangleLegacy { position, size }
488− ]
531+ ]
489− IsEnabled cont → do
532+ IsEnabled cont → do
490− res ← get (inSession : inElement : LP.Enabled : Nil)
533+ res ← get (inSession : inElement : LP.Enabled : Nil)
491− map cont $ throwLeft $ J.decodeJson res
534+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
492− ClickEl next → do
535+ ClickEl next → do
536+ _ ← tryAndCache "chromedriver75 update clickElement"
537+ [ post' (inSession : inElement : LP.Click : Nil)
493− _ ← post_ (inSession : inElement : LP.Click : Nil)
538+ , post (inSession : inElement : LP.Click : Nil) $ LT.encodeElement el
539+ ]
494− pure next
540+ pure next
495− ClearEl next → do
541+ ClearEl next → do
542+ _ ← tryAndCache "chromedriver75 update clearElement"
496− _ ← post_ (inSession : inElement : LP.Clear : Nil)
543+ [ post' (inSession : inElement : LP.Clear : Nil)
544+ , post (inSession : inElement : LP.Click : Nil) $ LT.encodeElement el
545+ ]
497− pure next
546+ pure next
498− SendKeysEl txt next → do
547+ SendKeysEl txt next → do
499− _ ← tryAndCache "send keys chromedriver hack"
548+ _ ← tryAndCache "send keys chromedriver hack"
500− [ post (inSession : inElement : LP.Value : Nil) (LT.encodeSendKeysRequest txt)
549+ [ post (inSession : inElement : LP.Value : Nil) (LT.encodeSendKeysRequest txt)
501− , post (inSession : inElement : LP.Value : Nil)
550+ , post (inSession : inElement : LP.Value : Nil)
551+ $ J.encodeJson
552+ $ FO.singleton "value"
502− $ J.encodeJson $ FO.singleton "value" $ Str.toCharArray txt
553+ $ Str.toCharArray txt
503− ]
554+ ]
504− pure next
555+ pure next
505− IsDisplayed cont → do
556+ IsDisplayed cont → do
506− res ← tryAndCache "is element displayed"
557+ res ← tryAndCache "is element displayed"
507− [ get (inSession : inElement : LP.Displayed : Nil)
558+ [ get (inSession : inElement : LP.Displayed : Nil)
559+ , do
560+ let
508− , do let script =
561+ script =
509− { script: """var el = arguments[0]; return el.offsetHeight > 0 && el.offsetWidth > 0"""
562+ { script: """var el = arguments[0]; return el.offsetHeight > 0 && el.offsetWidth > 0"""
510− , args: [ LT.encodeElement el ]
563+ , args: [ LT.encodeElement el ]
511− }
564+ }
512− handleLunapark inp $ ExecuteScript script identity
565+ handleLunapark inp $ ExecuteScript script identity
513− ]
566+ ]
514− map cont $ throwLeft $ J.decodeJson res
567+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
515− Submit next → do
568+ Submit next → do
569+ _ ← tryAndCache "chromedriver75 update submit form"
570+ [ post' (inSession : inElement : LP.Submit : Nil)
516− _ ← post_ (inSession : inElement : LP.Submit : Nil)
571+ , post (inSession : inElement : LP.Submit : Nil) $ LT.encodeElement el
572+ ]
517− pure next
573+ pure next
518
574
519 where
575 where
520 delete a = liftAndRethrow $ LP.delete inp.uri a
576 delete a = liftAndRethrow $ LP.delete inp.uri a
521 post a b = liftAndRethrow $ LP.post inp.uri a b
577 post a b = liftAndRethrow $ LP.post inp.uri a b
522 get a = liftAndRethrow $ LP.get inp.uri a
578 get a = liftAndRethrow $ LP.get inp.uri a
523− post_ a = liftAndRethrow $ LP.post_ inp.uri a
579+ post' a = liftAndRethrow $ LP.post' inp.uri a
524
580
581+ -- | It caches an index of an action that is valid for current webdriver implementation.
582+ -- | So you don't need to search correct one by tring them each time
525− tryAndCache ∷ ∀ a. String → Array (BaseRun r a) → BaseRun r a
583+ tryAndCache ∷ ∀ a. String → Array (Run (BASE_EFFECTS r) a) → Run (BASE_EFFECTS r) a
526 tryAndCache key actions = do
584 tryAndCache key actions = do
527− let emptyCases = throwLeft $ Left $ "No valid cases for " <> key <> " caching"
528− let incorrectCache = throwLeft $ Left $ "Fallback for " <> key <> " error"
529−
530 mp ← R.liftEffect $ Ref.read inp.requestMapRef
585 mp ← R.liftEffect $ Ref.read inp.requestMapRef
531 case Map.lookup key mp of
586 case Map.lookup key mp of
532 Just ix → case A.index actions ix of
587 Just ix → case A.index actions ix of
533 Just action → action
588 Just action → action
534− Nothing → incorrectCache
589+ Nothing → RE.throw $ LE.CachingError $ LE.IncorrectCache key
535 Nothing →
590 Nothing →
536 let
591 let
537 go ix acc act =
592 go ix acc act =
593+ let
538− let try' = do
594+ try' = do
539− a ← act
595+ a ← act
540− R.liftEffect $ Ref.modify_ (Map.insert key ix) inp.requestMapRef
596+ R.liftEffect $ Ref.modify_ (Map.insert key ix) inp.requestMapRef
541− pure a
597+ pure a
598+ in
542− in catch try' \_ → acc
599+ catch try' \_ → acc
543 in
600 in
544− FI.foldlWithIndex go emptyCases actions
601+ FI.foldlWithIndex go (RE.throw $ LE.CachingError $ LE.EmptyCases key) actions
545
602
546 inSession ∷ LP.EndpointPart
603 inSession ∷ LP.EndpointPart
547 inSession = LP.InSession inp.session
604 inSession = LP.InSession inp.session
src/Lunapark/ActionF.purs+19−20
@@ -2,12 +2,12 @@ module Lunapark.ActionF where
2
2
3import Prelude
3import Prelude
4
4
5−import Data.Symbol (SProxy(..))
5+import Type.Proxy (Proxy(..))
6import Data.Time.Duration (Milliseconds)
6import Data.Time.Duration (Milliseconds)
7import Lunapark.Types as LT
7import Lunapark.Types as LT
8+import Run (Run)
8import Run as R
9import Run as R
9
10
10−
11data ActionF a
11data ActionF a
12 = Click LT.Button a
12 = Click LT.Button a
13 | ButtonDown LT.Button a
13 | ButtonDown LT.Button a
@@ -30,51 +30,50 @@ data TouchF a
30derive instance functorActionF ∷ Functor ActionF
30derive instance functorActionF ∷ Functor ActionF
31derive instance functorTouchF ∷ Functor TouchF
31derive instance functorTouchF ∷ Functor TouchF
32
32
33−_lunaparkActions = SProxy ∷ SProxy "lunaparkActions"
33+_lunaparkActions = Proxy ∷ Proxy "lunaparkActions"
34−type LUNAPARK_ACTIONS = R.FProxy ActionF
34+type LUNAPARK_ACTIONS r = (lunaparkActions ∷ ActionF | r)
35−type WithAction r = R.Run (lunaparkActions ∷ LUNAPARK_ACTIONS|r) Unit
36
35
37−liftAction ∷ ∀ r. ActionF Unit → WithAction r
36+liftAction ∷ ∀ r. ActionF Unit → Run (LUNAPARK_ACTIONS r) Unit
38liftAction = R.lift _lunaparkActions
37liftAction = R.lift _lunaparkActions
39
38
40−click ∷ ∀ r. LT.Button → WithAction r
39+click ∷ ∀ r. LT.Button → Run (LUNAPARK_ACTIONS r) Unit
41click btn = liftAction $ Click btn unit
40click btn = liftAction $ Click btn unit
42
41
43−buttonDown ∷ ∀ r. LT.Button → WithAction r
42+buttonDown ∷ ∀ r. LT.Button → Run (LUNAPARK_ACTIONS r) Unit
44buttonDown btn = liftAction $ ButtonDown btn unit
43buttonDown btn = liftAction $ ButtonDown btn unit
45
44
46−buttonUp ∷ ∀ r. LT.Button → WithAction r
45+buttonUp ∷ ∀ r. LT.Button → Run (LUNAPARK_ACTIONS r) Unit
47buttonUp btn = liftAction $ ButtonUp btn unit
46buttonUp btn = liftAction $ ButtonUp btn unit
48
47
49−doubleClick ∷ ∀ r. LT.Button → WithAction r
48+doubleClick ∷ ∀ r. LT.Button → Run (LUNAPARK_ACTIONS r) Unit
50doubleClick btn = liftAction $ DoubleClick btn unit
49doubleClick btn = liftAction $ DoubleClick btn unit
51
50
52−sendKeys ∷ ∀ r. String → WithAction r
51+sendKeys ∷ ∀ r. String → Run (LUNAPARK_ACTIONS r) Unit
53sendKeys txt = liftAction $ SendKeys txt unit
52sendKeys txt = liftAction $ SendKeys txt unit
54
53
55−moveTo ∷ ∀ r. LT.PointerMove → WithAction r
54+moveTo ∷ ∀ r. LT.PointerMove → Run (LUNAPARK_ACTIONS r) Unit
56moveTo move = liftAction $ MoveTo move unit
55moveTo move = liftAction $ MoveTo move unit
57
56
58−pause ∷ ∀ r. Milliseconds → WithAction r
57+pause ∷ ∀ r. Milliseconds → Run (LUNAPARK_ACTIONS r) Unit
59pause ms = liftAction $ Pause ms unit
58pause ms = liftAction $ Pause ms unit
60
59
61−tap ∷ ∀ r. WithAction r
60+tap ∷ ∀ r. Run (LUNAPARK_ACTIONS r) Unit
62tap = liftAction $ InTouch $ Tap unit
61tap = liftAction $ InTouch $ Tap unit
63
62
64−touchDown ∷ ∀ r. WithAction r
63+touchDown ∷ ∀ r. Run (LUNAPARK_ACTIONS r) Unit
65touchDown = liftAction $ InTouch $ TouchDown unit
64touchDown = liftAction $ InTouch $ TouchDown unit
66
65
67−touchUp ∷ ∀ r. WithAction r
66+touchUp ∷ ∀ r. Run (LUNAPARK_ACTIONS r) Unit
68touchUp = liftAction $ InTouch $ TouchUp unit
67touchUp = liftAction $ InTouch $ TouchUp unit
69
68
70−longTap ∷ ∀ r. WithAction r
69+longTap ∷ ∀ r. Run (LUNAPARK_ACTIONS r) Unit
71longTap = liftAction $ InTouch $ LongClick unit
70longTap = liftAction $ InTouch $ LongClick unit
72
71
73−flick ∷ ∀ r. LT.PointerMove → WithAction r
72+flick ∷ ∀ r. LT.PointerMove → Run (LUNAPARK_ACTIONS r) Unit
74flick move = liftAction $ InTouch $ Flick move unit
73flick move = liftAction $ InTouch $ Flick move unit
75
74
76−scroll ∷ ∀ r. LT.PointerMove → WithAction r
75+scroll ∷ ∀ r. LT.PointerMove → Run (LUNAPARK_ACTIONS r) Unit
77scroll move = liftAction $ InTouch $ Scroll move unit
76scroll move = liftAction $ InTouch $ Scroll move unit
78
77
79−doubleTap ∷ ∀ r. WithAction r
78+doubleTap ∷ ∀ r. Run (LUNAPARK_ACTIONS r) Unit
80doubleTap = liftAction $ InTouch $ DoubleTap unit
79doubleTap = liftAction $ InTouch $ DoubleTap unit
src/Lunapark/Endpoint.purs+22−14
@@ -3,17 +3,23 @@
3-- | So, to have something like `/session/:sessId/element/:elId/doubleclick` we have
3-- | So, to have something like `/session/:sessId/element/:elId/doubleclick` we have
4-- | `InSession sessId : InElement elId : DoubleClick : Nil`
4-- | `InSession sessId : InElement elId : DoubleClick : Nil`
5-- | This is not as typesafe as it could be, but at least it saves from typos.
5-- | This is not as typesafe as it could be, but at least it saves from typos.
6−module Lunapark.Endpoint where
6+module Lunapark.Endpoint
7+ ( delete
8+ , get
9+ , post
10+ , post'
11+ , EndpointPart(..)
12+ ) where
7
13
8import Prelude
14import Prelude
9
15
10−import Affjax as N
16+import Affjax.Node as N
11import Affjax.RequestBody as NQ
17import Affjax.RequestBody as NQ
12import Affjax.ResponseFormat as NR
18import Affjax.ResponseFormat as NR
13import Affjax.StatusCode (StatusCode(..))
19import Affjax.StatusCode (StatusCode(..))
14import Data.Argonaut.Core (Json)
20import Data.Argonaut.Core (Json)
15import Data.Argonaut.Decode.Class (decodeJson) as J
21import Data.Argonaut.Decode.Class (decodeJson) as J
16−import Data.Argonaut.Decode.Combinators ((.?)) as J
22+import Data.Argonaut.Decode.Combinators ((.:)) as J
17import Data.Bifunctor (lmap)
23import Data.Bifunctor (lmap)
18import Data.Either (Either(..), either)
24import Data.Either (Either(..), either)
19import Data.Foldable as F
25import Data.Foldable as F
@@ -23,6 +29,7 @@ import Data.Newtype (un)
23import Effect.Aff (Aff)
29import Effect.Aff (Aff)
24import Lunapark.Error as LE
30import Lunapark.Error as LE
25import Lunapark.Types as LT
31import Lunapark.Types as LT
32+import Lunapark.WebDriverError as LWE
26
33
27data EndpointPart
34data EndpointPart
28 = Session
35 = Session
@@ -169,23 +176,24 @@ printPart = case _ of
169 Flick → "flick"
176 Flick → "flick"
170
177
171handleAPIError
178handleAPIError
172− ∷ N.Response (Either N.ResponseFormatError Json)
179+ ∷ Either N.Error (N.Response Json)
173 → Either LE.Error Json
180 → Either LE.Error Json
181+handleAPIError (Left error) = Left $ LE.AffjaxError error
174−handleAPIError r = case r.status of
182+handleAPIError (Right r) = case r.status of
175− StatusCode 200 → lmap LE.unknownError do
183+ StatusCode 200 → lmap LE.JsonDecodeError do
176− obj ← J.decodeJson =<< lmap N.printResponseFormatError r.body
184+ obj ← J.decodeJson r.body
177− obj J..? "value"
185+ obj J..: "value"
178− code →
186+ _ →
179− Left $ either (LE.unknownError <<< N.printResponseFormatError) LE.fromJson r.body
187+ Left $ either LE.JsonDecodeError LE.WebDriverError $ LWE.fromJson r.body
180
188
181get ∷ String → Endpoint → Aff (Either LE.Error Json)
189get ∷ String → Endpoint → Aff (Either LE.Error Json)
182−get uri ep = map handleAPIError $ N.get NR.json (uri <> print ep)
190+get uri ep = map handleAPIError $ N.get NR.json (uri <> print ep)
183
191
184post ∷ String → Endpoint → Json → Aff (Either LE.Error Json)
192post ∷ String → Endpoint → Json → Aff (Either LE.Error Json)
185−post uri ep obj = map handleAPIError $ N.post NR.json (uri <> print ep) $ NQ.json obj
193+post uri ep obj = map handleAPIError $ N.post NR.json (uri <> print ep) $ Just (NQ.json obj)
186
194
187−post_ ∷ String → Endpoint → Aff (Either LE.Error Json)
195+post' ∷ String → Endpoint → Aff (Either LE.Error Json)
188−post_ uri ep = map handleAPIError $ N.post' NR.json (uri <> print ep) Nothing
196+post' uri ep = map handleAPIError $ N.post NR.json (uri <> print ep) Nothing
189
197
190delete ∷ String → Endpoint → Aff (Either LE.Error Json)
198delete ∷ String → Endpoint → Aff (Either LE.Error Json)
191delete uri ep = map handleAPIError $ N.delete NR.json (uri <> print ep)
199delete uri ep = map handleAPIError $ N.delete NR.json (uri <> print ep)
src/Lunapark/Error.purs+36−120
@@ -1,123 +1,39 @@
1module Lunapark.Error where
1module Lunapark.Error where
2
2
3import Prelude
3import Prelude
4−
4+import Affjax as N
5−import Data.Argonaut.Core (Json) as J
5+import Lunapark.WebDriverError as LWE
6−import Data.Argonaut.Decode.Combinators ((.?)) as J
7−import Data.Argonaut.Decode.Class (decodeJson) as J
6+import Data.Argonaut.Decode (JsonDecodeError, printJsonDecodeError) as J
8−import Data.Either (Either(..), either)
7+
9−
8+data CachingError
10−data ErrorType
9+ = EmptyCases String
11− = ElementClickIntercepted
10+ | IncorrectCache String
12− | ElementNotSelectable
11+
13− | ElementNotInteractable
12+data Error
14− | InsecureCertificate
13+ = JsonDecodeError J.JsonDecodeError
15− | InvalidArgument
14+ | WebDriverError LWE.WebDriverError
16− | InvalidCookieDomain
15+ | AffjaxError N.Error
17− | InvalidCoordinates
16+ | CachingError CachingError
18− | InvalidElementState
17+
19− | InvalidSelector
18+printError ∷ Error → String
20− | InvalidSessionId
19+printError = case _ of
21− | JavaScriptError
20+ JsonDecodeError jsonDecodeError →
22− | MoveTargetOutOfBounds
21+ J.printJsonDecodeError jsonDecodeError
23− | NoSuchAlert
22+ WebDriverError webdriverError →
24− | NoSuchCookie
23+ "Response with error message:\n"
25− | NoSuchElement
26− | NoSuchFrame
27− | NoSuchWindow
28− | ScriptTimeout
29− | SessionNotCreated
30− | StaleElementReference
31− | Timeout
32− | UnableToSetCookie
33− | UnableToCaptureScreen
34− | UnexpectedAlertOpen
35− | UnknownCommand
36− | UnknownError
37− | UnknownMethod
38− | UnsupportedOperation
39−
40−fromStringCode ∷ String → Either String ErrorType
41−fromStringCode = case _ of
42− "element click intercepted" → Right ElementClickIntercepted
43− "element not selectable" → Right ElementNotSelectable
44− "element not interactable" → Right ElementNotInteractable
45− "insecure certificate" → Right InsecureCertificate
46− "invalid argument" → Right InvalidArgument
47− "invalid cookie domain" → Right InvalidCookieDomain
48− "invalid coordinates" → Right InvalidCoordinates
49− "invalid element state" → Right InvalidElementState
50− "invalid selector" → Right InvalidSelector
51− "invalid session id" → Right InvalidSessionId
52− "javascript error" → Right JavaScriptError
53− "move target out of bounds" → Right MoveTargetOutOfBounds
54− "no such alert" → Right NoSuchAlert
55− "no such cookie" → Right NoSuchCookie
56− "no such element" → Right NoSuchElement
57− "no such frame" → Right NoSuchFrame
58− "no such window" → Right NoSuchWindow
59− "script timeout" → Right ScriptTimeout
60− "session not created" → Right SessionNotCreated
61− "stale element reference" → Right StaleElementReference
62− "timeout" → Right Timeout
63− "unable to set cookie" → Right UnableToSetCookie
64− "unable to capture screen" → Right UnableToCaptureScreen
65− "unexpected alert open" → Right UnexpectedAlertOpen
66− "unknown command" → Right UnknownCommand
67− "unknown error" → Right UnknownError
68− "unknown method" → Right UnknownMethod
69− "unsupported operation" → Right UnsupportedOperation
70− s → Left s
71−
72−toStringCode ∷ ErrorType → String
73−toStringCode = case _ of
74− ElementClickIntercepted → "element click intercepted"
75− ElementNotSelectable → "element not selectable"
76− ElementNotInteractable → "element not interactable"
77− InsecureCertificate → "insecure certificate"
78− InvalidArgument → "invalid argument"
79− InvalidCookieDomain → "invalid cookie domain"
80− InvalidCoordinates → "invalid coordinates"
81− InvalidElementState → "invalid element state"
82− InvalidSelector → "invalid selector"
83− InvalidSessionId → "invalid session id"
84− JavaScriptError → "javascript error"
85− MoveTargetOutOfBounds → "move target out of bounds"
86− NoSuchAlert → "no such alert"
87− NoSuchCookie → "no such cookie"
88− NoSuchElement → "no such element"
89− NoSuchFrame → "no such frame"
90− NoSuchWindow → "no such window"
91− ScriptTimeout → "script timeout"
92− SessionNotCreated → "session not created"
93− StaleElementReference → "stale element reference"
94− Timeout → "timeout"
95− UnableToSetCookie → "unable to set cookie"
96− UnableToCaptureScreen → "unable to capture screen"
97− UnexpectedAlertOpen → "unexpected alert open"
98− UnknownCommand → "unknown command"
99− UnknownError → "unknown error"
100− UnknownMethod → "unknown method"
101− UnsupportedOperation → "unsupported operation"
102−
103−type Error =
24+ <> " error type: "
104− { error ∷ ErrorType
25+ <> LWE.toStringCode webdriverError.error
26+ <> "\n"
27+ <> " message: "
105− , message ∷ String
28+ <> webdriverError.message
29+ <> "\n"
106− , stacktrace ∷ String
30+ <> " stacktrace: "
107− }
31+ <> webdriverError.stacktrace
108−
32+ AffjaxError affjaxError →
109−fromJson ∷ J.Json → Error
33+ N.printError affjaxError
110−fromJson js = either unknownError identity do
34+ CachingError cachingError →
111− obj ← J.decodeJson js
35+ "Error during caching:\n " <> printCachingError cachingError
112− value ← obj J..? "value"
36+ where
113− error ← fromStringCode =<< value J..? "error"
37+ printCachingError = case _ of
114− message ← value J..? "message"
38+ EmptyCases key → "There is no working implementation for " <> key <> " action."
115− stacktrace ← value J..? "stacktrace"
39+ IncorrectCache key → "Trying another implementation for " <> key <> " action."
116− pure { error, message, stacktrace }
117−
118−unknownError ∷ String → Error
119−unknownError message =
120− { error: UnknownError
121− , message
122− , stacktrace: ""
123− }
src/Lunapark/LunaparkF.purs+58−58
@@ -3,8 +3,9 @@ module Lunapark.LunaparkF where
3import Prelude
3import Prelude
4
4
5import Data.Argonaut.Core as J
5import Data.Argonaut.Core as J
6−import Data.Symbol (SProxy(..))
6+import Type.Proxy (Proxy(..))
7import Lunapark.Types as LT
7import Lunapark.Types as LT
8+import Run (Run)
8import Run as R
9import Run as R
9
10
10data LunaparkF a
11data LunaparkF a
@@ -69,169 +70,168 @@ data ElementF a
69derive instance functorLunaparkF ∷ Functor LunaparkF
70derive instance functorLunaparkF ∷ Functor LunaparkF
70derive instance functorElementF ∷ Functor ElementF
71derive instance functorElementF ∷ Functor ElementF
71
72
72−_lunapark = SProxy ∷ SProxy "lunapark"
73+_lunapark = Proxy ∷ Proxy "lunapark"
73−type LUNAPARK = R.FProxy LunaparkF
74−type WithLunapark r a = R.Run (lunapark ∷ LUNAPARK|r) a
75
74
75+type LUNAPARK r = (lunapark ∷ LunaparkF | r)
76
76
77−liftLunapark ∷ ∀ a r. LunaparkF a → WithLunapark r a
77+liftLunapark ∷ ∀ a r. LunaparkF a → Run (LUNAPARK r) a
78liftLunapark = R.lift _lunapark
78liftLunapark = R.lift _lunapark
79
79
80−quit ∷ ∀ r. WithLunapark r Unit
80+quit ∷ ∀ r. Run (LUNAPARK r) Unit
81quit = liftLunapark $ Quit unit
81quit = liftLunapark $ Quit unit
82
82
83−status ∷ ∀ r. WithLunapark r LT.ServerStatus
83+status ∷ ∀ r. Run (LUNAPARK r) LT.ServerStatus
84status = liftLunapark $ Status identity
84status = liftLunapark $ Status identity
85
85
86−setTimeouts ∷ ∀ r. LT.Timeouts → WithLunapark r Unit
86+setTimeouts ∷ ∀ r. LT.Timeouts → Run (LUNAPARK r) Unit
87setTimeouts ts = liftLunapark $ SetTimeouts ts unit
87setTimeouts ts = liftLunapark $ SetTimeouts ts unit
88
88
89−getTimeouts ∷ ∀ r. WithLunapark r LT.Timeouts
89+getTimeouts ∷ ∀ r. Run (LUNAPARK r) LT.Timeouts
90getTimeouts = liftLunapark $ GetTimeouts identity
90getTimeouts = liftLunapark $ GetTimeouts identity
91
91
92−go ∷ ∀ r. String → WithLunapark r Unit
92+go ∷ ∀ r. String → Run (LUNAPARK r) Unit
93go uri = liftLunapark $ GoTo uri unit
93go uri = liftLunapark $ GoTo uri unit
94
94
95−getUrl ∷ ∀ r. WithLunapark r String
95+getUrl ∷ ∀ r. Run (LUNAPARK r) String
96getUrl = liftLunapark $ GetUrl identity
96getUrl = liftLunapark $ GetUrl identity
97
97
98−forward ∷ ∀ r. WithLunapark r Unit
98+forward ∷ ∀ r. Run (LUNAPARK r) Unit
99forward = liftLunapark $ Forward unit
99forward = liftLunapark $ Forward unit
100
100
101−back ∷ ∀ r. WithLunapark r Unit
101+back ∷ ∀ r. Run (LUNAPARK r) Unit
102back = liftLunapark $ Back unit
102back = liftLunapark $ Back unit
103
103
104−refresh ∷ ∀ r. WithLunapark r Unit
104+refresh ∷ ∀ r. Run (LUNAPARK r) Unit
105refresh = liftLunapark $ Refresh unit
105refresh = liftLunapark $ Refresh unit
106
106
107−getTitle ∷ ∀ r. WithLunapark r String
107+getTitle ∷ ∀ r. Run (LUNAPARK r) String
108getTitle = liftLunapark $ GetTitle identity
108getTitle = liftLunapark $ GetTitle identity
109
109
110−getWindowHandle ∷ ∀ r. WithLunapark r LT.WindowHandle
110+getWindowHandle ∷ ∀ r. Run (LUNAPARK r) LT.WindowHandle
111getWindowHandle = liftLunapark $ GetWindowHandle identity
111getWindowHandle = liftLunapark $ GetWindowHandle identity
112
112
113−getWindowHandles ∷ ∀ r. WithLunapark r (Array LT.WindowHandle)
113+getWindowHandles ∷ ∀ r. Run (LUNAPARK r) (Array LT.WindowHandle)
114getWindowHandles = liftLunapark $ GetWindowHandles identity
114getWindowHandles = liftLunapark $ GetWindowHandles identity
115
115
116−closeWindow ∷ ∀ r. WithLunapark r Unit
116+closeWindow ∷ ∀ r. Run (LUNAPARK r) Unit
117closeWindow = liftLunapark $ CloseWindow unit
117closeWindow = liftLunapark $ CloseWindow unit
118
118
119−switchToWindow ∷ ∀ r. LT.WindowHandle → WithLunapark r Unit
119+switchToWindow ∷ ∀ r. LT.WindowHandle → Run (LUNAPARK r) Unit
120switchToWindow w = liftLunapark $ SwitchToWindow w unit
120switchToWindow w = liftLunapark $ SwitchToWindow w unit
121
121
122−switchToFrame ∷ ∀ r. LT.FrameId → WithLunapark r Unit
122+switchToFrame ∷ ∀ r. LT.FrameId → Run (LUNAPARK r) Unit
123switchToFrame f = liftLunapark $ SwitchToFrame f unit
123switchToFrame f = liftLunapark $ SwitchToFrame f unit
124
124
125−switchToParentFrame ∷ ∀ r. WithLunapark r Unit
125+switchToParentFrame ∷ ∀ r. Run (LUNAPARK r) Unit
126switchToParentFrame = liftLunapark $ SwitchToParentFrame unit
126switchToParentFrame = liftLunapark $ SwitchToParentFrame unit
127
127
128−getWindowRectangle ∷ ∀ r. WithLunapark r LT.Rectangle
128+getWindowRectangle ∷ ∀ r. Run (LUNAPARK r) LT.Rectangle
129getWindowRectangle = liftLunapark $ GetWindowRectangle identity
129getWindowRectangle = liftLunapark $ GetWindowRectangle identity
130
130
131−setWindowRectangle ∷ ∀ r. LT.Rectangle → WithLunapark r Unit
131+setWindowRectangle ∷ ∀ r. LT.Rectangle → Run (LUNAPARK r) Unit
132setWindowRectangle r = liftLunapark $ SetWindowRectangle r unit
132setWindowRectangle r = liftLunapark $ SetWindowRectangle r unit
133
133
134−maximizeWindow ∷ ∀ r. WithLunapark r Unit
134+maximizeWindow ∷ ∀ r. Run (LUNAPARK r) Unit
135maximizeWindow = liftLunapark $ MaximizeWindow unit
135maximizeWindow = liftLunapark $ MaximizeWindow unit
136
136
137−minimizeWindow ∷ ∀ r. WithLunapark r Unit
137+minimizeWindow ∷ ∀ r. Run (LUNAPARK r) Unit
138minimizeWindow = liftLunapark $ MinimizeWindow unit
138minimizeWindow = liftLunapark $ MinimizeWindow unit
139
139
140−fullscreenWindow ∷ ∀ r. WithLunapark r Unit
140+fullscreenWindow ∷ ∀ r. Run (LUNAPARK r) Unit
141fullscreenWindow = liftLunapark $ FullscreenWindow unit
141fullscreenWindow = liftLunapark $ FullscreenWindow unit
142
142
143−executeScript ∷ ∀ r. LT.Script → WithLunapark r J.Json
143+executeScript ∷ ∀ r. LT.Script → Run (LUNAPARK r) J.Json
144executeScript script = liftLunapark $ ExecuteScript script identity
144executeScript script = liftLunapark $ ExecuteScript script identity
145
145
146−executeScriptAsync ∷ ∀ r. LT.Script → WithLunapark r J.Json
146+executeScriptAsync ∷ ∀ r. LT.Script → Run (LUNAPARK r) J.Json
147executeScriptAsync script = liftLunapark $ ExecuteScriptAsync script identity
147executeScriptAsync script = liftLunapark $ ExecuteScriptAsync script identity
148
148
149−getAllCookies ∷ ∀ r. WithLunapark r (Array LT.Cookie)
149+getAllCookies ∷ ∀ r. Run (LUNAPARK r) (Array LT.Cookie)
150getAllCookies = liftLunapark $ GetAllCookies identity
150getAllCookies = liftLunapark $ GetAllCookies identity
151
151
152−getCookie ∷ ∀ r. String → WithLunapark r LT.Cookie
152+getCookie ∷ ∀ r. String → Run (LUNAPARK r) LT.Cookie
153getCookie name = liftLunapark $ GetCookie name identity
153getCookie name = liftLunapark $ GetCookie name identity
154
154
155−addCookie ∷ ∀ r. LT.Cookie → WithLunapark r Unit
155+addCookie ∷ ∀ r. LT.Cookie → Run (LUNAPARK r) Unit
156addCookie cookie = liftLunapark $ AddCookie cookie unit
156addCookie cookie = liftLunapark $ AddCookie cookie unit
157
157
158−deleteCookie ∷ ∀ r. String → WithLunapark r Unit
158+deleteCookie ∷ ∀ r. String → Run (LUNAPARK r) Unit
159deleteCookie name = liftLunapark $ DeleteCookie name unit
159deleteCookie name = liftLunapark $ DeleteCookie name unit
160
160
161−deleteAllCookies ∷ ∀ r. WithLunapark r Unit
161+deleteAllCookies ∷ ∀ r. Run (LUNAPARK r) Unit
162deleteAllCookies = liftLunapark $ DeleteAllCookies unit
162deleteAllCookies = liftLunapark $ DeleteAllCookies unit
163
163
164−dismissAlert ∷ ∀ r. WithLunapark r Unit
164+dismissAlert ∷ ∀ r. Run (LUNAPARK r) Unit
165dismissAlert = liftLunapark $ DismissAlert unit
165dismissAlert = liftLunapark $ DismissAlert unit
166
166
167−acceptAlert ∷ ∀ r. WithLunapark r Unit
167+acceptAlert ∷ ∀ r. Run (LUNAPARK r) Unit
168acceptAlert = liftLunapark $ AcceptAlert unit
168acceptAlert = liftLunapark $ AcceptAlert unit
169
169
170−getAlertText ∷ ∀ r. WithLunapark r String
170+getAlertText ∷ ∀ r. Run (LUNAPARK r) String
171getAlertText = liftLunapark $ GetAlertText identity
171getAlertText = liftLunapark $ GetAlertText identity
172
172
173−sendAlertText ∷ ∀ r. String → WithLunapark r Unit
173+sendAlertText ∷ ∀ r. String → Run (LUNAPARK r) Unit
174sendAlertText txt = liftLunapark $ SendAlertText txt unit
174sendAlertText txt = liftLunapark $ SendAlertText txt unit
175
175
176−screenshot ∷ ∀ r. String → WithLunapark r Unit
176+screenshot ∷ ∀ r. String → Run (LUNAPARK r) Unit
177screenshot fp = liftLunapark $ Screenshot fp unit
177screenshot fp = liftLunapark $ Screenshot fp unit
178
178
179−elementScreenshot ∷ ∀ r. LT.Element → String → WithLunapark r Unit
179+elementScreenshot ∷ ∀ r. LT.Element → String → Run (LUNAPARK r) Unit
180elementScreenshot el fp = liftLunapark $ OnElement el $ ScreenshotEl fp unit
180elementScreenshot el fp = liftLunapark $ OnElement el $ ScreenshotEl fp unit
181
181
182−findElement ∷ ∀ r. LT.Locator → WithLunapark r LT.Element
182+findElement ∷ ∀ r. LT.Locator → Run (LUNAPARK r) LT.Element
183findElement l = liftLunapark $ FindElement l identity
183findElement l = liftLunapark $ FindElement l identity
184
184
185−findElements ∷ ∀ r. LT.Locator → WithLunapark r (Array LT.Element)
185+findElements ∷ ∀ r. LT.Locator → Run (LUNAPARK r) (Array LT.Element)
186findElements l = liftLunapark $ FindElements l identity
186findElements l = liftLunapark $ FindElements l identity
187
187
188−childElement ∷ ∀ r. LT.Element → LT.Locator → WithLunapark r LT.Element
188+childElement ∷ ∀ r. LT.Element → LT.Locator → Run (LUNAPARK r) LT.Element
189childElement el l = liftLunapark $ OnElement el $ ChildElement l identity
189childElement el l = liftLunapark $ OnElement el $ ChildElement l identity
190
190
191−childElements ∷ ∀ r. LT.Element → LT.Locator → WithLunapark r (Array LT.Element)
191+childElements ∷ ∀ r. LT.Element → LT.Locator → Run (LUNAPARK r) (Array LT.Element)
192childElements el l = liftLunapark $ OnElement el $ ChildElements l identity
192childElements el l = liftLunapark $ OnElement el $ ChildElements l identity
193
193
194−isSelected ∷ ∀ r. LT.Element → WithLunapark r Boolean
194+isSelected ∷ ∀ r. LT.Element → Run (LUNAPARK r) Boolean
195isSelected el = liftLunapark $ OnElement el $ IsSelected identity
195isSelected el = liftLunapark $ OnElement el $ IsSelected identity
196
196
197−getAttribute ∷ ∀ r. LT.Element → String → WithLunapark r String
197+getAttribute ∷ ∀ r. LT.Element → String → Run (LUNAPARK r) String
198getAttribute el name = liftLunapark $ OnElement el $ GetAttribute name identity
198getAttribute el name = liftLunapark $ OnElement el $ GetAttribute name identity
199
199
200−getProperty ∷ ∀ r. LT.Element → String → WithLunapark r J.Json
200+getProperty ∷ ∀ r. LT.Element → String → Run (LUNAPARK r) J.Json
201getProperty el name = liftLunapark $ OnElement el $ GetProperty name identity
201getProperty el name = liftLunapark $ OnElement el $ GetProperty name identity
202
202
203−getCss ∷ ∀ r. LT.Element → String → WithLunapark r String
203+getCss ∷ ∀ r. LT.Element → String → Run (LUNAPARK r) String
204getCss el name = liftLunapark $ OnElement el $ GetCss name identity
204getCss el name = liftLunapark $ OnElement el $ GetCss name identity
205
205
206−getText ∷ ∀ r. LT.Element → WithLunapark r String
206+getText ∷ ∀ r. LT.Element → Run (LUNAPARK r) String
207getText el = liftLunapark $ OnElement el $ GetText identity
207getText el = liftLunapark $ OnElement el $ GetText identity
208
208
209−getTagName ∷ ∀ r. LT.Element → WithLunapark r String
209+getTagName ∷ ∀ r. LT.Element → Run (LUNAPARK r) String
210getTagName el = liftLunapark $ OnElement el $ GetTagName identity
210getTagName el = liftLunapark $ OnElement el $ GetTagName identity
211
211
212−getRectangle ∷ ∀ r. LT.Element → WithLunapark r LT.Rectangle
212+getRectangle ∷ ∀ r. LT.Element → Run (LUNAPARK r) LT.Rectangle
213getRectangle el = liftLunapark $ OnElement el $ GetRectangle identity
213getRectangle el = liftLunapark $ OnElement el $ GetRectangle identity
214
214
215−isEnabled ∷ ∀ r. LT.Element → WithLunapark r Boolean
215+isEnabled ∷ ∀ r. LT.Element → Run (LUNAPARK r) Boolean
216isEnabled el = liftLunapark $ OnElement el $ IsEnabled identity
216isEnabled el = liftLunapark $ OnElement el $ IsEnabled identity
217
217
218−clickElement ∷ ∀ r. LT.Element → WithLunapark r Unit
218+clickElement ∷ ∀ r. LT.Element → Run (LUNAPARK r) Unit
219clickElement el = liftLunapark $ OnElement el $ ClickEl unit
219clickElement el = liftLunapark $ OnElement el $ ClickEl unit
220
220
221−clearElement ∷ ∀ r. LT.Element → WithLunapark r Unit
221+clearElement ∷ ∀ r. LT.Element → Run (LUNAPARK r) Unit
222clearElement el = liftLunapark $ OnElement el $ ClearEl unit
222clearElement el = liftLunapark $ OnElement el $ ClearEl unit
223
223
224−sendKeysElement ∷ ∀ r. LT.Element → String → WithLunapark r Unit
224+sendKeysElement ∷ ∀ r. LT.Element → String → Run (LUNAPARK r) Unit
225sendKeysElement el txt = liftLunapark $ OnElement el $ SendKeysEl txt unit
225sendKeysElement el txt = liftLunapark $ OnElement el $ SendKeysEl txt unit
226
226
227−isDisplayed ∷ ∀ r. LT.Element → WithLunapark r Boolean
227+isDisplayed ∷ ∀ r. LT.Element → Run (LUNAPARK r) Boolean
228isDisplayed el = liftLunapark $ OnElement el $ IsDisplayed identity
228isDisplayed el = liftLunapark $ OnElement el $ IsDisplayed identity
229
229
230−submitElement ∷ ∀ r. LT.Element → WithLunapark r Unit
230+submitElement ∷ ∀ r. LT.Element → Run (LUNAPARK r) Unit
231submitElement el = liftLunapark $ OnElement el $ Submit unit
231submitElement el = liftLunapark $ OnElement el $ Submit unit
232
232
233−performActions ∷ ∀ r. LT.ActionRequest → WithLunapark r Unit
233+performActions ∷ ∀ r. LT.ActionRequest → Run (LUNAPARK r) Unit
234performActions req = liftLunapark $ PerformActions req unit
234performActions req = liftLunapark $ PerformActions req unit
235
235
236−releaseActions ∷ ∀ r. WithLunapark r Unit
236+releaseActions ∷ ∀ r. Run (LUNAPARK r) Unit
237releaseActions = liftLunapark $ ReleaseActions unit
237releaseActions = liftLunapark $ ReleaseActions unit
src/Lunapark/Types.purs+129−135
@@ -1,17 +1,16 @@
1-- | This module contains types for requests and response.
1-- | This module contains types for requests and response.
2−-- | Most of them are records with `α → Json` and `Json → Either String α` functions
2+-- | Most of them are records with `α → J.Json` and `J.Json → Either J.JsonDecodeError α` functions
3-- | not newtypes with `Encode|DecodeJson` instances.
3-- | not newtypes with `Encode|DecodeJson` instances.
4module Lunapark.Types where
4module Lunapark.Types where
5
5
6import Prelude
6import Prelude
7
7
8−import CSS.Render as CSSR
8+import CSS as CSS
9−import CSS.Selector as CSS
10import Control.Alt ((<|>))
9import Control.Alt ((<|>))
11−import Data.Argonaut.Core (Json)
10+import Data.Argonaut.Core (Json, jsonEmptyObject, jsonNull, fromString) as J
12−import Data.Argonaut.Core (Json, jsonEmptyObject, jsonNull) as J
11+import Data.Argonaut.Decode (JsonDecodeError(..)) as J
13import Data.Argonaut.Decode.Class (decodeJson) as J
12import Data.Argonaut.Decode.Class (decodeJson) as J
14−import Data.Argonaut.Decode.Combinators ((.?))
13+import Data.Argonaut.Decode.Combinators ((.:))
15import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson) as J
14import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson) as J
16import Data.Argonaut.Encode.Combinators (extend) as J
15import Data.Argonaut.Encode.Combinators (extend) as J
17import Data.Array as A
16import Data.Array as A
@@ -20,13 +19,11 @@ import Data.Map as Map
20import Data.Maybe (Maybe(..))
19import Data.Maybe (Maybe(..))
21import Data.Newtype (class Newtype, un)
20import Data.Newtype (class Newtype, un)
22import Data.String as Str
21import Data.String as Str
23−import Data.Symbol (SProxy(..))
22+import Type.Proxy (Proxy(..))
24import Data.Time.Duration (Milliseconds(..))
23import Data.Time.Duration (Milliseconds(..))
25import Data.Traversable as F
24import Data.Traversable as F
26import Data.Tuple (Tuple(..))
25import Data.Tuple (Tuple(..))
27import Data.Variant as V
26import Data.Variant as V
28−import Data.XPath.AST as XA
29−import Data.XPath.Printer (printSelector)
30import Foreign.Object as FO
27import Foreign.Object as FO
31import Node.Encoding as NE
28import Node.Encoding as NE
32import Node.Path (FilePath)
29import Node.Path (FilePath)
@@ -57,28 +54,28 @@ derive instance newtypeElement ∷ Newtype Element _
57derive newtype instance eqElement ∷ Eq Element
54derive newtype instance eqElement ∷ Eq Element
58derive newtype instance ordElement ∷ Ord Element
55derive newtype instance ordElement ∷ Ord Element
59
56
60−decodeElement ∷ Json → Either String Element
57+decodeElement ∷ J.Json → Either J.JsonDecodeError Element
61decodeElement = J.decodeJson >=> \obj →
58decodeElement = J.decodeJson >=> \obj →
62− map Element $ obj .? "element-6066-11e4-a52e-4f735466cecf" <|> obj .? "ELEMENT"
59+ map Element $ obj .: "element-6066-11e4-a52e-4f735466cecf" <|> obj .: "ELEMENT"
63
60
64−encodeElement ∷ Element → Json
61+encodeElement ∷ Element → J.Json
65encodeElement (Element eid) = J.encodeJson $ FO.fromFoldable
62encodeElement (Element eid) = J.encodeJson $ FO.fromFoldable
66 [ Tuple "element-6066-11e4-a52e-4f735466cecf" eid
63 [ Tuple "element-6066-11e4-a52e-4f735466cecf" eid
67 , Tuple "ELEMENT" eid
64 , Tuple "ELEMENT" eid
68 ]
65 ]
69
66
70−decodeSessionId ∷ Json → Either String SessionId
67+decodeSessionId ∷ J.Json → Either J.JsonDecodeError SessionId
71decodeSessionId = map SessionId <<< J.decodeJson
68decodeSessionId = map SessionId <<< J.decodeJson
72
69
73type CreateSessionResponse =
70type CreateSessionResponse =
74− { session ∷ SessionId
71+ { session ∷ SessionId
75− , capabilities ∷ Array Capability
72+ , capabilities ∷ Array Capability
76− }
73+ }
77
74
78−decodeCreateSessionResponse ∷ Json → Either String CreateSessionResponse
75+decodeCreateSessionResponse ∷ J.Json → Either J.JsonDecodeError CreateSessionResponse
79decodeCreateSessionResponse = J.decodeJson >=> \obj → do
76decodeCreateSessionResponse = J.decodeJson >=> \obj → do
80− session ← decodeSessionId =<< obj .? "sessionId"
77+ session ← decodeSessionId =<< obj .: "sessionId"
81− capabilities ← decodeCapabilities =<< obj .? "capabilities"
78+ capabilities ← decodeCapabilities =<< obj .: "capabilities"
82 pure { session, capabilities }
79 pure { session, capabilities }
83
80
84type ServerStatus =
81type ServerStatus =
@@ -86,8 +83,8 @@ type ServerStatus =
86 , message ∷ String
83 , message ∷ String
87 }
84 }
88
85
89−decodeServerStatus ∷ Json → Either String ServerStatus
86+decodeServerStatus ∷ J.Json → Either J.JsonDecodeError ServerStatus
90−decodeServerStatus = J.decodeJson >=> \obj → { ready: _, message: _ } <$> obj .? "ready" <*> obj .? "message"
87+decodeServerStatus = J.decodeJson >=> \obj → { ready: _, message: _ } <$> obj .: "ready" <*> obj .: "message"
91
88
92type Timeouts =
89type Timeouts =
93 { script ∷ Milliseconds
90 { script ∷ Milliseconds
@@ -95,37 +92,37 @@ type Timeouts =
95 , implicit ∷ Milliseconds
92 , implicit ∷ Milliseconds
96 }
93 }
97
94
98−decodeTimeouts ∷ Json → Either String Timeouts
95+decodeTimeouts ∷ J.Json → Either J.JsonDecodeError Timeouts
99decodeTimeouts = J.decodeJson >=> \obj → do
96decodeTimeouts = J.decodeJson >=> \obj → do
100− script ← map Milliseconds $ obj .? "script"
97+ script ← map Milliseconds $ obj .: "script"
101− pageLoad ← map Milliseconds $ obj .? "pageLoad"
98+ pageLoad ← map Milliseconds $ obj .: "pageLoad"
102− implicit ← map Milliseconds $ obj .? "implicit"
99+ implicit ← map Milliseconds $ obj .: "implicit"
103 pure { script, pageLoad, implicit }
100 pure { script, pageLoad, implicit }
104
101
105−encodeTimeouts ∷ Timeouts → Json
102+encodeTimeouts ∷ Timeouts → J.Json
106encodeTimeouts r = J.encodeJson $ FO.fromFoldable
103encodeTimeouts r = J.encodeJson $ FO.fromFoldable
107 [ Tuple "script" (un Milliseconds r.script)
104 [ Tuple "script" (un Milliseconds r.script)
108 , Tuple "pageLoad" (un Milliseconds r.pageLoad)
105 , Tuple "pageLoad" (un Milliseconds r.pageLoad)
109 , Tuple "implicit" (un Milliseconds r.implicit)
106 , Tuple "implicit" (un Milliseconds r.implicit)
110 ]
107 ]
111
108
112−encodeLegacyTimeouts ∷ Timeouts → Array Json
109+encodeLegacyTimeouts ∷ Timeouts → Array J.Json
113encodeLegacyTimeouts r =
110encodeLegacyTimeouts r =
114 [ J.encodeJson $ FO.singleton "script" $ un Milliseconds r.script
111 [ J.encodeJson $ FO.singleton "script" $ un Milliseconds r.script
115 , J.encodeJson $ FO.singleton "implicit" $ un Milliseconds r.implicit
112 , J.encodeJson $ FO.singleton "implicit" $ un Milliseconds r.implicit
116 , J.encodeJson $ FO.singleton "page load" $ un Milliseconds r.pageLoad
113 , J.encodeJson $ FO.singleton "page load" $ un Milliseconds r.pageLoad
117 ]
114 ]
118
115
119−encodeGoRequest ∷ String → Json
116+encodeGoRequest ∷ String → J.Json
120encodeGoRequest url = J.encodeJson $ FO.fromFoldable [ Tuple "url" url ]
117encodeGoRequest url = J.encodeJson $ FO.fromFoldable [ Tuple "url" url ]
121
118
122−decodeWindowHandle ∷ Json → Either String WindowHandle
119+decodeWindowHandle ∷ J.Json → Either J.JsonDecodeError WindowHandle
123decodeWindowHandle = map WindowHandle <<< J.decodeJson
120decodeWindowHandle = map WindowHandle <<< J.decodeJson
124
121
125−encodeSwitchToWindowRequest ∷ WindowHandle → Json
122+encodeSwitchToWindowRequest ∷ WindowHandle → J.Json
126encodeSwitchToWindowRequest w = J.encodeJson $ FO.fromFoldable [ Tuple "handle" $ un WindowHandle w ]
123encodeSwitchToWindowRequest w = J.encodeJson $ FO.fromFoldable [ Tuple "handle" $ un WindowHandle w ]
127
124
128−encodeFrameId ∷ FrameId → Json
125+encodeFrameId ∷ FrameId → J.Json
129encodeFrameId fid = J.encodeJson $ FO.fromFoldable [ Tuple "id" encoded ]
126encodeFrameId fid = J.encodeJson $ FO.fromFoldable [ Tuple "id" encoded ]
130 where
127 where
131 encoded = case fid of
128 encoded = case fid of
@@ -140,31 +137,31 @@ type Rectangle =
140 , y ∷ Int
137 , y ∷ Int
141 }
138 }
142
139
143−decodeRectangle ∷ Json → Either String Rectangle
140+decodeRectangle ∷ J.Json → Either J.JsonDecodeError Rectangle
144decodeRectangle = J.decodeJson >=> \obj → do
141decodeRectangle = J.decodeJson >=> \obj → do
145− width ← obj .? "width"
142+ width ← obj .: "width"
146− height ← obj .? "height"
143+ height ← obj .: "height"
147− x ← obj .? "x"
144+ x ← obj .: "x"
148− y ← obj .? "y"
145+ y ← obj .: "y"
149 pure { width, height, x, y }
146 pure { width, height, x, y }
150
147
151−decodeRectangleLegacy ∷ { size ∷ Json, position ∷ Json } → Either String Rectangle
148+decodeRectangleLegacy ∷ { size ∷ J.Json, position ∷ J.Json } → Either J.JsonDecodeError Rectangle
152decodeRectangleLegacy { size, position } = do
149decodeRectangleLegacy { size, position } = do
153 sobj ← J.decodeJson size
150 sobj ← J.decodeJson size
154 pobj ← J.decodeJson position
151 pobj ← J.decodeJson position
155− x ← pobj .? "x"
152+ x ← pobj .: "x"
156− y ← pobj .? "y"
153+ y ← pobj .: "y"
157− width ← sobj .? "width"
154+ width ← sobj .: "width"
158− height ← sobj .? "height"
155+ height ← sobj .: "height"
159 pure { width, height, x, y }
156 pure { width, height, x, y }
160
157
161−encodeRectangleLegacy ∷ Rectangle → { size ∷ Json, position ∷ Json }
158+encodeRectangleLegacy ∷ Rectangle → { size ∷ J.Json, position ∷ J.Json }
162encodeRectangleLegacy r =
159encodeRectangleLegacy r =
163 { size: J.encodeJson $ FO.fromFoldable [ Tuple "width" r.width, Tuple "height" r.height ]
160 { size: J.encodeJson $ FO.fromFoldable [ Tuple "width" r.width, Tuple "height" r.height ]
164 , position: J.encodeJson $ FO.fromFoldable [ Tuple "x" r.x, Tuple "y" r.y ]
161 , position: J.encodeJson $ FO.fromFoldable [ Tuple "x" r.x, Tuple "y" r.y ]
165 }
162 }
166
163
167−encodeRectangle ∷ Rectangle → Json
164+encodeRectangle ∷ Rectangle → J.Json
168encodeRectangle r = J.encodeJson $ FO.fromFoldable
165encodeRectangle r = J.encodeJson $ FO.fromFoldable
169 [ Tuple "width" r.width
166 [ Tuple "width" r.width
170 , Tuple "height" r.height
167 , Tuple "height" r.height
@@ -174,7 +171,7 @@ encodeRectangle r = J.encodeJson $ FO.fromFoldable
174
171
175data Locator
172data Locator
176 = ByCss CSS.Selector
173 = ByCss CSS.Selector
177− | ByXPath XA.Selector
174+ | ByXPath String
178 | ByTagName String
175 | ByTagName String
179 | ByLinkText String
176 | ByLinkText String
180 | ByPartialLinkText String
177 | ByPartialLinkText String
@@ -185,15 +182,15 @@ type RawLocator =
185 , value ∷ String
182 , value ∷ String
186 }
183 }
187
184
188−encodeLocator ∷ Locator → Json
185+encodeLocator ∷ Locator → J.Json
189encodeLocator l = J.encodeJson $ FO.fromFoldable case l of
186encodeLocator l = J.encodeJson $ FO.fromFoldable case l of
190 ByCss sel →
187 ByCss sel →
191 [ Tuple "using" "css selector"
188 [ Tuple "using" "css selector"
192− , Tuple "value" $ CSSR.selector sel
189+ , Tuple "value" $ CSS.selector sel
193 ]
190 ]
194− ByXPath sel →
191+ ByXPath expr →
195 [ Tuple "using" "xpath"
192 [ Tuple "using" "xpath"
196− , Tuple "value" $ printSelector sel
193+ , Tuple "value" expr
197 ]
194 ]
198 ByLinkText sel →
195 ByLinkText sel →
199 [ Tuple "using" "link text"
196 [ Tuple "using" "link text"
@@ -212,15 +209,15 @@ encodeLocator l = J.encodeJson $ FO.fromFoldable case l of
212 , Tuple "value" r.value
209 , Tuple "value" r.value
213 ]
210 ]
214
211
215−encodeSendKeysRequest ∷ String → Json
212+encodeSendKeysRequest ∷ String → J.Json
216encodeSendKeysRequest txt = J.encodeJson $ FO.fromFoldable [ Tuple "text" txt ]
213encodeSendKeysRequest txt = J.encodeJson $ FO.fromFoldable [ Tuple "text" txt ]
217
214
218type Script =
215type Script =
219 { script ∷ String
216 { script ∷ String
220− , args ∷ Array Json
217+ , args ∷ Array J.Json
221 }
218 }
222
219
223−encodeScript ∷ Script → Json
220+encodeScript ∷ Script → J.Json
224encodeScript r = J.encodeJson $ FO.fromFoldable
221encodeScript r = J.encodeJson $ FO.fromFoldable
225 [ Tuple "script" $ J.encodeJson r.script
222 [ Tuple "script" $ J.encodeJson r.script
226 , Tuple "args" $ J.encodeJson r.args
223 , Tuple "args" $ J.encodeJson r.args
@@ -236,31 +233,32 @@ type Cookie =
236 , expiry ∷ Maybe Int
233 , expiry ∷ Maybe Int
237 }
234 }
238
235
239−encodeCookie ∷ Cookie → Json
236+encodeCookie ∷ Cookie → J.Json
240encodeCookie r = J.encodeJson $ FO.fromFoldable
237encodeCookie r = J.encodeJson $ FO.fromFoldable
241 [ Tuple "cookie" $ FO.fromFoldable
238 [ Tuple "cookie" $ FO.fromFoldable
239+ $
242− $ [ Tuple "name" $ J.encodeJson r.name
240+ [ Tuple "name" $ J.encodeJson r.name
243− , Tuple "value" $ J.encodeJson r.value
241+ , Tuple "value" $ J.encodeJson r.value
244− ]
242+ ]
245− <> maybeToAOfPair "path" r.path
243+ <> maybeToAOfPair "path" r.path
246− <> maybeToAOfPair "domain" r.domain
244+ <> maybeToAOfPair "domain" r.domain
247− <> maybeToAOfPair "secure" r.secure
245+ <> maybeToAOfPair "secure" r.secure
248− <> maybeToAOfPair "httpOnly" r.httpOnly
246+ <> maybeToAOfPair "httpOnly" r.httpOnly
249− <> maybeToAOfPair "expiry" r.expiry
247+ <> maybeToAOfPair "expiry" r.expiry
250 ]
248 ]
251 where
249 where
252 maybeToAOfPair ∷ ∀ a. J.EncodeJson a ⇒ String → Maybe a → Array (Tuple String J.Json)
250 maybeToAOfPair ∷ ∀ a. J.EncodeJson a ⇒ String → Maybe a → Array (Tuple String J.Json)
253 maybeToAOfPair key mb = F.foldMap (A.singleton <<< Tuple key <<< J.encodeJson) mb
251 maybeToAOfPair key mb = F.foldMap (A.singleton <<< Tuple key <<< J.encodeJson) mb
254
252
255−decodeCookie ∷ Json → Either String Cookie
253+decodeCookie ∷ J.Json → Either J.JsonDecodeError Cookie
256decodeCookie = J.decodeJson >=> \obj → do
254decodeCookie = J.decodeJson >=> \obj → do
257− name ← obj .? "name"
255+ name ← obj .: "name"
258− value ← obj .? "value"
256+ value ← obj .: "value"
259− path ← maybify $ obj .? "path"
257+ path ← maybify $ obj .: "path"
260− domain ← maybify $ obj .? "domain"
258+ domain ← maybify $ obj .: "domain"
261− secure ← maybify $ obj .? "secure"
259+ secure ← maybify $ obj .: "secure"
262− httpOnly ← maybify $ obj .? "httpOnly"
260+ httpOnly ← maybify $ obj .: "httpOnly"
263− expiry ← maybify $ obj .? "expiry"
261+ expiry ← maybify $ obj .: "expiry"
264 pure
262 pure
265 { name
263 { name
266 , value
264 , value
@@ -274,19 +272,18 @@ decodeCookie = J.decodeJson >=> \obj → do
274 maybify ∷ ∀ a b. Either a b → Either a (Maybe b)
272 maybify ∷ ∀ a b. Either a b → Either a (Maybe b)
275 maybify e = map Just e <|> Right Nothing
273 maybify e = map Just e <|> Right Nothing
276
274
277−
278type Screenshot =
275type Screenshot =
279 { content ∷ String
276 { content ∷ String
280 , encoding ∷ NE.Encoding
277 , encoding ∷ NE.Encoding
281 }
278 }
282
279
283−decodeScreenshot ∷ Json → Either String Screenshot
280+decodeScreenshot ∷ J.Json → Either J.JsonDecodeError Screenshot
284decodeScreenshot j =
281decodeScreenshot j =
285 { content: _, encoding: NE.Base64 } <$> J.decodeJson j
282 { content: _, encoding: NE.Base64 } <$> J.decodeJson j
286
283
287data Button = LeftBtn | MiddleBtn | RightBtn
284data Button = LeftBtn | MiddleBtn | RightBtn
288
285
289−encodeButton ∷ Button → Json
286+encodeButton ∷ Button → J.Json
290encodeButton = J.encodeJson <<< case _ of
287encodeButton = J.encodeJson <<< case _ of
291 LeftBtn → 0
288 LeftBtn → 0
292 MiddleBtn → 1
289 MiddleBtn → 1
@@ -297,7 +294,7 @@ data PointerMoveOrigin
297 | FromPointer
294 | FromPointer
298 | FromElement Element
295 | FromElement Element
299
296
300−encodeOrigin ∷ PointerMoveOrigin → Json
297+encodeOrigin ∷ PointerMoveOrigin → J.Json
301encodeOrigin = case _ of
298encodeOrigin = case _ of
302 FromViewport → J.encodeJson "viewport"
299 FromViewport → J.encodeJson "viewport"
303 FromPointer → J.encodeJson "pointer"
300 FromPointer → J.encodeJson "pointer"
@@ -310,7 +307,7 @@ type PointerMove =
310 , y ∷ Int
307 , y ∷ Int
311 }
308 }
312
309
313−encodePointerMove ∷ PointerMove → FO.Object Json
310+encodePointerMove ∷ PointerMove → FO.Object J.Json
314encodePointerMove r = FO.fromFoldable
311encodePointerMove r = FO.fromFoldable
315 [ Tuple "x" $ J.encodeJson r.x
312 [ Tuple "x" $ J.encodeJson r.x
316 , Tuple "y" $ J.encodeJson r.y
313 , Tuple "y" $ J.encodeJson r.y
@@ -318,7 +315,6 @@ encodePointerMove r = FO.fromFoldable
318 , Tuple "origin" $ encodeOrigin r.origin
315 , Tuple "origin" $ encodeOrigin r.origin
319 ]
316 ]
320
317
321−
322type Action = V.Variant
318type Action = V.Variant
323 ( pause ∷ Milliseconds
319 ( pause ∷ Milliseconds
324 , keyDown ∷ Char
320 , keyDown ∷ Char
@@ -328,56 +324,55 @@ type Action = V.Variant
328 , pointerMove ∷ PointerMove
324 , pointerMove ∷ PointerMove
329 )
325 )
330
326
331−pause ∷ ∀ r a. a → V.Variant (pause ∷ a|r)
327+pause ∷ ∀ r a. a → V.Variant (pause ∷ a | r)
332−pause = V.inj (SProxy ∷ SProxy "pause")
328+pause = V.inj (Proxy ∷ Proxy "pause")
333
329
334−keyDown ∷ ∀ r a. a → V.Variant (keyDown ∷ a|r)
330+keyDown ∷ ∀ r a. a → V.Variant (keyDown ∷ a | r)
335−keyDown = V.inj (SProxy ∷ SProxy "keyDown")
331+keyDown = V.inj (Proxy ∷ Proxy "keyDown")
336
332
337−keyUp ∷ ∀ r a. a → V.Variant (keyUp ∷ a|r)
333+keyUp ∷ ∀ r a. a → V.Variant (keyUp ∷ a | r)
338−keyUp = V.inj (SProxy ∷ SProxy "keyUp")
334+keyUp = V.inj (Proxy ∷ Proxy "keyUp")
339
335
340−pointerUp ∷ ∀ r a. a → V.Variant (pointerUp ∷ a|r)
336+pointerUp ∷ ∀ r a. a → V.Variant (pointerUp ∷ a | r)
341−pointerUp = V.inj (SProxy ∷ SProxy "pointerUp")
337+pointerUp = V.inj (Proxy ∷ Proxy "pointerUp")
342
338
343−pointerDown ∷ ∀ r a. a → V.Variant (pointerDown ∷ a|r)
339+pointerDown ∷ ∀ r a. a → V.Variant (pointerDown ∷ a | r)
344−pointerDown = V.inj (SProxy ∷ SProxy "pointerDown")
340+pointerDown = V.inj (Proxy ∷ Proxy "pointerDown")
345
341
346−pointerMove ∷ ∀ r a. a → V.Variant (pointerMove ∷ a|r)
342+pointerMove ∷ ∀ r a. a → V.Variant (pointerMove ∷ a | r)
347−pointerMove = V.inj (SProxy ∷ SProxy "pointerMove")
343+pointerMove = V.inj (Proxy ∷ Proxy "pointerMove")
348
344
349−encodeAction ∷ Action → Json
345+encodeAction ∷ Action → J.Json
350encodeAction = V.match
346encodeAction = V.match
351 { pause: \ms →
347 { pause: \ms →
352− J.encodeJson $ FO.fromFoldable
348+ J.encodeJson $ FO.fromFoldable
353− [ Tuple "duration" $ J.encodeJson $ un Milliseconds ms
349+ [ Tuple "duration" $ J.encodeJson $ un Milliseconds ms
354− , Tuple "type" $ J.encodeJson "pause"
350+ , Tuple "type" $ J.encodeJson "pause"
355− ]
351+ ]
356 , keyDown: \ch →
352 , keyDown: \ch →
357− J.encodeJson $ FO.fromFoldable
353+ J.encodeJson $ FO.fromFoldable
358− [ Tuple "value" $ J.encodeJson ch
354+ [ Tuple "value" $ J.encodeJson ch
359− , Tuple "type" $ J.encodeJson "keyDown"
355+ , Tuple "type" $ J.encodeJson "keyDown"
360− ]
356+ ]
361 , keyUp: \ch →
357 , keyUp: \ch →
362− J.encodeJson $ FO.fromFoldable
358+ J.encodeJson $ FO.fromFoldable
363− [ Tuple "value" $ J.encodeJson ch
359+ [ Tuple "value" $ J.encodeJson ch
364− , Tuple "type" $ J.encodeJson "keyUp"
360+ , Tuple "type" $ J.encodeJson "keyUp"
365− ]
361+ ]
366 , pointerUp: \btn →
362 , pointerUp: \btn →
367− J.encodeJson $ FO.fromFoldable
363+ J.encodeJson $ FO.fromFoldable
368− [ Tuple "button" $ encodeButton btn
364+ [ Tuple "button" $ encodeButton btn
369− , Tuple "type" $ J.encodeJson "pointerUp"
365+ , Tuple "type" $ J.encodeJson "pointerUp"
370− ]
366+ ]
371 , pointerDown: \btn →
367 , pointerDown: \btn →
372− J.encodeJson $ FO.fromFoldable
368+ J.encodeJson $ FO.fromFoldable
373− [ Tuple "button" $ encodeButton btn
369+ [ Tuple "button" $ encodeButton btn
374− , Tuple "type" $ J.encodeJson "pointerDown"
370+ , Tuple "type" $ J.encodeJson "pointerDown"
375− ]
371+ ]
376 , pointerMove: \pm →
372 , pointerMove: \pm →
377− J.encodeJson $ FO.insert "type" (J.encodeJson "pointerMove") $ encodePointerMove pm
373+ J.encodeJson $ FO.insert "type" (J.encodeJson "pointerMove") $ encodePointerMove pm
378 }
374 }
379
375
380−
381data PointerType = Mouse | Pen | Touch
376data PointerType = Mouse | Pen | Touch
382
377
383printPointerType ∷ PointerType → String
378printPointerType ∷ PointerType → String
@@ -397,17 +392,17 @@ data ActionSequence
397-- Right, this is not an `Array` but `StrMap` because all `ActionSequence`s are tagged with unique id's
392-- Right, this is not an `Array` but `StrMap` because all `ActionSequence`s are tagged with unique id's
398type ActionRequest = FO.Object ActionSequence
393type ActionRequest = FO.Object ActionSequence
399
394
400−encodeActionRequest ∷ ActionRequest → Json
395+encodeActionRequest ∷ ActionRequest → J.Json
401encodeActionRequest sm = J.encodeJson $ FO.singleton "actions" $ map encodePair arrayOfPairs
396encodeActionRequest sm = J.encodeJson $ FO.singleton "actions" $ map encodePair arrayOfPairs
402 where
397 where
403 arrayOfPairs ∷ Array (Tuple String ActionSequence)
398 arrayOfPairs ∷ Array (Tuple String ActionSequence)
404 arrayOfPairs = FO.toUnfoldable sm
399 arrayOfPairs = FO.toUnfoldable sm
405
400
406− encodePair ∷ Tuple String ActionSequence → Json
401+ encodePair ∷ Tuple String ActionSequence → J.Json
407 encodePair (Tuple identifier sequence) =
402 encodePair (Tuple identifier sequence) =
408 J.encodeJson $ FO.insert "id" (J.encodeJson identifier) $ encodeSequence sequence
403 J.encodeJson $ FO.insert "id" (J.encodeJson identifier) $ encodeSequence sequence
409
404
410− encodeSequence ∷ ActionSequence → FO.Object Json
405+ encodeSequence ∷ ActionSequence → FO.Object J.Json
411 encodeSequence = case _ of
406 encodeSequence = case _ of
412 NoSource as → FO.fromFoldable
407 NoSource as → FO.fromFoldable
413 [ Tuple "type" $ J.encodeJson "none"
408 [ Tuple "type" $ J.encodeJson "none"
@@ -465,10 +460,9 @@ data Capability
465 | PageLoadStrategy PageLoad
460 | PageLoadStrategy PageLoad
466 | DesiredTimeouts Timeouts
461 | DesiredTimeouts Timeouts
467 | UnhandledPromptBehavior UnhandledPrompt
462 | UnhandledPromptBehavior UnhandledPrompt
468− | CustomCapability String Json
463+ | CustomCapability String J.Json
469−
470
464
471−encodeCapability ∷ Capability → Tuple String Json
465+encodeCapability ∷ Capability → Tuple String J.Json
472encodeCapability = case _ of
466encodeCapability = case _ of
473 BrowserName bn → Tuple "browserName" $ J.encodeJson case bn of
467 BrowserName bn → Tuple "browserName" $ J.encodeJson case bn of
474 MSEdge → "MicrosoftEdge"
468 MSEdge → "MicrosoftEdge"
@@ -491,50 +485,50 @@ encodeCapability = case _ of
491 Dismiss → "dismiss"
485 Dismiss → "dismiss"
492 CustomCapability k v → Tuple k v
486 CustomCapability k v → Tuple k v
493
487
494−encodeCapabilities ∷ ∀ f. F.Foldable f ⇒ f Capability → Json
488+encodeCapabilities ∷ ∀ f. F.Foldable f ⇒ f Capability → J.Json
495encodeCapabilities = F.foldl (\b a → J.extend (encodeCapability a) b) J.jsonEmptyObject
489encodeCapabilities = F.foldl (\b a → J.extend (encodeCapability a) b) J.jsonEmptyObject
496
490
497−decodeCapabilities ∷ Json → Either String (Array Capability)
491+decodeCapabilities ∷ J.Json → Either J.JsonDecodeError (Array Capability)
498decodeCapabilities = J.decodeJson >=> \obj →
492decodeCapabilities = J.decodeJson >=> \obj →
499 F.for (FO.toUnfoldable obj) \l@(Tuple key val) →
493 F.for (FO.toUnfoldable obj) \l@(Tuple key val) →
500 decodeCapability l <|> Right (CustomCapability key val)
494 decodeCapability l <|> Right (CustomCapability key val)
501 where
495 where
502− decodeCapability ∷ Tuple String Json → Either String Capability
496+ decodeCapability ∷ Tuple String J.Json → Either J.JsonDecodeError Capability
503 decodeCapability (Tuple key val) = case key of
497 decodeCapability (Tuple key val) = case key of
504− "browserName" → BrowserName <$> decodeBrowserName val
498+ "browserName" → BrowserName <$> decodeBrowserType val
505 "browserVersion" → BrowserVersion <$> J.decodeJson val
499 "browserVersion" → BrowserVersion <$> J.decodeJson val
506 "acceptInsecureCerts" → AcceptInsecureCerts <$> J.decodeJson val
500 "acceptInsecureCerts" → AcceptInsecureCerts <$> J.decodeJson val
507− "pageLoadStrategy" → PageLoadStrategy <$> decodePageLoadStrategy val
501+ "pageLoadStrategy" → PageLoadStrategy <$> decodePageLoad val
508 "timeouts" → DesiredTimeouts <$> decodeTimeouts val
502 "timeouts" → DesiredTimeouts <$> decodeTimeouts val
509− "unhandledPromptBehaviour" → UnhandledPromptBehavior <$> decodePrompt val
503+ "unhandledPromptBehaviour" → UnhandledPromptBehavior <$> decodeUnhandledPrompt val
510− _ → Left "unhandled"
504+ other → Left $ J.Named "Capability" $ J.UnexpectedValue (J.fromString other)
511
505
512− decodeBrowserName ∷ Json → Either String BrowserType
506+ decodeBrowserType ∷ J.Json → Either J.JsonDecodeError BrowserType
513− decodeBrowserName = J.decodeJson >=> \str → case Str.toLower str of
507+ decodeBrowserType = J.decodeJson >=> \str → case Str.toLower str of
514 "microsoftedge" → Right MSEdge
508 "microsoftedge" → Right MSEdge
515 "chrome" → Right Chrome
509 "chrome" → Right Chrome
516 "firefox" → Right Firefox
510 "firefox" → Right Firefox
517− _ → Left "unhandled"
511+ other → Left $ J.Named "BrowserType" $ J.UnexpectedValue (J.fromString other)
518
512
519− decodePageLoadStrategy ∷ Json → Either String PageLoad
513+ decodePageLoad ∷ J.Json → Either J.JsonDecodeError PageLoad
520− decodePageLoadStrategy = J.decodeJson >=> \str → case Str.toLower str of
514+ decodePageLoad = J.decodeJson >=> \str → case Str.toLower str of
521 "none" → Right Immediate
515 "none" → Right Immediate
522 "normal" → Right Normal
516 "normal" → Right Normal
523 "eager" → Right Eager
517 "eager" → Right Eager
524− _ → Left "unhandled"
518+ other → Left $ J.Named "PageLoad" $ J.UnexpectedValue (J.fromString other)
525
519
526− decodePrompt ∷ Json → Either String UnhandledPrompt
520+ decodeUnhandledPrompt ∷ J.Json → Either J.JsonDecodeError UnhandledPrompt
527− decodePrompt = J.decodeJson >=> \str → case Str.toLower str of
521+ decodeUnhandledPrompt = J.decodeJson >=> \str → case Str.toLower str of
528 "accept" → Right Accept
522 "accept" → Right Accept
529 "dismiss" → Right Dismiss
523 "dismiss" → Right Dismiss
530− _ → Left "unhandled"
524+ other → Left $ J.Named "UnhandledPrompt" $ J.UnexpectedValue (J.fromString other)
531
525
532type CapabilitiesRequest =
526type CapabilitiesRequest =
533 { alwaysMatch ∷ Array Capability
527 { alwaysMatch ∷ Array Capability
534 , firstMatch ∷ Array (Array Capability)
528 , firstMatch ∷ Array (Array Capability)
535 }
529 }
536
530
537−encodeCapabilitiesRequest ∷ CapabilitiesRequest → Json
531+encodeCapabilitiesRequest ∷ CapabilitiesRequest → J.Json
538encodeCapabilitiesRequest r = J.encodeJson $ FO.singleton "capabilities" $ FO.fromFoldable
532encodeCapabilitiesRequest r = J.encodeJson $ FO.singleton "capabilities" $ FO.fromFoldable
539 [ Tuple "alwaysMatch" $ encodeCapabilities r.alwaysMatch
533 [ Tuple "alwaysMatch" $ encodeCapabilities r.alwaysMatch
540 , Tuple "firstMatch" $ J.encodeJson $ map encodeCapabilities r.firstMatch
534 , Tuple "firstMatch" $ J.encodeJson $ map encodeCapabilities r.firstMatch
@@ -546,11 +540,11 @@ type MoveToRequest =
546 , yoffset ∷ Int
540 , yoffset ∷ Int
547 }
541 }
548
542
549−encodeMoveToRequest ∷ MoveToRequest → Json
543+encodeMoveToRequest ∷ MoveToRequest → J.Json
550encodeMoveToRequest r = J.encodeJson $ FO.fromFoldable
544encodeMoveToRequest r = J.encodeJson $ FO.fromFoldable
551 [ Tuple "element" $ case r.element of
545 [ Tuple "element" $ case r.element of
552− Nothing → J.jsonNull
546+ Nothing → J.jsonNull
553− Just el → J.encodeJson $ un Element el
547+ Just el → J.encodeJson $ un Element el
554 , Tuple "xoffset" $ J.encodeJson r.xoffset
548 , Tuple "xoffset" $ J.encodeJson r.xoffset
555 , Tuple "yoffset" $ J.encodeJson r.yoffset
549 , Tuple "yoffset" $ J.encodeJson r.yoffset
556 ]
550 ]
src/Lunapark/UnicodeCharacters.pursnew file+177
@@ -0,0 +1,177 @@
1+module Lunapark.UnicodeCharacters where
2+
3+-- copied from https://github.com/webdriverio/webdriverio/blob/13d3a3419b951803c5e7a5db53e48764ca58f371/packages/webdriverio/src/constants.js#L315
4+
5+unidentified ∷ Char
6+unidentified = '\xE000'
7+
8+cancel ∷ Char
9+cancel = '\xE001'
10+
11+help ∷ Char
12+help = '\xE002'
13+
14+backspace ∷ Char
15+backspace = '\xE003'
16+
17+tab ∷ Char
18+tab = '\xE004'
19+
20+clear ∷ Char
21+clear = '\xE005'
22+
23+return ∷ Char
24+return = '\xE006'
25+
26+enter ∷ Char
27+enter = '\xE007'
28+
29+shift ∷ Char
30+shift = '\xE008'
31+
32+controlLeft ∷ Char
33+controlLeft = '\xE009'
34+
35+controlRight ∷ Char
36+controlRight = '\xE051'
37+
38+alt ∷ Char
39+alt = '\xE00A'
40+
41+pause ∷ Char
42+pause = '\xE00B'
43+
44+escape ∷ Char
45+escape = '\xE00C'
46+
47+space ∷ Char
48+space = '\xE00D'
49+
50+pageUp ∷ Char
51+pageUp = '\xE00E'
52+
53+pageDown ∷ Char
54+pageDown = '\xE00F'
55+
56+end ∷ Char
57+end = '\xE010'
58+
59+home ∷ Char
60+home = '\xE011'
61+
62+arrowLeft ∷ Char
63+arrowLeft = '\xE012'
64+
65+arrowUp ∷ Char
66+arrowUp = '\xE013'
67+
68+arrowRight ∷ Char
69+arrowRight = '\xE014'
70+
71+arrowDown ∷ Char
72+arrowDown = '\xE015'
73+
74+insert ∷ Char
75+insert = '\xE016'
76+
77+delete ∷ Char
78+delete = '\xE017'
79+
80+semicolon ∷ Char
81+semicolon = '\xE018'
82+
83+equals ∷ Char
84+equals = '\xE019'
85+
86+numpad0 ∷ Char
87+numpad0 = '\xE01A'
88+
89+numpad1 ∷ Char
90+numpad1 = '\xE01B'
91+
92+numpad2 ∷ Char
93+numpad2 = '\xE01C'
94+
95+numpad3 ∷ Char
96+numpad3 = '\xE01D'
97+
98+numpad4 ∷ Char
99+numpad4 = '\xE01E'
100+
101+numpad5 ∷ Char
102+numpad5 = '\xE01F'
103+
104+numpad6 ∷ Char
105+numpad6 = '\xE020'
106+
107+numpad7 ∷ Char
108+numpad7 = '\xE021'
109+
110+numpad8 ∷ Char
111+numpad8 = '\xE022'
112+
113+numpad9 ∷ Char
114+numpad9 = '\xE023'
115+
116+multiply ∷ Char
117+multiply = '\xE024'
118+
119+add ∷ Char
120+add = '\xE025'
121+
122+separator ∷ Char
123+separator = '\xE026'
124+
125+subtract ∷ Char
126+subtract = '\xE027'
127+
128+decimal ∷ Char
129+decimal = '\xE028'
130+
131+divide ∷ Char
132+divide = '\xE029'
133+
134+f1 ∷ Char
135+f1 = '\xE031'
136+
137+f2 ∷ Char
138+f2 = '\xE032'
139+
140+f3 ∷ Char
141+f3 = '\xE033'
142+
143+f4 ∷ Char
144+f4 = '\xE034'
145+
146+f5 ∷ Char
147+f5 = '\xE035'
148+
149+f6 ∷ Char
150+f6 = '\xE036'
151+
152+f7 ∷ Char
153+f7 = '\xE037'
154+
155+f8 ∷ Char
156+f8 = '\xE038'
157+
158+f9 ∷ Char
159+f9 = '\xE039'
160+
161+f10 ∷ Char
162+f10 = '\xE03A'
163+
164+f11 ∷ Char
165+f11 = '\xE03B'
166+
167+f12 ∷ Char
168+f12 = '\xE03C'
169+
170+command ∷ Char
171+command = '\xE03D'
172+
173+meta ∷ Char
174+meta = '\xE03D'
175+
176+zenkakuHankaku ∷ Char
177+zenkakuHankaku = '\xE040'
src/Lunapark/Utils.purs+12−10
@@ -2,33 +2,35 @@ module Lunapark.Utils where
2
2
3import Prelude
3import Prelude
4
4
5−import Effect.Aff (Aff)
5+import Data.Argonaut.Decode (JsonDecodeError) as J
6import Data.Bifunctor (lmap)
6import Data.Bifunctor (lmap)
7import Data.Either (Either)
7import Data.Either (Either)
8+import Effect.Aff (Aff)
8import Lunapark.Error as LE
9import Lunapark.Error as LE
9import Run as R
10import Run as R
10import Run.Except as RE
11import Run.Except as RE
12+import Type.Row (type (+))
11import Unsafe.Coerce (unsafeCoerce)
13import Unsafe.Coerce (unsafeCoerce)
12
14
13liftAndRethrow
15liftAndRethrow
14 ∷ ∀ r ε ω
16 ∷ ∀ r ε ω
15 . Aff (Either ε ω)
17 . Aff (Either ε ω)
16− → R.Run (aff ∷ R.AFF, except ∷ RE.EXCEPT ε|r) ω
18+ → R.Run (R.AFF + RE.EXCEPT ε + r) ω
17liftAndRethrow a = do
19liftAndRethrow a = do
18 res ← R.liftAff a
20 res ← R.liftAff a
19 RE.rethrow res
21 RE.rethrow res
20
22
21−throwLeft
23+rethrowAsJsonDecodeError
22 ∷ ∀ r
24 ∷ ∀ r
23− . Either String
25+ . Either J.JsonDecodeError
24− ~> R.Run (except ∷ RE.EXCEPT LE.Error|r)
26+ ~> R.Run (RE.EXCEPT LE.Error + r)
25−throwLeft =
27+rethrowAsJsonDecodeError =
26− RE.rethrow <<< lmap LE.unknownError
28+ RE.rethrow <<< lmap LE.JsonDecodeError
27
29
28-- Safe, since we actually want handler and result have same rows not, remove except
30-- Safe, since we actually want handler and result have same rows not, remove except
29catch
31catch
30 ∷ ∀ e r a
32 ∷ ∀ e r a
31− . R.Run (except ∷ RE.EXCEPT e|r) a
33+ . R.Run (RE.EXCEPT e + r) a
32− → (e → R.Run (except ∷ RE.EXCEPT e|r) a)
34+ → (e → R.Run (RE.EXCEPT e + r) a)
33− → R.Run (except ∷ RE.EXCEPT e|r) a
35+ → R.Run (RE.EXCEPT e + r) a
34catch = unsafeCoerce $ flip RE.catch
36catch = unsafeCoerce $ flip RE.catch
src/Lunapark/WebDriverError.pursnew file+117
@@ -0,0 +1,117 @@
1+module Lunapark.WebDriverError where
2+
3+import Prelude
4+
5+import Data.Argonaut.Core (Json, fromString) as J
6+import Data.Argonaut.Decode (JsonDecodeError(..)) as J
7+import Data.Argonaut.Decode.Combinators ((.:)) as J
8+import Data.Argonaut.Decode.Class (decodeJson) as J
9+import Data.Either (Either(..))
10+
11+data WebDriverErrorType
12+ = ElementClickIntercepted
13+ | ElementNotSelectable
14+ | ElementNotInteractable
15+ | InsecureCertificate
16+ | InvalidArgument
17+ | InvalidCookieDomain
18+ | InvalidCoordinates
19+ | InvalidElementState
20+ | InvalidSelector
21+ | InvalidSessionId
22+ | JavaScriptError
23+ | MoveTargetOutOfBounds
24+ | NoSuchAlert
25+ | NoSuchCookie
26+ | NoSuchElement
27+ | NoSuchFrame
28+ | NoSuchWindow
29+ | ScriptTimeout
30+ | SessionNotCreated
31+ | StaleElementReference
32+ | Timeout
33+ | UnableToSetCookie
34+ | UnableToCaptureScreen
35+ | UnexpectedAlertOpen
36+ | UnknownCommand
37+ | UnknownError
38+ | UnknownMethod
39+ | UnsupportedOperation
40+
41+fromStringCode ∷ String → Either J.JsonDecodeError WebDriverErrorType
42+fromStringCode = case _ of
43+ "element click intercepted" → Right ElementClickIntercepted
44+ "element not selectable" → Right ElementNotSelectable
45+ "element not interactable" → Right ElementNotInteractable
46+ "insecure certificate" → Right InsecureCertificate
47+ "invalid argument" → Right InvalidArgument
48+ "invalid cookie domain" → Right InvalidCookieDomain
49+ "invalid coordinates" → Right InvalidCoordinates
50+ "invalid element state" → Right InvalidElementState
51+ "invalid selector" → Right InvalidSelector
52+ "invalid session id" → Right InvalidSessionId
53+ "javascript error" → Right JavaScriptError
54+ "move target out of bounds" → Right MoveTargetOutOfBounds
55+ "no such alert" → Right NoSuchAlert
56+ "no such cookie" → Right NoSuchCookie
57+ "no such element" → Right NoSuchElement
58+ "no such frame" → Right NoSuchFrame
59+ "no such window" → Right NoSuchWindow
60+ "script timeout" → Right ScriptTimeout
61+ "session not created" → Right SessionNotCreated
62+ "stale element reference" → Right StaleElementReference
63+ "timeout" → Right Timeout
64+ "unable to set cookie" → Right UnableToSetCookie
65+ "unable to capture screen" → Right UnableToCaptureScreen
66+ "unexpected alert open" → Right UnexpectedAlertOpen
67+ "unknown command" → Right UnknownCommand
68+ "unknown error" → Right UnknownError
69+ "unknown method" → Right UnknownMethod
70+ "unsupported operation" → Right UnsupportedOperation
71+ s → Left $ J.Named "WebDriverErrorType" $ J.UnexpectedValue $ J.fromString s
72+
73+toStringCode ∷ WebDriverErrorType → String
74+toStringCode = case _ of
75+ ElementClickIntercepted → "element click intercepted"
76+ ElementNotSelectable → "element not selectable"
77+ ElementNotInteractable → "element not interactable"
78+ InsecureCertificate → "insecure certificate"
79+ InvalidArgument → "invalid argument"
80+ InvalidCookieDomain → "invalid cookie domain"
81+ InvalidCoordinates → "invalid coordinates"
82+ InvalidElementState → "invalid element state"
83+ InvalidSelector → "invalid selector"
84+ InvalidSessionId → "invalid session id"
85+ JavaScriptError → "javascript error"
86+ MoveTargetOutOfBounds → "move target out of bounds"
87+ NoSuchAlert → "no such alert"
88+ NoSuchCookie → "no such cookie"
89+ NoSuchElement → "no such element"
90+ NoSuchFrame → "no such frame"
91+ NoSuchWindow → "no such window"
92+ ScriptTimeout → "script timeout"
93+ SessionNotCreated → "session not created"
94+ StaleElementReference → "stale element reference"
95+ Timeout → "timeout"
96+ UnableToSetCookie → "unable to set cookie"
97+ UnableToCaptureScreen → "unable to capture screen"
98+ UnexpectedAlertOpen → "unexpected alert open"
99+ UnknownCommand → "unknown command"
100+ UnknownError → "unknown error"
101+ UnknownMethod → "unknown method"
102+ UnsupportedOperation → "unsupported operation"
103+
104+type WebDriverError =
105+ { error ∷ WebDriverErrorType
106+ , message ∷ String
107+ , stacktrace ∷ String
108+ }
109+
110+fromJson ∷ J.Json → Either J.JsonDecodeError WebDriverError
111+fromJson js = do
112+ obj ← J.decodeJson js
113+ value ← obj J..: "value"
114+ error ← fromStringCode =<< value J..: "error"
115+ message ← value J..: "message"
116+ stacktrace ← value J..: "stacktrace"
117+ pure { error, message, stacktrace }
test/Test/Main.pursnew file+12
@@ -0,0 +1,12 @@
1+module Test.Main where
2+
3+import Prelude
4+
5+import Effect (Effect)
6+import Effect.Class.Console (log)
7+
8+main :: Effect Unit
9+main = do
10+ log "🍕"
11+ log "You should add some tests."
12+
vendor/chromedriver.exedeleted

Binary file not shown.

vendor/edgedriver.exedeleted

Binary file not shown.

vendor/geckodriver.exedeleted

Binary file not shown.

vendor/selenium-3.11.0.jardeleted

Binary file not shown.