Repository navigation
fix(chromium): do not hang on pages without a renderer when connecting over CDP - #42936
Conversation
…g over CDP When connecting to a browser where a tab has no renderer, e.g. because it was discarded by the Memory Saver or its renderer crashed, renderer-bound initialization commands are never answered and connectOverCDP hangs. - Send Inspector.enable during page initialization, so that Chromium reports Inspector.targetCrashed for such a page. - Ignore responses to commands that were already rejected by the crash, instead of asserting on them. - Do not report a page that crashed before it was initialized. Fixes microsoft#41714.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Send Inspector.enable and skip crashed pages only for pages attached while connecting to an existing browser, tracked by BrowserContext._skipCrashedPages on the default context. A new page might not have a renderer yet, e.g. an Electron window before its first navigation, which is not a crash. Inspector.enable is now the first command sent to such a page, so that the crash is reported as early as possible. The discard test compares against the actual url of the discards page, which Edge rewrites to edge://discards/.
e35f62b to
6458ae7
Compare
Test results for "tests 1"4 flaky52396 passed, 1243 skipped Merge workflow run. |
Test results for "MCP"1 failed 8828 passed, 1480 skipped Merge workflow run. |
|
Hi, I'm the Playwright bot and I took a first look at the CI failure here. 🟢 The one failure is a pre-existing flake, unrelated to this PR
DetailsThe latest merged report for Pre-existing flake / infra
Triaged by the Playwright bot - agent run |
Test results for "tests 2"4 failed 45 flaky107752 passed, 4646 skipped Merge workflow run. |
|
Hi, I'm the Playwright bot and I took a first look at the latest "tests 2" failures. 🟡 Three failures are known flakes; one Android failure is unproven but likely unrelatedThe two Firefox failures and DetailsThe PR's product changes only run while connecting over CDP. The new code checks Pre-existing flake / infra
Uncertain
Triaged by the Playwright bot - agent run |
| if (this._lifecycle === 'crashed' && this.browserContext._skipCrashedPages) { | ||
| // When connecting, any crashed/discarded/unloaded page is not reported to the client at all. | ||
| // This is not a default behavior to avoid false positives when a newly created | ||
| // page is navigating slowly for whatever reason. TODO: fix in chromium upstream. |
There was a problem hiding this comment.
If it is just navigating slowly, it should not be marked as 'crashed', no?
There was a problem hiding this comment.
Yes, indeed. That's the upstream issue we should fix.
| for (const initScript of this._crPage._page.allInitScripts()) | ||
| promises.push(this._evaluateOnNewDocument(initScript, 'main', true /* runImmediately */)); | ||
| } | ||
| if (inspectorEnabled) |
There was a problem hiding this comment.
Do we actually get a response if the tab is unloaded?
There was a problem hiding this comment.
Yes, we get it from the browser process.
132be89
into
microsoft:main
## ✨ Highlights - **👥 Use different signed-in users in one session** — `playwright-cli tab-new https://example.com --isolated-context=user-b` opens a tab with separate cookies and storage. Tabs with the same context name share their login state; different names stay isolated. ([microsoft/playwright#43087](microsoft/playwright#43087)) - **🎬 Smaller video recordings with less encoding CPU** — `playwright-cli video-start demo.webm` now records with VP9, keeping the same WebM output format. Stop and save the recording with `playwright-cli video-stop`. ([microsoft/playwright#43021](microsoft/playwright#43021)) - **📋 Keep console messages and requests across navigations** ([#479](#479)) — `playwright-cli console --all` and `playwright-cli requests --all` include retained entries from earlier navigations, so warnings and failed requests are not lost when checking a multi-page flow. Request numbers stay stable for `playwright-cli request 5`. ([microsoft/playwright#43526](microsoft/playwright#43526)) - **🔎 Keep common searches from flooding the agent's context** ([microsoft/playwright#42077](microsoft/playwright#42077)) — `playwright-cli find button --max-results=5` returns at most five matching items and reports the total match count. ([microsoft/playwright#42947](microsoft/playwright#42947)) - **🍪 Delete one site's cookie without signing out of others** ([microsoft/playwright#43310](microsoft/playwright#43310)) — `playwright-cli cookie-delete session_id --domain=example.com --path=/` removes only the cookie matching that name, domain and path, leaving same-named cookies elsewhere intact. ([microsoft/playwright#43319](microsoft/playwright#43319)) - **🔒 Redact session tokens in URLs printed in responses** ([microsoft/playwright-mcp#1791](microsoft/playwright-mcp#1791)) — add `"redactUrlParams": ["access_token", "code"]` to `.playwright/cli.config.json` to replace those query and fragment parameter values with `<redacted>` in command responses. ([microsoft/playwright#43258](microsoft/playwright#43258)) ## 🐛 Fixes - `fix(cli): do not force-kill the browser on close` — `playwright-cli close` lets Chrome shut down normally, preventing temporary app-clone folders from accumulating on macOS. ([#475](#475), [microsoft/playwright#43229](microsoft/playwright#43229)) - `fix(cli): respect npm registry config in update check` — update checks honor npm's registry, scoped registry, proxy and authentication settings instead of contacting the public registry directly when a custom registry is configured. ([#478](#478), [#484](#484)) - `fix(cli): report run-code route handler exception once and verbatim` — asynchronous route callback errors return their original message without duplicated errors or an extra `Error:` prefix. ([#476](#476), [microsoft/playwright#43203](microsoft/playwright#43203)) - `fix(chromium): do not hang on pages without a renderer when connecting over CDP` — `attach --cdp` handles discarded or crashed tabs without wedging every command; a follow-up closes those tabs while preserving live ones. ([microsoft/playwright#41714](microsoft/playwright#41714), [microsoft/playwright#42936](microsoft/playwright#42936), [microsoft/playwright#43075](microsoft/playwright#43075)) - `fix(chromium): report local frames of existing oopifs when connecting over CDP` — attaching to an already-loaded page discovers nested frames correctly instead of replacing the main document with a sandboxed iframe. ([microsoft/playwright#42955](microsoft/playwright#42955), [microsoft/playwright#43000](microsoft/playwright#43000)) - `fix(mcp): report invalid element targets and accept locators in any language` — action targets accept JavaScript, Python, Java and C# locators. Invalid targets explain the accepted forms, including how to pass a bare snapshot ref. ([microsoft/playwright-mcp#1797](microsoft/playwright-mcp#1797), [microsoft/playwright#43539](microsoft/playwright#43539)) - `fix(mcp): normalize bare host URLs and loopback IP addresses` — `playwright-cli open 127.0.0.1:3000` uses HTTP, and bare external hosts with ports are normalized to HTTPS rather than mistaken for custom schemes. ([microsoft/playwright#43263](microsoft/playwright#43263), [microsoft/playwright#43264](microsoft/playwright#43264)) - `fix(mcp): race browser_navigate_back and forward against modal states` — `go-back` and `go-forward` surface navigation dialogs immediately so they can be handled, rather than hanging until timeout. ([microsoft/playwright#43251](microsoft/playwright#43251), [microsoft/playwright#43252](microsoft/playwright#43252)) - `fix(mcp): preserve origin filters when modifying request headers` — header-only `route` handlers no longer skip configured allowed/blocked-origin filters. ([microsoft/playwright#43630](microsoft/playwright#43630), [microsoft/playwright#43637](microsoft/playwright#43637)) - `fix(mcp): pass custom headers to route.fulfill when mocking response` — mocked `route` responses retain supplied headers, including CORS and cache headers. ([microsoft/playwright#43245](microsoft/playwright#43245), [microsoft/playwright#43244](microsoft/playwright#43244)) - `fix(mcp): match browser_route header names case-insensitively` — request-header replacement and removal work consistently regardless of header-name casing. ([microsoft/playwright#43215](microsoft/playwright#43215), [microsoft/playwright#43227](microsoft/playwright#43227)) - `fix(mcp): match cookie list domain filter on domain boundaries` — `cookie-list --domain=example.com` includes that domain and its subdomains, not unrelated names such as `my-example.com`; matching ignores case and a leading dot. ([microsoft/playwright#43308](microsoft/playwright#43308), [microsoft/playwright#43316](microsoft/playwright#43316)) - `fix(mcp): do not match sibling paths in cookie-list path filter` — `cookie-list --path=/api` includes `/api` and paths under `/api/`, not `/apikeys`. ([microsoft/playwright#43366](microsoft/playwright#43366), [microsoft/playwright#43368](microsoft/playwright#43368)) - `fix(mcp): ask for a cookie domain when the page has no host` — `cookie-set` on `about:blank` or a data URL asks for `--domain` instead of returning an internal assertion error. ([microsoft/playwright#43309](microsoft/playwright#43309), [microsoft/playwright#43318](microsoft/playwright#43318)) - `fix(mcp): pass credentials from --proxy-server as proxy username/password` — authenticated proxy URLs supplied through `PLAYWRIGHT_MCP_PROXY_SERVER` retain their credentials instead of failing proxy authentication. ([microsoft/playwright#43048](microsoft/playwright#43048), [microsoft/playwright#43071](microsoft/playwright#43071)) - `fix(mcp): accept Windows paths in browser_resume location` — `pause-at` accepts Windows source locations such as `C:\tests\example.spec.ts:42`. ([microsoft/playwright#43340](microsoft/playwright#43340), [microsoft/playwright#43349](microsoft/playwright#43349)) - `fix(video): hide ffmpeg console windows on Windows` — `video-start` no longer opens a terminal window that steals focus during background recording. ([microsoft/playwright#43515](microsoft/playwright#43515), [microsoft/playwright#43575](microsoft/playwright#43575)) - `feat(cli): keep sockets in XDG_RUNTIME_DIR` — Unix CLI sessions and the dashboard prefer `$XDG_RUNTIME_DIR/playwright` over the shared temporary directory when it is usable. ([microsoft/playwright#43698](microsoft/playwright#43698), [microsoft/playwright#43732](microsoft/playwright#43732)) - `fix(tracing): do not store secrets in trace context options` — trace metadata no longer copies credential-bearing context options such as HTTP credentials, proxy credentials, extra headers and storage-state cookies. ([microsoft/playwright#38673](microsoft/playwright#38673), [microsoft/playwright#43220](microsoft/playwright#43220)) - `fix(aria): preserve iframe snapshots with fallback text` — snapshots show a loaded iframe's content and element refs even when its HTML contains fallback text. ([microsoft/playwright#43628](microsoft/playwright#43628), [microsoft/playwright#43635](microsoft/playwright#43635)) - `fix(aria): quote ~, .inf and .nan in aria snapshots` — YAML-special text remains a string when snapshot output is parsed or reused. ([microsoft/playwright#43451](microsoft/playwright#43451), [microsoft/playwright#43469](microsoft/playwright#43469)) - `fix(a11y): treat inert elements and content outside of modal dialogs as hidden` — snapshots exclude controls that cannot currently be used, and click/fill actions wait for targets to stop being inert rather than silently misfiring. ([microsoft/playwright#36938](microsoft/playwright#36938), [microsoft/playwright#42967](microsoft/playwright#42967), [microsoft/playwright#43211](microsoft/playwright#43211)) - `fix(webmcp): handle Chromium tool API changes` — WebMCP tool discovery tolerates Chromium's null input schemas while preserving the existing tool shape. ([microsoft/playwright#43578](microsoft/playwright#43578)) ## 📦 Upgrading ```bash npm install -g @playwright/cli@0.1.23 ``` This release uses Playwright `1.65.0-alpha-2026-10-30`. Co-authored-by: microsoft-playwright-automation[bot] <203992400+microsoft-playwright-automation[bot]@users.noreply.github.com>
When connecting to a browser where a tab has no renderer, e.g. because it was discarded by the Memory Saver or its renderer crashed, renderer-bound initialization commands are never answered and
connectOverCDPhangs.Inspector.enablefor pages attached while connecting to an existing browser, so that Chromium reportsInspector.targetCrashedfor such a page. Chromium already does this in response toInspector.enable, but we never sent it. This is the first command sent to such a page.Inspector.targetCrashedbefore the response toInspector.enable, so by the time the response arrives its callback is gone.Both behaviors are limited to pages attached while connecting, tracked by
BrowserContext._skipCrashedPageson the default context. A new page might not have a renderer yet, e.g. an Electron window before its first navigation, and must not be treated as crashed.Tests: one crashes a page through
chrome://crashbefore reconnecting, and one discards a tab throughchrome://discards(from #42930). The latter compares against the actual url of the discards page, since Edge rewrites it toedge://discards/.Fixes #41714.