Repository navigation
WebDriver: frames, shadow roots, alerts, windows, uploads and print - #12
Merged
Merged
Conversation
Extend the single global --allow-domains list into layered policies:
- internal/policy: domain rules (allow/deny, *.sub, *), principals and a
JSON --policy-file defining named tokens with their own rules, an admin
flag and a scripts permission. --deny-domains adds a global denylist.
- Auth attaches the token's principal to the request context; --token is
the admin "default" principal.
- Tab ownership: non-admin tokens only see their own tabs, get their own
per-site default tabs, and cannot adopt existing tabs.
- core.RulesPolicy checks global ∩ requester ∩ owner ∩ session rules,
re-checks the final URL, and guards restricted tabs in the browser via
the DevTools Fetch domain so redirects, clicks and page script obey the
same rules.
- API: session rules on tab create, GET/PUT /tabs/{id}/policy, /whoami.
WebDriver: tether:options.policy, ownership on every command, and
Execute Script gated by the scripts permission.
- Docs: docs/POLICIES.md, SECURITY.md, ARCHITECTURE.md, README, example
policy file. Integration test drives a real Chrome as a restricted token.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfsJJgC4Jp8VqckdcChH4W
…rint Close the remaining WebDriver gaps on top of new cdp.Tab primitives: - Switch To Frame / Parent Frame for same- and cross-site (out-of-process) frames at any depth, via cdp.Tab.InFrame and iframe auto-attach. - Get Element Shadow Root and Find From Shadow Root, including closed roots; shadow roots round-trip through scripts. - Alert commands and unhandledPromptBehavior; calls blocked by a dialog fail fast instead of hanging. - Multiple windows: New Window, popups joined automatically, switching, closing; the session ends with its last window. - Window rect, maximise, minimise and fullscreen, applied only to windows that hold nothing but Tether tabs. - File inputs via Element Send Keys plus Selenium's /se/file upload. - Print Page. - Focus emulation on attached tabs so input reaches background tabs with cross-site iframes promptly. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhaxD4mv92X8w5zV8j34MD
POST/DELETE /session/{id}/actions dispatch key, mouse, pen, touch and
wheel input as real CDP events, tick by tick, with element/pointer/viewport
origins, animated moves and scrolls, click counting, US-layout Shift, and
input state that persists until Release Actions.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EnJnokVdV3oFBMpLc45zcJ
…t click Chrome routes input into frames asynchronously, and on some versions a real click into a cross-site frame of a background tab never arrives. Arm a one-shot listener before clicking inside a frame, wait briefly for it, and click from script if the real click did not land. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhaxD4mv92X8w5zV8j34MD
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhaxD4mv92X8w5zV8j34MD
Attaching to a tab that is closing can fail after Target.getTargetInfo succeeds (Page.enable: session not found). Map that to ErrNoSuchTab so faces answer 410/no such window instead of 500. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhaxD4mv92X8w5zV8j34MD
Resolves conflicts with #7 (console logs): Tab gets both Guard and Logs, the API keeps the policy routes and adds /tabs/{id}/logs, and docs list both features. Also makes TestConsoleLogs tolerate a late favicon 404 between the two WebDriver log reads (it asserted the second read was empty; it should assert no entry repeats). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9CEjRcHsJmgWdtz6ZTKsk
Tab gains Mouse/Touch alongside Guard and Logs; the WebDriver session keeps the log cursor and the Actions input state; docs list everything. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9CEjRcHsJmgWdtz6ZTKsk
# Conflicts: # README.md # internal/cdp/cdptest/cdptest.go
Conflict resolution plus one fix the combination needs: popups and new windows now belong to the session that opened them. A popup is attached as the session's own tab (same owner, same session rules, guarded), so a non-admin token can switch to its popups, and a restricted session can no longer leave its allowlist through window.open or New Window. A popup that loaded a forbidden page before Tether attached is closed and the switch fails. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9CEjRcHsJmgWdtz6ZTKsk
# Conflicts: # CHANGELOG.md # docs/WEBDRIVER.md # internal/cdp/cdptest/cdptest.go # internal/webdriver/errors.go # internal/webdriver/webdriver.go # test/integration/integration_test.go
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.
Requested by Adeel · project thread
What
Before: WebDriver sessions were one tab with no frames, shadow DOM, dialogs, extra windows, window control, file uploads or PDF. Those commands returned
unknown commandorunsupported operation.After: Selenium scripts that use these features work against the real browser:
unhandledPromptBehavior(all five values). A click or navigation that opens a dialog returns normally; a script that opens one returnsnull.window.open,target=_blank) join the session automatically, switching, closing. The session ends with its last window, and deleting it closes the windows it owns.window/new {"type":"window"}ortether:options.newWindow). Windows shared with the person's tabs are left alone, as before.<input type=file>sets files throughDOM.setFileInputFiles, and Selenium's/se/fileremote upload is supported. Uploaded files are deleted when the session ends.Why
These were the gaps listed in
docs/WEBDRIVER.md, and they are needed for the first release. The Actions API is being done in a separate PR.How
cdp.TabgainedInFrame(path),ShadowRoot,SetFiles,PrintPDF,Dialog/HandleDialog.cdp.BrowsergainedNewWindow,Window/SetWindow, andTabInfo.OpenerID.ErrDialogOpeninstead of hanging on a blocked page.Emulation.setFocusEmulationEnabled, which fixes this without taking focus.How tested
make checkequivalents: gofmt,go vet(with and withoutintegration, and on Go 1.23), golangci-lint v2.5.0 (0 issues), unit tests with-racemake test-integration: four new end-to-end tests against real headless Chromium (frames incl. an out-of-processlocalhostframe inside a127.0.0.1page, open and closed shadow roots, all dialog types and prompt behaviours, popups, new tabs and windows, resizing, local and remote uploads, PDF). All pass, along with the existing tests.docs/WEBDRIVER.md,docs/ARCHITECTURE.md, README table, SECURITY threat model, CHANGELOG)Security
/se/fileendpoint sits behind the same auth. Archive entry names are reduced to a base name (no zip-slip), and unpacked size is capped at 256 MiB.🤖 Generated with Claude Code
https://claude.ai/code/session_01AhaxD4mv92X8w5zV8j34MD
Generated by Claude Code