webdriver-precore 0.2.0.2 → 0.3.0.2
raw patch · 19 files changed
+519/−142 lines, 19 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- WebDriverPreCore.HTTP.HttpResponse: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.HttpResponse.HttpResponse
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.Actions
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.ElementId
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.Handle
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.SameSite
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.Script
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.Session
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.SessionResponse
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.ShadowRootElementId
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.Status
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Generics.Generic WebDriverPreCore.HTTP.Protocol.WindowRect
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Action
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Actions
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Cookie
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.ElementId
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.FrameReference
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Handle
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.HandleType
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.KeyAction
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Pointer
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.PointerAction
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.PointerOrigin
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.SameSite
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Script
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Selector
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Session
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.SessionResponse
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.ShadowRootElementId
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.Status
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.WheelAction
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.WindowHandleSpec
- WebDriverPreCore.HTTP.Protocol: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.Protocol.WindowRect
- WebDriverPreCore.HTTP.SpecDefinition: instance GHC.Internal.Show.Show WebDriverPreCore.HTTP.SpecDefinition.HttpSpecShowable
- WebDriverPreCore.HTTP.SpecDefinition: instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (WebDriverPreCore.HTTP.SpecDefinition.HttpSpec a)
+ WebDriverPreCore.BiDi.API: browsingContextSetBypassCSP :: SetBypassCSP -> Command ()
+ WebDriverPreCore.BiDi.API: browsingContextStartScreencast :: StartScreencast -> Command StartScreencastResult
+ WebDriverPreCore.BiDi.API: browsingContextStopScreencast :: StopScreencast -> Command StopScreencastResult
+ WebDriverPreCore.BiDi.API: emulationSetScrollbarTypeOverride :: SetScrollbarTypeOverride -> Command ()
+ WebDriverPreCore.BiDi.Protocol: BrowsingContextSetBypassCSP :: KnownCommand
+ WebDriverPreCore.BiDi.Protocol: BrowsingContextStartScreencast :: KnownCommand
+ WebDriverPreCore.BiDi.Protocol: BrowsingContextStopScreencast :: KnownCommand
+ WebDriverPreCore.BiDi.Protocol: Classic :: ScrollbarType
+ WebDriverPreCore.BiDi.Protocol: EmulationSetScrollbarTypeOverride :: KnownCommand
+ WebDriverPreCore.BiDi.Protocol: EnableBypassCSP :: BypassCSPOverride
+ WebDriverPreCore.BiDi.Protocol: ForceDisableScripting :: ScriptingOverride
+ WebDriverPreCore.BiDi.Protocol: MkMediaTrackConstraints :: Maybe JSUInt -> Maybe JSUInt -> Maybe JSUInt -> MediaTrackConstraints
+ WebDriverPreCore.BiDi.Protocol: MkScreencast :: Text -> Screencast
+ WebDriverPreCore.BiDi.Protocol: MkSetBypassCSP :: BypassCSPOverride -> Maybe [BrowsingContext] -> Maybe [UserContext] -> SetBypassCSP
+ WebDriverPreCore.BiDi.Protocol: MkSetScrollbarTypeOverride :: ScrollbarType -> Maybe [BrowsingContext] -> Maybe [UserContext] -> SetScrollbarTypeOverride
+ WebDriverPreCore.BiDi.Protocol: MkStartScreencast :: BrowsingContext -> Maybe Text -> Maybe MediaTrackConstraints -> Maybe Bool -> StartScreencast
+ WebDriverPreCore.BiDi.Protocol: MkStartScreencastResult :: Screencast -> Text -> StartScreencastResult
+ WebDriverPreCore.BiDi.Protocol: MkStopScreencast :: Screencast -> StopScreencast
+ WebDriverPreCore.BiDi.Protocol: MkStopScreencastResult :: Text -> Maybe Text -> StopScreencastResult
+ WebDriverPreCore.BiDi.Protocol: Overlay :: ScrollbarType
+ WebDriverPreCore.BiDi.Protocol: PlatformDefault :: ScrollbarType
+ WebDriverPreCore.BiDi.Protocol: RestoreDefaultBypassCSP :: BypassCSPOverride
+ WebDriverPreCore.BiDi.Protocol: RestoreDefaultScripting :: ScriptingOverride
+ WebDriverPreCore.BiDi.Protocol: [audio] :: StartScreencast -> Maybe Bool
+ WebDriverPreCore.BiDi.Protocol: [bypass] :: SetBypassCSP -> BypassCSPOverride
+ WebDriverPreCore.BiDi.Protocol: [frameRate] :: MediaTrackConstraints -> Maybe JSUInt
+ WebDriverPreCore.BiDi.Protocol: [mimeType] :: StartScreencast -> Maybe Text
+ WebDriverPreCore.BiDi.Protocol: [screencastId] :: Screencast -> Text
+ WebDriverPreCore.BiDi.Protocol: [screencast] :: StopScreencast -> Screencast
+ WebDriverPreCore.BiDi.Protocol: [scrollbarType] :: SetScrollbarTypeOverride -> ScrollbarType
+ WebDriverPreCore.BiDi.Protocol: [video] :: StartScreencast -> Maybe MediaTrackConstraints
+ WebDriverPreCore.BiDi.Protocol: data BypassCSPOverride
+ WebDriverPreCore.BiDi.Protocol: data MediaTrackConstraints
+ WebDriverPreCore.BiDi.Protocol: data ScriptingOverride
+ WebDriverPreCore.BiDi.Protocol: data ScrollbarType
+ WebDriverPreCore.BiDi.Protocol: data SetBypassCSP
+ WebDriverPreCore.BiDi.Protocol: data SetScrollbarTypeOverride
+ WebDriverPreCore.BiDi.Protocol: data StartScreencast
+ WebDriverPreCore.BiDi.Protocol: data StartScreencastResult
+ WebDriverPreCore.BiDi.Protocol: data StopScreencastResult
+ WebDriverPreCore.BiDi.Protocol: newtype Screencast
+ WebDriverPreCore.BiDi.Protocol: newtype StopScreencast
+ WebDriverPreCore.HTTP.HttpResponse: instance GHC.Show.Show WebDriverPreCore.HTTP.HttpResponse.HttpResponse
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.Actions
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.ElementId
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.Handle
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.SameSite
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.Script
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.Session
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.SessionResponse
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.ShadowRootElementId
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.Status
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Generics.Generic WebDriverPreCore.HTTP.Protocol.WindowRect
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Action
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Actions
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Cookie
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.ElementId
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.FrameReference
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Handle
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.HandleType
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.KeyAction
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Pointer
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.PointerAction
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.PointerOrigin
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.SameSite
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Script
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Selector
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Session
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.SessionResponse
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.ShadowRootElementId
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.Status
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.WheelAction
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.WindowHandleSpec
+ WebDriverPreCore.HTTP.Protocol: instance GHC.Show.Show WebDriverPreCore.HTTP.Protocol.WindowRect
+ WebDriverPreCore.HTTP.SpecDefinition: instance GHC.Show.Show WebDriverPreCore.HTTP.SpecDefinition.HttpSpecShowable
+ WebDriverPreCore.HTTP.SpecDefinition: instance GHC.Show.Show a => GHC.Show.Show (WebDriverPreCore.HTTP.SpecDefinition.HttpSpec a)
- WebDriverPreCore.BiDi.Protocol: MkSetScriptingEnabled :: Maybe Bool -> Maybe [BrowsingContext] -> Maybe [UserContext] -> SetScriptingEnabled
+ WebDriverPreCore.BiDi.Protocol: MkSetScriptingEnabled :: ScriptingOverride -> Maybe [BrowsingContext] -> Maybe [UserContext] -> SetScriptingEnabled
- WebDriverPreCore.BiDi.Protocol: [enabled] :: SetScriptingEnabled -> Maybe Bool
+ WebDriverPreCore.BiDi.Protocol: [enabled] :: SetScriptingEnabled -> ScriptingOverride
- WebDriverPreCore.BiDi.Protocol: [partition] :: DeleteCookies -> Maybe PartitionDescriptor
+ WebDriverPreCore.BiDi.Protocol: [partition] :: SetCookie -> Maybe PartitionDescriptor
Files
- ChangeLog.md +31/−0
- README.md +1/−1
- src/WebDriverPreCore/BiDi/API.hs +35/−3
- src/WebDriverPreCore/BiDi/BrowsingContext.hs +93/−0
- src/WebDriverPreCore/BiDi/Command.hs +12/−0
- src/WebDriverPreCore/BiDi/Emulation.hs +51/−1
- src/WebDriverPreCore/Error.hs +1/−1
- src/WebDriverPreCore/HTTP/Capabilities.hs +14/−14
- src/WebDriverPreCore/HTTP/Protocol.hs +17/−17
- src/WebDriverPreCore/HTTP/SpecDefinition.hs +64/−64
- test/ApiCoverageTest.hs +1/−1
- test/BiDi/Actions.hs +14/−0
- test/BiDi/Demos/BrowsingContextDemos.hs +89/−0
- test/BiDi/Demos/EmulationDemos.hs +53/−10
- test/BiDi/Demos/WebExtensionDemos.hs +0/−1
- test/DebugConfig.hs +19/−8
- test/ErrorCoverageTest.hs +1/−1
- test/Test.hs +14/−15
- webdriver-precore.cabal +9/−5
ChangeLog.md view
@@ -1,3 +1,34 @@+# webdriver-precore-0.3.0.2 (2026-07-24)++## HTTP Spec Update++- Spec reference URL updated from 28 October 2025 Working Draft to 02 July 2026 Working Draft.+- No API changes — all HTTP endpoints, capabilities, and types remain identical between versions.++## BiDi Spec Update++Updated to [W3C WebDriver BiDi Working Draft of 29 June 2026](https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/).++### New Commands++- **`browsingContext.setBypassCSP`** — Bypass Content Security Policy restrictions for automated testing.+ - New types: `SetBypassCSP`, `BypassCSPOverride`+- **`browsingContext.startScreencast`** / **`browsingContext.stopScreencast`** — Record browser sessions as video files.+ - New types: `StartScreencast`, `StartScreencastResult`, `StopScreencast`, `StopScreencastResult`, `MediaTrackConstraints`, `Screencast`+- **`emulation.setScrollbarTypeOverride`** — Override scrollbar appearance for consistent cross-platform testing.+ - New types: `SetScrollbarTypeOverride`, `ScrollbarType`++### Breaking Changes+#### Type Changes++- **`SetScriptingEnabled`**: `enabled` field changed from `Maybe Bool` to `ScriptingOverride` for improved type safety (encodes `false` or `null`, not `true`).+ - New type: `ScriptingOverride` with constructors `ForceDisableScripting` and `RestoreDefaultScripting`.++### Other++- Spec reference URLs and dates updated throughout BiDi source files.+- CPP flag `BiDiSpecURL` updated to point to 29 June 2026 Working Draft.+ # webdriver-precore-0.2.0.1 (2026-01-17) ## Breaking Changes
README.md view
@@ -15,7 +15,7 @@ ## What is This Library? -This library provides typed definitions for the W3C WebDriver Protocol, supporting both the [HTTP](https://www.w3.org/TR/2025/WD-webdriver2-20251028/) and the [BiDi](https://www.w3.org/TR/2025/WD-webdriver-bidi-20251212/) protocols.+This library provides typed definitions for the W3C WebDriver Protocol, supporting both the [HTTP](https://www.w3.org/TR/2026/WD-webdriver2-20260702/) and the [BiDi](https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/) protocols. This library is intended as a foundation for building WebDriver client implementations. **It is type constructors only**, and does not include any executable client code.
src/WebDriverPreCore/BiDi/API.hs view
@@ -27,7 +27,10 @@ browsingContextNavigate, browsingContextPrint, browsingContextReload,+ browsingContextSetBypassCSP, browsingContextSetViewport,+ browsingContextStartScreencast,+ browsingContextStopScreencast, browsingContextTraverseHistory, -- * Browser Commands@@ -46,6 +49,7 @@ emulationSetNetworkConditions, emulationSetScreenOrientationOverride, emulationSetScreenSettingsOverride,+ emulationSetScrollbarTypeOverride, emulationSetScriptingEnabled, emulationSetTimezoneOverride, emulationSetTouchOverride,@@ -192,6 +196,11 @@ ResponseStarted, SessionNewResult, SessionStatusResult,+ SetBypassCSP,+ StartScreencast,+ StartScreencastResult,+ StopScreencast,+ StopScreencastResult, SessionSubscibe (..), SessionSubscribeResult (..), SessionUnsubscribe (..),@@ -208,6 +217,7 @@ SetNetworkConditions, SetScreenOrientationOverride, SetScreenSettingsOverride,+ SetScrollbarTypeOverride, SetScriptingEnabled, SetTimezoneOverride, SetTouchOverride,@@ -332,12 +342,30 @@ browsingContextReload :: Reload -> Command () browsingContextReload = mkCommand BrowsingContextReload +-- | Specification Entry: <BiDiSpecURL#command-browsingContext-setBypassCSP browsingContext.setBypassCSP>+--+-- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/#command-browsingContext-setBypassCSP 29 June 2026 - Working Draft>+browsingContextSetBypassCSP :: SetBypassCSP -> Command ()+browsingContextSetBypassCSP = mkCommand BrowsingContextSetBypassCSP+ -- | Specification Entry: <BiDiSpecURL#command-browsingContext-setViewport browsingContext.setViewport> -- -- First added to Spec: <https://www.w3.org/TR/2024/WD-webdriver-bidi-20241121/#command-browsingContext-setViewport 21 November 2024 - First Public Working Draft> browsingContextSetViewport :: SetViewport -> Command () browsingContextSetViewport = mkCommand BrowsingContextSetViewport +-- | Specification Entry: <BiDiSpecURL#command-browsingContext-startScreencast browsingContext.startScreencast>+--+-- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/#command-browsingContext-startScreencast 29 June 2026 - Working Draft>+browsingContextStartScreencast :: StartScreencast -> Command StartScreencastResult+browsingContextStartScreencast = mkCommand BrowsingContextStartScreencast++-- | Specification Entry: <BiDiSpecURL#command-browsingContext-stopScreencast browsingContext.stopScreencast>+--+-- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/#command-browsingContext-stopScreencast 29 June 2026 - Working Draft>+browsingContextStopScreencast :: StopScreencast -> Command StopScreencastResult+browsingContextStopScreencast = mkCommand BrowsingContextStopScreencast+ -- | Specification Entry: <BiDiSpecURL#command-browsingContext-traverseHistory browsingContext.traverseHistory> -- -- First added to Spec: <https://www.w3.org/TR/2024/WD-webdriver-bidi-20241121/#command-browsingContext-traverseHistory 21 November 2024 - First Public Working Draft>@@ -429,7 +457,11 @@ emulationSetScreenSettingsOverride :: SetScreenSettingsOverride -> Command () emulationSetScreenSettingsOverride = mkCommand EmulationSetScreenSettingsOverride --- since 11-08-2025 https://www.w3.org/TR/2025/WD-webdriver-bidi-20250811+-- since 11-08-2025 https://www.w3.org/TR/2025/WD-webdriver-bidi-20250811-- | Specification Entry: <BiDiSpecURL#command-emulation-setScrollbarTypeOverride emulation.setScrollbarTypeOverride>+--+-- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/#command-emulation-setScrollbarTypeOverride 29 June 2026 - Working Draft>+emulationSetScrollbarTypeOverride :: SetScrollbarTypeOverride -> Command ()+emulationSetScrollbarTypeOverride = mkCommand EmulationSetScrollbarTypeOverride -- | Specification Entry: <BiDiSpecURL#command-emulation-setScriptingEnabled emulation.setScriptingEnabled> -- -- First added to Spec: <https://www.w3.org/TR/2025/WD-webdriver-bidi-20250811/#command-emulation-setScriptingEnabled 11 August 2025>@@ -442,10 +474,10 @@ emulationSetTimezoneOverride :: SetTimezoneOverride -> Command () emulationSetTimezoneOverride = mkCommand EmulationSetTimezoneOverride --- since 09-01-2026 https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109+-- since 29-06-2026 https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629 -- | Specification Entry: <BiDiSpecURL#command-emulation-setTouchOverride emulation.setTouchOverride> ----- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109/#command-emulation-setTouchOverride 09 January 2026>+-- First added to Spec: <https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/#command-emulation-setTouchOverride 29 June 2026> emulationSetTouchOverride :: SetTouchOverride -> Command () emulationSetTouchOverride = mkCommand EmulationSetTouchOverride
src/WebDriverPreCore/BiDi/BrowsingContext.hs view
@@ -1,5 +1,6 @@ module WebDriverPreCore.BiDi.BrowsingContext ( Activate (..),+ BypassCSPOverride (..), CaptureScreenshot (..), ScreenShotOrigin (..), ClipRectangle (..),@@ -15,7 +16,10 @@ Orientation (..), PageRange (..), Reload (..),+ SetBypassCSP (..), SetViewport (..),+ StartScreencast (..),+ StopScreencast (..), TraverseHistory (..), MatchType (..), Locator (..),@@ -24,10 +28,14 @@ PrintMargin (..), PrintPage (..), Viewport (..),+ MediaTrackConstraints (..),+ Screencast (..), GetTreeResult (..), LocateNodesResult (..), CaptureScreenshotResult (..), PrintResult (..),+ StartScreencastResult (..),+ StopScreencastResult (..), Info (..), NavigateResult (..), BrowsingContextEvent (..),@@ -272,6 +280,32 @@ toJSON :: Reload -> Value toJSON = toJSONOmitNothing +-- | Bypass CSP override for setBypassCSP command+-- Per spec: bypass can be true or null (not false)+data BypassCSPOverride+ = EnableBypassCSP -- ^ Encode as true - enable CSP bypass+ | RestoreDefaultBypassCSP -- ^ Encode as null - restore to default (don't bypass)+ deriving (Show, Eq, Generic)++instance ToJSON BypassCSPOverride where+ toJSON :: BypassCSPOverride -> Value+ toJSON = \case+ EnableBypassCSP -> Bool True+ RestoreDefaultBypassCSP -> Null++-- | for setBypassCSP command+data SetBypassCSP = MkSetBypassCSP+ { bypass :: BypassCSPOverride,+ contexts :: Maybe [BrowsingContext],+ userContexts :: Maybe [UserContext]+ }+ deriving (Show, Eq, Generic)++instance ToJSON SetBypassCSP where+ toJSON :: SetBypassCSP -> Value+ toJSON MkSetBypassCSP {bypass, contexts, userContexts} =+ object $ ["bypass" .= bypass] <> catMaybes [opt "contexts" contexts, opt "userContexts" userContexts]+ -- | for setViewport command data SetViewport = MkSetViewport { context :: Maybe BrowsingContext,@@ -285,6 +319,45 @@ toJSON :: SetViewport -> Value toJSON = toJSONOmitNothing +-- | for startScreencast command+data StartScreencast = MkStartScreencast+ { context :: BrowsingContext,+ mimeType :: Maybe Text,+ video :: Maybe MediaTrackConstraints,+ audio :: Maybe Bool+ }+ deriving (Show, Eq, Generic)++instance ToJSON StartScreencast where+ toJSON :: StartScreencast -> Value+ toJSON = toJSONOmitNothing++-- | Media track constraints for screencast+data MediaTrackConstraints = MkMediaTrackConstraints+ { width :: Maybe JSUInt,+ height :: Maybe JSUInt,+ frameRate :: Maybe JSUInt+ }+ deriving (Show, Eq, Generic)++instance ToJSON MediaTrackConstraints where+ toJSON :: MediaTrackConstraints -> Value+ toJSON = toJSONOmitNothing++-- | Screencast identifier+newtype Screencast = MkScreencast+ { screencastId :: Text+ }+ deriving newtype (Show, Eq, FromJSON, ToJSON)++-- | for stopScreencast command+newtype StopScreencast = MkStopScreencast+ { screencast :: Screencast+ }+ deriving (Show, Eq, Generic)++instance ToJSON StopScreencast+ -- | for traverseHistory command data TraverseHistory = MkTraverseHistory { context :: BrowsingContext,@@ -453,6 +526,26 @@ instance FromJSON PrintResult where parseJSON :: Value -> Parser PrintResult parseJSON = fmap MkPrintResult . parseTextData "PrintResult"++data StartScreencastResult = MkStartScreencastResult+ { screencast :: Screencast,+ path :: Text+ }+ deriving (Show, Eq, Generic)++instance FromJSON StartScreencastResult where+ parseJSON :: Value -> Parser StartScreencastResult+ parseJSON = parseJSONOmitNothing++data StopScreencastResult = MkStopScreencastResult+ { path :: Text,+ error :: Maybe Text+ }+ deriving (Show, Eq, Generic)++instance FromJSON StopScreencastResult where+ parseJSON :: Value -> Parser StopScreencastResult+ parseJSON = parseJSONOmitNothing data Info = MkInfo { children :: Maybe [Info],
src/WebDriverPreCore/BiDi/Command.hs view
@@ -72,7 +72,10 @@ | BrowsingContextNavigate | BrowsingContextPrint | BrowsingContextReload+ | BrowsingContextSetBypassCSP | BrowsingContextSetViewport+ | BrowsingContextStartScreencast+ | BrowsingContextStopScreencast | BrowsingContextTraverseHistory | EmulationSetForcedColorsModeThemeOverride | EmulationSetGeolocationOverride@@ -80,6 +83,7 @@ | EmulationSetNetworkConditions | EmulationSetScreenOrientationOverride | EmulationSetScreenSettingsOverride+ | EmulationSetScrollbarTypeOverride | EmulationSetScriptingEnabled | EmulationSetTimezoneOverride | EmulationSetTouchOverride@@ -220,7 +224,10 @@ "browsingContext.navigate" -> p BrowsingContextNavigate "browsingContext.print" -> p BrowsingContextPrint "browsingContext.reload" -> p BrowsingContextReload+ "browsingContext.setBypassCSP" -> p BrowsingContextSetBypassCSP "browsingContext.setViewport" -> p BrowsingContextSetViewport+ "browsingContext.startScreencast" -> p BrowsingContextStartScreencast+ "browsingContext.stopScreencast" -> p BrowsingContextStopScreencast "browsingContext.traverseHistory" -> p BrowsingContextTraverseHistory "emulation.setForcedColorsModeThemeOverride" -> p EmulationSetForcedColorsModeThemeOverride "emulation.setGeolocationOverride" -> p EmulationSetGeolocationOverride@@ -228,6 +235,7 @@ "emulation.setNetworkConditions" -> p EmulationSetNetworkConditions "emulation.setScreenOrientationOverride" -> p EmulationSetScreenOrientationOverride "emulation.setScreenSettingsOverride" -> p EmulationSetScreenSettingsOverride+ "emulation.setScrollbarTypeOverride" -> p EmulationSetScrollbarTypeOverride "emulation.setScriptingEnabled" -> p EmulationSetScriptingEnabled "emulation.setTimezoneOverride" -> p EmulationSetTimezoneOverride "emulation.setTouchOverride" -> p EmulationSetTouchOverride@@ -297,7 +305,10 @@ BrowsingContextNavigate -> "browsingContext.navigate" BrowsingContextPrint -> "browsingContext.print" BrowsingContextReload -> "browsingContext.reload"+ BrowsingContextSetBypassCSP -> "browsingContext.setBypassCSP" BrowsingContextSetViewport -> "browsingContext.setViewport"+ BrowsingContextStartScreencast -> "browsingContext.startScreencast"+ BrowsingContextStopScreencast -> "browsingContext.stopScreencast" BrowsingContextTraverseHistory -> "browsingContext.traverseHistory" EmulationSetForcedColorsModeThemeOverride -> "emulation.setForcedColorsModeThemeOverride" EmulationSetGeolocationOverride -> "emulation.setGeolocationOverride"@@ -305,6 +316,7 @@ EmulationSetNetworkConditions -> "emulation.setNetworkConditions" EmulationSetScreenOrientationOverride -> "emulation.setScreenOrientationOverride" EmulationSetScreenSettingsOverride -> "emulation.setScreenSettingsOverride"+ EmulationSetScrollbarTypeOverride -> "emulation.setScrollbarTypeOverride" EmulationSetScriptingEnabled -> "emulation.setScriptingEnabled" EmulationSetTimezoneOverride -> "emulation.setTimezoneOverride" EmulationSetTouchOverride -> "emulation.setTouchOverride"
src/WebDriverPreCore/BiDi/Emulation.hs view
@@ -8,7 +8,10 @@ SetForcedColorsModeThemeOverride (..), SetNetworkConditions (..), SetUserAgentOverride (..),+ ScriptingOverride (..), SetScriptingEnabled (..),+ SetScrollbarTypeOverride (..),+ ScrollbarType (..), GeoProperty (..), GeolocationCoordinates (..), GeolocationPositionError (..),@@ -178,8 +181,22 @@ opt "userContexts" userContexts ] +-- | Scripting override for setScriptingEnabled command+-- Per spec: enabled can be false or null (not true)+data ScriptingOverride+ = ForceDisableScripting -- ^ Encode as false - explicitly disable scripting+ | RestoreDefaultScripting -- ^ Encode as null - restore to initial browser configuration+ deriving (Show, Eq, Generic)++instance ToJSON ScriptingOverride where+ toJSON :: ScriptingOverride -> Value+ toJSON = \case+ ForceDisableScripting -> Bool False+ RestoreDefaultScripting -> Null++-- | for setScriptingEnabled command data SetScriptingEnabled = MkSetScriptingEnabled- { enabled :: Maybe Bool,+ { enabled :: ScriptingOverride, contexts :: Maybe [BrowsingContext], userContexts :: Maybe [UserContext] }@@ -307,3 +324,36 @@ instance ToJSON NetworkConditionsOffline where toJSON :: NetworkConditionsOffline -> Value toJSON _ = object ["type" .= "offline"]++-- | Scrollbar type for emulation.setScrollbarTypeOverride command+-- Per spec: scrollbarType can be "classic" / "overlay" / null+-- Classic and Overlay encode as their string values, PlatformDefault encodes as null+data ScrollbarType+ = Classic -- Always-visible scrollbars (typical on Windows/Linux)+ | Overlay -- Auto-hiding scrollbars (typical on macOS)+ | PlatformDefault -- Restore platform default (encodes as null)+ deriving (Show, Eq, Generic)++instance ToJSON ScrollbarType where+ toJSON :: ScrollbarType -> Value+ toJSON = \case+ Classic -> String "classic"+ Overlay -> String "overlay"+ PlatformDefault -> Null++data SetScrollbarTypeOverride = MkSetScrollbarTypeOverride+ { scrollbarType :: ScrollbarType,+ contexts :: Maybe [BrowsingContext],+ userContexts :: Maybe [UserContext]+ }+ deriving (Show, Eq, Generic)++instance ToJSON SetScrollbarTypeOverride where+ toJSON :: SetScrollbarTypeOverride -> Value+ toJSON MkSetScrollbarTypeOverride {scrollbarType, contexts, userContexts} =+ object $+ ["scrollbarType" .= scrollbarType]+ <> catMaybes+ [ opt "contexts" contexts,+ opt "userContexts" userContexts+ ]
src/WebDriverPreCore/Error.hs view
@@ -59,7 +59,7 @@ -- | Known WevDriver Error Types ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#errors)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#errors) data ErrorType = ElementClickIntercepted | ElementNotInteractable
src/WebDriverPreCore/HTTP/Capabilities.hs view
@@ -54,7 +54,7 @@ import AesonUtils (opt, parseOpt, toJSONOmitNothing, parseJSONOmitNothing) {- references:-- https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities+- https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities - https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities - https://mucsi96.gitbook.io/w3c-webdriver/capabilities@@ -64,7 +64,7 @@ -- | 'FullCapabilities' is the object that is passed to webdriver to define the properties of the session via the 'Spec.newSession' function. -- It is a combination of 'alwaysMatch' and 'firstMatch' properties. ----- [spec](https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) -- -- See also: 'Capabilities' and related constructors such as 'minCapabilities', 'minFullCapabilities', 'minFirefoxCapabilities' and 'minChromeCapabilities' data FullCapabilities = MkFullCapabilities@@ -100,19 +100,19 @@ -- -- It is very common for 'alwaysMatch' to be the only field populated and the 'firstMatch' field to be empty. ----- [spec](https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- [spec](https://https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) alwaysMatchCapabilities :: Capabilities -> FullCapabilities alwaysMatchCapabilities = flip MkFullCapabilities [] . Just -- | Returns the minimal FullCapabilities object for a given browser -- The browserName in the 'alwaysMatch' field is the only field populated--- [spec](https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- [spec](https://https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) minFullCapabilities :: BrowserName -> FullCapabilities minFullCapabilities = alwaysMatchCapabilities . minCapabilities -- | Returns the minimal Capabilities object for a given browser -- The browserName is the only field populated--- [spec](https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- [spec](https://https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) minCapabilities :: BrowserName -> Capabilities minCapabilities browserName = MkCapabilities@@ -140,7 +140,7 @@ -- Custom Types for Enums --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) data UnhandledPromptBehavior = Dismiss | Accept@@ -149,7 +149,7 @@ | Ignore deriving (Show, Generic, Enum, Bounded, Eq) --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) data PageLoadStrategy = None' | Eager@@ -171,7 +171,7 @@ "normal" -> pure Normal _ -> fail "Invalid PageLoadStrategy" --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) data BrowserName = Chrome | Firefox@@ -180,7 +180,7 @@ | InternetExplorer deriving (Show, Generic, Enum, Bounded, Eq) --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) data PlatformName = Windows | Mac@@ -192,7 +192,7 @@ -- | 'Capabilities' define the properties of the session and are passed to the webdriver -- via fields of the 'FullCapabilities' object. ----- [spec](https://https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities)+-- [spec](https://https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities) -- -- See also: 'FullCapabilities' and related constructors such as: 'minCapabilities', -- 'minFullCapabilities', 'minFirefoxCapabilities' and 'minChromeCapabilities'@@ -264,7 +264,7 @@ vendorSpecific <- parseVendorSpecific v pure MkCapabilities {..} --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#proxy)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#proxy) data SocksProxy = MkSocksProxy { socksProxy :: Text, socksVersion :: Int@@ -287,7 +287,7 @@ socksVersion <- v .: "socksVersion" pure MkSocksProxy {..} --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#proxy)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#proxy) data Proxy = Direct | Manual@@ -351,7 +351,7 @@ -- Vendor Capabilities --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#extensions-0)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#extensions-0) data VendorSpecific = -- | Chrome capabilities - [spec](https://developer.chrome.com/docs/chromedriver/capabilities) --@@ -699,7 +699,7 @@ m = parseFieldMaybe o -- | Timeouts in milliseconds--- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#timeouts)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#timeouts) data Timeouts = MkTimeouts { implicit :: Maybe Int, -- field order needs to be the same as FromJSON below pageLoad :: Maybe Int,
src/WebDriverPreCore/HTTP/Protocol.hs view
@@ -113,7 +113,7 @@ import WebDriverPreCore.Internal.HTTPBidiCommon as Url (URL (..)) import Prelude hiding (id) --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-get-window-handle)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-get-window-handle) newtype Handle = MkHandle {handle :: Text} deriving (Show, Eq, Generic) @@ -130,7 +130,7 @@ pure $ MkHandle h v -> fail $ unpack $ "Expected Handle as String or Object with handle property, got: " <> txt v --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#new-window)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#new-window) data WindowHandleSpec = HandleSpec { handle :: Handle, handletype :: HandleType@@ -168,7 +168,7 @@ "tab" -> pure Tab v -> fail $ unpack $ "Unknown HandleType " <> v --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-find-element)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-find-element) newtype ElementId = MkElement {id :: Text} deriving (Show, Eq, Generic) @@ -195,7 +195,7 @@ withObject "ElementId" $ fmap MkShadowRootElementId . (.: shadowRootFieldName) --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-new-sessions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-new-sessions) newtype Session = MkSession {id :: Text} deriving (Show, Eq, Generic) @@ -275,7 +275,7 @@ KM.insert webSocketKey (Bool True) o -- change to Bool _ -> o -- no change if property not present --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-status)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-status) data Status = MkStatus { ready :: Bool, message :: Text@@ -286,7 +286,7 @@ instance FromJSON Status --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#cookies)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#cookies) data SameSite = Lax | Strict@@ -299,7 +299,7 @@ toJSON :: SameSite -> Value toJSON = String . txt --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-switch-to-frame)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-switch-to-frame) data FrameReference = TopLevelFrame | FrameNumber Word16@@ -326,7 +326,7 @@ shadowRootFieldName :: Key shadowRootFieldName = "shadow-6066-11e4-a52e-4f735466cecf" --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#cookies)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#cookies) data Cookie = MkCookie { name :: Text, value :: Text,@@ -370,7 +370,7 @@ opt "expiry" expiry ] --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#locator-strategies)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#locator-strategies) data Selector = CSS Text | XPath Text@@ -390,7 +390,7 @@ where sJSON using value = object ["using" .= using, "value" .= value] --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dfn-get-element-rect)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dfn-get-element-rect) data WindowRect = Rect { x :: Int, y :: Int,@@ -416,7 +416,7 @@ height = floor height } --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) newtype Actions = MkActions {actions :: [Action]} deriving (Show, Eq, Generic) @@ -427,7 +427,7 @@ [ "actions" .= actions ] --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data KeyAction = PauseKey {duration :: Maybe Int} -- ms | KeyDown@@ -458,7 +458,7 @@ -- Pointer subtypes --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data Pointer = Mouse | Pen@@ -472,7 +472,7 @@ toJSON :: Pointer -> Value toJSON = mkLwrTxt --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data PointerOrigin = Viewport | OriginPointer@@ -486,7 +486,7 @@ OriginPointer -> "pointer" OriginElement (MkElement id') -> object ["element" .= id'] --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data Action = NoneAction { id :: Text,@@ -515,7 +515,7 @@ } deriving (Show, Eq) --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data WheelAction = PauseWheel {duration :: Maybe Int} -- ms | Scroll@@ -550,7 +550,7 @@ "deltaY" .= deltaY ] --- | [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#actions)+-- | [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#actions) data PointerAction = PausePointer {duration :: Maybe Int} -- ms | Up
src/WebDriverPreCore/HTTP/SpecDefinition.hs view
@@ -217,7 +217,7 @@ -- ########################### WebDriver API ############################ -- ###################################################################### --- https://www.w3.org/TR/2025/WD-webdriver2-20251028/+-- https://www.w3.org/TR/2026/WD-webdriver2-20260702/ -- 61 endpoints -- Method URI Template Command @@ -228,7 +228,7 @@ -- -- 'newSession'' can be used if 'FullCapabilities' doesn't meet your requirements. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#new-session)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#new-session) -- -- @POST \/session New Session@ newSession :: FullCapabilities -> HttpSpec SessionResponse@@ -241,9 +241,9 @@ -- The 'FullCapabilities' type and associated types should work for the vast majority use cases, but if the required capabilities are not covered by the types provided, 'newSession''. -- can be used with a custom type instead. 'newSession'' works with any type that implements 'ToJSON', (including an Aeson 'Value'). ----- Obviously, any type used must produce a JSON object compatible with [capabilities as defined W3C spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#capabilities).+-- Obviously, any type used must produce a JSON object compatible with [capabilities as defined W3C spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#capabilities). ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#new-session)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#new-session) -- -- @POST \/session New Session@ newSession' :: (ToJSON a) => a -> HttpSpec SessionResponse@@ -253,7 +253,7 @@ -- -- Return a spec to get the status of the driver. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#status)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#status) -- -- @GET \/status Status@ status :: HttpSpec Status@@ -265,7 +265,7 @@ -- -- Return a spec to delete a session given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#delete-session)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#delete-session) -- -- @DELETE \/session\/{session id} Delete Session@ deleteSession :: Session -> HttpSpec ()@@ -275,7 +275,7 @@ -- -- Return a spec to get the timeouts of a session given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-timeouts)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-timeouts) -- -- @GET \/session\/{session id}\/timeouts Get Timeouts@ getTimeouts :: Session -> HttpSpec Timeouts@@ -285,7 +285,7 @@ -- -- Return a spec to set the timeouts of a session given a 'Session' and 'Timeouts'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#set-timeouts)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#set-timeouts) -- -- @POST \/session\/{session id}\/timeouts Set Timeouts@ setTimeouts :: Session -> Timeouts -> HttpSpec ()@@ -296,7 +296,7 @@ -- -- Return a spec to navigate to a URL given a 'Session' and a 'Text' URL. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#navigate-to)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#navigate-to) -- -- @POST \/session\/{session id}\/url Navigate To@ navigateTo :: Session -> URL -> HttpSpec ()@@ -306,7 +306,7 @@ -- -- Return a spec to get the current URL of a session given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-current-url)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-current-url) -- -- @GET \/session\/{session id}\/url Get Current URL@ getCurrentUrl :: Session -> HttpSpec URL@@ -316,7 +316,7 @@ -- -- Return a spec to navigate back in the browser history given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#back)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#back) -- -- @POST \/session\/{session id}\/back Back@ back :: Session -> HttpSpec ()@@ -326,7 +326,7 @@ -- -- Return a spec to navigate forward in the browser history given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#forward)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#forward) -- -- @POST \/session\/{session id}\/forward Forward@ forward :: Session -> HttpSpec ()@@ -336,7 +336,7 @@ -- -- Return a spec to refresh the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#refresh)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#refresh) -- -- @POST \/session\/{session id}\/refresh Refresh@ refresh :: Session -> HttpSpec ()@@ -346,7 +346,7 @@ -- -- Return a spec to get the title of the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-title)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-title) -- -- @GET \/session\/{session id}\/title Get Title@ getTitle :: Session -> HttpSpec Text@@ -356,7 +356,7 @@ -- -- Return a spec to get the current window handle given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-window-handle)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-window-handle) -- -- @GET \/session\/{session id}\/window Get Window Handle@ getWindowHandle :: Session -> HttpSpec Handle@@ -366,7 +366,7 @@ -- -- Return a spec to create a new window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#new-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#new-window) -- -- @POST \/session\/{session id}\/window\/new New Window@ newWindow :: Session -> HttpSpec WindowHandleSpec@@ -376,7 +376,7 @@ -- -- Return a spec to close the current window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#close-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#close-window) -- -- @DELETE \/session\/{session id}\/window Close Window@ closeWindow :: Session -> HttpSpec [Handle]@@ -386,7 +386,7 @@ -- -- Return a spec to switch to a different window given a 'Session' and 'WindowHandle'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#switch-to-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#switch-to-window) -- -- @POST \/session\/{session id}\/window Switch To Window@ switchToWindow :: Session -> Handle -> HttpSpec ()@@ -396,7 +396,7 @@ -- -- Return a spec to switch to a different frame given a 'Session' and 'FrameReference'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#switch-to-frame)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#switch-to-frame) -- -- @POST \/session\/{session id}\/frame Switch To Frame@ switchToFrame :: Session -> FrameReference -> HttpSpec ()@@ -406,7 +406,7 @@ -- -- Return a spec to get the source of the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-page-source)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-page-source) -- -- @GET \/session\/{session id}\/source Get Page Source@ getPageSource :: Session -> HttpSpec Text@@ -416,7 +416,7 @@ -- -- Return a spec to execute a script in the context of the current page given a 'Session', 'Text' script, and a list of 'Value' arguments. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#execute-script)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#execute-script) -- -- @POST \/session\/{session id}\/execute\/sync Execute Script@ executeScript :: Session -> Script -> HttpSpec Value@@ -426,7 +426,7 @@ -- -- Return a spec to execute an asynchronous script in the context of the current page given a 'Session', 'Text' script, and a list of 'Value' arguments. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#execute-async-script)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#execute-async-script) -- -- @POST \/session\/{session id}\/execute\/async Execute Async Script@ executeScriptAsync :: Session -> Script -> HttpSpec Value@@ -436,7 +436,7 @@ -- -- Return a spec to get all cookies of the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-all-cookies)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-all-cookies) -- -- @GET \/session\/{session id}\/cookie Get All Cookies@ getAllCookies :: Session -> HttpSpec [Cookie]@@ -446,7 +446,7 @@ -- -- Return a spec to get a named cookie of the current page given a 'Session' and cookie name. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-named-cookie)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-named-cookie) -- -- @GET \/session\/{session id}\/cookie\/{name} Get Named Cookie@ getNamedCookie :: Session -> Text -> HttpSpec Cookie@@ -456,7 +456,7 @@ -- -- Return a spec to add a cookie to the current page given a 'Session' and 'Cookie'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#add-cookie)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#add-cookie) -- -- @POST \/session\/{session id}\/cookie Add Cookie@ addCookie :: Session -> Cookie -> HttpSpec ()@@ -466,7 +466,7 @@ -- -- Return a spec to delete a named cookie from the current page given a 'Session' and cookie name. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#delete-cookie)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#delete-cookie) -- -- @DELETE \/session\/{session id}\/cookie\/{name} Delete Cookie@ deleteCookie :: Session -> Text -> HttpSpec ()@@ -476,7 +476,7 @@ -- -- Return a spec to delete all cookies from the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#delete-all-cookies)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#delete-all-cookies) -- -- @DELETE \/session\/{session id}\/cookie Delete All Cookies@ deleteAllCookies :: Session -> HttpSpec ()@@ -486,7 +486,7 @@ -- -- Return a spec to perform actions on the current page given a 'Session' and 'Actions'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#perform-actions)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#perform-actions) -- -- @POST \/session\/{session id}\/actions Perform Actions@ performActions :: Session -> Actions -> HttpSpec ()@@ -496,7 +496,7 @@ -- -- Return a spec to release actions on the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#release-actions)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#release-actions) -- -- @DELETE \/session\/{session id}\/actions Release Actions@ releaseActions :: Session -> HttpSpec ()@@ -506,7 +506,7 @@ -- -- Return a spec to dismiss an alert on the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#dismiss-alert)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#dismiss-alert) -- -- @POST \/session\/{session id}\/alert\/dismiss Dismiss Alert@ dismissAlert :: Session -> HttpSpec ()@@ -516,7 +516,7 @@ -- -- Return a spec to accept an alert on the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#accept-alert)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#accept-alert) -- -- @POST \/session\/{session id}\/alert\/accept Accept Alert@ acceptAlert :: Session -> HttpSpec ()@@ -526,7 +526,7 @@ -- -- Return a spec to get the text of an alert on the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-alert-text)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-alert-text) -- -- @GET \/session\/{session id}\/alert\/text Get Alert Text@ getAlertText :: Session -> HttpSpec Text@@ -536,7 +536,7 @@ -- -- Return a spec to send text to an alert on the current page given a 'Session' and 'Text'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#send-alert-text)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#send-alert-text) -- -- @POST \/session\/{session id}\/alert\/text Send Alert Text@ sendAlertText :: Session -> Text -> HttpSpec ()@@ -546,7 +546,7 @@ -- -- Return a spec to take a screenshot of the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#take-screenshot)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#take-screenshot) -- -- @GET \/session\/{session id}\/screenshot Take Screenshot@ takeScreenshot :: Session -> HttpSpec Text@@ -556,7 +556,7 @@ -- -- Return a spec to print the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#print-page)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#print-page) -- -- @POST \/session\/{session id}\/print Print Page@ printPage :: Session -> HttpSpec Text@@ -568,7 +568,7 @@ -- -- Return a spec to get all window handles of the current session given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-window-handles)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-window-handles) -- -- @GET \/session\/{session id}\/window\/handles Get Window Handles@ getWindowHandles :: Session -> HttpSpec [Handle]@@ -578,7 +578,7 @@ -- -- Return a spec to get the window rect of the current window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-window-rect)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-window-rect) -- -- @GET \/session\/{session id}\/window\/rect Get Window Rect@ getWindowRect :: Session -> HttpSpec WindowRect@@ -588,7 +588,7 @@ -- -- Return a spec to set the window rect of the current window given a 'Session' and 'WindowRect'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#set-window-rect)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#set-window-rect) -- -- @POST \/session\/{session id}\/window\/rect Set Window Rect@ setWindowRect :: Session -> WindowRect -> HttpSpec WindowRect@@ -598,7 +598,7 @@ -- -- Return a spec to maximize the current window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#maximize-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#maximize-window) -- -- @POST \/session\/{session id}\/window\/maximize Maximize Window@ maximizeWindow :: Session -> HttpSpec WindowRect@@ -608,7 +608,7 @@ -- -- Return a spec to minimize the current window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#minimize-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#minimize-window) -- -- @POST \/session\/{session id}\/window\/minimize Minimize Window@ minimizeWindow :: Session -> HttpSpec WindowRect@@ -618,7 +618,7 @@ -- -- Return a spec to fullscreen the current window given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#fullscreen-window)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#fullscreen-window) -- -- @POST \/session\/{session id}\/window\/fullscreen Fullscreen Window@ fullscreenWindow :: Session -> HttpSpec WindowRect@@ -630,7 +630,7 @@ -- -- Return a spec to switch to the parent frame given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#switch-to-parent-frame)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#switch-to-parent-frame) -- -- @POST \/session\/{session id}\/frame\/parent Switch To Parent Frame@ switchToParentFrame :: Session -> HttpSpec ()@@ -642,7 +642,7 @@ -- -- Return a spec to get the active element of the current page given a 'Session'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-active-element)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-active-element) -- -- @GET \/session\/{session id}\/element\/active Get Active Element@ getActiveElement :: Session -> HttpSpec ElementId@@ -652,7 +652,7 @@ -- -- Return a spec to find an element on the current page given a 'Session' and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-element)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-element) -- -- @POST \/session\/{session id}\/element Find Element@ findElement :: Session -> Selector -> HttpSpec ElementId@@ -662,7 +662,7 @@ -- -- Return a spec to find elements on the current page given a 'Session' and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-elements)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-elements) -- -- @POST \/session\/{session id}\/elements Find Elements@ findElements :: Session -> Selector -> HttpSpec [ElementId]@@ -674,7 +674,7 @@ -- -- Return a spec to get the shadow root of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-shadow-root)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-shadow-root) -- -- @GET \/session\/{session id}\/element\/{element id}\/shadow Get Element Shadow Root@ getElementShadowRoot :: Session -> ElementId -> HttpSpec ShadowRootElementId@@ -684,7 +684,7 @@ -- -- Return a spec to find an element from another element given a 'Session', 'ElementId', and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-element-from-element)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-element-from-element) -- -- @POST \/session\/{session id}\/element\/{element id}\/element Find Element From Element@ findElementFromElement :: Session -> ElementId -> Selector -> HttpSpec ElementId@@ -694,7 +694,7 @@ -- -- Return a spec to find elements from another element given a 'Session', 'ElementId', and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-elements-from-element)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-elements-from-element) -- -- @POST \/session\/{session id}\/element\/{element id}\/elements Find Elements From Element@ findElementsFromElement :: Session -> ElementId -> Selector -> HttpSpec [ElementId]@@ -704,7 +704,7 @@ -- -- Return a spec to check if an element is selected given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#is-element-selected)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#is-element-selected) -- -- @GET \/session\/{session id}\/element\/{element id}\/selected Is Element Selected@ isElementSelected :: Session -> ElementId -> HttpSpec Bool@@ -714,7 +714,7 @@ -- -- Return a spec to get an attribute of an element given a 'Session', 'ElementId', and attribute name. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-attribute)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-attribute) -- -- @GET \/session\/{session id}\/element\/{element id}\/attribute\/{name} Get Element Attribute@ getElementAttribute :: Session -> ElementId -> Text -> HttpSpec Text@@ -724,7 +724,7 @@ -- -- Return a spec to get a property of an element given a 'Session', 'ElementId', and property name. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-property)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-property) -- -- @GET \/session\/{session id}\/element\/{element id}\/property\/{name} Get Element Property@ getElementProperty :: Session -> ElementId -> Text -> HttpSpec Value@@ -734,7 +734,7 @@ -- -- Return a spec to get the CSS value of an element given a 'Session', 'ElementId', and CSS property name. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-css-value)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-css-value) -- -- @GET \/session\/{session id}\/element\/{element id}\/css\/{property name} Get Element CSS Value@ getElementCssValue :: Session -> ElementId -> Text -> HttpSpec Text@@ -744,7 +744,7 @@ -- -- Return a spec to get the text of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-text)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-text) -- -- @GET \/session\/{session id}\/element\/{element id}\/text Get Element Text@ getElementText :: Session -> ElementId -> HttpSpec Text@@ -754,7 +754,7 @@ -- -- Return a spec to get the tag name of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-tag-name)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-tag-name) -- -- @GET \/session\/{session id}\/element\/{element id}\/name Get Element Tag Name@ getElementTagName :: Session -> ElementId -> HttpSpec Text@@ -764,7 +764,7 @@ -- -- Return a spec to get the rect of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-element-rect)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-element-rect) -- -- @GET \/session\/{session id}\/element\/{element id}\/rect Get Element Rect@ getElementRect :: Session -> ElementId -> HttpSpec WindowRect@@ -774,7 +774,7 @@ -- -- Return a spec to check if an element is enabled given a 'Session' and 'ElementId'. --SAP will foc--- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#is-element-enabled)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#is-element-enabled) -- -- @GET \/session\/{session id}\/element\/{element id}\/enabled Is Element Enabled@ isElementEnabled :: Session -> ElementId -> HttpSpec Bool@@ -784,7 +784,7 @@ -- -- Return a spec to get the computed role of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-computed-role)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-computed-role) -- -- @GET \/session\/{session id}\/element\/{element id}\/computedrole Get Computed Role@ getElementComputedRole :: Session -> ElementId -> HttpSpec Text@@ -794,7 +794,7 @@ -- -- Return a spec to get the computed label of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#get-computed-label)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#get-computed-label) -- -- @GET \/session\/{session id}\/element\/{element id}\/computedlabel Get Computed Label@ getElementComputedLabel :: Session -> ElementId -> HttpSpec Text@@ -804,7 +804,7 @@ -- -- Return a spec to click an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#element-click)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#element-click) -- -- @POST \/session\/{session id}\/element\/{element id}\/click Element Click@ elementClick :: Session -> ElementId -> HttpSpec ()@@ -814,7 +814,7 @@ -- -- Return a spec to clear an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#element-clear)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#element-clear) -- -- @POST \/session\/{session id}\/element\/{element id}\/clear Element Clear@ elementClear :: Session -> ElementId -> HttpSpec ()@@ -824,7 +824,7 @@ -- -- Return a spec to send keys to an element given a 'Session', 'ElementId', and keys to send. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#element-send-keys)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#element-send-keys) -- -- @POST \/session\/{session id}\/element\/{element id}\/value Element Send Keys@ elementSendKeys :: Session -> ElementId -> Text -> HttpSpec ()@@ -834,7 +834,7 @@ -- -- Return a spec to take a screenshot of an element given a 'Session' and 'ElementId'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#take-element-screenshot)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#take-element-screenshot) -- -- @GET \/session\/{session id}\/element\/{element id}\/screenshot Take Element Screenshot@ takeElementScreenshot :: Session -> ElementId -> HttpSpec Text@@ -846,7 +846,7 @@ -- -- Return a spec to find an element from the shadow root given a 'Session', 'ElementId', and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-element-from-shadow-root)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-element-from-shadow-root) -- -- @POST \/session\/{session id}\/shadow\/{shadow id}\/element Find Element From Shadow Root@ findElementFromShadowRoot :: Session -> ShadowRootElementId -> Selector -> HttpSpec ElementId@@ -856,7 +856,7 @@ -- -- Return a spec to find elements from the shadow root given a 'Session', 'ElementId', and 'Selector'. ----- [spec](https://www.w3.org/TR/2025/WD-webdriver2-20251028/#find-elements-from-shadow-root)+-- [spec](https://www.w3.org/TR/2026/WD-webdriver2-20260702/#find-elements-from-shadow-root) -- -- @POST \/session\/{session id}\/shadow\/{shadow id}\/elements Find Elements From Shadow Root@ findElementsFromShadowRoot :: Session -> ShadowRootElementId -> Selector -> HttpSpec [ElementId]
test/ApiCoverageTest.hs view
@@ -25,7 +25,7 @@ {- !! Replace this the endepoints from the spec with every release -https://www.w3.org/TR/2025/WD-webdriver2-20251028/#endpoints- W3C Working Draft 28 October 2025 +https://www.w3.org/TR/2026/WD-webdriver2-20260702/#endpoints- W3C Working Draft 02 July 2026 -} endPointsCopiedFromSpc :: Text endPointsCopiedFromSpc =
test/BiDi/Actions.hs view
@@ -91,6 +91,7 @@ SessionSubscibe (..), SessionSubscribeResult (..), SessionUnsubscribe (..),+ SetBypassCSP, SetCacheBehavior, SetClientWindowState, SetCookie,@@ -104,10 +105,15 @@ SetNetworkConditions, SetScreenOrientationOverride, SetScreenSettingsOverride,+ SetScrollbarTypeOverride, SetScriptingEnabled, SetTimezoneOverride, SetTouchOverride, SetUserAgentOverride,+ StartScreencast,+ StartScreencastResult,+ StopScreencast,+ StopScreencastResult, SetViewport, SubscriptionId (..), TraverseHistory,@@ -143,7 +149,10 @@ browsingContextNavigate :: Navigate -> IO NavigateResult, browsingContextPrint :: Print -> IO PrintResult, browsingContextReload :: Reload -> IO (),+ browsingContextSetBypassCSP :: SetBypassCSP -> IO (), browsingContextSetViewport :: SetViewport -> IO (),+ browsingContextStartScreencast :: StartScreencast -> IO StartScreencastResult,+ browsingContextStopScreencast :: StopScreencast -> IO StopScreencastResult, browsingContextTraverseHistory :: TraverseHistory -> IO (), -- Browser commandssendCommandNoWait socket browserClose :: IO (),@@ -160,6 +169,7 @@ emulationSetNetworkConditions :: SetNetworkConditions -> IO (), emulationSetScreenOrientationOverride :: SetScreenOrientationOverride -> IO (), emulationSetScreenSettingsOverride :: SetScreenSettingsOverride -> IO (),+ emulationSetScrollbarTypeOverride :: SetScrollbarTypeOverride -> IO (), emulationSetScriptingEnabled :: SetScriptingEnabled -> IO (), emulationSetTimezoneOverride :: SetTimezoneOverride -> IO (), emulationSetTouchOverride :: SetTouchOverride -> IO (),@@ -297,7 +307,10 @@ browsingContextNavigate = send . API.browsingContextNavigate, browsingContextPrint = send . API.browsingContextPrint, browsingContextReload = send . API.browsingContextReload,+ browsingContextSetBypassCSP = send . API.browsingContextSetBypassCSP, browsingContextSetViewport = send . API.browsingContextSetViewport,+ browsingContextStartScreencast = send . API.browsingContextStartScreencast,+ browsingContextStopScreencast = send . API.browsingContextStopScreencast, browsingContextTraverseHistory = send . API.browsingContextTraverseHistory, -- Browser commands browserClose = send API.browserClose,@@ -314,6 +327,7 @@ emulationSetNetworkConditions = send . API.emulationSetNetworkConditions, emulationSetScreenOrientationOverride = send . API.emulationSetScreenOrientationOverride, emulationSetScreenSettingsOverride = send . API.emulationSetScreenSettingsOverride,+ emulationSetScrollbarTypeOverride = send . API.emulationSetScrollbarTypeOverride, emulationSetScriptingEnabled = send . API.emulationSetScriptingEnabled, emulationSetTimezoneOverride = send . API.emulationSetTimezoneOverride, emulationSetTouchOverride = send . API.emulationSetTouchOverride,
test/BiDi/Demos/BrowsingContextDemos.hs view
@@ -9,6 +9,7 @@ import TestData (contentPageUrl, framesUrl, loginUrl, navigation1Url, navigation2Url, navigation3Url, navigation4Url, navigation5Url, navigation6Url, nestedFramesUrl, scriptRealmUrl) import WebDriverPreCore.BiDi.Protocol ( Activate (..),+ BypassCSPOverride (..), CaptureScreenshot (..), ClipRectangle (..), Close (..),@@ -27,6 +28,7 @@ LocateNodes (..), LocateNodesResult (..), Locator (..),+ MediaTrackConstraints (..), Navigate (..), NodeRemoteValue (..), Orientation (..),@@ -38,9 +40,14 @@ ReadinessState (..), Reload (..), ScreenShotOrigin (..),+ SetBypassCSP (..), SetViewport (..), SharedId (..), SharedReference (..),+ StartScreencast (..),+ StartScreencastResult (..),+ StopScreencast (..),+ StopScreencastResult (..), Target (..), TraverseHistory (..), Viewport (..),@@ -1016,4 +1023,86 @@ userContexts = Nothing } logShow "Set viewport result - reset to null" setViewportNull+ pause++-- >>> runDemo browsingContextSetBypassCSPDemo+-- *** Exception: BiDIError (ProtocolException {error = UnknownCommand, description = "A command could not be executed because the remote end is not aware of it", message = "Unknown command 'browsingContext.setBypassCSP'.", stacktrace = Nothing, errorData = Nothing, response = Object (fromList [("error",String "unknown command"),("id",Number 2.0),("message",String "Unknown command 'browsingContext.setBypassCSP'."),("type",String "error")])})+browsingContextSetBypassCSPDemo :: BiDiDemo+browsingContextSetBypassCSPDemo =+ demo "Browsing Context - Set Bypass CSP - since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629" action+ where+ action :: DemoActions -> BiDiActions -> IO ()+ action utils@MkDemoActions {..} bidi@MkBiDiActions {..} = do+ bc <- rootContext utils bidi++ logTxt "Test 1: Enable CSP bypass for the browsing context"+ let enableBypass = MkSetBypassCSP+ { bypass = EnableBypassCSP,+ contexts = Just [bc],+ userContexts = Nothing+ }+ browsingContextSetBypassCSP enableBypass+ logTxt "CSP bypass enabled - test infrastructure can now inject scripts"+ pause++ logTxt "Test 2: Restore default CSP enforcement"+ let restoreCSP = MkSetBypassCSP+ { bypass = RestoreDefaultBypassCSP,+ contexts = Just [bc],+ userContexts = Nothing+ }+ browsingContextSetBypassCSP restoreCSP+ logTxt "CSP enforcement restored to default"+ pause++-- >>> runDemo browsingContextScreencastDemo+-- *** Exception: BiDIError (ProtocolException {error = UnknownCommand, description = "A command could not be executed because the remote end is not aware of it", message = "Unknown command 'browsingContext.startScreencast'.", stacktrace = Nothing, errorData = Nothing, response = Object (fromList [("error",String "unknown command"),("id",Number 3.0),("message",String "Unknown command 'browsingContext.startScreencast'."),("type",String "error")])})+browsingContextScreencastDemo :: BiDiDemo+browsingContextScreencastDemo =+ demo "Browsing Context - Start and Stop Screencast - since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629" action+ where+ action :: DemoActions -> BiDiActions -> IO ()+ action utils@MkDemoActions {..} bidi@MkBiDiActions {..} = do+ bc <- rootContext utils bidi++ contentPage <- contentPageUrl+ logTxt "Navigate to content page for screencast recording"+ navResult <- browsingContextNavigate $ MkNavigate {context = bc, url = contentPage, wait = Just Complete}+ logShow "Navigation result" navResult+ pause++ logTxt "Test 1: Start screencast with default settings"+ let screencastParams = MkStartScreencast+ { context = bc,+ mimeType = Nothing,+ video = Nothing,+ audio = Nothing+ }+ MkStartScreencastResult {screencast = screencastId1, path = path1} <- browsingContextStartScreencast screencastParams+ logShow "Screencast started - default settings" (screencastId1, path1)+ pause++ logTxt "Stop screencast and retrieve recording"+ MkStopScreencastResult {path = stopPath1, error = stopError1} <- browsingContextStopScreencast $ MkStopScreencast {screencast = screencastId1}+ logShow "Screencast stopped" (stopPath1, stopError1)+ pause++ logTxt "Test 2: Start screencast with custom video constraints"+ let customScreencast = MkStartScreencast+ { context = bc,+ mimeType = Just "video/webm",+ video = Just $ MkMediaTrackConstraints+ { width = Just $ MkJSUInt 1280,+ height = Just $ MkJSUInt 720,+ frameRate = Just $ MkJSUInt 30+ },+ audio = Just True+ }+ MkStartScreencastResult {screencast = screencastId2, path = path2} <- browsingContextStartScreencast customScreencast+ logShow "Screencast started - 1280x720@30fps with audio" (screencastId2, path2)+ pause++ logTxt "Stop custom screencast"+ MkStopScreencastResult {path = stopPath2, error = stopError2} <- browsingContextStopScreencast $ MkStopScreencast {screencast = screencastId2}+ logShow "Custom screencast stopped" (stopPath2, stopError2) pause
test/BiDi/Demos/EmulationDemos.hs view
@@ -11,12 +11,15 @@ NetworkConditions (..), ScreenArea (..), ScreenOrientationOverride (..),+ ScrollbarType (..), SetForcedColorsModeThemeOverride (..), SetGeolocationOverride (..), SetLocaleOverride (..), SetNetworkConditions (..), SetScreenOrientationOverride (..), SetScreenSettingsOverride (..),+ SetScrollbarTypeOverride (..),+ ScriptingOverride (..), SetScriptingEnabled (..), SetTimezoneOverride (..), SetTouchOverride (..),@@ -84,7 +87,7 @@ logTxt "Set geolocation position error" let positionError = MkGeolocationPositionError { errorType = "positionUnavailable" }- let errorOverride = MkSetGeolocationOverride+ errorOverride = MkSetGeolocationOverride { override = PositionError positionError, contexts = Just [bc], userContexts = Nothing@@ -326,7 +329,7 @@ -- >>> runDemo emulationSetTouchOverrideDemo emulationSetTouchOverrideDemo :: BiDiDemo emulationSetTouchOverrideDemo =- demo "Emulation - Set Touch Override - since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109" action+ demo "Emulation - Set Touch Override - since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629" action where action :: DemoActions -> BiDiActions -> IO () action utils@MkDemoActions {..} bidi@MkBiDiActions {..} = do@@ -649,22 +652,62 @@ action utils@MkDemoActions {..} bidi@MkBiDiActions {..} = do bc <- rootContext utils bidi - logTxt "Test 1: Disable JavaScript"+ logTxt "Test 1: Force disable JavaScript" let disableJS = MkSetScriptingEnabled- { enabled = Just False,+ { enabled = ForceDisableScripting, contexts = Just [bc], userContexts = Nothing } result1 <- emulationSetScriptingEnabled disableJS- logShow "JavaScript disabled" result1+ logShow "JavaScript forcibly disabled" result1 pause - logTxt "Test 2: Re-enable JavaScript (clear override)"- let enableJS = MkSetScriptingEnabled- { enabled = Nothing,+ logTxt "Test 2: Restore default JavaScript state (clear override)"+ let restoreJS = MkSetScriptingEnabled+ { enabled = RestoreDefaultScripting, contexts = Just [bc], userContexts = Nothing }- result2 <- emulationSetScriptingEnabled enableJS- logShow "JavaScript re-enabled" result2+ result2 <- emulationSetScriptingEnabled restoreJS+ logShow "JavaScript restored to initial browser configuration" result2+ pause++-- >>> runDemo emulationSetScrollbarTypeOverrideDemo+-- *** Exception: BiDIError (ProtocolException {error = UnknownCommand, description = "A command could not be executed because the remote end is not aware of it", message = "Unknown command 'emulation.setScrollbarTypeOverride'.", stacktrace = Nothing, errorData = Nothing, response = Object (fromList [("error",String "unknown command"),("id",Number 2.0),("message",String "Unknown command 'emulation.setScrollbarTypeOverride'."),("type",String "error")])})+emulationSetScrollbarTypeOverrideDemo :: BiDiDemo+emulationSetScrollbarTypeOverrideDemo =+ demo "Emulation - Set Scrollbar Type Override - since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629" action+ where+ action :: DemoActions -> BiDiActions -> IO ()+ action utils@MkDemoActions {..} bidi@MkBiDiActions {..} = do+ bc <- rootContext utils bidi++ logTxt "Test 1: Set scrollbar type to classic (always-visible)"+ let classicScrollbar = MkSetScrollbarTypeOverride+ { scrollbarType = Classic,+ contexts = Just [bc],+ userContexts = Nothing+ }+ emulationSetScrollbarTypeOverride classicScrollbar+ logTxt "Scrollbar type set to classic - always-visible (Windows/Linux style)"+ pause++ logTxt "Test 2: Set scrollbar type to overlay (auto-hiding)"+ let overlayScrollbar = MkSetScrollbarTypeOverride+ { scrollbarType = Overlay,+ contexts = Just [bc],+ userContexts = Nothing+ }+ emulationSetScrollbarTypeOverride overlayScrollbar+ logTxt "Scrollbar type set to overlay - auto-hiding (macOS style)"+ pause++ logTxt "Test 3: Restore platform default scrollbar type"+ let platformDefault = MkSetScrollbarTypeOverride+ { scrollbarType = PlatformDefault,+ contexts = Just [bc],+ userContexts = Nothing+ }+ emulationSetScrollbarTypeOverride platformDefault+ logTxt "Scrollbar type restored to platform default" pause
test/BiDi/Demos/WebExtensionDemos.hs view
@@ -18,7 +18,6 @@ _stopDemoUnusedWarning = runDemo -- >>> runDemo webExtensionInstallPathDemo--- *** Exception: BiDIError (ProtocolException {error = UnknownError, description = "An unknown error occurred in the remote end while processing the command", message = "Method not available.", stacktrace = Just "Error\n at new UnknownErrorException (<anonymous>:65:5630)\n at CommandProcessor.processCommand (<anonymous>:485:13324)", errorData = Nothing, response = Object (fromList [("error",String "unknown error"),("id",Number 1.0),("message",String "Method not available."),("stacktrace",String "Error\n at new UnknownErrorException (<anonymous>:65:5630)\n at CommandProcessor.processCommand (<anonymous>:485:13324)"),("type",String "error")])}) webExtensionInstallPathDemo :: BiDiDemo webExtensionInstallPathDemo = demo "WebExtension - Install from Path" action
test/DebugConfig.hs view
@@ -3,22 +3,29 @@ ) where +import Data.Text (Text) import Config ( Config (..), DemoBrowser (..), )-import Data.Text (Text)+import Const (Timeout, seconds) +_sec :: Timeout+_sec = seconds+ debugConfig :: Config-debugConfig = +debugConfig = --- -- _firefoxSilent- -- _chromeSilent++ -- _chromeDebug -- _firefoxHeadlessLogging+ -- _firefoxDebug+ -- _firefoxSilent+ _chromeSilent -- _chromeHeadlessLogging- _firefoxDebug- -- _chromeDebug+ -- _firefoxDebugNoPause + _firefoxSilent :: Config _firefoxSilent = MkConfig@@ -46,9 +53,14 @@ logging = True, httpUrl = "127.0.0.1", httpPort = 4444,- pauseMS = 0+ pauseMS = 1_000 } +_firefoxDebugNoPause :: Config+_firefoxDebugNoPause =+ _firefoxDebug {pauseMS = 0}++ _chromeSilent :: Config _chromeSilent = MkConfig@@ -81,4 +93,3 @@ profilePath :: Maybe Text profilePath = Just "/home/john-walker/test-firefox-profile"-
test/ErrorCoverageTest.hs view
@@ -17,7 +17,7 @@ {- !! Replace this the endepoints from the spec with every release !! remove full stops and replace tabs with " | " -https://www.w3.org/TR/2025/WD-webdriver2-20251028 - W3C Editor's Draft 10 February 2025 +https://www.w3.org/TR/2026/WD-webdriver2-20260702 - W3C Working Draft 02 July 2026 61 endpoints Error Code HTTP Status JSON Error Code Description NOTE: This entry is moved out because it is duplicated, with a slightly different description in the BiDi spec
test/Test.hs view
@@ -202,15 +202,12 @@ [ Browser.browserGetClientWindowsDemo, Browser.browserCreateUserContextDemo, Browser.browserGetUserContextsDemo,- unknownCommand [Firefox', Chrome']- Browser.browserSetClientWindowStateDemo,+ Browser.browserSetClientWindowStateDemo, Browser.browserRemoveUserContextDemo, Browser.browserCompleteWorkflowDemo, expectFail [Firefox'] "Closing the browser in a session started with WebDriver classic is not supported" Browser.browserCloseDemo,- unknownCommand [Firefox']- -- since https://www.w3.org/TR/2025/WD-webdriver-bidi-20250918/#command-browser-seProtocolExceptiontDownloadBehavior Browser.browserSetDownloadBehaviorDemo ], run@@ -225,6 +222,12 @@ BrowsingContext.browsingContextContextLocatorDemo, BrowsingContext.browsingContextPrintDemo, BrowsingContext.browsingContextSetViewportDemo,+ unknownCommand [Firefox', Chrome']+ -- since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629+ BrowsingContext.browsingContextSetBypassCSPDemo,+ unknownCommand [Firefox', Chrome']+ -- since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629+ BrowsingContext.browsingContextScreencastDemo, BiDiError.errorDemo -- TODO: WHEN NEW DRIVERS ADDED make conditional - hangs in firefox -- , BrowsingContext.browsingContextSetViewportResetDemo@@ -241,19 +244,17 @@ "Expected \\\\\\\"coordinates\\\\\\\" to be an object" Emulation.emulationSetGeolocationOverridePositionErrorDemo, Emulation.emulationSetLocaleOverrideDemo,- unknownCommand [Firefox']- -- since https://www.w3.org/TR/2025/WD-webdriver-bidi-20251007- Emulation.emulationSetNetworkConditionsDemo,+ Emulation.emulationSetNetworkConditionsDemo, Emulation.emulationSetScreenOrientationOverrideDemo,- unknownCommand [Chrome']- -- since https://www.w3.org/TR/2025/WD-webdriver-bidi-20251120- Emulation.emulationSetScreenSettingsOverrideDemo,+ Emulation.emulationSetScreenSettingsOverrideDemo, unknownCommand [Firefox'] -- since https://www.w3.org/TR/2025/WD-webdriver-bidi-20250811 Emulation.emulationSetScriptingEnabledDemo,- Emulation.emulationSetTimezoneOverrideDemo, unknownCommand [Firefox', Chrome']- -- since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109+ -- since https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629+ Emulation.emulationSetScrollbarTypeOverrideDemo,+ Emulation.emulationSetTimezoneOverrideDemo,+ unknownCommand [Firefox'] Emulation.emulationSetTouchOverrideDemo, Emulation.emulationSetUserAgentOverrideDemo, Emulation.emulationCompleteWorkflowDemo@@ -356,9 +357,7 @@ run "WebExtension" [ -- ChromeDriver doesn't support BiDi WebExtension methods- expectFail [Chrome']- "Method not available"- WebExtension.webExtensionInstallPathDemo,+ WebExtension.webExtensionInstallPathDemo, expectFail [Chrome'] "Archived and Base64 extensions are not supported" WebExtension.webExtensionInstallArchiveDemo,
webdriver-precore.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: webdriver-precore-version: 0.2.0.2+version: 0.3.0.2 homepage: https://github.com/pyrethrum/webdriver-precore#readme bug-reports: https://github.com/pyrethrum/webdriver-precore/issues author: John Walker, Adrian Glouftsis@@ -16,12 +16,12 @@ README.md ChangeLog.md -tested-with: GHC == 9.8.2 || == 9.8.4 || == 9.10.1+tested-with: GHC == 9.8.2 || == 9.8.4 || == 9.10.1 || == 9.12.4 synopsis: A typed wrapper for W3C WebDriver (HTTP and BiDi) protocols. description:- This library provides typed definitions for the WebDriver W3C spec, both @<https://www.w3.org/TR/2025/WD-webdriver2-20251028/ HTTP>@ and @<https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109/ BiDi>@.+ This library provides typed definitions for the WebDriver W3C spec, both @<https://www.w3.org/TR/2026/WD-webdriver2-20260702/ HTTP>@ and @<https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/ BiDi>@. It is designed as a foundation for building WebDriver client libraries providing type-safe endpoint definitions and response parsers without any client implementation. @@ -30,6 +30,10 @@ __For complete documentation, module organisation, and migration guides, see "WebDriverPreCore".__ See also the @<https://github.com/pyrethrum/webdriver project repo>@ and the test directory for @<https://github.com/pyrethrum/webdriver/tree/main/webdriver-precore/test#readme examples>@.++source-repository head+ type: git+ location: https://github.com/pyrethrum/webdriver-precore.git common commonExtensions default-extensions:@@ -103,8 +107,8 @@ -fbyte-code-and-object-code -- -fdefer-type-errors cpp-options: - -DHTMLSpecURL=https://www.w3.org/TR/2025/WD-webdriver2-20251028/- -DBiDiSpecURL=https://www.w3.org/TR/2026/WD-webdriver-bidi-20260109/+ -DHTMLSpecURL=https://www.w3.org/TR/2026/WD-webdriver2-20260702/+ -DBiDiSpecURL=https://www.w3.org/TR/2026/WD-webdriver-bidi-20260629/ library utils-internal import: commonExtensions, commonGhcOptions