Selenium BiDi Network APIs and CI Stability
Selenium, the browser automation project at SeleniumHQ/selenium, had 57 commits in the last week, and the useful thread is not a release note. The interesting work is a set of BiDi network helpers for Python, more .NET BiDi transport cleanup, and CI fixes that make browser tests less random.
Python BiDi network gets real handlers
The Python binding got the most user visible activity. The maintainers added a request handler API, then followed it with a response handler API, an auth handler API, and an extra headers API. That is more useful than raw BiDi event plumbing for most test suites.
The request handler tests show the intended shape. Code can register driver.network.add_request_handler("before_request", callback), call request.continue_request() from the callback, and remove the handler later. There is also a before_request_sent alias, which matters for people coming from protocol names and not Selenium helper names. The sharp edge is explicit too: unsupported aliases raise ValueError instead of silently doing nothing.
def callback(request):
request.continue_request()
callback_id = driver.network.add_request_handler("before_request", callback)
driver.browsing_context.navigate(
context=driver.current_window_handle,
url=target_url,
wait=ReadinessState.COMPLETE,
)
driver.network.remove_request_handler("before_request", callback_id)
For teams replacing CDP based network hooks, this is the part to track. It moves common tasks like request inspection, auth, and header setup into the Selenium API surface. The browser support matrix is still not magic. The tests still mark data URL behavior as expected to fail in major browsers, so treat this as active API hardening, not a promise that every network edge case is finished.
Python script BiDi is being aligned
The network work did not land alone. The maintainers also aligned the Python BiDi script module with the cross binding API design. That sounds internal, but it matters if a suite mixes script events, preload scripts, network callbacks, and classic WebDriver calls.
BiDi has been growing module by module in Selenium. A consistent Python shape reduces small translation costs between examples and bindings. Fewer special cases also helps generated code, because the project is building a lot of this surface from protocol data plus a local enhancement manifest.
Concrete items worth checking in Python suites:
driver.network.add_request_handlerdriver.network.remove_request_handlerdriver.network.clear_request_handlersdriver.network.add_auth_handlerdriver.network.remove_auth_handlerdriver.browsing_context.navigate
The practical advice is simple. If a test suite already has wrapper code around BiDi network calls, keep it thin for now. Selenium is adding the helpers that wrappers usually provide.
.NET BiDi keeps separating transport
The .NET binding had a cluster of BiDi commits that look like plumbing, but they point in a clean direction. The maintainers made it possible to use an external transport, then introduced a fake BiDi transport for tests. That is the kind of change that pays off when protocol code needs fast unit tests and fewer live browser dependencies.
The current .NET shape uses a BiDiOptionsBuilder with a default WebSocket transport. It can configure ClientWebSocketOptions, while an internal ITransport boundary handles send and receive. Users may not touch that boundary directly, but contributors should care. It gives the binding a place to test broker behavior, event streams, cancellation, and disposal without launching a browser for every case.
There was also JSON cleanup. The maintainers added additional JSON data for commands and results, added additional JSON data for event args, and fixed reflection based deserialization of additional data. If you maintain .NET BiDi tests, this is a signal to add cases around unknown fields and vendor fields. Protocols move. Clients should not fall over because a remote end sent one more property.
CI fixes are about noisy browsers
Several commits were boring in the useful way. The build workflow now starts X server before launching Fluxbox. That is exactly the kind of ordering bug that only appears when a runner is cold, slow, or both. Browser automation CI is full of these paper cuts.
Windows cleanup was adjusted too. One commit deleted pre installed browsers and drivers in CI, then a follow up kept Windows browsers and deleted only drivers. That reversal is useful context. Cleaning too much on hosted runners can create fresh failure modes, especially when the build expects a browser to exist but wants Selenium Manager or pinned drivers to control the driver side.
The build also got better failure reporting. The maintainers improved Bazel error messages and aggregate lint errors instead of failing fast. For contributors, that means less push and wait when fixing style or target failures. Small mercy, real time saved.
How to prepare
- Python users should watch the BiDi network helper names and keep custom wrappers narrow. The API is becoming easier to call directly.
- .NET contributors should add tests for extra JSON fields and transport failure paths. The new transport split makes that cheaper.
- CI maintainers running Selenium forks should review browser cleanup on Windows and display startup on Ubuntu. Those two areas changed because they were causing noise.
This was not a release week story. It was a maintenance week with real API movement under it. The part worth reading is where Selenium is replacing low level BiDi ceremony with binding level helpers, while also making the build less annoying to trust.