Skip to content

[py] Add high-level BiDi network response handler API#17623

Merged
AutomatedTester merged 2 commits into
trunkfrom
py-bidi-network-response-handlers
Jun 4, 2026
Merged

[py] Add high-level BiDi network response handler API#17623
AutomatedTester merged 2 commits into
trunkfrom
py-bidi-network-response-handlers

Conversation

@AutomatedTester
Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

Adds the doc-aligned high-level response interception API to driver.network (Phase 2 of the BiDi Protocol API Design, following #17619):

  • add_response_handler(callback) / add_response_handler(url_patterns, callback) with the same glob URL patterns as request handlers (*, **, ?), plus remove_response_handler(handler_id) and clear_response_handlers()
  • New Response object at the responseStarted intercept phase exposing url, status, reason_phrase, headers, mime_type, with set_status/set_headers/set_cookies/set_body mutators (BiDi does not expose the original body or parsed cookies at this phase, so those start empty)
  • After all matching handlers run, the outcome is reconciled into exactly one BiDi command per response: a mutated body is delivered via network.provideResponse (carrying over the current status/headers), other mutations via network.continueResponse, untouched responses are continued unmodified — observer-only handlers never stall the page
  • Graceful degradation: if the browser rejects provideResponse at this phase (Firefox only supports the body parameter at beforeRequestSent), the response is continued with the remaining mutations instead of leaving the page blocked

🔧 Implementation Notes

  • The request/response registries now share a _BaseHandlerRegistry in py/private/_network_handlers.py parameterized by intercept phase, event key and wrapper class; RequestHandlerRegistry behavior is unchanged (all pre-existing unit tests pass unmodified)
  • clear_request_handlers() (the legacy clear-everything sweep) now preserves response-handler intercepts and re-establishes the response registry's event subscription; clear_response_handlers() symmetrically only touches response handlers
  • The response_started event is overridden in the enhancement manifest to deliver raw dict params — the same fix the manifest already applies to auth_required/before_request, because the generated ResponseStartedParameters dataclass only keeps response, dropping request, isBlocked and intercepts (without this, blocked responses were never continued and navigation hung)

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code
    • What was generated: Response/registry refactor in _network_handlers.py, manifest glue, and tests, from the BiDi Protocol API Design doc
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

  • High-risk area: wire-level network interception semantics — the new reconciliation applies to the new-style response handlers only; request-handler and legacy paths are preserved
  • Verified locally: 39/39 unit tests; live browser runs — Chrome 23 passed / 1 skipped, Firefox 22 passed / 2 xfailed (test_change_response_body xfails on Firefox with the provideResponse phase limitation)
  • Remaining phases: callback-based authentication handlers with cancel(), extra-headers API, Script module alignment
  • Cross-binding parity (Java/Ruby/JS) for the doc-aligned naming is follow-up work

🔄 Types of changes

  • New feature (non-breaking change which adds functionality and tests!)

Phase 2 of the BiDi protocol API design: add_response_handler /
remove_response_handler / clear_response_handlers with a Response
object surface (status, headers, mime_type, set_status / set_headers /
set_cookies / set_body) at the responseStarted intercept phase.

Mutated bodies are delivered via network.provideResponse (carrying over
the current status and headers); other mutations via
network.continueResponse; untouched responses are continued unmodified
so observers never stall the page.  If provideResponse is unsupported
at this phase (Firefox), the response is continued with the remaining
mutations instead of staying blocked.

The request/response registries now share a common base, and
clear_request_handlers preserves response handlers (and vice versa).
The response_started event is overridden to deliver raw dict params,
matching the existing auth_required override, because the generated
ResponseStartedParameters dataclass drops request/isBlocked/intercepts.
@AutomatedTester AutomatedTester force-pushed the py-bidi-network-response-handlers branch from c40c1e7 to 3f73196 Compare June 4, 2026 13:53
@AutomatedTester AutomatedTester merged commit 1c84a03 into trunk Jun 4, 2026
38 of 40 checks passed
@AutomatedTester AutomatedTester deleted the py-bidi-network-response-handlers branch June 4, 2026 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-py Python Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants