[py] generate the internal BiDi protocol layer from the shared binding-neutral schema#17761
[py] generate the internal BiDi protocol layer from the shared binding-neutral schema#17761titusfortner wants to merge 11 commits into
Conversation
…or and verify test
… clean ref object-shape error
PR Summary by QodoAdd generated internal Python BiDi protocol layer (selenium.webdriver._bidi)
AI Description
Diagram
High-Level Assessment
Files changed (26)
|
There was a problem hiding this comment.
Pull request overview
This PR adds a new internal Python WebDriver BiDi protocol layer under selenium.webdriver._bidi, generated from the shared binding-neutral BiDi schema, plus a small handwritten runtime (serialization + transport seam) and Bazel/CI wiring to keep checked-in generated files in sync.
Changes:
- Introduces the generated internal
_bidiprotocol package (domains, types, commands/events metadata) and a handwritten runtime (serialization.py,transport.py). - Wires
RemoteWebDriverto create a per-session_bidi_transportlazily when BiDi is started. - Adds unit + end-to-end tests, plus a
verify-bidi-protocolBazel target and CI step to detect drift/hand-edits.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
py/verify_bidi_protocol.py |
Verifies checked-in _bidi files match generator output. |
py/test/unit/selenium/webdriver/common/bidi_transport_tests.py |
Unit coverage for the handwritten transport/domain seam. |
py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py |
Unit coverage for strict (de)serialization runtime rules. |
py/test/unit/selenium/webdriver/common/bidi_protocol_command_tests.py |
Exercises generated command surfaces over a stand-in transport. |
py/test/selenium/webdriver/common/bidi_protocol_tests.py |
Browser-level sanity checks that generated types round-trip against a real BiDi session. |
py/selenium/webdriver/remote/webdriver.py |
Adds _bidi_transport lifecycle + lazy import/creation in _start_bidi(). |
py/selenium/webdriver/_bidi/__init__.py |
Generated package initializer exporting domain classes. |
py/selenium/webdriver/_bidi/serialization.py |
Handwritten serialization runtime used by generated records/unions (plus registry). |
py/selenium/webdriver/_bidi/transport.py |
Handwritten websocket seam (Transport) and base domain (Domain). |
py/selenium/webdriver/_bidi/browsing_context.py |
Generated browsingContext domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/bluetooth.py |
Generated bluetooth domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/browser.py |
Generated browser domain (types + commands). |
py/selenium/webdriver/_bidi/emulation.py |
Generated emulation domain (types + commands). |
py/selenium/webdriver/_bidi/input.py |
Generated input domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/log.py |
Generated log domain (types + event metadata). |
py/selenium/webdriver/_bidi/network.py |
Generated network domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/permissions.py |
Generated permissions domain (types + commands). |
py/selenium/webdriver/_bidi/script.py |
Generated script domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/session.py |
Generated session domain (types + commands). |
py/selenium/webdriver/_bidi/speculation.py |
Generated speculation domain (types + event metadata). |
py/selenium/webdriver/_bidi/storage.py |
Generated storage domain (types + commands). |
py/selenium/webdriver/_bidi/user_agent_client_hints.py |
Generated userAgentClientHints domain (types + commands). |
py/selenium/webdriver/_bidi/web_extension.py |
Generated webExtension domain (types + commands). |
py/BUILD.bazel |
Adds generator target, _bidi library, and verify test; packages _bidi. |
.github/workflows/ci-python.yml |
Runs //py:verify-bidi-protocol in CI alongside unit tests. |
Code Review by Qodo
Context used✅ Compliance rules (platform):
17 rules 1.
|
| rendered = gen.render_all(schema_path) | ||
| stale = [ | ||
| name | ||
| for name, contents in rendered.items() | ||
| if not (bidi_dir / name).exists() or (bidi_dir / name).read_text() != contents | ||
| ] |
There was a problem hiding this comment.
5. Verifier misses extra files 🐞 Bug ⚙ Maintainability
verify_bidi_protocol.py only checks that files produced by the generator match the committed copies; it never fails if _bidi/ contains extra .py files not produced by the generator. This can allow removed/renamed generated modules to linger unnoticed.
Agent Prompt
## Issue description
The verification step does not detect extra files present on disk but not produced by `render_all()`, so stale generated modules can persist.
## Issue Context
This is a drift-guard completeness gap: it catches mismatches for expected outputs but not unexpected leftovers.
## Fix Focus Areas
- py/verify_bidi_protocol.py[36-41]
## Implementation direction
- After computing `rendered`, list `bidi_dir/*.py` (and possibly exclude hand-written runtime files like `serialization.py`, `transport.py`) and fail if any generated-looking file is not in `rendered.keys()`.
- Print the unexpected file list alongside stale mismatches.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| # bazel run //py:generate-bidi-protocol | ||
|
|
||
|
|
||
| from __future__ import annotations |
There was a problem hiding this comment.
We should not be checking in generated code
There was a problem hiding this comment.
My original thought was to check it in until we used it to implement the user facing code, but we can change it to build only now after we've agreed that this is the right shape for the generated code.
Do you have any concerns with the conventions or naming of the output?
🔗 Related Issues
💥 What does this PR do?
selenium.webdriver._bidipackage with code generated from the CDDL via a shared binding-neutral schema🔧 Implementation Notes
common/bidicode and its CDDL generator are left untouched — retiring or migrating that is out of scope.Transportis built per session and owned by theWebDriver(imported lazily so non-BiDi sessions don't load the generated package)bazel run //py:generate-bidi-protocol. The files are committed here for review only; a follow-up will move generation to build time (see Considerations).🤖 AI assistance
💡 Additional Considerations
🔄 Types of changes