8000 feat(webdriver): W3C Actions API (key, pointer, wheel) by adeelahmad · Pull Request #13 · adeelahmad/Tether · GitHub
[go: up one dir, main page]

Skip to content

feat(webdriver): W3C Actions API (key, pointer, wheel) - #13

Merged
adeelahmad merged 5 commits into
mainfrom
claude/wd-actions-s9sfyc
Oct 11, 2026
Merged

adeelahmad merged 5 commits into
mainfrom
claude/wd-actions-s9sfyc

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

What

Before: POST /session/{id}/actions returned unknown command, so Selenium ActionChains (hover, drag and drop, double/context click, key chords, scroll) failed.

After: POST and DELETE /session/{id}/actions implement the W3C Actions API. Key, mouse, pen, touch and wheel actions become real CDP input events, so pages see trusted events.

  • Tick-by-tick execution across sources; pause, and pointerMove/scroll with duration animate frame by frame.
  • viewport, pointer and element origins (element in-view centre; off-screen elements are scrolled into view). Out-of-viewport targets give move target out of bounds.
  • All W3C key codes (left/right modifiers, F-keys, numpad), US-layout Shift, Ctrl/Meta chords without text; key-source modifiers apply to pointer and wheel events.
  • Click counting (down/up/down/up is a double click), pen pressure/tilt/twist, multi-touch.
  • Input state persists until Release Actions, which lets go of everything still held.

Why

Part of the first-release feature set: "most Selenium scripts just work" needs ActionChains.

How

New internal/webdriver/actions.go parses and validates the body (sources are only created once the whole body is valid), then dispatches through two new cdp.Tab primitives, Mouse and Touch. Touch brings the tab to the front first, because Chrome never acknowledges touch input in a background tab (the dispatch hangs). cdptest.Tab now records input events and can return a script result, for unit tests.

How tested

  • make check equivalents: gofmt, go vet (with and without integration tag), golangci-lint (0 issues), go test -race ./...
  • make test-integration: new TestWebDriverActions against real headless Chrome covers double click, context click, ctrl-click, drag, shifted typing, touch tap, element below the fold, wheel scroll, out-of-bounds error and release
  • Docs updated (docs/WEBDRIVER.md Actions section, README roadmap, CHANGELOG)

Security

  • No new way to reach the browser without auth, and nothing new is logged that could hold a cookie or token.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EnJnokVdV3oFBMpLc45zcJ


Generated by Claude Code

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
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
@adeelahmad adeelahmad self-assigned this Oct 11, 2026
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
@adeelahmad
adeelahmad merged commit d571024 into main Oct 11, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0