Skip to content

fix(native): close the gaps the repo's gates found (11 of 13 pass in full) - #14

Merged
unohee merged 1 commit into
masterfrom
feat/native-gate-parity
Oct 25, 2026
Merged

unohee merged 1 commit into
masterfrom
feat/native-gate-parity

Conversation

@unohee

@unohee unohee commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Stacked on #13. The repo's own gates found gaps on the native driver; this PR closes them.

Gates on native (macOS, Chrome 155, cdp guard)

gate native playwright on the same machine
browser 63/63 fails at "declared submission executes"
click 120/120 pass
downloads 198/198 pass
dialogs 110/110 pass
forms 58/58 —
wait 130/130 —
motion 82/82 fails at "every batch loaded"
snapshot 148/148 —
click_refusal 272/272 fails at check 3
redirect_hop 354/354 fails at POST 307
scriptredirect 50/50 —
tabs 70 pass, then stops at the headful-relaunch check stops at the same check
cdp_guard 217 pass, including all 35 guard scenarios; only the Linux-only /proc sections fail times out

What the gates found

  • Escape opened chrome://help. nativeVirtualKeyCode is read in each platform's own key codes, and on macOS 27 is not Escape. Chrome took the key for a browser shortcut. The fix stops sending that field.
  • A popup arrived paused and the click that opened it hung, even with waitForDebuggerOnStart off. Each tab is now released with Runtime.runIfWaitingForDebugger before it is set up. Dedicated workers had the same problem and are released the same way. This does not release cdp_guard's own hold: 60 of 60 refused popup and iframe requests never reached the server (headless and headful), and all 35 guard scenarios pass.
  • A popup now counts as a tab only once its URL commits, which is how Playwright handles it. A popup the guard refused is never a tab. A download such a popup starts belongs to its opener.
  • click and press now wait for a navigation they requested, as Playwright's do.
  • Refs stay the same across snapshots of one document.
  • The stability check no longer fails in frames that never paint. It falls back to comparing boxes when a frame gets no animation frames.
  • API gaps the gates hit directly, now filled:
    • the enter-frame selector;
    • Page.frames, content, input_value and click;
    • set_default_timeout;
    • context cookies.

page.evaluate still runs in an isolated world by default, as patchright does. The tabs gate reads the page's own globals with world="main".

@unohee
unohee force-pushed the feat/native-rollout-docs branch from b2bbf85 to 1af6429 Compare October 25, 2026 04:03
…full)

Run on the native driver, scripts/verify_*_e2e.py found what the smokes did
not. Each fix below is measured against the gate that found it:

- Keys: no nativeVirtualKeyCode. It is read in the platform's own codes; on
  macOS 27 is not Escape, and Chrome took it for a browser shortcut that
  opened chrome://help, which the session then followed (browser).
- Popups: every attached tab is released with Runtime.runIfWaitingForDebugger
  before it is set up. A window.open popup arrives paused even with
  waitForDebuggerOnStart off, and the click that opened it got no answer
  (Input.dispatchMouseEvent hung). cdp_guard's own hold is not released by it:
  measured, 60 of 60 refused popup and iframe requests never reached the
  server, headless and headful, and all 35 guard scenarios pass.
- A popup opened with a URL is reported once that URL commits, as Playwright
  reports it: one refused by the guard (or a 204) is never a tab (tabs);
  a download such a popup starts belongs to its opener (downloads).
- Dedicated workers are attached only to be released: one arrived paused and
  never ran (cdp_guard workers-fetch-away).
- click / press wait for a navigation they requested to commit or stop, as
  Playwright's do: a click on a slow link times out (click), Enter that leaves
  the site answers blocked_by_policy (click_refusal).
- Refs are stable within a document: a region read hands out the refs the
  whole page did (snapshot).
- Stability falls back to comparing boxes when a frame gets no animation
  frames (a sandboxed ad frame) instead of reporting "not stable".
- internal:control=enter-frame in selectors; Page.frames / main_frame
  (url, evaluate, wait_for_load_state) with evaluation sent to the frame's
  own session; Page.content, input_value, click; Context/Page
  set_default_timeout; Context cookies / add_cookies / clear_cookies.
- verify_tabs_e2e.py reads the page's own globals with world="main" through
  tools.forms._main_world, as patchright would need too.

Gates on native (macOS, Chrome 155): browser 63, click 120, downloads 198,
dialogs 110, forms 58, wait 130, motion 82, snapshot 148, click_refusal 272,
redirect_hop 354, scriptredirect 50 pass in full; tabs passes 70 and stops at
the headful-relaunch check the playwright driver stops at here; cdp_guard
passes 217 and fails only its Linux-only /proc sections. pytest 1755 passed;
the native smokes and the parity script pass.
@unohee
unohee force-pushed the feat/native-gate-parity branch from e2da7c4 to 986f28b Compare October 25, 2026 04:06
@unohee
unohee changed the base branch from feat/native-rollout-docs to master October 25, 2026 04:06
@unohee
unohee marked this pull request as ready for review October 25, 2026 04:06
@unohee
unohee merged commit d279de9 into master Oct 25, 2026
4 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.

1 participant