Skip to content

[py] Align BiDi script module with the cross-binding API design#17624

Merged
AutomatedTester merged 2 commits into
trunkfrom
py-bidi-script-alignment
Jun 4, 2026
Merged

[py] Align BiDi script module with the cross-binding API design#17624
AutomatedTester merged 2 commits into
trunkfrom
py-bidi-script-alignment

Conversation

@AutomatedTester
Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

Aligns driver.script with the Script Module section of the BiDi Protocol API Design (Phase 5, following #17619 and #17623):

  • add_error_handler(callback) / add_console_handler(callback) deliver the doc's ScriptError / ConsoleMessage payloads carrying source URL, line/column numbers and a formatted stack trace (extracted from the BiDi stackTrace call frames). The longer-standing add_javascript_error_handler / add_console_message_handler keep their generated log-entry payloads unchanged
  • clear_error_handlers() / clear_console_handlers() / clear_dom_mutation_handlers() counterparts for every handler family (each clears both the doc-named and legacy registrations of its category)
  • pin() now returns a PinnedScript(id, source, realm) — a str subclass, so existing code that treats the return value as a plain script ID keeps working — and execute(pinned, code) returns a non-raising ScriptResult(value, error, realm); the legacy execute(function_declaration, *args) path is unchanged
  • add_dom_mutation_handler(callback, mutation_types=...) can now observe childList and characterData mutations (DomMutation gains type, target, added_nodes, removed_nodes); the default stays attributes-only so existing handlers see no behavior change

🔧 Implementation Notes

  • The subscription machinery moves out of the enhancement-manifest glue strings into a new py/private/_script_handlers.py helper module (same pattern as _network_handlers.py): LogHandlerRegistry shares a single log.entryAdded subscription across all console/error handlers (previously each handler family managed its own bookkeeping), and DomMutationRegistry owns the observer preload scripts and the script.message channel
  • script.addPreloadScript arguments may only be channels, so the mutation-type options are inlined into the preload function declaration rather than passed as a LocalValue argument
  • The shared javascript/bidi-support/bidi-mutation-listener.js is intentionally untouched — Java (RemoteScript) and the JS binding embed it, so the extended listener (attributes/childList/characterData behind an options object) lives Python-side in the helper module for now
  • Handlers that request additional mutation types install one further observer covering only the missing types, so no mutation is ever reported twice; each handler only receives the types it registered for

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code
    • What was generated: _script_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: BiDi script-module manifest glue — the log/mutation subscription machinery was refactored into the helper module; all pre-existing bidi_script_tests pass unmodified on both browsers
  • Verified locally: 17 new unit tests (FakeConnection recorder pattern); full bidi_script_tests integration suites green on Chrome and Firefox (90 tests each, including 7 new alignment tests and 4 new mutation-type tests)
  • The upstream doc's Script Module section is still marked [WIP]; naming here follows the doc as written (add_error_handler, add_console_handler, clear_*)
  • Follow-up: file an issue to converge the bindings on an options-aware shared bidi-mutation-listener.js (Java/JS currently emit attributes only); cross-binding parity for the doc-aligned naming is also follow-up
  • Remaining phases: callback-based authentication handlers with cancel(), extra-headers API

🔄 Types of changes

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

Adds the script-module surface from the BiDi protocol API design doc:

- add_error_handler / add_console_handler deliver ScriptError and
  ConsoleMessage payloads carrying source URL, line/column numbers and a
  formatted stack trace; the existing add_javascript_error_handler /
  add_console_message_handler keep their generated log-entry payloads
- clear_error_handlers / clear_console_handlers / clear_dom_mutation_handlers
  counterparts for every handler family
- pin() now returns a PinnedScript (a str subclass, so existing code using
  the return value as a script ID keeps working) and execute(pinned, code)
  returns a non-raising ScriptResult(value, error, realm)
- add_dom_mutation_handler grows an opt-in mutation_types parameter
  (attributes, childList, characterData); the default stays attributes-only
  for compatibility

The subscription machinery moves out of manifest glue strings into a new
py/private/_script_handlers.py helper module (same pattern as
_network_handlers.py), with LogHandlerRegistry sharing one log.entryAdded
subscription across all console/error handlers and DomMutationRegistry
owning the observer preload scripts and script.message channel.

The childList/characterData observation uses a Python-side extended
listener; the shared javascript/bidi-support/bidi-mutation-listener.js is
intentionally untouched (Java and JS bindings consume it) - converging the
bindings on the extended listener is follow-up work.
@selenium-ci selenium-ci added C-py Python Bindings B-build Includes scripting, bazel and CI integrations labels Jun 4, 2026
@AutomatedTester AutomatedTester merged commit c1ffd8c into trunk Jun 4, 2026
39 of 41 checks passed
@AutomatedTester AutomatedTester deleted the py-bidi-script-alignment 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

B-build Includes scripting, bazel and CI integrations C-py Python Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants