@@ -22,20 +22,25 @@ import Effect.Aff.Class (class MonadAff, liftAff)
2222import Effect.Class (liftEffect)
2323import Effect.Ref as Ref
2424import Foreign.Object as FO
25−import Lunapark.ActionF (_lunaparkActions, LUNAPARK_ACTIONS, ActionF(..), TouchF(..))
25+import Lunapark.ActionF (_lunaparkActions, ActionF(..), TouchF(..), ActionsEffect)
2626import Lunapark.Endpoint as LP
2727import Lunapark.Error as LE
28−import Lunapark.LunaparkF (_lunapark, LUNAPARK, ElementF(..), LunaparkF(..), performActions, findElement)
28+import Lunapark.LunaparkF (_lunapark, ElementF(..), LunaparkF(..), LunaparkEffect, performActions, findElement)
2929import Lunapark.Types as LT
30−import Lunapark.Utils (liftAndRethrow, throwLeft, catch)
30+import Lunapark.Utils (liftAndRethrow, rethrowAsJsonDecodeError, catch)
3131import Node.Buffer as B
3232import Node.FS.Aff as FS
33+import Run (Run)
3334import Run as R
3435import Run.Except (EXCEPT)
36+import Type.Row (type (+))
37+import Run.Except as RE
3538
36−newtype Interpreter r = Interpreter (Lunapark r ~> BaseRun r)
39+type Lunapark r a = Run (BaseEffects + LunaparkEffect + ActionsEffect + r) a
3740
38−runInterpreter ∷ ∀ r. Interpreter r → Lunapark r ~> BaseRun r
41+newtype Interpreter r = Interpreter (Run (BaseEffects + LunaparkEffect + ActionsEffect + r) ~> Run (BaseEffects r))
42+
43+runInterpreter ∷ ∀ r. Interpreter r → Run (BaseEffects + LunaparkEffect + ActionsEffect + r) ~> Run (BaseEffects r)
3944runInterpreter (Interpreter f) = f
4045
4146init
@@ -54,7 +59,7 @@ init uri caps = do
5459 let
5560 sessionResponse = do
5661 sessObj ← res
57− lmap LE.unknownError $ LT.decodeCreateSessionResponse sessObj
62+ lmap LE.JsonDecodeError $ LT.decodeCreateSessionResponse sessObj
5863
5964 T.for sessionResponse \{ session, capabilities } → do
6065 timeoutsRef ←
@@ -88,24 +93,24 @@ init uri caps = do
8893interpret
8994 ∷ ∀ r
9095 . HandleLunaparkInput
91− → Lunapark r
92− ~> BaseRun r
96+ → Run (BaseEffects + LunaparkEffect + ActionsEffect + r )
97+ ~> Run (BaseEffects r)
9398interpret input = runLunapark input <<< runLunaparkActions input
9499
95−
96−type Lunapark r = BaseRun (lunapark ∷ LUNAPARK, lunaparkActions ∷ LUNAPARK_ACTIONS|r)
97−
98−type BaseRun r = R.Run
100+type BaseEffects r =
99101 ( except ∷ EXCEPT LE.Error
100102 , aff ∷ R.AFF
101103 , effect ∷ R.EFFECT
102104 | r)
103105
104−runLunapark ∷ ∀ r. HandleLunaparkInput → BaseRun (lunapark ∷ LUNAPARK|r) ~> BaseRun r
106+runLunapark ∷ ∀ r. HandleLunaparkInput → Run (BaseEffects + LunaparkEffect + r) ~> Run (BaseEffects r)
105107runLunapark input = do
106108 R.interpretRec (R.on _lunapark (handleLunapark input) R.send)
107109
108−runLunaparkActions ∷ ∀ r. HandleLunaparkInput → Lunapark r ~> BaseRun (lunapark ∷ LUNAPARK|r)
110+runLunaparkActions
111+ ∷ ∀ r. HandleLunaparkInput
112+ → Run (BaseEffects + LunaparkEffect + ActionsEffect + r )
113+ ~> Run (BaseEffects + LunaparkEffect + r)
109114runLunaparkActions input
110115 | input.actionsEnabled = interpretW3CActions Nil
111116 | otherwise = R.interpretRec (R.on _lunaparkActions (jsonWireActions input) R.send)
@@ -113,8 +118,8 @@ runLunaparkActions input
113118interpretW3CActions
114119 ∷ ∀ r
115120 . List LT.ActionSequence
116− → Lunapark r
117− ~> BaseRun (lunapark ∷ LUNAPARK|r)
121+ → Run (BaseEffects + LunaparkEffect + ActionsEffect + r )
122+ ~> Run (BaseEffects + LunaparkEffect + r )
118123interpretW3CActions acc as = case R.peel as of
119124 Left la → case tag la of
120125 Left a → w3cActions acc interpretW3CActions a
@@ -130,11 +135,11 @@ w3cActions
130135 ∷ ∀ r a
131136 . List LT.ActionSequence
132137 → ( List LT.ActionSequence
133− → Lunapark r
134− ~> BaseRun (lunapark ∷ LUNAPARK|r)
138+ → Run (BaseEffects + LunaparkEffect + ActionsEffect + r )
139+ ~> Run (BaseEffects + LunaparkEffect + r)
135140 )
136− → ActionF (Lunapark r a)
137− → BaseRun (lunapark ∷ LUNAPARK|r) a
141+ → ActionF (Run (BaseEffects + LunaparkEffect + ActionsEffect + r ) a)
142+ → Run (BaseEffects + LunaparkEffect + r) a
138143w3cActions acc loop = case _ of
139144 Click btn next →
140145 let seq = [ LT.pointerDown btn, LT.pointerUp btn ]
@@ -219,7 +224,7 @@ type HandleLunaparkInput =
219224 , actionsEnabled ∷ Boolean
220225 }
221226
222−jsonWireActions ∷ ∀ r. HandleLunaparkInput → ActionF ~> BaseRun (lunapark ∷ LUNAPARK|r)
227+jsonWireActions ∷ ∀ r. HandleLunaparkInput → ActionF ~> Run (BaseEffects + LunaparkEffect + r)
223228jsonWireActions inp = case _ of
224229 Click btn next → do
225230 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
@@ -232,7 +237,7 @@ jsonWireActions inp = case _ of
232237 pure next
233238 DoubleClick btn next → do
234239 _ ← case btn of
235− LT.LeftBtn → post_ (LP.DoubleClick : Nil)
240+ LT.LeftBtn → post' (LP.DoubleClick : Nil)
236241 other → do
237242 _ ← post (LP.Click : Nil) (LT.encodeButton btn)
238243 post (LP.Click : Nil) (LT.encodeButton btn)
@@ -253,16 +258,16 @@ jsonWireActions inp = case _ of
253258 pure next
254259 InTouch tch → case tch of
255260 Tap next → do
256− _ ← post_ (LP.Touch : LP.Click : Nil)
261+ _ ← post' (LP.Touch : LP.Click : Nil)
257262 pure next
258263 TouchDown next → do
259− _ ← post_ (LP.Touch : LP.Down : Nil)
264+ _ ← post' (LP.Touch : LP.Down : Nil)
260265 pure next
261266 TouchUp next → do
262− _ ← post_ (LP.Touch : LP.Up : Nil)
267+ _ ← post' (LP.Touch : LP.Up : Nil)
263268 pure next
264269 LongClick next → do
265− _ ← post_ (LP.Touch : LP.LongClick : Nil)
270+ _ ← post' (LP.Touch : LP.LongClick : Nil)
266271 pure next
267272 Flick move next → do
268273 element ← case move.origin of
@@ -281,23 +286,23 @@ jsonWireActions inp = case _ of
281286 _ ← post (LP.Touch : LP.Scroll : Nil) (LT.encodeMoveToRequest req)
282287 pure next
283288 DoubleTap next → do
284− _ ← post_ (LP.Touch : LP.DoubleClick : Nil)
289+ _ ← post' (LP.Touch : LP.DoubleClick : Nil)
285290 pure next
286291 where
287292 post a b = liftAndRethrow $ LP.post inp.uri (inSession : a) b
288− post_ a = liftAndRethrow $ LP.post_ inp.uri (inSession : a)
293+ post' a = liftAndRethrow $ LP.post' inp.uri (inSession : a)
289294
290295 inSession ∷ LP.EndpointPart
291296 inSession = LP.InSession inp.session
292297
293−handleLunapark ∷ ∀ r. HandleLunaparkInput → LunaparkF ~> BaseRun r
298+handleLunapark ∷ ∀ r. HandleLunaparkInput → LunaparkF ~> Run (BaseEffects r)
294299handleLunapark inp = case _ of
295300 Quit next → do
296301 _ ← delete $ inSession : Nil
297302 pure next
298303 Status cont → do
299304 res ← get $ LP.Status : Nil
300− ss ← throwLeft $ LT.decodeServerStatus res
305+ ss ← rethrowAsJsonDecodeError $ LT.decodeServerStatus res
301306 pure $ cont ss
302307 GetTimeouts cont → do
303308 res ← R.liftEffect $ Ref.read inp.timeoutsRef
@@ -314,31 +319,31 @@ handleLunapark inp = case _ of
314319 pure next
315320 GetUrl cont → do
316321 res ← get $ inSession : LP.Url : Nil
317− map cont $ throwLeft $ J.decodeJson res
322+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
318323 Back next → do
319− _ ← post_ (inSession : LP.Back : Nil)
324+ _ ← post' (inSession : LP.Back : Nil)
320325 pure next
321326 Forward next → do
322− _ ← post_ (inSession : LP.Forward : Nil)
327+ _ ← post' (inSession : LP.Forward : Nil)
323328 pure next
324329 Refresh next → do
325− _ ← post_ (inSession : LP.Refresh : Nil)
330+ _ ← post' (inSession : LP.Refresh : Nil)
326331 pure next
327332 GetTitle cont → do
328333 res ← get (inSession : LP.Title : Nil)
329− map cont $ throwLeft $ J.decodeJson res
334+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
330335 GetWindowHandle cont → do
331336 res ← tryAndCache "get window handle"
332337 [ get (inSession : LP.Window : Nil)
333338 , get (inSession : LP.WindowHandle : Nil)
334339 ]
335− map cont $ throwLeft $ LT.decodeWindowHandle res
340+ map cont $ rethrowAsJsonDecodeError $ LT.decodeWindowHandle res
336341 GetWindowHandles cont → do
337342 res ← tryAndCache "get window handles"
338343 [ get (inSession : LP.Window : LP.Handles : Nil)
339344 , get (inSession : LP.WindowHandles : Nil)
340345 ]
341− map cont $ throwLeft $ T.traverse LT.decodeWindowHandle =<< J.decodeJson res
346+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeWindowHandle =<< J.decodeJson res
342347 CloseWindow next → do
343348 _ ← delete (inSession : LP.Window : Nil)
344349 pure next
@@ -349,15 +354,15 @@ handleLunapark inp = case _ of
349354 _ ← post (inSession : LP.Frame : Nil) (LT.encodeFrameId fid)
350355 pure next
351356 SwitchToParentFrame next → do
352− _ ← post_ (inSession : LP.Frame : LP.Parent : Nil)
357+ _ ← post' (inSession : LP.Frame : LP.Parent : Nil)
353358 pure next
354359 GetWindowRectangle cont → do
355360 res ← tryAndCache "get window rectangle"
356361 [ do res ← get (inSession : LP.Window : LP.Rect : Nil)
357− throwLeft $ LT.decodeRectangle res
362+ rethrowAsJsonDecodeError $ LT.decodeRectangle res
358363 , do position ← get (inSession : LP.Window : LP.Position : Nil)
359364 size ← get (inSession : LP.Window : LP.Size : Nil)
360− throwLeft $ LT.decodeRectangleLegacy { position, size }
365+ rethrowAsJsonDecodeError $ LT.decodeRectangleLegacy { position, size }
361366 ]
362367 pure $ cont res
363368 SetWindowRectangle r next → do
@@ -369,13 +374,13 @@ handleLunapark inp = case _ of
369374 ]
370375 pure next
371376 MaximizeWindow next → do
372− _ ← post_ (inSession : LP.Window : LP.Maximize : Nil)
377+ _ ← post' (inSession : LP.Window : LP.Maximize : Nil)
373378 pure next
374379 MinimizeWindow next → do
375− _ ← post_ (inSession : LP.Window : LP.Minimize : Nil)
380+ _ ← post' (inSession : LP.Window : LP.Minimize : Nil)
376381 pure next
377382 FullscreenWindow next → do
378− _ ← post_ (inSession : LP.Window : LP.Fullscreen : Nil)
383+ _ ← post' (inSession : LP.Window : LP.Fullscreen : Nil)
379384 pure next
380385 ExecuteScript script cont → do
381386 map cont $ tryAndCache "execute script"
@@ -389,10 +394,10 @@ handleLunapark inp = case _ of
389394 ]
390395 GetAllCookies cont → do
391396 res ← get (inSession : LP.Cookies : Nil)
392− map cont $ throwLeft $ T.traverse LT.decodeCookie =<< J.decodeJson res
397+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeCookie =<< J.decodeJson res
393398 GetCookie name cont → do
394399 res ← get (inSession : LP.Cookie name : Nil)
395− map cont $ throwLeft $ LT.decodeCookie res
400+ map cont $ rethrowAsJsonDecodeError $ LT.decodeCookie res
396401 DeleteAllCookies next → do
397402 _ ← delete (inSession : LP.Cookies : Nil)
398403 pure next
@@ -404,14 +409,14 @@ handleLunapark inp = case _ of
404409 pure next
405410 DismissAlert next → do
406411 _ ← tryAndCache "dismiss alert"
407− [ post_ (inSession : LP.Alert : LP.Dismiss : Nil)
408− , post_ (inSession : LP.DismissAlert : Nil)
412+ [ post' (inSession : LP.Alert : LP.Dismiss : Nil)
413+ , post' (inSession : LP.DismissAlert : Nil)
409414 ]
410415 pure next
411416 AcceptAlert next → do
412417 _ ← tryAndCache "accept alert"
413− [ post_ (inSession : LP.Alert : LP.Accept : Nil)
414− , post_ (inSession : LP.AcceptAlert : Nil)
418+ [ post' (inSession : LP.Alert : LP.Accept : Nil)
419+ , post' (inSession : LP.AcceptAlert : Nil)
415420 ]
416421 pure next
417422 GetAlertText cont → do
@@ -419,7 +424,7 @@ handleLunapark inp = case _ of
419424 [ get (inSession : LP.Alert : LP.Text : Nil)
420425 , get (inSession : LP.AlertText : Nil)
421426 ]
422− map cont $ throwLeft $ J.decodeJson res
427+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
423428 SendAlertText str next → do
424429 _ ← tryAndCache "send alert text"
425430 [ post (inSession : LP.Alert : LP.Text : Nil) (LT.encodeSendKeysRequest str)
@@ -428,19 +433,19 @@ handleLunapark inp = case _ of
428433 pure next
429434 Screenshot fp next → do
430435 res ← get (inSession : LP.Screenshot : Nil)
431− screenshotPack ← throwLeft $ LT.decodeScreenshot res
436+ screenshotPack ← rethrowAsJsonDecodeError $ LT.decodeScreenshot res
432437 buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
433438 R.liftAff $ FS.writeFile fp buffer
434439 pure next
435440 FindElement loc cont → do
436441 res ← post (inSession : LP.Element : Nil) (LT.encodeLocator loc)
437− map cont $ throwLeft $ LT.decodeElement res
442+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
438443 FindElements loc cont → do
439444 res ← post (inSession : LP.Elements : Nil) (LT.encodeLocator loc)
440− map cont $ throwLeft $ T.traverse LT.decodeElement =<< J.decodeJson res
445+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeElement =<< J.decodeJson res
441446 GetActiveElement cont → do
442447 res ← get (inSession : LP.Element : LP.Active : Nil)
443− map cont $ throwLeft $ LT.decodeElement res
448+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
444449 PerformActions req next → do
445450 when inp.actionsEnabled
446451 $ void $ post
@@ -455,53 +460,53 @@ handleLunapark inp = case _ of
455460 in case elF of
456461 ChildElement loc cont → do
457462 res ← post (inSession : inElement : LP.Element : Nil) (LT.encodeLocator loc)
458− map cont $ throwLeft $ LT.decodeElement res
463+ map cont $ rethrowAsJsonDecodeError $ LT.decodeElement res
459464 ChildElements loc cont → do
460465 res ← post (inSession : inElement : LP.Elements : Nil) (LT.encodeLocator loc)
461− map cont $ throwLeft $ T.traverse LT.decodeElement =<< J.decodeJson res
466+ map cont $ rethrowAsJsonDecodeError $ T.traverse LT.decodeElement =<< J.decodeJson res
462467 ScreenshotEl fp next → do
463468 res ← get (inSession : inElement : LP.Screenshot : Nil)
464− screenshotPack ← throwLeft $ LT.decodeScreenshot res
469+ screenshotPack ← rethrowAsJsonDecodeError $ LT.decodeScreenshot res
465470 buffer ← R.liftEffect $ B.fromString screenshotPack.content screenshotPack.encoding
466471 R.liftAff $ FS.writeFile fp buffer
467472 pure next
468473 IsSelected cont → do
469474 res ← get (inSession : inElement : LP.Selected : Nil)
470− map cont $ throwLeft $ J.decodeJson res
475+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
471476 GetAttribute attr cont → do
472477 res ← get (inSession : inElement : LP.Attribute attr : Nil)
473− map cont $ throwLeft $ J.decodeJson res
478+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
474479 GetProperty prop cont → do
475480 map cont $ get (inSession : inElement : LP.Property prop : Nil)
476481 GetCss css cont → do
477482 res ← get (inSession : inElement : LP.CssValue css : Nil)
478− map cont $ throwLeft $ J.decodeJson res
483+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
479484 GetText cont → do
480485 res ← get (inSession : inElement : LP.Text : Nil)
481− map cont $ throwLeft $ J.decodeJson res
486+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
482487 GetTagName cont → do
483488 res ← get (inSession : inElement : LP.Name : Nil)
484− map cont $ throwLeft $ J.decodeJson res
489+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
485490 GetRectangle cont →
486491 map cont $ tryAndCache "get element rectangle"
487492 [ do res ← get (inSession : inElement : LP.Rect : Nil)
488− throwLeft $ LT.decodeRectangle res
493+ rethrowAsJsonDecodeError $ LT.decodeRectangle res
489494 , do position ← get (inSession : inElement : LP.Position : Nil)
490495 size ← get (inSession : inElement : LP.Size : Nil)
491− throwLeft $ LT.decodeRectangleLegacy { position, size }
496+ rethrowAsJsonDecodeError $ LT.decodeRectangleLegacy { position, size }
492497 ]
493498 IsEnabled cont → do
494499 res ← get (inSession : inElement : LP.Enabled : Nil)
495− map cont $ throwLeft $ J.decodeJson res
500+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
496501 ClickEl next → do
497502 _ ← tryAndCache "chromedriver75 update clickElement"
498− [ post_ (inSession : inElement : LP.Click : Nil)
503+ [ post' (inSession : inElement : LP.Click : Nil)
499504 , post (inSession : inElement : LP.Click : Nil) $ LT.encodeElement el
500505 ]
501506 pure next
502507 ClearEl next → do
503508 _ ← tryAndCache "chromedriver75 update clearElement"
504− [ post_ (inSession : inElement : LP.Clear : Nil)
509+ [ post' (inSession : inElement : LP.Clear : Nil)
505510 , post (inSession : inElement : LP.Click : Nil) $ LT.encodeElement el
506511 ]
507512 pure next
@@ -521,10 +526,10 @@ handleLunapark inp = case _ of
521526 }
522527 handleLunapark inp $ ExecuteScript script identity
523528 ]
524− map cont $ throwLeft $ J.decodeJson res
529+ map cont $ rethrowAsJsonDecodeError $ J.decodeJson res
525530 Submit next → do
526531 _ ← tryAndCache "chromedriver75 update submit form"
527− [ post_ (inSession : inElement : LP.Submit : Nil)
532+ [ post' (inSession : inElement : LP.Submit : Nil)
528533 , post (inSession: inElement : LP.Submit : Nil) $ LT.encodeElement el
529534 ]
530535 pure next
@@ -533,18 +538,17 @@ handleLunapark inp = case _ of
533538 delete a = liftAndRethrow $ LP.delete inp.uri a
534539 post a b = liftAndRethrow $ LP.post inp.uri a b
535540 get a = liftAndRethrow $ LP.get inp.uri a
536− post_ a = liftAndRethrow $ LP.post_ inp.uri a
541+ post' a = liftAndRethrow $ LP.post' inp.uri a
537542
538− tryAndCache ∷ ∀ a. String → Array (BaseRun r a) → BaseRun r a
543+ -- | It caches an index of an action that is valid for current webdriver implementation.
544+ -- | So you don't need to search correct one by tring them each time
545+ tryAndCache ∷ ∀ a. String → Array (Run (BaseEffects r) a) → Run (BaseEffects r) a
539546 tryAndCache key actions = do
540− let emptyCases = throwLeft $ Left $ "No valid cases for " <> key <> " caching"
541− let incorrectCache = throwLeft $ Left $ "Fallback for " <> key <> " error"
542−
543547 mp ← R.liftEffect $ Ref.read inp.requestMapRef
544548 case Map.lookup key mp of
545549 Just ix → case A.index actions ix of
546550 Just action → action
547− Nothing → incorrectCache
551+ Nothing → RE.throw $ LE.CachingError $ LE.IncorrectCache key
548552 Nothing →
549553 let
550554 go ix acc act =
@@ -554,7 +558,7 @@ handleLunapark inp = case _ of
554558 pure a
555559 in catch try' \_ → acc
556560 in
557− FI.foldlWithIndex go emptyCases actions
561+ FI.foldlWithIndex go (RE.throw $ LE.CachingError $ LE.EmptyCases key) actions
558562
559563 inSession ∷ LP.EndpointPart
560564 inSession = LP.InSession inp.session