git.iko.soy/rowtype-yoga/purescript-playwright
on main help sign in
Use untagged-union for options
commited09f4bc826b22068e11cac6fb3017732ca9c102 authorVladimir Kalnitsky <klntsky@gmail.com> dateTue 15 Sep 2020, 19:47 (6 years ago) parent5dc2b7a
6 files changed+136−187
spago.dhall−1 src/Playwright.purs+41−55 src/Playwright/Internal.js+10−2 src/Playwright/Internal.purs+7−3 src/Playwright/Options.purs+73−119 test/Main.purs+5−7
spago.dhall−1
@@ -5,7 +5,6 @@
55 , "prelude"
66 , "psci-support"
77 , "aff-promise"
8− , "options"
98 , "test-unit"
109 , "untagged-union"
1110 , "node-buffer"
src/Playwright.purs+41−55
@@ -18,95 +18,86 @@ where
1818import Prelude
1919import Effect (Effect)
2020import Control.Promise (toAffE)
21−import Data.Options (Options, options)
2221import Effect.Aff (Aff)
2322import Untagged.Union (type (|+|))
2423import Node.Buffer (Buffer)
2524import Playwright.Data
2625import Playwright.Options
27−import Playwright.Internal (effProp)
26+import Playwright.Internal (effCall, effProp)
2827
29−launch :: BrowserType -> Options Launch -> Aff Browser
28+launch :: BrowserType -> LaunchOptions -> Aff Browser
3029launch bt =
31− options >>>
32− effProp "launch" (\_ -> launch) bt >>>
30+ effCall "launch" (\_ -> launch) bt >>>
3331 toAffE
3432
3533close :: Browser |+| BrowserContext |+| Page -> Aff Unit
3634close =
37− effProp "close" (\_ -> close) >>> toAffE
35+ effCall "close" (\_ -> close) >>> toAffE
3836
3937contexts :: Browser -> Effect (Array BrowserContext)
4038contexts =
41− effProp "contexts" (\_ -> contexts)
39+ effCall "contexts" (\_ -> contexts)
4240
4341isConnected :: Browser -> Effect Boolean
4442isConnected =
45− effProp "isConnected" (\_ -> isConnected)
43+ effCall "isConnected" (\_ -> isConnected)
4644
4745version :: Browser -> Effect String
4846version =
49− effProp "version" (\_ -> version)
47+ effCall "version" (\_ -> version)
5048
51−newPage :: Browser |+| BrowserContext -> Options Newpage -> Aff Page
49+newPage :: Browser |+| BrowserContext -> NewpageOptions -> Aff Page
5250newPage sth =
53− options >>>
54− effProp "newPage" (\_ -> newPage) sth >>>
51+ effCall "newPage" (\_ -> newPage) sth >>>
5552 toAffE
5653
57−goForward
58− :: Page
59− -> Options Go
60− -> Aff (Null |+| Response)
54+goForward :: Page -> GoOptions -> Aff (Null |+| Response)
6155goForward page =
62− options >>>
63− effProp "goForward" (\_ -> goForward) page >>>
56+ effCall "goForward" (\_ -> goForward) page >>>
6457 toAffE
6558
66−goBack
67− :: Page
68− -> Options Go
69− -> Aff (Null |+| Response)
59+goBack :: Page -> GoOptions -> Aff (Null |+| Response)
7060goBack page =
71− options >>>
72− effProp "goBack" (\_ -> goBack) page >>>
61+ effCall "goBack" (\_ -> goBack) page >>>
7362 toAffE
7463
75−goto
76− :: Page |+| Frame
77− -> URL
78− -> Options Goto
79− -> Aff (Null |+| Response)
64+goto :: Page |+| Frame -> URL -> GotoOptions -> Aff (Null |+| Response)
8065goto sth url' =
81− options >>>
82− effProp "goto" (\_ -> goto) sth url' >>>
66+ effCall "goto" (\_ -> goto) sth url' >>>
8367 toAffE
8468
85−hover
86− :: Page |+| Frame |+| ElementHandle
87− -> Options Hover
88− -> Aff Unit
69+hover :: Page |+| Frame |+| ElementHandle -> HoverOptions -> Aff Unit
8970hover sth =
90− options >>>
91− effProp "hover" (\_ -> hover) sth >>>
71+ effCall "hover" (\_ -> hover) sth >>>
9272 toAffE
9373
9474innerHTML
9575 :: Page |+| Frame |+| ElementHandle
9676 -> Selector
97− -> Options InnerHTML
77+ -> InnerHTMLOptions
9878 -> Aff String
9979innerHTML sth selector =
100− options >>>
101− effProp "innerHTML" (\_ -> innerHTML) sth selector
80+ effCall "innerHTML" (\_ -> innerHTML) sth selector
81+
82+innerText
83+ :: Page |+| Frame |+| ElementHandle
84+ -> Selector
85+ -> InnerTextOptions
86+ -> Aff String
87+innerText sth selector =
88+ effCall "innerText" (\_ -> innerText) sth selector
89+
90+isClosed :: Page -> Effect Boolean
91+isClosed = effCall "isClosed" \_ -> isClosed
92+
93+keyboard :: Page -> Effect Keyboard
94+keyboard = effProp "keyboard"
10295
10396-- | `sth.$(selector)`
10497query
105− :: ElementHandle |+| Page |+| Frame
106− -> Selector
107− -> Aff ElementHandle
98+ :: ElementHandle |+| Page |+| Frame -> Selector -> Aff ElementHandle
10899query sth =
109− toAffE <<< effProp "$" (\_ -> query) sth
100+ toAffE <<< effCall "$" (\_ -> query) sth
110101
111102-- | `sth.$$(selector)`
112103queryMany
@@ -114,26 +105,21 @@ queryMany
114105 -> Selector
115106 -> Aff (Array ElementHandle)
116107queryMany sth =
117− toAffE <<< effProp "$$" (\_ -> queryMany) sth
108+ toAffE <<< effCall "$$" (\_ -> queryMany) sth
118109
119110screenshot
120− :: ElementHandle |+| Page
121− -> Options Screenshot
122− -> Aff Buffer
111+ :: ElementHandle |+| Page -> ScreenshotOptions -> Aff Buffer
123112screenshot sth =
124− options >>>
125− effProp "screenshot" (\_ -> screenshot) sth >>>
113+ effCall "screenshot" (\_ -> screenshot) sth >>>
126114 toAffE
127115
128116textContent
129− :: Page |+| Frame |+| ElementHandle
130− -> Selector
131− -> Aff (Null |+| String)
117+ :: Page |+| Frame |+| ElementHandle -> Selector -> Aff (Null |+| String)
132118textContent sth =
133− effProp "textContent" (\_ -> textContent) sth >>>
119+ effCall "textContent" (\_ -> textContent) sth >>>
134120 toAffE
135121
136122url
137123 :: Page |+| Frame |+| Download |+| Request |+| Response |+| Worker
138124 -> Effect String
139−url = effProp "url" \_ -> url
125+url = effCall "url" \_ -> url
src/Playwright/Internal.js+10−2
@@ -34,8 +34,16 @@ function effectfulGetter (property, n) {
3434 };
3535}
3636
37−exports.unsafeEffectfulGetter = function (prop) {
37+exports.unsafeEffCall = function (method) {
3838 return function (argsCount) {
39− return effectfulGetter(prop, argsCount);
39+ return effectfulGetter(method, argsCount);
4040 };
4141};
42+
43+exports.effProp = function (prop) {
44+ return function (object) {
45+ return function () {
46+ return object[prop];
47+ };
48+ };
49+}
src/Playwright/Internal.purs+7−3
@@ -1,12 +1,14 @@
11module Playwright.Internal
22 ( class NumberOfArgs
33 , numberOfArgs
4+ , effCall
45 , effProp
56 )
67 where
78
89import Type.Proxy
910import Prelude
11+import Effect
1012
1113class NumberOfArgs x where
1214 numberOfArgs :: Proxy x -> Int
@@ -49,11 +51,13 @@ countArgs f = numberOfArgs (proxyOf (f unit)) - 1
4951 proxyOf :: forall a. a -> Proxy a
5052 proxyOf _ = Proxy :: Proxy a
5153
52−foreign import unsafeEffectfulGetter
54+foreign import unsafeEffCall
5355 :: forall r
5456 . String
5557 -> Int
5658 -> r
5759
58−effProp :: forall f r. NumberOfArgs f => String -> (Unit -> f) -> r
59−effProp p f = unsafeEffectfulGetter p (countArgs f)
60+effCall :: forall f r. NumberOfArgs f => String -> (Unit -> f) -> r
61+effCall p f = unsafeEffCall p (countArgs f)
62+
63+foreign import effProp :: forall obj r. String -> obj -> Effect r
src/Playwright/Options.purs+73−119
@@ -2,124 +2,78 @@ module Playwright.Options where
22
33import Playwright.Data
44
5−import Data.Options (Option, Options, opt)
65import Foreign.Object (Object)
76import Foreign (Foreign)
8−
9−foreign import data Launch :: Type
10−
11−headless :: Option Launch Boolean
12−headless = opt "headless"
13−
14−executablePath :: Option Launch String
15−executablePath = opt "executablePath"
16−
17−args :: Option Launch String
18−args = opt "args"
19−
20−ignoreDefaultArgs :: Option Launch (Array String)
21−ignoreDefaultArgs = opt "ignoreDefaultArgs"
22−
23−proxy :: Option Launch (Options Proxy)
24−proxy = opt "proxy"
25−
26−downloadsPath :: Option Launch String
27−downloadsPath = opt "downloadsPath"
28−
29−chromiumSandbox :: Option Launch Boolean
30−chromiumSandbox = opt "chromiumSandbox"
31−
32−firefoxUserPrefs :: Option Launch Foreign
33−firefoxUserPrefs = opt "firefoxUserPrefs"
34−
35−handleSIGINT :: Option Launch Boolean
36−handleSIGINT = opt "handleSIGINT"
37−
38−handleSIGTERM :: Option Launch Boolean
39−handleSIGTERM = opt "handleSIGTERM"
40−
41−handleSIGHUP :: Option Launch Boolean
42−handleSIGHUP = opt "handleSIGHUP"
43−
44−timeout :: Option Launch Number
45−timeout = opt "timeout"
46−
47−env :: Option Launch (Object String)
48−env = opt "env"
49−
50−devtools :: Option Launch Boolean
51−devtools = opt "devtools"
52−
53−slowMo :: Option Launch Number
54−slowMo = opt "slowMo"
55−
56−foreign import data Proxy :: Type
57−
58−server :: Option Proxy String
59−server = opt "server"
60−
61−bypass :: Option Proxy String
62−bypass = opt "bypass"
63−
64−username :: Option Proxy String
65−username = opt "username"
66−
67−password :: Option Proxy String
68−password = opt "password"
69−
70−foreign import data Newpage :: Type
71−
72−foreign import data Screenshot :: Type
73−
74−path :: Option Screenshot String
75−path = opt "path"
76−
77−screenshotType :: Option Screenshot ScreenshotType
78−screenshotType = opt "type"
79−
80−quality :: Option Screenshot Number
81−quality = opt "quality"
82−
83−omitBackground :: Option Screenshot Boolean
84−omitBackground = opt "omitBackground"
85−
86−screenshotTimeout :: Option Screenshot Number
87−screenshotTimeout = opt "timeout"
88−
89−foreign import data Goto :: Type
90−
91−gotoTimeout :: Option Goto Int
92−gotoTimeout = opt "timeout"
93−
94−gotoWaitUntil :: Option Goto WaitUntil
95−gotoWaitUntil = opt "waitUntil"
96−
97−referer :: Option Goto String
98−referer = opt "referer"
99−
100−foreign import data Go :: Type
101−
102−goTimeout :: Option Go Int
103−goTimeout = opt "timeout"
104−
105−goWaitUntil :: Option Go WaitUntil
106−goWaitUntil = opt "waitUntil"
107−
108−foreign import data Hover :: Type
109−
110−position :: Option Hover { x :: Number, y :: Number }
111−position = opt "position"
112−
113−modifier :: Option Hover (Array Modifier)
114−modifier = opt "modifier"
115−
116−force :: Option Hover Boolean
117−force = opt "force"
118−
119−hoverTimeout :: Option Hover Number
120−hoverTimeout = opt "timeout"
121−
122−foreign import data InnerHTML :: Type
123−
124−innerHTMLTimeout :: Option InnerHTML Number
125−innerHTMLTimeout = opt "timeout"
7+import Untagged.Union (UndefinedOr, type (|+|))
8+import Untagged.Coercible (class Coercible, coerce)
9+
10+-- | A "no options" value, defined as `coerce {}`.
11+empty :: forall a. Coercible {} a => a
12+empty = coerce {}
13+
14+type Op a = UndefinedOr a
15+
16+type LaunchOptions =
17+ { headless :: Op Boolean
18+ , executablePath :: Op String
19+ , args :: Op String
20+ , ignoreDefaultArgs :: Op (Array String)
21+ , proxy :: Op ProxyOptions
22+ , downloadsPath :: Op String
23+ , chromiumSandbox :: Op Boolean
24+ , firefoxUserPrefs :: Op Foreign
25+ , handleSIGINT :: Op Boolean
26+ , handleSIGTERM :: Op Boolean
27+ , handleSIGHUP :: Op Boolean
28+ , timeout :: Op Number
29+ , env :: Op (Object String)
30+ , devtools :: Op Boolean
31+ , slowMo :: Op Number
32+ }
33+
34+type ProxyOptions =
35+ { server :: Op String
36+ , bypass :: Op String
37+ , username :: Op String
38+ , password :: Op String
39+ }
40+
41+type ScreenshotOptions =
42+ { path :: Op String
43+ , "type" :: Op ScreenshotType
44+ , quality :: Op Number
45+ , omitBackground :: Op Boolean
46+ , timeout :: Op Number
47+ }
48+
49+type GotoOptions =
50+ { timeout :: Op Int
51+ , waitUntil :: Op WaitUntil
52+ , referer :: Op String
53+ }
54+
55+type NewpageOptions =
56+ { acceptDownloads :: Op Boolean
57+ , ignoreHTTPSErrors :: Op Boolean
58+ , bypassCSP :: Op Boolean
59+ , viewport :: Op (Null |+| { width :: Int, height :: Int })
60+ }
61+
62+type GoOptions =
63+ { timeout :: Op Int
64+ , waitUntil :: Op WaitUntil
65+ }
66+
67+type HoverOptions =
68+ { position :: Op { x :: Number, y :: Number }
69+ , modifier :: Op (Array Modifier)
70+ , force :: Op Boolean
71+ }
72+
73+type InnerHTMLOptions =
74+ { timeout :: Op Number
75+ }
76+
77+type InnerTextOptions =
78+ { timeout :: Op Number
79+ }
test/Main.purs+5−7
@@ -3,10 +3,10 @@ module Test.Main where
33import Prelude
44import Playwright
55import Effect (Effect)
6−import Data.Options ((:=))
76import Test.Unit (suite, test)
87import Test.Unit.Main (runTest)
98import Untagged.Union (asOneOf, fromOneOf)
9+import Untagged.Coercible
1010import Test.Unit.Assert as Assert
1111import Data.Maybe (Maybe(..))
1212
@@ -18,17 +18,15 @@ main :: Effect Unit
1818main = runTest do
1919 suite "browser" do
2020 test "launch" do
21− browser <- launch firefox $
22− headless := false <>
23− slowMo := 100.0
21+ browser <- launch firefox (coerce {})
2422 close $ asOneOf browser
2523 test "textContent" do
26− browser <- launch firefox mempty
27− page <- newPage (asOneOf browser) mempty
24+ browser <- launch firefox (coerce {})
25+ page <- newPage (asOneOf browser) (coerce {})
2826 void $ goto
2927 (asOneOf page)
3028 (static "hello.html")
31− mempty
29+ (coerce {})
3230 text <- textContent (asOneOf page) (Selector "body")
3331 Assert.equal (Just "hello\n") (fromOneOf text)
3432 close $ asOneOf browser