Use untagged-union

This commit is contained in:
Vladimir Kalnitsky 2020-09-12 22:11:56 +03:00
parent 9ad8280f65
commit d35b4e5217
11 changed files with 317 additions and 185 deletions

View File

@ -1,8 +1,8 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20200822/packages.dhall sha256:b4f151f1af4c5cb6bf5437489f4231fbdd92792deaf32971e6bcb0047b3dd1f8
https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20200911-2/packages.dhall sha256:872c06349ed9c8210be43982dc6466c2ca7c5c441129826bcb9bf3672938f16e
let overrides = {=}
let additions = {=}
in upstream ⫽ overrides ⫽ additions
in upstream // overrides // additions

View File

@ -7,6 +7,8 @@
, "aff-promise"
, "options"
, "test-unit"
, "untagged-union"
, "node-buffer"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]

View File

@ -1,180 +1,82 @@
module Playwright
( BrowserType
, Browser
, firefox
, chromium
, webkit
, launch
, LaunchOptions
, headless
, executablePath
, args
, ignoreDefaultArgs
, ProxyOptions
, server
, bypass
, username
, password
, proxy
, downloadsPath
, chromiumSandbox
, firefoxUserPrefs
, handleSIGINT
, handleSIGTERM
, handleSIGHUP
, timeout
, env
, devtools
, slowMo
, class Close
( launch
, contexts
, isConnected
, version
, close
, class NewPage
, newPage
, NewpageOptions
, Frame
, ElementHandle
, Page
, class Query
, query
, queryMany
, module Playwright.Data
, module Playwright.Options
)
where
import Prelude
import Effect (Effect)
import Control.Promise (Promise, toAffE)
import Data.Options (Option, Options, opt, options)
import Control.Promise (toAffE)
import Data.Options (Options, options)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Foreign.Object (Object)
import Untagged.Union (type (|+|))
import Node.Buffer (Buffer)
import Playwright.Data
import Playwright.Options
import Playwright.Internal (prop)
foreign import data BrowserType :: Type
foreign import data Browser :: Type
launch :: BrowserType -> Options Launch -> Aff Browser
launch bt =
options >>>
prop "launch" (\_ -> launch) bt >>>
toAffE
foreign import firefox :: BrowserType
foreign import chromium :: BrowserType
foreign import webkit :: BrowserType
close :: Browser |+| BrowserContext |+| Page -> Aff Unit
close =
prop "close" (\_ -> close) >>> toAffE
foreign import _launch :: BrowserType -> Foreign -> Effect (Promise Browser)
contexts :: Browser -> Effect (Array BrowserContext)
contexts =
prop "contexts" (\_ -> contexts)
launch :: BrowserType -> Options LaunchOptions -> Aff Browser
launch bt opts = toAffE $ _launch bt (options opts)
isConnected :: Browser -> Effect Boolean
isConnected =
prop "isConnected" (\_ -> isConnected)
foreign import data LaunchOptions :: Type
version :: Browser -> Effect String
version =
prop "version" (\_ -> version)
headless :: Option LaunchOptions Boolean
headless = opt "headless"
newPage :: Browser |+| BrowserContext -> Options Newpage -> Aff Page
newPage sth =
options >>>
prop "newPage" (\_ -> newPage) sth >>>
toAffE
executablePath :: Option LaunchOptions String
executablePath = opt "executablePath"
-- | `sth.$(selector)`
query
:: ElementHandle |+| Page |+| Frame
-> Selector
-> Aff ElementHandle
query sth =
toAffE <<< prop "$" (\_ -> query) sth
args :: Option LaunchOptions String
args = opt "args"
-- | `sth.$$(selector)
queryMany
:: ElementHandle |+| Page |+| Frame
-> Selector
-> Aff (Array ElementHandle)
queryMany sth =
toAffE <<< prop "$$" (\_ -> queryMany) sth
ignoreDefaultArgs :: Option LaunchOptions (Array String)
ignoreDefaultArgs = opt "ignoreDefaultArgs"
screenshot
:: ElementHandle |+| Page
-> Options Screenshot
-> Aff Buffer
screenshot sth =
options >>>
prop "screenshot" (\_ -> screenshot) sth >>>
toAffE
foreign import data ProxyOptions :: Type
server :: Option ProxyOptions String
server = opt "server"
bypass :: Option ProxyOptions String
bypass = opt "bypass"
username :: Option ProxyOptions String
username = opt "username"
password :: Option ProxyOptions String
password = opt "password"
proxy :: Option LaunchOptions (Options ProxyOptions)
proxy = opt "proxy"
downloadsPath :: Option LaunchOptions String
downloadsPath = opt "downloadsPath"
chromiumSandbox :: Option LaunchOptions Boolean
chromiumSandbox = opt "chromiumSandbox"
firefoxUserPrefs :: Option LaunchOptions Foreign
firefoxUserPrefs = opt "firefoxUserPrefs"
handleSIGINT :: Option LaunchOptions Boolean
handleSIGINT = opt "handleSIGINT"
handleSIGTERM :: Option LaunchOptions Boolean
handleSIGTERM = opt "handleSIGTERM"
handleSIGHUP :: Option LaunchOptions Boolean
handleSIGHUP = opt "handleSIGHUP"
timeout :: Option LaunchOptions Number
timeout = opt "timeout"
env :: Option LaunchOptions (Object String)
env = opt "env"
devtools :: Option LaunchOptions Boolean
devtools = opt "devtools"
slowMo :: Option LaunchOptions Number
slowMo = opt "slowMo"
class Close sth
instance closeBrowser :: Close Browser
close :: forall sth. Close sth => sth -> Aff Unit
close = toAffE <<< _close
foreign import _close :: forall sth. sth -> Effect (Promise Unit)
foreign import data BrowserContext :: Type
foreign import contexts :: Browser -> Effect (Array BrowserContext)
foreign import isConnected :: Browser -> Effect Boolean
foreign import version :: Browser -> Effect String
foreign import data NewpageOptions :: Type
foreign import data Page :: Type
class NewPage sth
instance newpageBrowser :: NewPage Browser
instance newpageBrowserContext :: NewPage BrowserContext
newPage :: forall sth. NewPage sth => sth -> Options NewpageOptions -> Aff Page
newPage sth opts = toAffE $ _newPage sth (options opts)
foreign import _newPage :: forall sth. sth -> Foreign -> Effect (Promise Page)
foreign import data ElementHandle :: Type
class Query sth
instance queryElementHandle :: Query ElementHandle
instance queryPage :: Query Page
instance queryFrame :: Query Frame
type Selector = String
foreign import data Frame :: Type
foreign import query_ :: forall sth. sth -> Selector -> Effect (Promise ElementHandle)
foreign import queryMany_ :: forall sth. sth -> Selector -> Effect (Promise (Array ElementHandle))
query :: forall sth. Query sth => sth -> Selector -> Aff ElementHandle
query sth = toAffE <<< query_ sth
queryMany :: forall sth. Query sth => sth -> Selector -> Aff (Array ElementHandle)
queryMany sth = toAffE <<< queryMany_ sth
url
:: Page |+| Frame |+| Download |+| Request |+| Response |+| Worker
-> Effect String
url = prop "url" \_ -> url

9
src/Playwright/Data.js Normal file
View File

@ -0,0 +1,9 @@
/* global require exports */
var P = require('playwright');
exports.png = "png";
exports.jpg = "jpg";
exports.chromium = P.chromium;
exports.firefox = P.firefox;
exports.webkit = P.webkit;

36
src/Playwright/Data.purs Normal file
View File

@ -0,0 +1,36 @@
module Playwright.Data where
import Prelude
foreign import data BrowserType :: Type
foreign import data Browser :: Type
foreign import data BrowserContext :: Type
foreign import data Page :: Type
foreign import data Frame :: Type
foreign import data ElementHandle :: Type
foreign import data JSHandle :: Type
foreign import data ConsoleMessage :: Type
foreign import data Dialog :: Type
foreign import data Download :: Type
foreign import data FileChooser :: Type
foreign import data Keyboard :: Type
foreign import data Mouse :: Type
foreign import data Request :: Type
foreign import data Response :: Type
foreign import data Selectors :: Type
foreign import data Route :: Type
foreign import data Worker :: Type
foreign import data ScreenshotType :: Type
foreign import png :: ScreenshotType
foreign import jpg :: ScreenshotType
newtype Selector = Selector String
derive newtype instance eqSelector :: Eq Selector
derive newtype instance showSelector :: Show Selector
derive newtype instance ordSelector :: Ord Selector
foreign import firefox :: BrowserType
foreign import chromium :: BrowserType
foreign import webkit :: BrowserType

View File

@ -1,6 +1,4 @@
/* global require exports */
var P = require('playwright');
/* global exports */
/**
* @param {string} property - method to call on object
@ -36,15 +34,8 @@ function effectfulGetter (property, n) {
};
}
exports.chromium = P.chromium;
exports.firefox = P.firefox;
exports.webkit = P.webkit;
exports._launch = effectfulGetter('launch', 1);
exports._close = effectfulGetter('close', 0);
exports.contexts = effectfulGetter('contexts', 0);
exports.isConnected = effectfulGetter('isConnected', 0);
exports.version = effectfulGetter('version', 0);
exports._newPage = effectfulGetter('newPage', 1);
exports.queryMany_ = effectfulGetter('$$', 1);
exports.query_ = effectfulGetter('$', 1);
exports.unsafeEffectfulGetter = function (prop) {
return function (argsCount) {
return effectfulGetter(prop, argsCount);
};
};

View File

@ -0,0 +1,59 @@
module Playwright.Internal
( class NumberOfArgs
, numberOfArgs
, prop
)
where
import Type.Proxy
import Prelude
class NumberOfArgs x where
numberOfArgs :: Proxy x -> Int
-- More may be added later...
instance numberOfArgsFunction6 :: NumberOfArgs (a -> b -> c -> d -> e -> f -> g) where
numberOfArgs _ = 6
else instance numberOfArgsFunction5 :: NumberOfArgs (a -> b -> c -> d -> e -> f) where
numberOfArgs _ = 5
else instance numberOfArgsFunction4 :: NumberOfArgs (a -> b -> c -> d -> e) where
numberOfArgs _ = 4
else instance numberOfArgsFunction3 :: NumberOfArgs (a -> b -> c -> d) where
numberOfArgs _ = 3
else instance numberOfArgsFunction2 :: NumberOfArgs (a -> b -> c) where
numberOfArgs _ = 2
else instance numberOfArgsFunction1 :: NumberOfArgs (a -> b) where
numberOfArgs _ = 1
else instance numberOfArgsFunction0 :: NumberOfArgs a where
numberOfArgs _ = 0
-- | This function is used to prevent "The value of x is undefined here"
-- | errors.
-- |
-- | E.g.:
-- |
-- | ```purescript
-- | url = unsafeEffectfulGetter "url" (countArgs \_ -> url)
-- | ```
-- |
-- | Thus we can guarantee type safety at least in the number of arguments.
countArgs :: forall a. NumberOfArgs a => (Unit -> a) -> Int
countArgs f = numberOfArgs (proxyOf (f unit)) - 1
where
proxyOf :: forall a. a -> Proxy a
proxyOf _ = Proxy :: Proxy a
foreign import unsafeEffectfulGetter
:: forall r
. String
-> Int
-> r
prop :: forall f r. NumberOfArgs f => String -> (Unit -> f) -> r
prop p f = unsafeEffectfulGetter p (countArgs f)

View File

@ -0,0 +1,43 @@
module Playwright.Logger where
import Prelude
import Effect
import Control.Promise
import Data.Options
import Effect.Aff
import Foreign
import Data.Function.Uncurried
import Data.Op
import Data.Functor.Contravariant
import Prim.Row as Row
import Unsafe.Coerce (unsafeCoerce)
-- foreign import data LoggerOptions :: Type
data Severity = Verbose | Info | Warning | Error
showSeverity :: Severity -> String
showSeverity Verbose = "verbose"
showSeverity Info = "info"
showSeverity Warning = "warning"
showSeverity Error = "error"
-- isEnabled :: Option LoggerOptions (Fn2 String Severity Boolean)
-- isEnabled = opt "isEnabled"
type LoggerOptions =
( log :: String -> Severity -> String -> Array String -> Effect Unit
, isEnabled :: String -> Severity -> Boolean
)
foreign import data Logger :: Type
mkLogger
:: forall o t
. Row.Union o t LoggerOptions
=> { | o }
-> Logger
mkLogger = unsafeCoerce
-- log :: Option LoggerOptions (Fn4 String Severity String (Array String) Unit)
-- log = opt "log"

View File

@ -0,0 +1,85 @@
module Playwright.Options where
import Data.Options (Option, Options, opt, options)
import Playwright.Data
import Foreign.Object (Object)
import Foreign (Foreign)
foreign import data Launch :: Type
foreign import data Proxy :: Type
headless :: Option Launch Boolean
headless = opt "headless"
executablePath :: Option Launch String
executablePath = opt "executablePath"
args :: Option Launch String
args = opt "args"
ignoreDefaultArgs :: Option Launch (Array String)
ignoreDefaultArgs = opt "ignoreDefaultArgs"
proxy :: Option Launch (Options Proxy)
proxy = opt "proxy"
downloadsPath :: Option Launch String
downloadsPath = opt "downloadsPath"
chromiumSandbox :: Option Launch Boolean
chromiumSandbox = opt "chromiumSandbox"
firefoxUserPrefs :: Option Launch Foreign
firefoxUserPrefs = opt "firefoxUserPrefs"
handleSIGINT :: Option Launch Boolean
handleSIGINT = opt "handleSIGINT"
handleSIGTERM :: Option Launch Boolean
handleSIGTERM = opt "handleSIGTERM"
handleSIGHUP :: Option Launch Boolean
handleSIGHUP = opt "handleSIGHUP"
timeout :: Option Launch Number
timeout = opt "timeout"
env :: Option Launch (Object String)
env = opt "env"
devtools :: Option Launch Boolean
devtools = opt "devtools"
slowMo :: Option Launch Number
slowMo = opt "slowMo"
server :: Option Proxy String
server = opt "server"
bypass :: Option Proxy String
bypass = opt "bypass"
username :: Option Proxy String
username = opt "username"
password :: Option Proxy String
password = opt "password"
foreign import data Newpage :: Type
foreign import data Screenshot :: Type
path :: Option Screenshot String
path = opt "path"
screenshotType :: Option Screenshot ScreenshotType
screenshotType = opt "type"
quality :: Option Screenshot Number
quality = opt "quality"
omitBackground :: Option Screenshot Boolean
omitBackground = opt "omitBackground"
screenshotTimeout :: Option Screenshot Number
screenshotTimeout = opt "timeout"

View File

@ -1,13 +1,12 @@
module Test.Main where
import Prelude
import Playwright (close, firefox, headless, launch, slowMo)
import Effect (Effect)
import Effect.Console (log)
import Test.Unit.Assert as Assert
import Playwright
import Data.Options
import Test.Unit
import Test.Unit.Main
import Data.Options ((:=))
import Test.Unit (suite, test)
import Test.Unit.Main (runTest)
import Untagged.Union (asOneOf)
main :: Effect Unit
main = runTest do
@ -16,6 +15,4 @@ main = runTest do
browser <- launch firefox $
headless := false <>
slowMo := 100.0
close browser
pure unit
close $ asOneOf browser

8
test/static/index.html Normal file
View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="someid"></div>
</body>
</html>