[py] Use generated Bidi files instead of hand curated ones#17266
[py] Use generated Bidi files instead of hand curated ones#17266AutomatedTester wants to merge 31 commits intotrunkfrom
Conversation
…revert unrelated requirements changes
… the window to the size we want
There was a problem hiding this comment.
Pull request overview
This PR migrates Selenium’s Python WebDriver BiDi implementation from hand-curated source files to Bazel-generated modules produced from the BiDi CDDL specification (per #16914), and adjusts supporting build/test infrastructure accordingly.
Changes:
- Remove the hand-maintained
py/selenium/webdriver/common/bidi/*modules and wire Bazel to generate them fromcommon/bidi/spec/*.cddl. - Update Python runtime plumbing to support generated BiDi dataclasses over WebSocket (custom JSON encoding +
RemoteWebDriver.execute()accepting BiDi command generators). - Add/adjust supporting tooling and tests (local dev copy task, CLI alias, minor test robustness tweaks).
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/update_copyright.py | Stop excluding a removed BiDi file from copyright updates. |
| rake_tasks/python.rake | Copy generated BiDi files into the source tree for local dev workflows. |
| py/test/selenium/webdriver/common/bidi_browsing_context_tests.py | Make viewport assertions tolerant to minor WM differences. |
| py/test/selenium/webdriver/common/bidi_browser_tests.py | Update imports/constants + locator usage to match generated BiDi APIs. |
| py/selenium/webdriver/remote/websocket_connection.py | Add BiDi-oriented JSON encoding for dataclass payloads when sending WS commands. |
| py/selenium/webdriver/remote/webdriver.py | Allow execute() to accept BiDi command generators and route them via WebSocket. |
| py/selenium/webdriver/common/proxy.py | Add __future__ annotations + formatting adjustments. |
| py/selenium/webdriver/common/by.py | Add __future__ annotations + reformat ByType literal. |
| py/selenium/webdriver/common/bidi/webextension.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/storage.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/session.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/script.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/permissions.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/network.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/log.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/input.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/emulation.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/console.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/common.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/browsing_context.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/browser.py | Remove hand-curated BiDi module (replaced by generated). |
| py/selenium/webdriver/common/bidi/init.py | Remove hand-curated package init (replaced by generated). |
| py/selenium/common/exceptions.py | Formatting-only changes to exception constructors. |
| py/private/generate_bidi.bzl | Add Bazel rule to generate BiDi Python modules from CDDL. |
| py/private/cdp.py | Tighten devtools version directory detection. |
| py/private/_event_manager.py | Add shared event manager used by generated BiDi modules. |
| py/private/BUILD.bazel | Export generator support files for Bazel consumption. |
| py/conftest.py | Add --browser CLI alias for --driver. |
| py/BUILD.bazel | Wire BiDi generation into the Python build graph. |
| py/AGENTS.md | Update Python 3.10+ guidance for agents/contributors. |
| dotnet/src/webdriver/BiDi/EventDispatcher.cs | Refactor event dispatcher internals (currently contains compile-breaking issues). |
| common/bidi/spec/remote.cddl | Add BiDi CDDL “remote” spec inputs for generation. |
| common/bidi/spec/local.cddl | Add BiDi CDDL “local” spec inputs for generation. |
| common/bidi/spec/BUILD.bazel | Export CDDL specs for the Python generator rule. |
Comments suppressed due to low confidence (2)
dotnet/src/webdriver/BiDi/EventDispatcher.cs:43
- The channel is typed as
Channel<EventItem>, but this file only definesPendingEventandEnqueueEventwritesPendingEventinstances. This won’t compile unlessEventItemexists and matches the written type; either switch the channel back toChannel<PendingEvent>or introduce a consistentEventItemtype and use it everywhere.
private readonly Channel<EventItem> _pendingEvents = Channel.CreateUnbounded<EventItem>(new()
{
SingleReader = true,
SingleWriter = true
});
dotnet/src/webdriver/BiDi/EventDispatcher.cs:99
- Inside
ProcessEventsAsync, the loop reads intoevt, but the code still referencesresult.Method/result.EventArgs. This won’t compile and will also read the wrong values. Use the variable you actually read from the channel consistently (and ensure its type matches the channel’s item type).
while (await reader.WaitToReadAsync().ConfigureAwait(false))
{
while (reader.TryRead(out var evt))
{
if (_eventRegistrations.TryGetValue(result.Method, out var registration))
{
foreach (var handler in registration.GetHandlers()) // copy-on-write array, safe to iterate
{
var runningHandlerTask = InvokeHandlerAsync(handler, result.EventArgs);
if (!runningHandlerTask.IsCompleted)
{
| var subscribeResult = await _sessionProvider().SubscribeAsync([eventName], new() { Contexts = options?.Contexts, UserContexts = options?.UserContexts }, cancellationToken).ConfigureAwait(false); | ||
|
|
||
| registration.AddHandler(eventHandler); | ||
|
|
||
| return new Subscription(subscribeResult.Subscription, this, eventHandler); | ||
| return new Subscription(subscribeResult.Subscription, this, eventHandler); | ||
| } | ||
| catch | ||
| { | ||
| registration.RemoveHandler(eventHandler); | ||
| throw; | ||
| } |
There was a problem hiding this comment.
SubscribeAsync has a catch block without a corresponding try and the return statement is mis-indented, which will not compile. Wrap the subscription + registration logic in a try and keep the catch immediately after it, or remove the catch if it’s not needed.
|
We need to add the directory to ruff config in You can add it to: |
|
@AutomatedTester I pushed a fix to your branch that resolves all the comments I made and also adds the generated files to |
CI Feedback 🧐A test triggered by this PR failed. Here is an AI-generated analysis of the failure:
|
|
there are still some linting/formatting errors in the new generation code |
🔗 Related Issues
💥 What does this PR do?
Deletes all the hand curated bidi code in the python tree and uses the generated code created in #16914 . Once that PR is approved we can merge this into there or do it into trunk as a 2nd PR. #16914 MUST BE FIRST INTO TRUNK
🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes