Skip to content

[build] generate webref_cddl.bzl from the BiDi spec's external specifications list - #18055

Merged
titusfortner merged 3 commits into
SeleniumHQ:trunkfrom
titusfortner:webref-cddl-external-specs
Sep 19, 2026
Merged

titusfortner merged 3 commits into
SeleniumHQ:trunkfrom
titusfortner:webref-cddl-external-specs

Conversation

@titusfortner

Copy link
Copy Markdown
Member

💥 What does this PR do?

  • Makes common/webref_cddl.bzl entirely generated by update_cddl.py similar to how browser pinning works.
  • Removes the hard coded list of cddl files in favor of parsing WebDriver BiDi spec's "External specifications" section
  • Merges a subset of the Digital Credentials spec into the shared schema

🔧 Implementation Notes

  • No longer pins specs we don't use, or CDDL files without their dfns index (both were artifacts of the handwritten lists)
  • The extension declares its repos as root-module direct deps so a stale use_repo block warns at build time
  • Digital Credentials doesn't list its command in a *Command aggregate, which is how the generator discovers commands, so it is added to KNOWN_INCOMPLETE (see additional considerations)
  • Note that the update-cddl workflow is only creating an update PR if a new pin changes the schema.json file, and is ignored otherwise
  • Includes a method (stripReffyCddlHeaderPrefix) that can be removed when Strip the header that ReSpec adds to CDDL blocks w3c/reffy#2167 lands

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code (Fable 5.1)
    • What was generated: the script rewrite and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

  • Next PR replaces KNOWN_INCOMPLETE with spec-shaped overlays in common/bidi for the Digital Credentials command aggregate and the two unlisted Web Bluetooth events, so the command and events reach the bindings.

🔄 Types of changes

  • Cleanup (build tooling)

@selenium-ci selenium-ci added C-nodejs JavaScript Bindings B-build Includes scripting, bazel and CI integrations B-devtools Includes everything BiDi or Chrome DevTools related labels Sep 18, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Generate Webref CDDL pins from BiDi external specifications

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Generates Webref pins from WebDriver BiDi’s upstream external-specification list.
• Centralizes Bazel schema inputs and declares generated repositories as direct dependencies.
• Merges Digital Credentials definitions while tolerating its missing command aggregate.
Diagram

graph TD
  HTML["BiDi HTML"] --> Updater["CDDL updater"] --> Pins["Generated pins"] --> Extension["Bazel extension"] --> Inputs["Pinned schemas"] --> Generator["BiDi generator"] --> Schema["Schema JSON"]
  Index["Webref index"] --> Updater
Loading
High-Level Assessment

The upstream-driven approach is preferable to maintaining duplicate hard-coded specification lists because BiDi remains the source of truth and generated Bazel labels keep consumers synchronized. A full HTML parser or a local registry was considered, but the narrowly scoped extraction includes fail-fast validation and avoids another dependency while preserving automatic discovery.

Files changed (7) +385 / -253

Enhancement (2) +304 / -177
schema.jsonAdd Digital Credentials schema definitions +92/-0

Add Digital Credentials schema definitions

• Adds the virtual-wallet action enum, command parameters, command record, result alias, and synthetic response type. The command remains excluded from inbound and outbound aggregates until the upstream specification provides its command aggregate.

common/bidi/schema.json

update_cddl.pyDiscover and generate BiDi Webref dependencies +212/-177

Discover and generate BiDi Webref dependencies

• Rewrites the updater to parse BiDi’s external-specifications list, resolve each URL through Webref metadata, hash its CDDL and definitions artifacts, and render the complete Bazel extension file. It also regenerates the matching 'use_repo' block and always advances both upstream pins, leaving schema-change filtering to the workflow.

scripts/update_cddl.py

Bug fix (2) +21 / -6
generate_bidi.mjsNormalize malformed Reffy CDDL definition names +12/-1

Normalize malformed Reffy CDDL definition names

• Strips an erroneous 'CDDL' header prefix from affected parsed definitions before generation. This temporary compatibility workaround allows the Digital Credentials extract to resolve its references correctly.

javascript/selenium-webdriver/generate_bidi.mjs

project_bidi_schema.mjsAllow incomplete Digital Credentials command aggregation +9/-5

Allow incomplete Digital Credentials command aggregation

• Adds 'digitalCredentials.setVirtualWalletBehavior' to the completeness exception set because the upstream specification does not expose it through a command aggregate. Existing stale-entry detection will identify when the workaround can be removed.

javascript/selenium-webdriver/project_bidi_schema.mjs

Refactor (1) +8 / -19
BUILD.bazelConsume generated BiDi schema input lists +8/-19

Consume generated BiDi schema input lists

• Replaces duplicated CDDL and definitions labels with constants exported by the generated Webref configuration. This automatically includes Digital Credentials and future external BiDi modules discovered by the updater.

javascript/selenium-webdriver/BUILD.bazel

Other (2) +52 / -51
MODULE.bazelSynchronize direct repositories with generated Webref pins +1/-1

Synchronize direct repositories with generated Webref pins

• Removes the unused AT Driver repository and exposes the new Digital Credentials definitions index. The generated repository list now matches the artifacts consumed by schema generation.

MODULE.bazel

webref_cddl.bzlGenerate centralized CDDL and definitions pins +51/-50

Generate centralized CDDL and definitions pins

• Converts the file into fully generated Bazel configuration containing only BiDi and its declared external specifications. Exports canonical CDDL and definitions label lists, adds Digital Credentials definitions, and reports every repository as a reproducible direct dependency.

common/webref_cddl.bzl

@qodo-code-review

qodo-code-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

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

Grey Divider


Action required

1. Spec discovery changes go untested 📘 Rule violation ☼ Reliability
Description
external_spec_urls, resolve_specs, render, and update_module replace the pin generator's
core behavior without focused test coverage. An upstream HTML or index-shape change now reaches
generated repository declarations and both binding inputs, while scripts/BUILD.bazel still
declares only the updater binary.
Code

scripts/update_cddl.py[R155-158]

+def external_spec_urls(spec_html):
+    """The specs the rendered core spec's "External specifications" section links to, without fragments."""
+    section = re.search(r'id="external-specifications".*?<ol>(.*?)</ol>', spec_html, re.DOTALL)
+    if not section:
Evidence
Compliance rule 4 requires focused tests for changed behavior. The cited updater code introduces
HTML parsing and specification resolution, while the scripts build definition contains an executable
target but no corresponding test target.

AGENTS.md: Provide Focused Tests and Avoid Contract-Misrepresenting Mocks
scripts/update_cddl.py[155-191]
scripts/BUILD.bazel[53-58]

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 rewritten CDDL updater discovers external specifications, resolves Webref entries, renders build declarations, and rewrites `MODULE.bazel` without focused automated tests.

## Fix Focus Areas
- scripts/update_cddl.py[155-191]
- scripts/update_cddl.py[209-252]
- scripts/BUILD.bazel[53-58]

## Recommended Fix
Add a Python test target with fixture HTML and Webref index data. Cover successful discovery and rendering, fragment and trailing-slash normalization, missing or ambiguous matches, absent CDDL extracts, and exact replacement of the extension repository block without network access.

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


2. Header cleanup changes go untested ✗ Dismissed 📘 Rule violation ≡ Correctness
Description
stripReffyCddlHeaderPrefix mutates every parsed definition name but has no focused test for its
matching and preservation behavior. Any future parser output beginning with the selected prefix
passes through this path before overrides, normalization, schema projection, and generated bindings.
Code

javascript/selenium-webdriver/generate_bidi.mjs[R207-210]

+function stripReffyCddlHeaderPrefix(ast) {
+  for (const def of ast) {
+    if (/^CDDL[a-z]/.test(def?.Name ?? '')) def.Name = def.Name.slice('CDDL'.length)
+  }
Evidence
Compliance rule 4 requires focused coverage for changed behavior. The cited helper introduces a
name-rewriting workaround used for every parsed CDDL input, and repository search shows no test
exercising the helper.

AGENTS.md: Provide Focused Tests and Avoid Contract-Misrepresenting Mocks
javascript/selenium-webdriver/generate_bidi.mjs[198-212]

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 new Reffy header workaround mutates parsed definition names without focused coverage proving that affected names are corrected and unrelated names remain unchanged.

## Fix Focus Areas
- javascript/selenium-webdriver/generate_bidi.mjs[198-212]

## Recommended Fix
Extract or export the cleanup helper for unit testing, then add cases for affected Digital Credentials names, unaffected definitions, missing names, uppercase characters after the prefix, and multiple definitions. Verify the helper preserves the AST apart from intended name corrections.

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



Remediation recommended

3. Python omits digital credentials types ✗ Dismissed 🐞 Bug ≡ Correctness
Description
BIDI_EXTENSION_CDDL_FILES adds Digital Credentials to the shared extension set, while Python's
create-bidi-src target still passes a hard-coded list without that specification. When Python
bindings are generated, its public BiDi package therefore lacks the Digital Credentials definitions
included in the JavaScript and shared-schema pipelines, and future externally listed modules will
diverge the same way.
Code

common/webref_cddl.bzl[R49-50]

+BIDI_EXTENSION_CDDL_FILES = [
+    "@digital_credentials_all_cddl//file:spec.cddl",
Evidence
The generated list explicitly includes Digital Credentials, and JavaScript passes that complete list
into generation. Python instead enumerates only Permissions, Prefetch, User Agent Client Hints, and
Web Bluetooth, while its output declaration also lacks a digital credentials module; the resulting
shared schema already contains digitalCredentials.* definitions, proving that the pipelines now
consume different specification sets.

common/webref_cddl.bzl[49-55]
javascript/selenium-webdriver/BUILD.bazel[90-96]
py/BUILD.bazel[762-774]
py/private/generate_bidi.bzl[11-29]
common/bidi/schema.json[14719-14799]

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 generated external-specification list is consumed by JavaScript but Python retains a separate hard-coded list, causing its generated BiDi package to omit Digital Credentials and future additions.

## Fix Focus Areas
- common/webref_cddl.bzl[49-55]
- py/BUILD.bazel[762-774]
- py/private/generate_bidi.bzl[11-29]

## Recommended Fix
Load and pass `BIDI_EXTENSION_CDDL_FILES` from `common/webref_cddl.bzl` in the Python target as well. Update the Python generation rule to declare the Digital Credentials module output and apply the required Reffy header-prefix correction before parsing that grammar.

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


Grey Divider

Context sources
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 11/18, lines 638/200; both must reach the floor). Router rationale: This is a behavior-changing build/tooling rewrite spanning dynamic spec discovery, generated Bazel dependencies, schema generation, and JavaScript parsing, with many independent paths where subtle defects could be missed in one pass.

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/update_cddl.py
Comment thread javascript/selenium-webdriver/generate_bidi.mjs
Comment thread common/webref_cddl.bzl
@titusfortner
titusfortner merged commit 0ba6df7 into SeleniumHQ:trunk Sep 19, 2026
50 checks passed
This was referenced Oct 1, 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 C-nodejs JavaScript Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants