diff --git a/common/bidi/schema.json b/common/bidi/schema.json index bb30134189c0f..b73ac955b2372 100644 --- a/common/bidi/schema.json +++ b/common/bidi/schema.json @@ -1729,6 +1729,7 @@ "unknown error", "unsupported operation" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-errorcode" }, "SessionCommand": { @@ -2131,6 +2132,7 @@ "dismiss", "ignore" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-session-UserPromptHandlerType" }, "session.Subscription": { @@ -3561,6 +3563,7 @@ "interactive", "complete" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-browsingContext-ReadinessState" }, "browsingContext.UserPromptType": { @@ -3571,6 +3574,7 @@ "confirm", "prompt" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-browsingContext-UserPromptType" }, "browsingContext.Activate": { @@ -3905,6 +3909,7 @@ "tab", "window" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-browsingcontextcreatetype" }, "browsingContext.CreateParameters": { @@ -5671,6 +5676,7 @@ "light", "dark" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationforcedcolorsmodetheme" }, "emulation.SetForcedColorsModeThemeOverrideResult": { @@ -5952,35 +5958,271 @@ "inbound": false }, "emulation.MediaFeatures": { - "kind": "alias", - "type": { - "list": { - "ref": "emulation.MediaFeature" - } - }, - "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationmediafeatures" - }, - "emulation.MediaFeature": { "kind": "record", "fields": [ { - "name": "name", - "wire": "name", - "required": true, + "name": "anyHover", + "wire": "any-hover", + "required": false, "type": { - "primitive": "string" + "ref": "emulation.MediaFeaturesAnyHover", + "nullable": true } }, { - "name": "value", - "wire": "value", - "required": true, + "name": "anyPointer", + "wire": "any-pointer", + "required": false, "type": { - "primitive": "string" + "ref": "emulation.MediaFeaturesAnyPointer", + "nullable": true + } + }, + { + "name": "color", + "wire": "color", + "required": false, + "type": { + "ref": "js-uint", + "nullable": true + } + }, + { + "name": "colorGamut", + "wire": "color-gamut", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesColorGamut", + "nullable": true + } + }, + { + "name": "colorIndex", + "wire": "color-index", + "required": false, + "type": { + "ref": "js-uint", + "nullable": true + } + }, + { + "name": "displayMode", + "wire": "display-mode", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesDisplayMode", + "nullable": true + } + }, + { + "name": "dynamicRange", + "wire": "dynamic-range", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesDynamicRange", + "nullable": true + } + }, + { + "name": "environmentBlending", + "wire": "environment-blending", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesEnvironmentBlending", + "nullable": true + } + }, + { + "name": "forcedColors", + "wire": "forced-colors", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesForcedColors", + "nullable": true + } + }, + { + "name": "grid", + "wire": "grid", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesGrid", + "nullable": true + } + }, + { + "name": "horizontalViewportSegments", + "wire": "horizontal-viewport-segments", + "required": false, + "type": { + "ref": "js-uint", + "nullable": true + } + }, + { + "name": "hover", + "wire": "hover", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesHover", + "nullable": true + } + }, + { + "name": "invertedColors", + "wire": "inverted-colors", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesInvertedColors", + "nullable": true + } + }, + { + "name": "monochrome", + "wire": "monochrome", + "required": false, + "type": { + "ref": "js-uint", + "nullable": true + } + }, + { + "name": "navControls", + "wire": "nav-controls", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesNavControls", + "nullable": true + } + }, + { + "name": "overflowBlock", + "wire": "overflow-block", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesOverflowBlock", + "nullable": true + } + }, + { + "name": "overflowInline", + "wire": "overflow-inline", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesOverflowInline", + "nullable": true + } + }, + { + "name": "pointer", + "wire": "pointer", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPointer", + "nullable": true + } + }, + { + "name": "prefersColorScheme", + "wire": "prefers-color-scheme", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPrefersColorScheme", + "nullable": true + } + }, + { + "name": "prefersContrast", + "wire": "prefers-contrast", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPrefersContrast", + "nullable": true + } + }, + { + "name": "prefersReducedData", + "wire": "prefers-reduced-data", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPrefersReducedData", + "nullable": true + } + }, + { + "name": "prefersReducedMotion", + "wire": "prefers-reduced-motion", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPrefersReducedMotion", + "nullable": true + } + }, + { + "name": "prefersReducedTransparency", + "wire": "prefers-reduced-transparency", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesPrefersReducedTransparency", + "nullable": true + } + }, + { + "name": "scan", + "wire": "scan", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesScan", + "nullable": true + } + }, + { + "name": "scripting", + "wire": "scripting", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesScripting", + "nullable": true + } + }, + { + "name": "update", + "wire": "update", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesUpdate", + "nullable": true + } + }, + { + "name": "verticalViewportSegments", + "wire": "vertical-viewport-segments", + "required": false, + "type": { + "ref": "js-uint", + "nullable": true + } + }, + { + "name": "videoColorGamut", + "wire": "video-color-gamut", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesVideoColorGamut", + "nullable": true + } + }, + { + "name": "videoDynamicRange", + "wire": "video-dynamic-range", + "required": false, + "type": { + "ref": "emulation.MediaFeaturesVideoDynamicRange", + "nullable": true } } ], - "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationmediafeature", + "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationmediafeatures", "outbound": true, "inbound": false }, @@ -6204,6 +6446,7 @@ "portrait", "landscape" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationscreenorientationnatural" }, "emulation.ScreenOrientationType": { @@ -6214,6 +6457,7 @@ "landscape-primary", "landscape-secondary" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-emulationscreenorientationtype" }, "emulation.ScreenOrientation": { @@ -7052,6 +7296,7 @@ "values": [ "blob" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-network-CollectorType" }, "network.SameSite": { @@ -7062,6 +7307,7 @@ "none", "default" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-networksamesite" }, "network.Cookie": { @@ -7175,6 +7421,7 @@ "request", "response" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-network-dataType" }, "network.FetchTimingInfo": { @@ -7942,6 +8189,7 @@ "responseStarted", "authRequired" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-networkinterceptphase" }, "network.AddInterceptResult": { @@ -9938,6 +10186,7 @@ "Infinity", "-Infinity" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-scriptspecialnumber" }, "script.NumberValue": { @@ -10400,6 +10649,7 @@ "audio-worklet", "worklet" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-script-RealmType" }, "script.RemoteReference": { @@ -11479,6 +11729,7 @@ "root", "none" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#type-script-ResultOwnership" }, "script.SerializationOptions": { @@ -12769,6 +13020,7 @@ "warn", "error" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-loglevel" }, "log.Entry": { @@ -13371,6 +13623,7 @@ "pen", "touch" ], + "primitive": "string", "specHref": "https://w3c.github.io/webdriver-bidi/#cddl-type-inputpointertype" }, "input.PointerParameters": { @@ -14354,7 +14607,8 @@ "granted", "denied", "prompt" - ] + ], + "primitive": "string" }, "permissions.setPermission": { "kind": "record", @@ -14434,6 +14688,7 @@ "success", "failure" ], + "primitive": "string", "specHref": "https://wicg.github.io/nav-speculation/prefetch.html#cddl-type-speculationpreloadingstatus" }, "SpeculationEvent": { @@ -16058,6 +16313,7 @@ "minimized", "normal" ], + "primitive": "string", "synthetic": true, "owner": "browser.ClientWindowInfo", "label": "State" @@ -16069,6 +16325,7 @@ "maximized", "minimized" ], + "primitive": "string", "synthetic": true, "owner": "browser.SetClientWindowStateParameters_ClientWindowNamedState", "label": "State" @@ -16079,6 +16336,7 @@ "full", "partial" ], + "primitive": "string", "synthetic": true, "owner": "browsingContext.InnerTextLocator", "label": "MatchType" @@ -16089,6 +16347,7 @@ "viewport", "document" ], + "primitive": "string", "synthetic": true, "owner": "browsingContext.CaptureScreenshotParameters", "label": "Origin" @@ -16099,16 +16358,296 @@ "portrait", "landscape" ], + "primitive": "string", "synthetic": true, "owner": "browsingContext.PrintParameters", "label": "Orientation" }, + "emulation.MediaFeaturesAnyHover": { + "kind": "enum", + "values": [ + "none", + "hover" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "AnyHover" + }, + "emulation.MediaFeaturesAnyPointer": { + "kind": "enum", + "values": [ + "none", + "coarse", + "fine" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "AnyPointer" + }, + "emulation.MediaFeaturesColorGamut": { + "kind": "enum", + "values": [ + "srgb", + "p3", + "rec2020" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "ColorGamut" + }, + "emulation.MediaFeaturesDisplayMode": { + "kind": "enum", + "values": [ + "fullscreen", + "standalone", + "minimal-ui", + "browser", + "picture-in-picture" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "DisplayMode" + }, + "emulation.MediaFeaturesDynamicRange": { + "kind": "enum", + "values": [ + "standard", + "high" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "DynamicRange" + }, + "emulation.MediaFeaturesEnvironmentBlending": { + "kind": "enum", + "values": [ + "opaque", + "additive", + "subtractive" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "EnvironmentBlending" + }, + "emulation.MediaFeaturesForcedColors": { + "kind": "enum", + "values": [ + "none", + "active" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "ForcedColors" + }, + "emulation.MediaFeaturesGrid": { + "kind": "enum", + "values": [ + 0, + 1 + ], + "primitive": "integer", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Grid" + }, + "emulation.MediaFeaturesHover": { + "kind": "enum", + "values": [ + "none", + "hover" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Hover" + }, + "emulation.MediaFeaturesInvertedColors": { + "kind": "enum", + "values": [ + "none", + "inverted" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "InvertedColors" + }, + "emulation.MediaFeaturesNavControls": { + "kind": "enum", + "values": [ + "none", + "back" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "NavControls" + }, + "emulation.MediaFeaturesOverflowBlock": { + "kind": "enum", + "values": [ + "none", + "scroll", + "optional-paged", + "paged" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "OverflowBlock" + }, + "emulation.MediaFeaturesOverflowInline": { + "kind": "enum", + "values": [ + "none", + "scroll" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "OverflowInline" + }, + "emulation.MediaFeaturesPointer": { + "kind": "enum", + "values": [ + "none", + "coarse", + "fine" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Pointer" + }, + "emulation.MediaFeaturesPrefersColorScheme": { + "kind": "enum", + "values": [ + "light", + "dark" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "PrefersColorScheme" + }, + "emulation.MediaFeaturesPrefersContrast": { + "kind": "enum", + "values": [ + "no-preference", + "more", + "less", + "custom" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "PrefersContrast" + }, + "emulation.MediaFeaturesPrefersReducedData": { + "kind": "enum", + "values": [ + "no-preference", + "reduce" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "PrefersReducedData" + }, + "emulation.MediaFeaturesPrefersReducedMotion": { + "kind": "enum", + "values": [ + "no-preference", + "reduce" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "PrefersReducedMotion" + }, + "emulation.MediaFeaturesPrefersReducedTransparency": { + "kind": "enum", + "values": [ + "no-preference", + "reduce" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "PrefersReducedTransparency" + }, + "emulation.MediaFeaturesScan": { + "kind": "enum", + "values": [ + "interlace", + "progressive" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Scan" + }, + "emulation.MediaFeaturesScripting": { + "kind": "enum", + "values": [ + "none", + "initial-only", + "enabled" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Scripting" + }, + "emulation.MediaFeaturesUpdate": { + "kind": "enum", + "values": [ + "none", + "slow", + "fast" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "Update" + }, + "emulation.MediaFeaturesVideoColorGamut": { + "kind": "enum", + "values": [ + "srgb", + "p3", + "rec2020" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "VideoColorGamut" + }, + "emulation.MediaFeaturesVideoDynamicRange": { + "kind": "enum", + "values": [ + "standard", + "high" + ], + "primitive": "string", + "synthetic": true, + "owner": "emulation.MediaFeatures", + "label": "VideoDynamicRange" + }, "emulation.SetScrollbarTypeOverrideParametersScrollbarType": { "kind": "enum", "values": [ "classic", "overlay" ], + "primitive": "string", "synthetic": true, "owner": "emulation.SetScrollbarTypeOverrideParameters", "label": "ScrollbarType" @@ -16121,6 +16660,7 @@ "preflight", "other" ], + "primitive": "string", "synthetic": true, "owner": "network.Initiator", "label": "Type" @@ -16131,6 +16671,7 @@ "default", "cancel" ], + "primitive": "string", "synthetic": true, "owner": "network.ContinueWithAuthParameters_NoCredentials", "label": "Action" @@ -16141,6 +16682,7 @@ "default", "bypass" ], + "primitive": "string", "synthetic": true, "owner": "network.SetCacheBehaviorParameters", "label": "CacheBehavior" @@ -16151,6 +16693,7 @@ "open", "closed" ], + "primitive": "string", "synthetic": true, "owner": "script.NodeProperties", "label": "Mode" @@ -16162,6 +16705,7 @@ "open", "all" ], + "primitive": "string", "synthetic": true, "owner": "script.SerializationOptions", "label": "IncludeShadowTree" @@ -16173,6 +16717,7 @@ "powered-off", "powered-on" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateAdapterParameters", "label": "State" @@ -16183,6 +16728,7 @@ "add", "remove" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateServiceParameters", "label": "Type" @@ -16193,6 +16739,7 @@ "add", "remove" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateCharacteristicParameters", "label": "Type" @@ -16205,6 +16752,7 @@ "subscribe-to-notifications", "unsubscribe-from-notifications" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateCharacteristicResponseParameters", "label": "Type" @@ -16215,6 +16763,7 @@ "add", "remove" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateDescriptorParameters", "label": "Type" @@ -16225,6 +16774,7 @@ "read", "write" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.SimulateDescriptorResponseParameters", "label": "Type" @@ -16238,6 +16788,7 @@ "subscribe-to-notifications", "unsubscribe-from-notifications" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.CharacteristicEventGeneratedParameters", "label": "Type" @@ -16248,6 +16799,7 @@ "read", "write" ], + "primitive": "string", "synthetic": true, "owner": "bluetooth.DescriptorEventGeneratedParameters", "label": "Type" diff --git a/common/webref_cddl.bzl b/common/webref_cddl.bzl index 27c8cdc9642e9..297628ecb7631 100644 --- a/common/webref_cddl.bzl +++ b/common/webref_cddl.bzl @@ -5,7 +5,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") # Pinned to a single w3c/webref "main" commit (kept on main so pin-to-pin diffs # stay auditable) and regenerated by the //scripts:update_cddl Bazel target: # https://github.com/w3c/webref/tree/main/ed/cddl -_COMMIT = "f6229ab7d17cf855385c98919a671c5a6ca37341" +_COMMIT = "5e914258243bbca0ccbfe184bdc62eb82d53c6b7" _BASE_URL = "https://raw.githubusercontent.com/w3c/webref/{commit}/ed/cddl".format(commit = _COMMIT) # The webref "definitions index" for each spec (same commit, so it stays in lockstep @@ -21,8 +21,8 @@ _DFNS_BASE_URL = "https://raw.githubusercontent.com/w3c/webref/{commit}/ed/dfns" # step runs extract_bidi_anchors.mjs over it to build the prose-anchor index. This is a # separate repo/branch from the webref pin above, so //scripts:update_cddl repins it to # gh-pages' own tip; both track the same editor's draft, within a day of each other. -_BIDI_SPEC_HTML_COMMIT = "afa9413adb1f11da188d0cb4af19ce84d596ec19" -_BIDI_SPEC_HTML_SHA256 = "9c731584b1eb856b343cc0d05f450f80cbb2e802ad4af6b92a5224accc3b20e0" +_BIDI_SPEC_HTML_COMMIT = "975a118c247b6f0e0b64f8093b5f01238423bab1" +_BIDI_SPEC_HTML_SHA256 = "ddfc94f2d7692a3da189c997cb3e88388044b661d2459e68cf7a977a11807446" _BIDI_SPEC_HTML_URL = "https://raw.githubusercontent.com/w3c/webdriver-bidi/{commit}/index.html".format( commit = _BIDI_SPEC_HTML_COMMIT, ) @@ -41,7 +41,7 @@ _CDDL_FILES = [ ("prefetch_all_cddl", "prefetch-all.cddl", "51409b998176a81f681252f8ee16bea5a54a3be9d1cfee9f13ca34efd1feb5ea"), ("ua_client_hints_all_cddl", "ua-client-hints-all.cddl", "6bb41f05d09c755305226b7350970e54f6404698510ea2e1e7a931eaa2647aeb"), ("web_bluetooth_all_cddl", "web-bluetooth-all.cddl", "bc687d19c1e92cf4f0a37bbf7f9aa21db956344b34d8cdda4319b7f4615b6d1d"), - ("webdriver_bidi_all_cddl", "webdriver-bidi-all.cddl", "912e70e34c48e02ef871756b020b1d370189c88574f356021b7cb5b5cfd7ab98"), + ("webdriver_bidi_all_cddl", "webdriver-bidi-all.cddl", "ddc307a435c508bdccdaef3c7869187f5f91fe48510162b099a4daabff2dbfc0"), ] def webref_cddl(): @@ -59,7 +59,7 @@ def webref_cddl(): # and referenced as @//file:dfns.json. Only the specs merged into the BiDi # schema (see the javascript/ and py/ BUILD merge lists) need one. _DFNS_FILES = [ - ("webdriver_bidi_dfns", "webdriver-bidi.json", "f57dc9eb577551478b0c6449009dd6fa8d635dfa025ec8f62a1921709aa9ecee"), + ("webdriver_bidi_dfns", "webdriver-bidi.json", "80823455873e25af598e6d5a6b616dc84f96b2649d5623b962092df596fcd090"), ("permissions_dfns", "permissions.json", "bc5d2907c61e2548c6fc4a42a32c86396b56a68033c62299c4d563db510c105f"), ("prefetch_dfns", "prefetch.json", "b647ef493f8f09a6266c2269c344b16b28344bd14b2b987d660df01ce5833433"), ("ua_client_hints_dfns", "ua-client-hints.json", "56a31bf6fd2ba03158500498d14742f8edd7a2d560580b4aa7f4a703977e40cf"), diff --git a/javascript/selenium-webdriver/project_bidi_schema.mjs b/javascript/selenium-webdriver/project_bidi_schema.mjs index a5cfffcd00796..31a0d5428f5d5 100644 --- a/javascript/selenium-webdriver/project_bidi_schema.mjs +++ b/javascript/selenium-webdriver/project_bidi_schema.mjs @@ -22,7 +22,7 @@ * straight mapping into a small vocabulary: * * type node: { kind: 'record', fields: [field], map?, extensible?, specHref? } - * | { kind: 'enum', values: [string], specHref? } + * | { kind: 'enum', values: [scalar], primitive?, specHref? } * | { kind: 'union', variants: [ref], selector, objectOnly?, specHref? } * | { kind: 'alias', type, specHref? } * selector: { by, variants: [{ value, ref }], default? } // discriminated @@ -216,17 +216,32 @@ function projectEntry(e) { return { primitive: PRIMITIVES[e.Type] ?? 'unknown' } } +// A wire key that is already an identifier is kept verbatim, so `namespaceURI` stays +// wire-faithful; a quoted CDDL key that is not (`prefers-color-scheme`) is camelCased so +// every binding derives an identifier from `name` without re-solving punctuation itself. +const IDENTIFIER = /^[A-Za-z][A-Za-z0-9]*$/ + +function fieldName(wire) { + if (IDENTIFIER.test(wire)) return wire + const [head, ...rest] = wire.split(/[^A-Za-z0-9]+/).filter(Boolean) + if (!head) return wire + return head + rest.map((part) => part[0].toUpperCase() + part.slice(1)).join('') +} + function projectField(prop) { + // A vendor-prefixed key (moz:allowPrivateBrowsing) keeps its wire form: extractVendor + // routes it out of the shared types, and the vendor pipeline drops the namespace itself. + const vendor = prop['x-selenium-vendor'] const field = { - name: prop.Name, + name: vendor ? prop.Name : fieldName(prop.Name), wire: prop.Name, required: (prop.Occurrence?.n ?? 1) >= 1, type: projectRef(prop.Type), } // Provenance stamped by a vendor overlay (generate_bidi.mjs). Carried on the field so // extractVendor can route it out of the shared schema; stripped there before it ships. - if (prop['x-selenium-vendor']) { - field.vendor = prop['x-selenium-vendor'] + if (vendor) { + field.vendor = vendor field.via = prop['x-selenium-vendor-via'] } return field @@ -252,7 +267,14 @@ function unionMemberRefs(def) { function projectType(def) { if (def.Type === 'variable') { const pt = def.PropertyType ?? [] - if (pt.length && pt.every(isLiteral)) return { kind: 'enum', values: pt.map((e) => e.Value) } + if (pt.length && pt.every(isLiteral)) { + // Carry the literals' shared primitive so every binding reads the value type + // rather than re-deriving it from the JSON values (which arrive differently typed + // per language). Matches what enumNode does for an un-hoisted inline choice. + const values = pt.map((e) => e.Value) + const primitive = literalPrimitive(values) + return primitive ? { kind: 'enum', values, primitive } : { kind: 'enum', values } + } // A union of refs is a union even when some arms are inline groups wrapping a // ref (e.g. script.LocalValue's date/regexp arms): projectRef resolves those to // refs, so promote the all-ref result to a first-class union (it gets a selector) @@ -792,7 +814,16 @@ export function checkSchema(schema) { for (const [name, node] of Object.entries(schema.types)) { if (node.synthetic && !has(node.owner)) errors.push(`${name}: synthetic owner ${node.owner} does not resolve`) if (node.kind === 'record') { - for (const f of node.fields) report(`${name}.${f.name}`, f.type) + const wireByName = new Map() + for (const f of node.fields) { + report(`${name}.${f.name}`, f.type) + // Two wire keys that camelCase to one name would collapse into a single + // attribute downstream, silently keeping whichever the binding wrote last. + const prior = wireByName.get(f.name) + if (prior !== undefined && prior !== f.wire) + errors.push(`${name}: wire keys ${prior} and ${f.wire} both project to field name ${f.name}`) + wireByName.set(f.name, f.wire) + } if (node.map) report(`${name}.*`, node.map) } else if (node.kind === 'union') { for (const v of node.variants) if (!has(v)) errors.push(`${name}: unresolved variant ${v}`) diff --git a/javascript/selenium-webdriver/project_bidi_schema_test.mjs b/javascript/selenium-webdriver/project_bidi_schema_test.mjs index 03f543e382292..d837ec17463fe 100644 --- a/javascript/selenium-webdriver/project_bidi_schema_test.mjs +++ b/javascript/selenium-webdriver/project_bidi_schema_test.mjs @@ -64,6 +64,7 @@ describe('projectSchema', () => { assert.deepEqual(schema.types['network.SetCacheBehaviorParametersCacheBehavior'], { kind: 'enum', values: ['default', 'bypass'], + primitive: 'string', synthetic: true, owner: 'network.SetCacheBehaviorParameters', label: 'CacheBehavior', @@ -73,6 +74,27 @@ describe('projectSchema', () => { }) }) + it('tags a numeric enum with its value primitive, so a binding reads the type rather than deriving it', () => { + const ast = [group('x.T', [field('grid', [lit(0), lit(1)])])] + const [, def] = Object.entries(projectSchema(ast, {}).types).find(([, t]) => t.kind === 'enum') + assert.deepEqual(def.values, [0, 1]) + assert.equal(def.primitive, 'integer') + }) + + it('camelCases a quoted wire key into an identifier, keeping the wire name exact', () => { + const ast = [group('x.T', [field('prefers-color-scheme', ['text'], { n: 0, m: 1 })])] + const [f] = projectSchema(ast, {}).types['x.T'].fields + assert.equal(f.name, 'prefersColorScheme') + assert.equal(f.wire, 'prefers-color-scheme') + }) + + it('leaves a wire key that is already an identifier verbatim (namespaceURI is not mangled)', () => { + const ast = [group('x.T', [field('namespaceURI', ['text'])])] + const [f] = projectSchema(ast, {}).types['x.T'].fields + assert.equal(f.name, 'namespaceURI') + assert.equal(f.wire, 'namespaceURI') + }) + it('hoists an inline record so the field is a plain ref (no inline records), tagged with its origin', () => { assert.deepEqual(schema.types['session.Caps'].fields[0].type, { ref: 'session.CapsExtra' }) const extra = schema.types['session.CapsExtra'] @@ -772,6 +794,26 @@ describe('checkSchema (referential integrity)', () => { assert.deepEqual(checkSchema(schema), ['x.T.a: unresolved type x.Missing']) }) + it('flags two wire keys projecting to one field name', () => { + const schema = { + schemaVersion: 1, + commands: [], + events: [], + types: { + 'x.T': { + kind: 'record', + fields: [ + { name: 'colorGamut', wire: 'colorGamut', required: false, type: { primitive: 'string' } }, + { name: 'colorGamut', wire: 'color-gamut', required: false, type: { primitive: 'string' } }, + ], + }, + }, + } + assert.deepEqual(checkSchema(schema), [ + 'x.T: wire keys colorGamut and color-gamut both project to field name colorGamut', + ]) + }) + it('catches an unresolved ref inside an alias', () => { const schema = { schemaVersion: 1, diff --git a/py/generate_bidi_protocol.py b/py/generate_bidi_protocol.py index 7579891da0d02..843e7766c653f 100644 --- a/py/generate_bidi_protocol.py +++ b/py/generate_bidi_protocol.py @@ -69,6 +69,11 @@ _RESERVED_FIELDS = {"as_json", "from_json", "extensions"} +# The Enum mixin for a schema enum's declared value primitive. A primitive with no +# mixin (bool cannot be subclassed) gets a plain Enum: the runtime serializes through +# `.value`, so the member keeps its real type either way. +_ENUM_MIXINS = {"string": "str", "integer": "int", "number": "float"} + # --------------------------------------------------------------------------- # # Naming helpers @@ -188,6 +193,7 @@ class EnumIR: class_name: str schema_name: str members: list[tuple[str, Any]] + primitive: str | None = None spec_href: str | None = None @@ -301,7 +307,11 @@ def enums_for(self, domain: str) -> list[EnumIR]: members = [(enum_member(v), v) for v in type_["values"]] out.append( EnumIR( - class_name=type_class_name(name), schema_name=name, members=members, spec_href=type_.get("specHref") + class_name=type_class_name(name), + schema_name=name, + members=members, + primitive=type_.get("primitive"), + spec_href=type_.get("specHref"), ) ) return out @@ -837,7 +847,9 @@ def _spec_docstring(name: str, spec_href: str | None) -> list[str]: def _emit_enum(e: EnumIR) -> str: - lines = [f"@register({lit(e.schema_name)})", f"class {e.class_name}(str, Enum):"] + mixin = _ENUM_MIXINS.get(e.primitive) + bases = f"{mixin}, Enum" if mixin else "Enum" + lines = [f"@register({lit(e.schema_name)})", f"class {e.class_name}({bases}):"] lines += _spec_docstring(e.schema_name, e.spec_href) for member, value in e.members: lines.append(f" {member} = {lit(value)}") diff --git a/py/selenium/webdriver/common/_bidi/serialization.py b/py/selenium/webdriver/common/_bidi/serialization.py index 38fbcf62cd859..84d251da857eb 100644 --- a/py/selenium/webdriver/common/_bidi/serialization.py +++ b/py/selenium/webdriver/common/_bidi/serialization.py @@ -248,8 +248,12 @@ def _validate_enum(self, name: str, w: _Wire, value: Any) -> None: if isinstance(item, enum_cls): continue try: - enum_cls(item) + member = enum_cls(item) except ValueError: + member = None + # bool is a subclass of int, so each resolves to the other's member and would + # then serialize as the wrong JSON type: True as a number, or 1 as a boolean. + if member is None or (type(item) is bool) != (type(member.value) is bool): raise BiDiSerializationError( f"{type(self).__name__}.{name}: {item!r} is not a valid {enum_cls.__name__}" ) from None @@ -405,9 +409,14 @@ def _read_scalar(cls: type, name: str, w: _Wire, raw: Any) -> Any: if w.enum is not None: enum_cls = resolve(w.enum) try: - return enum_cls(raw) + member = enum_cls(raw) except ValueError: + member = None + # Same bool/int exclusion the primitive checks make: True would otherwise resolve + # to an int-valued member, and 1 to a boolean one. + if member is None or (type(raw) is bool) != (type(member.value) is bool): raise BiDiSerializationError(f"{cls.__name__}.{name}: {raw!r} is not a valid {enum_cls.__name__}") from None + return member if w.ref is not None: klass = resolve(w.ref) # A record must arrive as an object; a union may legitimately be a bare scalar diff --git a/rb/lib/selenium/webdriver/bidi/protocol/emulation.rb b/rb/lib/selenium/webdriver/bidi/protocol/emulation.rb index c4ff877f7818d..640eba53b3a99 100644 --- a/rb/lib/selenium/webdriver/bidi/protocol/emulation.rb +++ b/rb/lib/selenium/webdriver/bidi/protocol/emulation.rb @@ -48,6 +48,140 @@ class Emulation < Domain landscape_secondary: 'landscape-secondary' }.freeze + MEDIA_FEATURES_ANY_HOVER = { + none: 'none', + hover: 'hover' + }.freeze + + MEDIA_FEATURES_ANY_POINTER = { + none: 'none', + coarse: 'coarse', + fine: 'fine' + }.freeze + + MEDIA_FEATURES_COLOR_GAMUT = { + srgb: 'srgb', + p3: 'p3', + rec2020: 'rec2020' + }.freeze + + MEDIA_FEATURES_DISPLAY_MODE = { + fullscreen: 'fullscreen', + standalone: 'standalone', + minimal_ui: 'minimal-ui', + browser: 'browser', + picture_in_picture: 'picture-in-picture' + }.freeze + + MEDIA_FEATURES_DYNAMIC_RANGE = { + standard: 'standard', + high: 'high' + }.freeze + + MEDIA_FEATURES_ENVIRONMENT_BLENDING = { + opaque: 'opaque', + additive: 'additive', + subtractive: 'subtractive' + }.freeze + + MEDIA_FEATURES_FORCED_COLORS = { + none: 'none', + active: 'active' + }.freeze + + MEDIA_FEATURES_GRID = { + _0: 0, + _1: 1 + }.freeze + + MEDIA_FEATURES_HOVER = { + none: 'none', + hover: 'hover' + }.freeze + + MEDIA_FEATURES_INVERTED_COLORS = { + none: 'none', + inverted: 'inverted' + }.freeze + + MEDIA_FEATURES_NAV_CONTROLS = { + none: 'none', + back: 'back' + }.freeze + + MEDIA_FEATURES_OVERFLOW_BLOCK = { + none: 'none', + scroll: 'scroll', + optional_paged: 'optional-paged', + paged: 'paged' + }.freeze + + MEDIA_FEATURES_OVERFLOW_INLINE = { + none: 'none', + scroll: 'scroll' + }.freeze + + MEDIA_FEATURES_POINTER = { + none: 'none', + coarse: 'coarse', + fine: 'fine' + }.freeze + + MEDIA_FEATURES_PREFERS_COLOR_SCHEME = { + light: 'light', + dark: 'dark' + }.freeze + + MEDIA_FEATURES_PREFERS_CONTRAST = { + no_preference: 'no-preference', + more: 'more', + less: 'less', + custom: 'custom' + }.freeze + + MEDIA_FEATURES_PREFERS_REDUCED_DATA = { + no_preference: 'no-preference', + reduce: 'reduce' + }.freeze + + MEDIA_FEATURES_PREFERS_REDUCED_MOTION = { + no_preference: 'no-preference', + reduce: 'reduce' + }.freeze + + MEDIA_FEATURES_PREFERS_REDUCED_TRANSPARENCY = { + no_preference: 'no-preference', + reduce: 'reduce' + }.freeze + + MEDIA_FEATURES_SCAN = { + interlace: 'interlace', + progressive: 'progressive' + }.freeze + + MEDIA_FEATURES_SCRIPTING = { + none: 'none', + initial_only: 'initial-only', + enabled: 'enabled' + }.freeze + + MEDIA_FEATURES_UPDATE = { + none: 'none', + slow: 'slow', + fast: 'fast' + }.freeze + + MEDIA_FEATURES_VIDEO_COLOR_GAMUT = { + srgb: 'srgb', + p3: 'p3', + rec2020: 'rec2020' + }.freeze + + MEDIA_FEATURES_VIDEO_DYNAMIC_RANGE = { + standard: 'standard', + high: 'high' + }.freeze + SET_SCROLLBAR_TYPE_OVERRIDE_PARAMETERS_SCROLLBAR_TYPE = { classic: 'classic', overlay: 'overlay' @@ -120,17 +254,149 @@ class SetGeolocationOverrideParameters < Serialization::Union # @see https://www.selenium.dev/documentation/warnings/bidi-implementation/ # @see https://w3c.github.io/webdriver-bidi/#cddl-type-emulationsetmediafeaturesoverrideparameters SetMediaFeaturesOverrideParameters = Serialization::Record.define( - features: {wire_key: 'features', nullable: true, ref: 'Emulation::MediaFeature', list: true}, + features: {wire_key: 'features', nullable: true, ref: 'Emulation::MediaFeatures'}, contexts: {wire_key: 'contexts', required: false, list: true}, user_contexts: {wire_key: 'userContexts', required: false, list: true} ) # @api private # @see https://www.selenium.dev/documentation/warnings/bidi-implementation/ - # @see https://w3c.github.io/webdriver-bidi/#cddl-type-emulationmediafeature - MediaFeature = Serialization::Record.define( - name: {wire_key: 'name', primitive: 'string'}, - value: {wire_key: 'value', primitive: 'string'} + # @see https://w3c.github.io/webdriver-bidi/#cddl-type-emulationmediafeatures + MediaFeatures = Serialization::Record.define( + any_hover: { + wire_key: 'any-hover', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_ANY_HOVER' + }, + any_pointer: { + wire_key: 'any-pointer', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_ANY_POINTER' + }, + color: {wire_key: 'color', required: false, nullable: true, primitive: 'integer'}, + color_gamut: { + wire_key: 'color-gamut', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_COLOR_GAMUT' + }, + color_index: {wire_key: 'color-index', required: false, nullable: true, primitive: 'integer'}, + display_mode: { + wire_key: 'display-mode', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_DISPLAY_MODE' + }, + dynamic_range: { + wire_key: 'dynamic-range', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_DYNAMIC_RANGE' + }, + environment_blending: { + wire_key: 'environment-blending', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_ENVIRONMENT_BLENDING' + }, + forced_colors: { + wire_key: 'forced-colors', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_FORCED_COLORS' + }, + grid: {wire_key: 'grid', required: false, nullable: true, enum: 'Emulation::MEDIA_FEATURES_GRID'}, + horizontal_viewport_segments: { + wire_key: 'horizontal-viewport-segments', + required: false, + nullable: true, + primitive: 'integer' + }, + hover: {wire_key: 'hover', required: false, nullable: true, enum: 'Emulation::MEDIA_FEATURES_HOVER'}, + inverted_colors: { + wire_key: 'inverted-colors', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_INVERTED_COLORS' + }, + monochrome: {wire_key: 'monochrome', required: false, nullable: true, primitive: 'integer'}, + nav_controls: { + wire_key: 'nav-controls', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_NAV_CONTROLS' + }, + overflow_block: { + wire_key: 'overflow-block', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_OVERFLOW_BLOCK' + }, + overflow_inline: { + wire_key: 'overflow-inline', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_OVERFLOW_INLINE' + }, + pointer: {wire_key: 'pointer', required: false, nullable: true, enum: 'Emulation::MEDIA_FEATURES_POINTER'}, + prefers_color_scheme: { + wire_key: 'prefers-color-scheme', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_PREFERS_COLOR_SCHEME' + }, + prefers_contrast: { + wire_key: 'prefers-contrast', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_PREFERS_CONTRAST' + }, + prefers_reduced_data: { + wire_key: 'prefers-reduced-data', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_PREFERS_REDUCED_DATA' + }, + prefers_reduced_motion: { + wire_key: 'prefers-reduced-motion', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_PREFERS_REDUCED_MOTION' + }, + prefers_reduced_transparency: { + wire_key: 'prefers-reduced-transparency', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_PREFERS_REDUCED_TRANSPARENCY' + }, + scan: {wire_key: 'scan', required: false, nullable: true, enum: 'Emulation::MEDIA_FEATURES_SCAN'}, + scripting: { + wire_key: 'scripting', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_SCRIPTING' + }, + update: {wire_key: 'update', required: false, nullable: true, enum: 'Emulation::MEDIA_FEATURES_UPDATE'}, + vertical_viewport_segments: { + wire_key: 'vertical-viewport-segments', + required: false, + nullable: true, + primitive: 'integer' + }, + video_color_gamut: { + wire_key: 'video-color-gamut', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_VIDEO_COLOR_GAMUT' + }, + video_dynamic_range: { + wire_key: 'video-dynamic-range', + required: false, + nullable: true, + enum: 'Emulation::MEDIA_FEATURES_VIDEO_DYNAMIC_RANGE' + } ) # @api private @@ -245,7 +511,7 @@ class SetGeolocationOverrideParameters < Serialization::Union def geolocation_coordinates(**) = GeolocationCoordinates.new(**) def geolocation_position_error(**) = GeolocationPositionError.new(**) - def media_feature(**) = MediaFeature.new(**) + def media_features(**) = MediaFeatures.new(**) def network_conditions_offline(**) = NetworkConditionsOffline.new(**) def screen_area(**) = ScreenArea.new(**) def screen_orientation(**) = ScreenOrientation.new(**) diff --git a/rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb b/rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb index bff300ba3703b..0c20ea8579c8d 100644 --- a/rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb +++ b/rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb @@ -137,14 +137,16 @@ def self.enum_const_path(type_name) # snake_case hash key for an enum value (only a label for the wire value it maps to). # Preserves camelCase word boundaries (beforeRequestSent → before_request_sent), maps a # leading minus to "neg" (-0 → neg0, -Infinity → neg_infinity; no underscore before a - # digit, so the key stays normalcase), and collapses other punctuation - # (dedicated-worker → dedicated_worker). + # digit, so the key stays normalcase), collapses other punctuation + # (dedicated-worker → dedicated_worker), and prefixes a numeric value so the key + # is still a valid symbol (0 → _0). def self.enum_key(value) - camel_to_snake(value.to_s) - .sub(/\A-(?=\d)/, 'neg') - .sub(/\A-/, 'neg_') - .gsub(/[^a-z0-9]+/, '_') - .gsub(/\A_+|_+\z/, '') + token = camel_to_snake(value.to_s) + .sub(/\A-(?=\d)/, 'neg') + .sub(/\A-/, 'neg_') + .gsub(/[^a-z0-9]+/, '_') + .gsub(/\A_+|_+\z/, '') + token.empty? || token.match?(/\A\d/) ? "_#{token}" : token end # ruby_name is the snake_case keyword argument; wire_name is the exact key the @@ -308,9 +310,16 @@ def render(indent) def type_entry = "'#{wire_name}' => #{payload_ref || 'nil'}" end - # constant_name is the SCREAMING_SNAKE hash name; pairs are [symbol_key, wire_value] tuples. - # spec_href links to the type's definition in the live spec (nil when the schema has none). - Enum = Struct.new(:constant_name, :pairs, :spec_href, keyword_init: true) + # The RBS type a schema value primitive maps to; an unrecognized one is untyped. + RBS_VALUE_TYPES = {'string' => 'String', 'integer' => 'Integer', 'number' => 'Float', + 'boolean' => 'bool'}.freeze + + # constant_name is the SCREAMING_SNAKE hash name; pairs are [symbol_key, wire_value] tuples; + # primitive is the schema's declared value type. spec_href links to the type's definition in + # the live spec (nil when the schema has none). + Enum = Struct.new(:constant_name, :pairs, :primitive, :spec_href, keyword_init: true) do + def rbs_value_type = RBS_VALUE_TYPES.fetch(primitive, 'untyped') + end # The generated Protocol::ErrorCode module (filename 'error_code'): `codes` is the [wire, class_name] # pairs in schema order (the full map); `new_classes` is the subset of class names the classic @@ -694,9 +703,9 @@ def enums_for(domain) next unless type['kind'] == 'enum' next unless name.start_with?("#{domain}.") - pairs = type['values'].map { |v| [BiDiGenerate.enum_key(v), v.to_s] } + pairs = type['values'].map { |v| [BiDiGenerate.enum_key(v), v] } Enum.new(constant_name: BiDiGenerate.screaming_snake(name.sub("#{domain}.", '')), pairs: pairs, - spec_href: type['specHref']) + primitive: type['primitive'], spec_href: type['specHref']) end end diff --git a/rb/lib/selenium/webdriver/bidi/support/templates/module.rb.erb b/rb/lib/selenium/webdriver/bidi/support/templates/module.rb.erb index 3534410f61eaf..e78a50c0c3d45 100644 --- a/rb/lib/selenium/webdriver/bidi/support/templates/module.rb.erb +++ b/rb/lib/selenium/webdriver/bidi/support/templates/module.rb.erb @@ -40,7 +40,7 @@ module Selenium # @see <%= enum.spec_href %> <%- end -%> <%= enum.constant_name %> = { - <%= enum.pairs.map { |key, wire_val| "#{key}: '#{wire_val}'" }.join(",\n ") %> + <%= enum.pairs.map { |key, wire_val| "#{key}: #{BiDiGenerate.ruby_literal(wire_val)}" }.join(",\n ") %> }.freeze <%- end -%> diff --git a/rb/lib/selenium/webdriver/bidi/support/templates/module.rbs.erb b/rb/lib/selenium/webdriver/bidi/support/templates/module.rbs.erb index 04166aeb676e5..0f619e6411c8a 100644 --- a/rb/lib/selenium/webdriver/bidi/support/templates/module.rbs.erb +++ b/rb/lib/selenium/webdriver/bidi/support/templates/module.rbs.erb @@ -27,7 +27,7 @@ module Selenium <%- end -%> <%- mod.enums.each do |enum| -%> - <%= enum.constant_name %>: Hash[Symbol, String] + <%= enum.constant_name %>: Hash[Symbol, <%= enum.rbs_value_type %>] <%- end -%> <%- mod.types.select(&:union?).each do |union| -%> diff --git a/rb/sig/lib/selenium/webdriver/bidi/protocol/emulation.rbs b/rb/sig/lib/selenium/webdriver/bidi/protocol/emulation.rbs index d56ccd6ecdd72..3a4c5bd377c67 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/protocol/emulation.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/protocol/emulation.rbs @@ -29,6 +29,54 @@ module Selenium SCREEN_ORIENTATION_TYPE: Hash[Symbol, String] + MEDIA_FEATURES_ANY_HOVER: Hash[Symbol, String] + + MEDIA_FEATURES_ANY_POINTER: Hash[Symbol, String] + + MEDIA_FEATURES_COLOR_GAMUT: Hash[Symbol, String] + + MEDIA_FEATURES_DISPLAY_MODE: Hash[Symbol, String] + + MEDIA_FEATURES_DYNAMIC_RANGE: Hash[Symbol, String] + + MEDIA_FEATURES_ENVIRONMENT_BLENDING: Hash[Symbol, String] + + MEDIA_FEATURES_FORCED_COLORS: Hash[Symbol, String] + + MEDIA_FEATURES_GRID: Hash[Symbol, Integer] + + MEDIA_FEATURES_HOVER: Hash[Symbol, String] + + MEDIA_FEATURES_INVERTED_COLORS: Hash[Symbol, String] + + MEDIA_FEATURES_NAV_CONTROLS: Hash[Symbol, String] + + MEDIA_FEATURES_OVERFLOW_BLOCK: Hash[Symbol, String] + + MEDIA_FEATURES_OVERFLOW_INLINE: Hash[Symbol, String] + + MEDIA_FEATURES_POINTER: Hash[Symbol, String] + + MEDIA_FEATURES_PREFERS_COLOR_SCHEME: Hash[Symbol, String] + + MEDIA_FEATURES_PREFERS_CONTRAST: Hash[Symbol, String] + + MEDIA_FEATURES_PREFERS_REDUCED_DATA: Hash[Symbol, String] + + MEDIA_FEATURES_PREFERS_REDUCED_MOTION: Hash[Symbol, String] + + MEDIA_FEATURES_PREFERS_REDUCED_TRANSPARENCY: Hash[Symbol, String] + + MEDIA_FEATURES_SCAN: Hash[Symbol, String] + + MEDIA_FEATURES_SCRIPTING: Hash[Symbol, String] + + MEDIA_FEATURES_UPDATE: Hash[Symbol, String] + + MEDIA_FEATURES_VIDEO_COLOR_GAMUT: Hash[Symbol, String] + + MEDIA_FEATURES_VIDEO_DYNAMIC_RANGE: Hash[Symbol, String] + SET_SCROLLBAR_TYPE_OVERRIDE_PARAMETERS_SCROLLBAR_TYPE: Hash[Symbol, String] type set_geolocation_override_parameters = ::Selenium::WebDriver::BiDi::Protocol::Emulation::SetGeolocationOverrideParameters::Coordinates | ::Selenium::WebDriver::BiDi::Protocol::Emulation::SetGeolocationOverrideParameters::Error @@ -79,16 +127,43 @@ module Selenium end class SetMediaFeaturesOverrideParameters < ::Selenium::WebDriver::BiDi::Serialization::Record - attr_reader features: Array[::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeature]? + attr_reader features: ::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeatures? attr_reader contexts: untyped attr_reader user_contexts: untyped - def self.new: (features: Array[::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeature]?, ?contexts: Array[String], ?user_contexts: Array[String]) -> instance + def self.new: (features: ::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeatures?, ?contexts: Array[String], ?user_contexts: Array[String]) -> instance end - class MediaFeature < ::Selenium::WebDriver::BiDi::Serialization::Record - attr_reader name: String - attr_reader value: String - def self.new: (name: String, value: String) -> instance + class MediaFeatures < ::Selenium::WebDriver::BiDi::Serialization::Record + attr_reader any_hover: untyped + attr_reader any_pointer: untyped + attr_reader color: untyped + attr_reader color_gamut: untyped + attr_reader color_index: untyped + attr_reader display_mode: untyped + attr_reader dynamic_range: untyped + attr_reader environment_blending: untyped + attr_reader forced_colors: untyped + attr_reader grid: untyped + attr_reader horizontal_viewport_segments: untyped + attr_reader hover: untyped + attr_reader inverted_colors: untyped + attr_reader monochrome: untyped + attr_reader nav_controls: untyped + attr_reader overflow_block: untyped + attr_reader overflow_inline: untyped + attr_reader pointer: untyped + attr_reader prefers_color_scheme: untyped + attr_reader prefers_contrast: untyped + attr_reader prefers_reduced_data: untyped + attr_reader prefers_reduced_motion: untyped + attr_reader prefers_reduced_transparency: untyped + attr_reader scan: untyped + attr_reader scripting: untyped + attr_reader update: untyped + attr_reader vertical_viewport_segments: untyped + attr_reader video_color_gamut: untyped + attr_reader video_dynamic_range: untyped + def self.new: (?any_hover: Symbol?, ?any_pointer: Symbol?, ?color: Integer?, ?color_gamut: Symbol?, ?color_index: Integer?, ?display_mode: Symbol?, ?dynamic_range: Symbol?, ?environment_blending: Symbol?, ?forced_colors: Symbol?, ?grid: Symbol?, ?horizontal_viewport_segments: Integer?, ?hover: Symbol?, ?inverted_colors: Symbol?, ?monochrome: Integer?, ?nav_controls: Symbol?, ?overflow_block: Symbol?, ?overflow_inline: Symbol?, ?pointer: Symbol?, ?prefers_color_scheme: Symbol?, ?prefers_contrast: Symbol?, ?prefers_reduced_data: Symbol?, ?prefers_reduced_motion: Symbol?, ?prefers_reduced_transparency: Symbol?, ?scan: Symbol?, ?scripting: Symbol?, ?update: Symbol?, ?vertical_viewport_segments: Integer?, ?video_color_gamut: Symbol?, ?video_dynamic_range: Symbol?) -> instance end class SetNetworkConditionsParameters < ::Selenium::WebDriver::BiDi::Serialization::Record @@ -173,14 +248,14 @@ module Selenium def geolocation_coordinates: (latitude: Numeric, longitude: Numeric, ?accuracy: Numeric, ?altitude: Numeric?, ?altitude_accuracy: Numeric?, ?heading: Numeric?, ?speed: Numeric?) -> GeolocationCoordinates def geolocation_position_error: (?type: String) -> GeolocationPositionError - def media_feature: (name: String, value: String) -> MediaFeature + def media_features: (?any_hover: Symbol?, ?any_pointer: Symbol?, ?color: Integer?, ?color_gamut: Symbol?, ?color_index: Integer?, ?display_mode: Symbol?, ?dynamic_range: Symbol?, ?environment_blending: Symbol?, ?forced_colors: Symbol?, ?grid: Symbol?, ?horizontal_viewport_segments: Integer?, ?hover: Symbol?, ?inverted_colors: Symbol?, ?monochrome: Integer?, ?nav_controls: Symbol?, ?overflow_block: Symbol?, ?overflow_inline: Symbol?, ?pointer: Symbol?, ?prefers_color_scheme: Symbol?, ?prefers_contrast: Symbol?, ?prefers_reduced_data: Symbol?, ?prefers_reduced_motion: Symbol?, ?prefers_reduced_transparency: Symbol?, ?scan: Symbol?, ?scripting: Symbol?, ?update: Symbol?, ?vertical_viewport_segments: Integer?, ?video_color_gamut: Symbol?, ?video_dynamic_range: Symbol?) -> MediaFeatures def network_conditions_offline: (?type: String) -> NetworkConditionsOffline def screen_area: (width: Integer, height: Integer) -> ScreenArea def screen_orientation: (natural: Symbol, type: Symbol) -> ScreenOrientation def set_forced_colors_mode_theme_override: (theme: Symbol?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped def set_geolocation_override: (?contexts: Array[String], ?user_contexts: Array[String], ?coordinates: ::Selenium::WebDriver::BiDi::Protocol::Emulation::GeolocationCoordinates?, ?error: ::Selenium::WebDriver::BiDi::Protocol::Emulation::GeolocationPositionError) -> untyped def set_locale_override: (locale: String?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped - def set_media_features_override: (features: Array[::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeature]?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped + def set_media_features_override: (features: ::Selenium::WebDriver::BiDi::Protocol::Emulation::MediaFeatures?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped def set_network_conditions: (network_conditions: ::Selenium::WebDriver::BiDi::Protocol::Emulation::NetworkConditionsOffline?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped def set_screen_orientation_override: (screen_orientation: ::Selenium::WebDriver::BiDi::Protocol::Emulation::ScreenOrientation?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped def set_screen_settings_override: (screen_area: ::Selenium::WebDriver::BiDi::Protocol::Emulation::ScreenArea?, ?contexts: Array[String], ?user_contexts: Array[String]) -> untyped diff --git a/rb/spec/unit/selenium/webdriver/bidi/support/bidi_generate_spec.rb b/rb/spec/unit/selenium/webdriver/bidi/support/bidi_generate_spec.rb index 1fcf383ebfeb1..16f8b1a19f125 100644 --- a/rb/spec/unit/selenium/webdriver/bidi/support/bidi_generate_spec.rb +++ b/rb/spec/unit/selenium/webdriver/bidi/support/bidi_generate_spec.rb @@ -43,6 +43,10 @@ module BiDiGenerate it 'collapses punctuation' do expect(BiDiGenerate.enum_key('dedicated-worker')).to eq('dedicated_worker') end + + it 'prefixes a numeric value so the key is a valid symbol' do + expect(BiDiGenerate.enum_key(0)).to eq('_0') + end end describe '.check_accessor_collisions!' do