Repository navigation
feat: waitForNetworkIdle / waitForResponse (CDP + BiDi) - #85
Merged
Merged
Conversation
Prototype per the 09-26 design note: CDP path on Chromium, BiDi path on browsers implementing HasBiDi (Firefox), throws on neither. Both paths track an in-flight request counter + last-activity timestamp; idle means the counter is 0 and quietFor has elapsed, bounded by an overall timeout. Verified manually against real headless Chrome (not part of the unit suite, no browser required there): - Static page: idle correctly at ~quietFor after load (545ms observed for quietFor=500ms). - Page with a request fired 200ms after load, taking 1.5s to respond: wait correctly extends past it (2361ms observed vs. a naive page-load-only wait), proving it isn't just measuring page load. Not verified against Firefox/BiDi locally — the firefox binary here is an unconfigured snap stub, no real browser available. Code path mirrors the CDP one exactly (in-flight counter + BeforeRequestSent/ ResponseCompleted/FetchError) but is unexercised. Spike only — not wired into WaitEngine's public API, no unit tests added (needs a real browser, which the existing suite deliberately avoids). Next: decide scope (wire into WaitEngine, add waitForResponse(urlPattern), pick BiDi-only vs BiDi+CDP everywhere) and verify the BiDi path against real Firefox before that. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Installed a real Firefox (156.0.1, official Mozilla tarball — the system 'firefox' was an unconfigured snap stub) + geckodriver v0.37.1 locally and ran the same delayed-slow-request scenario used to verify the CDP path. Result: firefox idle-reached ms=2300, matching the Chrome CDP result (2361ms) for the same scenario (200ms delay + 1.5s response + 500ms quietFor). BiDi path (onBeforeRequestSent/onResponseCompleted/ onFetchError via org.openqa.selenium.bidi.module.Network) confirmed working on a real browser, not just code-reviewed. Also verified end-to-end in selenium-boot-test (the consumer demo suite) via a throwaway test — real BaseTest lifecycle, real Chrome, real consumer classpath — same result, removed after (not part of that repo's public example). Both CDP and BiDi paths are now verified. Remaining before this can be considered for merge (unchanged from the PR description): wire into WaitEngine's public API, decide waitForResponse(urlPattern) scope, add test coverage once the API shape is settled. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
Author
|
Update: installed a real Firefox (156.0.1, official tarball — the system one was an unconfigured snap stub) + geckodriver v0.37.1 and verified the BiDi path. Same scenario as the CDP verification (a page firing a delayed 1.5s-slow request): firefox idle-reached ms=2300, matching Chrome's 2361ms for the equivalent run. Both paths now proven on real browsers, not just reviewed. Also ran it end-to-end through Still needs before merge: wire into |
Builds out the spike into WaitEngine's real API:
- WaitEngine.waitForNetworkIdle() / waitForNetworkIdle(Duration quietFor)
— waits until no request has been in flight for the quiet period
(default 500ms), bounded by the configured explicit timeout.
- WaitEngine.waitForResponse(String urlPattern) /
waitForResponse(String urlPattern, Duration timeout) — waits for a
response whose URL matches (same glob syntax as NetworkMock.stub),
returns its HTTP status code.
- Both: CDP on Chrome/Edge, BiDi (org.openqa.selenium.bidi.module.Network)
on any HasBiDi driver (Firefox), UnsupportedOperationException on
neither.
Implementation split for testability: NetworkActivityTracker.IdleState
and ResponseLatch are pure, driver-independent logic (in-flight
counter + last-activity timestamp; a CompletableFuture-backed latch)
and are unit tested directly (8 new tests, 547/547 total green). CDP/
BiDi wiring itself needs a real browser and is verified manually —
same convention NetworkMockTest documents for CDP request
interception.
Real gap found and fixed while verifying end-to-end: without this,
Firefox raised a raw BiDiException ("Unable to create a BiDi
connection") instead of working out of the box, because
LocalFirefoxDriverProvider never requested a BiDi session. Fixed by
setting the "webSocketUrl" capability by default (an explicit value
in the user's own capabilities still wins) — otherwise every Firefox
user would have needed to know to add that capability manually,
breaking the framework's zero-config promise for this feature.
Verified twice end-to-end via selenium-boot-test (real BaseTest
lifecycle, real Chrome and real Firefox, zero manual config) with a
throwaway test removed after — not part of that repo's permanent
example. Chrome: waitForNetworkIdle correctly waited past a delayed
1.5s request; waitForResponse returned 200. Firefox: same, and
reproduced+fixed the BiDi gap in the same pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
shossain786
marked this pull request as ready for review
September 27, 2026 07:55
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
WaitEngine.waitForNetworkIdle()/waitForNetworkIdle(Duration quietFor)— waits until no request has been in flight for a quiet period (default 500ms), bounded by the configured explicit timeout.WaitEngine.waitForResponse(String urlPattern)/waitForResponse(String urlPattern, Duration timeout)— waits for a response whose URL matches (same glob syntax asNetworkMock.stub), returns its HTTP status code.Both: CDP on Chrome/Edge, BiDi on any
HasBiDidriver (Firefox),UnsupportedOperationExceptionon neither.Why
Design note from the 09-26 roadmap entry. Locator's stale-proof re-resolution (#67/#68) and zero-config (#66) closed the framework's other cold-start gaps; this is the next held-back item — waiting for network activity has been a hand-rolled Thread.sleep/JS-polling problem for every consumer until now.
How
Split for testability:
NetworkActivityTracker.IdleState(in-flight counter + last-activity timestamp) andResponseLatch(a CompletableFuture-backed latch) are pure, driver-independent logic — unit tested directly. CDP/BiDi wiring itself needs a real browser and is verified manually, same conventionNetworkMockTestdocuments for CDP request interception.Real gap found and fixed while verifying end-to-end: without this PR's fix, Firefox raised a raw BiDiException instead of working out of the box —
LocalFirefoxDriverProvidernever requested a BiDi session. Fixed by defaulting thewebSocketUrlcapability (an explicit value in the user's own capabilities still wins).Tests
IdleState/ResponseLatch— 547/547 total green.selenium-boot-test(real BaseTest lifecycle, zero manual config) against real Chrome and real Firefox — a delayed 1.5s request correctly extends the wait; waitForResponse returns the right status. Throwaway test removed after, not part of that repo's permanent example.🤖 Generated with Claude Code