Skip to content

[js][py][rb] derive BiDi field names and enum value types in the schema - #17966

Merged
titusfortner merged 9 commits into
SeleniumHQ:trunkfrom
titusfortner:bidi-schema-names-and-types
Aug 31, 2026
Merged

[js][py][rb] derive BiDi field names and enum value types in the schema#17966
titusfortner merged 9 commits into
SeleniumHQ:trunkfrom
titusfortner:bidi-schema-names-and-types

Conversation

@titusfortner

Copy link
Copy Markdown
Member

🔗 Related Issues

Surfaced by #17954, whose CDDL repin caused test failures.

4.48.0 shipped without that repin so this is fixing things for the next release.

💥 What does this PR do?

  • The schema now stores an identifier-safe name alongside the exact wire key, so each binding derives an attribute name without re-solving punctuation itself
  • The schema declares each enum's value primitive, and the bindings honor it, so a numeric enum serializes as a number rather than a string
  • Repins the CDDL to the spec revision that exercises both, and regenerates the schema and Ruby protocol from it

🔧 Implementation Notes

  • name and wire held the same value, so a key that is not an identifier (prefers-color-scheme) reached every binding unconverted. A key that already is one is left alone, so namespaceURI and the other 255 existing keys are unchanged.
  • CamelCasing can collapse two wire keys onto one name (colorGamut and color-gamut), which a Python dataclass would silently accept as an overwrite, so checkSchema rejects it.
  • Vendor-prefixed keys (moz:allowPrivateBrowsing) are exempt — extractVendor routes them out of the shared types and the vendor pipeline drops the namespace itself.
  • Enum values are the payload, so they stay exact, but their type is now declared once: the projector already computed it for inline choices via literalPrimitive and discarded it when hoisting to a named enum, so named enums now keep it. Python and Ruby read that instead of introspecting the values, and Java gets to use its existing primitiveToJava rather than instanceof-chaining on Object. Without it both bindings sent "0" where "grid": 0 / 1 requires 0.
  • Member names still come from each binding, since the values are the payload and each language brands its own constants — hence the leading-digit guard that turns 0 into _0, which Python already had and Ruby now matches.

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code (Opus 5)
    • What was generated: CI log analysis, the schema and generator fixes, tests, and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

  • [java][bidi] Add BiDi code generator #17777 gets the naming half for free: its parseField reads name, which is now already a valid Java identifier. Its enum path will need the same numeric handling Ruby and Python got here, though, once it rebases past the repin — appendEnumBody types values as List<String>, toEnumConstant would emit 0 as a constant name, and the generated enum boxes its value as a String.

🔄 Types of changes

  • Bug fix (backwards compatible)

@selenium-ci selenium-ci added C-py Python Bindings C-rb Ruby Bindings C-nodejs JavaScript Bindings B-build Includes scripting, bazel and CI integrations B-devtools Includes everything BiDi or Chrome DevTools related B-support Issue or PR related to support classes labels Aug 28, 2026
@selenium-ci

Copy link
Copy Markdown
Member

Thank you, @titusfortner for this code suggestion.

The support packages contain example code that many users find helpful, but they do not necessarily represent
the best practices for using Selenium, and the Selenium team is not currently merging changes to them.

After reviewing the change, unless it is a critical fix or a feature that is needed for Selenium
to work, we will likely close the PR.

We actively encourage people to add the wrapper and helper code that makes sense for them to their own frameworks.
If you have any questions, please contact us

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Derive BiDi field names and preserve enum primitive types

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Separates identifier-safe field names from exact BiDi wire keys in the shared schema.
• Declares enum primitives so numeric values retain wire types across bindings.
• Repins BiDi CDDL and regenerates Ruby media-feature protocol models.
Diagram

graph TD
  CDDL["Pinned CDDL"] --> Projector["JS Projector"] --> Schema["BiDi Schema"] --> PyGen["Python Generator"] --> PyBindings["Python Enums"]
  Schema --> RubyGen["Ruby Generator"] --> RubyBindings["Ruby Protocol"]
Loading
High-Level Assessment

The PR's schema-first approach is the best fit because field naming and enum payload types are protocol facts shared by every binding. Re-deriving them independently in Python and Ruby was considered but would duplicate punctuation and runtime-type heuristics, increasing drift; central metadata plus collision validation keeps wire fidelity and binding behavior consistent.

Files changed (11) +1045 / -58

Bug fix (8) +994 / -53
schema.jsonRegenerate schema with safe names and typed media-feature enums +571/-19

Regenerate schema with safe names and typed media-feature enums

• Adds primitive metadata to named and synthetic enums, including the integer-valued media-features grid enum. Replaces the generic media-feature list with the repinned specification's structured MediaFeatures record, preserving exact hyphenated wire keys alongside camel-cased schema names.

common/bidi/schema.json

project_bidi_schema.mjsProject safe field names and enum primitive metadata +37/-6

Project safe field names and enum primitive metadata

• Derives camel-cased schema field names for non-identifier wire keys while retaining exact wire names and exempting vendor-prefixed fields. Preserves the shared primitive of hoisted literal enums and rejects collisions where distinct wire keys map to one field name.

javascript/selenium-webdriver/project_bidi_schema.mjs

generate_bidi_protocol.pyGenerate Python enums with primitive-specific mixins +11/-2

Generate Python enums with primitive-specific mixins

• Carries enum primitive metadata into the Python generator IR. Integer and number enums now use int and float mixins respectively, while unspecified and string enums retain the existing str behavior.

py/generate_bidi_protocol.py

emulation.rbRegenerate Ruby structured media-features protocol models +272/-6

Regenerate Ruby structured media-features protocol models

• Replaces generic name/value media-feature entries with the specification's structured MediaFeatures record and enum constants. Numeric grid values remain integers and hyphenated wire keys are exposed through Ruby-safe keyword names.

rb/lib/selenium/webdriver/bidi/protocol/emulation.rb

bidi_generate.rbPreserve Ruby enum payload types during generation +18/-10

Preserve Ruby enum payload types during generation

• Stops coercing enum payloads to strings, creates valid underscore-prefixed keys for numeric members, and records each enum's primitive. Maps declared primitives to matching RBS value types for generated enum hashes.

rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb

module.rb.erbRender Ruby enum values as typed literals +1/-1

Render Ruby enum values as typed literals

• Uses the generator's Ruby literal renderer instead of always quoting enum payloads. Numeric enum values therefore serialize as numbers rather than strings.

rb/lib/selenium/webdriver/bidi/support/templates/module.rb.erb

module.rbs.erbEmit primitive-aware Ruby enum signatures +1/-1

Emit primitive-aware Ruby enum signatures

• Changes generated enum hash signatures from a fixed String value type to the enum primitive's mapped RBS type.

rb/lib/selenium/webdriver/bidi/support/templates/module.rbs.erb

emulation.rbsRegenerate RBS signatures for structured media features +83/-8

Regenerate RBS signatures for structured media features

• Adds signatures for all generated media-feature enum constants, including Integer values for grid. Replaces the generic MediaFeature array API with the optional, typed MediaFeatures record and factory signatures.

rb/sig/lib/selenium/webdriver/bidi/protocol/emulation.rbs

Tests (2) +46 / -0
project_bidi_schema_test.mjsCover field projection, enum typing, and naming collisions +42/-0

Cover field projection, enum typing, and naming collisions

• Adds tests for numeric enum primitives, hyphenated wire-key camel-casing, preservation of existing identifier casing, and collision detection. Updates the existing synthetic-enum expectation to include its string primitive.

javascript/selenium-webdriver/project_bidi_schema_test.mjs

bidi_generate_spec.rbTest numeric Ruby enum member naming +4/-0

Test numeric Ruby enum member naming

• Verifies that a numeric enum payload receives an underscore-prefixed symbol key, producing a valid Ruby member label without changing its payload.

rb/spec/unit/selenium/webdriver/bidi/support/bidi_generate_spec.rb

Other (1) +5 / -5
webref_cddl.bzlRepin WebRef CDDL and BiDi specification inputs +5/-5

Repin WebRef CDDL and BiDi specification inputs

• Updates the WebRef commit, BiDi HTML revision, and associated CDDL and definitions checksums. The new pin introduces the structured media-features definition that exercises safe field naming and numeric enum values.

common/webref_cddl.bzl

@qodo-code-review

qodo-code-review Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Action required

1. _read_scalar boolean guard untested 📘 Rule violation ☼ Reliability
Description
The new inbound enum guard changes rejection behavior for boolean/integer lookalikes, but the enum
inbound tests cover only string-valued enums. Without focused boolean- and integer-valued enum
tests, this regression fix can silently break.
Code

py/selenium/webdriver/common/_bidi/serialization.py[R415-417]

+        # 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):
Evidence
PR Compliance ID 5 requires focused regression coverage for behavioral changes. The changed guard at
serialization.py[415-417] introduces distinct boolean/integer enum validation, while the existing
inbound enum coverage at bidi_serialization_tests.py[524-533] exercises only the string-valued
Color enum and does not verify either new rejection path.

AGENTS.md: Provide Focused Tests and Avoid Contract-Misrepresenting Mocks
py/selenium/webdriver/common/_bidi/serialization.py[412-419]
py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[524-533]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Add focused regression tests for `_read_scalar` rejecting boolean/integer enum lookalikes.

## Issue Context
The new guard must reject `True` for integer-valued enums and `1` for boolean-valued enums while continuing to accept correctly typed values.

## Fix Focus Areas
- py/selenium/webdriver/common/_bidi/serialization.py[412-419]
- py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[524-533]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. int enums accept booleans ✗ Dismissed 📘 Rule violation ≡ Correctness
Description
Generating numeric enums with Python's int/float mixins makes True compare equal to enum value
1, so enum validation accepts it and serialization can emit JSON true instead of the required
number. This makes Python's shared protocol serialization inconsistent with the declared schema
primitive and other bindings.
Code

py/generate_bidi_protocol.py[R850-852]

+    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}):"]
Evidence
Compliance rule 2 requires aligned shared protocol serialization. The changed emitter creates
int/float-mixed enums, while the runtime validates raw enum values by calling enum_cls(item);
because Python booleans are integer subclasses and compare equal to 0/1, a boolean can pass
numeric-enum membership and remain a boolean when _as_json serializes the raw field value.

AGENTS.md: Maintain Cross-Binding Consistency for User-Visible Behavior
py/generate_bidi_protocol.py[850-852]
py/selenium/webdriver/common/_bidi/serialization.py[245-255]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Python numeric enum lookup treats booleans as numbers, allowing `True` for an enum whose declared primitive is `integer` or `number` and potentially serializing it as JSON `true`.

## Issue Context
`bool` subclasses `int`, and Python enum value lookup uses equality, so `enum_cls(True)` can resolve the member whose value is `1`. Both inbound enum conversion and outbound record validation need to enforce the schema enum's primitive before accepting raw values.

## Fix Focus Areas
- py/generate_bidi_protocol.py[850-852]
- py/selenium/webdriver/common/_bidi/serialization.py[397-410]
- py/selenium/webdriver/common/_bidi/serialization.py[245-255]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Python enum emission lacks tests 📘 Rule violation ☼ Reliability
Description
The Python generator now changes enum base types from str to int or float, but no focused test
asserts the generated class or its numeric serialization behavior. This leaves the numeric-enum fix
unprotected against regressions.
Code

py/generate_bidi_protocol.py[R848-849]

+    mixin = _ENUM_MIXINS.get(e.primitive, "str")
+    lines = [f"@register({lit(e.schema_name)})", f"class {e.class_name}({mixin}, Enum):"]
Evidence
Rule 4 requires focused coverage for changed behavior. The cited generator lines introduce
primitive-dependent enum classes, while the Python build definition only invokes the generator and
the repository contains no Python test referencing _emit_enum, _ENUM_MIXINS, or the generated
MediaFeaturesGrid enum.

AGENTS.md: Prefer Focused Unit Tests and Avoid Contract-Distorting Mocks
py/generate_bidi_protocol.py[848-849]
py/BUILD.bazel[779-807]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Python BiDi generator selects enum mixins from the schema primitive without focused coverage proving that integer and number enums are generated and serialized with numeric values.

## Issue Context
PR Compliance ID 4 requires small tests for changed behavior where practical. Add generator-level assertions for at least integer and number primitives, including the fallback string behavior.

## Fix Focus Areas
- py/generate_bidi_protocol.py[848-849]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Boolean enums accept integers ✓ Resolved 🐞 Bug ≡ Correctness
Description
The new check only rejects a bool that resolves to a non-boolean enum member; a boolean-valued
plain Enum still resolves raw 1/0 to True/False members because Python considers those
values equal. Since construction retains the raw input, _as_json emits JSON 1/0 instead of the
schema-declared boolean payload.
Code

py/selenium/webdriver/common/_bidi/serialization.py[R254-256]

+            # bool is a subclass of int, so True resolves to an int-valued member and would
+            # then serialize as JSON true rather than the number the schema declares.
+            if member is None or (type(item) is bool and type(member.value) is not bool):
Evidence
The generator deliberately emits boolean-valued schema enums without a numeric/string mixin
(py/generate_bidi_protocol.py[72-75]). _validate_enum resolves raw values through
enum_cls(item) but only tests whether the input itself is bool
(py/selenium/webdriver/common/_bidi/serialization.py[245-256]), while _as_json returns a raw
non-Enum unchanged (py/selenium/webdriver/common/_bidi/serialization.py[197-206]); therefore raw
integer inputs accepted through equality remain integers on the wire.

py/generate_bidi_protocol.py[72-75]
py/selenium/webdriver/common/_bidi/serialization.py[245-256]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Boolean-valued enums accept raw integer `1` and `0`, which are serialized as numbers rather than booleans.

## Issue Context
Python enum lookup treats `True == 1` and `False == 0`. The validation currently protects only the numeric-enum/boolean-input direction; boolean schema enums are emitted as plain `Enum` classes and raw accepted values are not replaced with the resolved member before serialization.

## Fix Focus Areas
- py/selenium/webdriver/common/_bidi/serialization.py[245-259]
- py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[431-445]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Boolean enums become strings ✓ Resolved 🐞 Bug ≡ Correctness
Description
_emit_enum defaults every primitive other than integer/number to str, so a valid schema enum
with primitive: "boolean" is generated as class X(str, Enum). Its boolean members are coerced to
string values for serialization and incoming boolean values do not resolve to those members.
Code

py/generate_bidi_protocol.py[73]

+_ENUM_MIXINS = {"integer": "int", "number": "float"}
Evidence
The projector recognizes all-boolean literals, but the added map omits boolean and falls back to
str. The generated members retain their literal source expressions and serialization directly
writes .value.

javascript/selenium-webdriver/project_bidi_schema.mjs[126-129]
py/generate_bidi_protocol.py[72-73]
py/generate_bidi_protocol.py[847-852]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]
py/selenium/webdriver/common/_bidi/serialization.py[405-410]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Boolean-valued schema enums fall through to the `str` Enum mixin, coercing JSON booleans to strings.

## Issue Context
The schema projector emits `primitive: "boolean"` for all-boolean literal choices, while Python serialization emits an enum member's `.value`.

## Fix Focus Areas
- py/generate_bidi_protocol.py[72-73]
- py/generate_bidi_protocol.py[847-852]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Leading digits remain invalid ✗ Dismissed 🐞 Bug ≡ Correctness
Description
fieldName() turns a quoted wire key such as 123-foo into 123Foo, which still starts with a
digit and causes Python/Ruby generators to emit an invalid parameter or attribute identifier on a
future schema repin. The new schema check only detects collisions, so this invalid projected name
passes validation until generated source fails to parse.
Code

javascript/selenium-webdriver/project_bidi_schema.mjs[228]

+  return head + rest.map((part) => part[0].toUpperCase() + part.slice(1)).join('')
Evidence
The projector itself defines identifiers as letter-leading, but its fallback concatenates an
unchecked first token. Both downstream generators consume that projected name and only handle
reserved names, while schema validation checks duplicates rather than syntax.

javascript/selenium-webdriver/project_bidi_schema.mjs[219-228]
javascript/selenium-webdriver/project_bidi_schema.mjs[814-825]
py/generate_bidi_protocol.py[101-107]
py/generate_bidi_protocol.py[366-376]
rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb[105-111]
rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb[951-958]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Ensure every non-vendor projected field name satisfies the schema's identifier grammar, including wire keys whose first alphanumeric segment begins with a digit.

## Issue Context
`fieldName('123-foo')` currently returns `123Foo`; downstream Python and Ruby naming helpers do not add a leading-character guard, and `checkSchema` only checks collisions.

## Fix Focus Areas
- javascript/selenium-webdriver/project_bidi_schema.mjs[222-228]
- javascript/selenium-webdriver/project_bidi_schema.mjs[817-825]
- javascript/selenium-webdriver/project_bidi_schema_test.mjs[84-96]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: 🚀 Fast: This is a single localized Ruby generator refactor that only renames a type-mapping constant and updates its reference, with no new logic or high-risk behavior.

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit bc250ce 🚀 Fast

Results up to commit 3950a0c 🧠 Deep


🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. Python enum emission lacks tests 📘 Rule violation ☼ Reliability
Description
The Python generator now changes enum base types from str to int or float, but no focused test
asserts the generated class or its numeric serialization behavior. This leaves the numeric-enum fix
unprotected against regressions.
Code

py/generate_bidi_protocol.py[R848-849]

+    mixin = _ENUM_MIXINS.get(e.primitive, "str")
+    lines = [f"@register({lit(e.schema_name)})", f"class {e.class_name}({mixin}, Enum):"]
Evidence
Rule 4 requires focused coverage for changed behavior. The cited generator lines introduce
primitive-dependent enum classes, while the Python build definition only invokes the generator and
the repository contains no Python test referencing _emit_enum, _ENUM_MIXINS, or the generated
MediaFeaturesGrid enum.

AGENTS.md: Prefer Focused Unit Tests and Avoid Contract-Distorting Mocks
py/generate_bidi_protocol.py[848-849]
py/BUILD.bazel[779-807]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Python BiDi generator selects enum mixins from the schema primitive without focused coverage proving that integer and number enums are generated and serialized with numeric values.

## Issue Context
PR Compliance ID 4 requires small tests for changed behavior where practical. Add generator-level assertions for at least integer and number primitives, including the fallback string behavior.

## Fix Focus Areas
- py/generate_bidi_protocol.py[848-849]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended
2. Leading digits remain invalid ✗ Dismissed 🐞 Bug ≡ Correctness
Description
fieldName() turns a quoted wire key such as 123-foo into 123Foo, which still starts with a
digit and causes Python/Ruby generators to emit an invalid parameter or attribute identifier on a
future schema repin. The new schema check only detects collisions, so this invalid projected name
passes validation until generated source fails to parse.
Code

javascript/selenium-webdriver/project_bidi_schema.mjs[228]

+  return head + rest.map((part) => part[0].toUpperCase() + part.slice(1)).join('')
Evidence
The projector itself defines identifiers as letter-leading, but its fallback concatenates an
unchecked first token. Both downstream generators consume that projected name and only handle
reserved names, while schema validation checks duplicates rather than syntax.

javascript/selenium-webdriver/project_bidi_schema.mjs[219-228]
javascript/selenium-webdriver/project_bidi_schema.mjs[814-825]
py/generate_bidi_protocol.py[101-107]
py/generate_bidi_protocol.py[366-376]
rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb[105-111]
rb/lib/selenium/webdriver/bidi/support/bidi_generate.rb[951-958]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Ensure every non-vendor projected field name satisfies the schema's identifier grammar, including wire keys whose first alphanumeric segment begins with a digit.

## Issue Context
`fieldName('123-foo')` currently returns `123Foo`; downstream Python and Ruby naming helpers do not add a leading-character guard, and `checkSchema` only checks collisions.

## Fix Focus Areas
- javascript/selenium-webdriver/project_bidi_schema.mjs[222-228]
- javascript/selenium-webdriver/project_bidi_schema.mjs[817-825]
- javascript/selenium-webdriver/project_bidi_schema_test.mjs[84-96]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Boolean enums become strings ✓ Resolved 🐞 Bug ≡ Correctness
Description
_emit_enum defaults every primitive other than integer/number to str, so a valid schema enum
with primitive: "boolean" is generated as class X(str, Enum). Its boolean members are coerced to
string values for serialization and incoming boolean values do not resolve to those members.
Code

py/generate_bidi_protocol.py[73]

+_ENUM_MIXINS = {"integer": "int", "number": "float"}
Evidence
The projector recognizes all-boolean literals, but the added map omits boolean and falls back to
str. The generated members retain their literal source expressions and serialization directly
writes .value.

javascript/selenium-webdriver/project_bidi_schema.mjs[126-129]
py/generate_bidi_protocol.py[72-73]
py/generate_bidi_protocol.py[847-852]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]
py/selenium/webdriver/common/_bidi/serialization.py[405-410]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Boolean-valued schema enums fall through to the `str` Enum mixin, coercing JSON booleans to strings.

## Issue Context
The schema projector emits `primitive: "boolean"` for all-boolean literal choices, while Python serialization emits an enum member's `.value`.

## Fix Focus Areas
- py/generate_bidi_protocol.py[72-73]
- py/generate_bidi_protocol.py[847-852]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 6aa0ca1 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. int enums accept booleans ✗ Dismissed 📘 Rule violation ≡ Correctness
Description
Generating numeric enums with Python's int/float mixins makes True compare equal to enum value
1, so enum validation accepts it and serialization can emit JSON true instead of the required
number. This makes Python's shared protocol serialization inconsistent with the declared schema
primitive and other bindings.
Code

py/generate_bidi_protocol.py[R850-852]

+    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}):"]
Evidence
Compliance rule 2 requires aligned shared protocol serialization. The changed emitter creates
int/float-mixed enums, while the runtime validates raw enum values by calling enum_cls(item);
because Python booleans are integer subclasses and compare equal to 0/1, a boolean can pass
numeric-enum membership and remain a boolean when _as_json serializes the raw field value.

AGENTS.md: Maintain Cross-Binding Consistency for User-Visible Behavior
py/generate_bidi_protocol.py[850-852]
py/selenium/webdriver/common/_bidi/serialization.py[245-255]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Python numeric enum lookup treats booleans as numbers, allowing `True` for an enum whose declared primitive is `integer` or `number` and potentially serializing it as JSON `true`.

## Issue Context
`bool` subclasses `int`, and Python enum value lookup uses equality, so `enum_cls(True)` can resolve the member whose value is `1`. Both inbound enum conversion and outbound record validation need to enforce the schema enum's primitive before accepting raw values.

## Fix Focus Areas
- py/generate_bidi_protocol.py[850-852]
- py/selenium/webdriver/common/_bidi/serialization.py[397-410]
- py/selenium/webdriver/common/_bidi/serialization.py[245-255]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit e985c8b 🚀 Fast


No changes from previous review

Results up to commit 9e7530e ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Boolean enums accept integers ✓ Resolved 🐞 Bug ≡ Correctness
Description
The new check only rejects a bool that resolves to a non-boolean enum member; a boolean-valued
plain Enum still resolves raw 1/0 to True/False members because Python considers those
values equal. Since construction retains the raw input, _as_json emits JSON 1/0 instead of the
schema-declared boolean payload.
Code

py/selenium/webdriver/common/_bidi/serialization.py[R254-256]

+            # bool is a subclass of int, so True resolves to an int-valued member and would
+            # then serialize as JSON true rather than the number the schema declares.
+            if member is None or (type(item) is bool and type(member.value) is not bool):
Evidence
The generator deliberately emits boolean-valued schema enums without a numeric/string mixin
(py/generate_bidi_protocol.py[72-75]). _validate_enum resolves raw values through
enum_cls(item) but only tests whether the input itself is bool
(py/selenium/webdriver/common/_bidi/serialization.py[245-256]), while _as_json returns a raw
non-Enum unchanged (py/selenium/webdriver/common/_bidi/serialization.py[197-206]); therefore raw
integer inputs accepted through equality remain integers on the wire.

py/generate_bidi_protocol.py[72-75]
py/selenium/webdriver/common/_bidi/serialization.py[245-256]
py/selenium/webdriver/common/_bidi/serialization.py[197-206]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Boolean-valued enums accept raw integer `1` and `0`, which are serialized as numbers rather than booleans.

## Issue Context
Python enum lookup treats `True == 1` and `False == 0`. The validation currently protects only the numeric-enum/boolean-input direction; boolean schema enums are emitted as plain `Enum` classes and raw accepted values are not replaced with the resolved member before serialization.

## Fix Focus Areas
- py/selenium/webdriver/common/_bidi/serialization.py[245-259]
- py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[431-445]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 657d189 🚀 Fast


No changes from previous review

Results up to commit 0628f9c ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. _read_scalar boolean guard untested 📘 Rule violation ☼ Reliability
Description
The new inbound enum guard changes rejection behavior for boolean/integer lookalikes, but the enum
inbound tests cover only string-valued enums. Without focused boolean- and integer-valued enum
tests, this regression fix can silently break.
Code

py/selenium/webdriver/common/_bidi/serialization.py[R415-417]

+        # 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):
Evidence
PR Compliance ID 5 requires focused regression coverage for behavioral changes. The changed guard at
serialization.py[415-417] introduces distinct boolean/integer enum validation, while the existing
inbound enum coverage at bidi_serialization_tests.py[524-533] exercises only the string-valued
Color enum and does not verify either new rejection path.

AGENTS.md: Provide Focused Tests and Avoid Contract-Misrepresenting Mocks
py/selenium/webdriver/common/_bidi/serialization.py[412-419]
py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[524-533]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Add focused regression tests for `_read_scalar` rejecting boolean/integer enum lookalikes.

## Issue Context
The new guard must reject `True` for integer-valued enums and `1` for boolean-valued enums while continuing to accept correctly typed values.

## Fix Focus Areas
- py/selenium/webdriver/common/_bidi/serialization.py[412-419]
- py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py[524-533]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread py/generate_bidi_protocol.py Outdated
Comment thread javascript/selenium-webdriver/project_bidi_schema.mjs
Comment thread py/generate_bidi_protocol.py Outdated
Comment thread py/generate_bidi_protocol.py
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 6aa0ca1

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit e985c8b

Comment thread py/selenium/webdriver/common/_bidi/serialization.py Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 9e7530e

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 657d189

Comment thread py/selenium/webdriver/common/_bidi/serialization.py
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 0628f9c

@titusfortner
titusfortner merged commit 8b8723b into SeleniumHQ:trunk Aug 31, 2026
42 of 43 checks passed
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit bc250ce

This was referenced Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations B-devtools Includes everything BiDi or Chrome DevTools related B-support Issue or PR related to support classes C-nodejs JavaScript Bindings C-py Python Bindings C-rb Ruby Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants