Skip to content

fix(chromium): do not hang on pages without a renderer when connecting over CDP - #42936

Merged
Dmitry Gozman (dgozman) merged 2 commits into
microsoft:mainfrom
dgozman:fix-41714
Sep 30, 2026
Merged

Dmitry Gozman (dgozman) merged 2 commits into
microsoft:mainfrom
dgozman:fix-41714

Conversation

@dgozman

@dgozman Dmitry Gozman (dgozman) commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

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 for pages attached while connecting to an existing browser, so that Chromium reports Inspector.targetCrashed for such a page. Chromium already does this in response to Inspector.enable, but we never sent it. This is the first command sent to such a page.
  • Ignore responses to commands that were already rejected by the crash, instead of asserting on them. Chromium sends Inspector.targetCrashed before the response to Inspector.enable, so by the time the response arrives its callback is gone.
  • Do not report a page that crashed while connecting. Connecting to a browser with one live page and one discarded page yields one page.

Both behaviors are limited to pages attached while connecting, 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, and must not be treated as crashed.

Tests: one crashes a page through chrome://crash before reconnecting, and one discards a tab through chrome://discards (from #42930). The latter compares against the actual url of the discards page, since Edge rewrites it to edge://discards/.

Fixes #41714.

…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.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

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/.
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

4 flaky ⚠️ [chromium-library] › library/video.spec.ts:762 › screencast › should work with video+trace `@chromium-ubuntu-22.04-arm-node20`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:436 › should produce network events, routing, and annotations for Service Worker (advanced) `@chromium-ubuntu-22.04-node20`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies `@firefox-ubuntu-22.04-node20`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:470 › top level 'Partitioned;' cookie and same origin iframe `@firefox-ubuntu-22.04-node20`

52396 passed, 1243 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

1 failed
❌ [firefox] › mcp/cli-keyboard.spec.ts:29 › keydown keyup @mcp-windows-latest-firefox

8828 passed, 1480 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

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

[firefox] › mcp/cli-keyboard.spec.ts:29 › keydown keyup on Windows has failed on main with the same error, in runs this PR can't have affected.

Details

The latest merged report for 6458ae7 has a single failure: 8828 tests passed and 1 failed. This PR changes the Chromium CDP connection and page setup (crBrowser.ts, crConnection.ts, crPage.ts), plus shared browserContext.ts and page.ts. None of that is Firefox-specific, and this failure only shows up with Firefox on Windows.

Pre-existing flake / infra

  • [firefox] › mcp/cli-keyboard.spec.ts:29 › keydown keyup (mcp-windows-latest-firefox). In the test-results DB, this test failed in 6 of 705 runs on this bot. 5 of those failures were on main pushes the PR can't be responsible for: 18205280 (run), da3a50aa (run), dc82cd77 (run), b8627f95 (run) and b5b5b5f1 (run). The sixth was on the unrelated fix(trace-viewer): store snapshot style text in an attribute #42405. Each time the error was the same: the snapshot showed - textbox [ref=e2] without the typed h or [active]. The test hasn't failed on any of the other 12 MCP browser/OS bots, which points to a Firefox-on-Windows input timing issue rather than anything in this diff.

Triaged by the Playwright bot - agent run

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 2"

4 failed
❌ [firefox-library] › library/inspector/cli-codegen-aria.spec.ts:87 › should update aria snapshot highlight @firefox-macos-15-large
❌ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies @firefox-macos-15-xlarge
❌ [android-page] › page/locator-is-visible.spec.ts:93 › isVisible and isHidden should work with list box options
❌ [android-page] › page/page-set-content.spec.ts:57 › should include shadow roots

45 flaky ⚠️ [chromium-library] › library/chromium/chromium.spec.ts:373 › should produce network events, routing, and annotations for Service Worker `@chrome-ubuntu-22.04`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:436 › should produce network events, routing, and annotations for Service Worker (advanced) `@chrome-ubuntu-22.04`
⚠️ [chromium-library] › library/trace-viewer.spec.ts:1536 › should update highlight when typing locator `@chrome-ubuntu-22.04`
⚠️ [chromium-library] › library/browsercontext-user-agent.spec.ts:110 › should work for navigator.userAgentData and sec-ch-ua headers `@msedge-windows-latest`
⚠️ [chromium-page] › page/workers.spec.ts:63 › should have timestamp on worker console messages `@chromium-windows-latest`
⚠️ [chromium-library] › library/beforeunload.spec.ts:20 › should close browser with beforeunload page `@chromium-macos-15-large`
⚠️ [chromium-library] › library/browsercontext-basic.spec.ts:36 › should be able to click across browser contexts `@chromium-macos-15-large`
⚠️ [chromium-library] › library/browsercontext-device.spec.ts:33 › device › should support clicking `@chromium-macos-15-large`
⚠️ [chromium-library] › library/browsercontext-events.spec.ts:30 › console event should work with element handles `@chromium-macos-15-large`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:179 › serviceWorker(), and fromServiceWorker() work `@chromium-macos-15-large`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:301 › should report intercepted service worker requests in HAR `@chromium-macos-15-large`
⚠️ [chromium-library] › library/browsercontext-proxy.spec.ts:165 › should proxy local network requests › with other bypasses › localhost `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/browsercontext-proxy.spec.ts:353 › should exclude patterns `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/chromium/connect-over-cdp.spec.ts:80 › should connect when an existing page has been discarded `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/fetch-proxy.spec.ts:82 › should support proxy.bypass `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/proxy.spec.ts:91 › should proxy local network requests › with other bypasses › localhost `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/proxy.spec.ts:235 › should exclude patterns `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/trace-viewer.spec.ts:1934 › should not leak recorders `@chromium-macos-14-xlarge`
⚠️ [chromium-library] › library/chromium/oopif.spec.ts:179 › should take screenshot `@chromium-macos-15-xlarge`
⚠️ [chromium-library] › library/defaultbrowsercontext-2.spec.ts:179 › should have passed URL when launching with ignoreDefaultArgs: true `@chrome-windows-latest`
⚠️ [chromium-library] › library/download.spec.ts:377 › download event › should delete downloads on browser gone `@chrome-windows-latest`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:179 › serviceWorker(), and fromServiceWorker() work `@chrome-beta-ubuntu-22.04`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:373 › should produce network events, routing, and annotations for Service Worker `@chrome-beta-ubuntu-22.04`
⚠️ [chromium-library] › library/inspector/cli-codegen-pytest.spec.ts:49 › should save the codegen output to a file if specified `@chrome-beta-ubuntu-22.04`
⚠️ [chromium-library] › library/inspector/cli-codegen-test.spec.ts:86 › should not generate recordHAR with --save-har `@chrome-beta-ubuntu-22.04`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:213 › should intercept service worker requests (main and within) `@chrome-macos-latest`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:436 › should produce network events, routing, and annotations for Service Worker (advanced) `@chrome-macos-latest`
⚠️ [chromium-library] › library/selector-generator.spec.ts:165 › selector generator › should try to improve text by shortening `@chrome-macos-latest`
⚠️ [chromium-library] › library/selector-generator.spec.ts:551 › selector generator › should accept valid aria-label for candidate consideration `@chrome-macos-latest`
⚠️ [chromium-library] › library/selector-generator.spec.ts:698 › selector generator › should generate noText: contenteditable heading `@chrome-macos-latest`
⚠️ [chromium-library] › library/trace-viewer.spec.ts:1934 › should not leak recorders `@chrome-macos-latest`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies `@tracing-firefox`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:470 › top level 'Partitioned;' cookie and same origin iframe `@tracing-firefox`
⚠️ [firefox-library] › library/browsertype-connect.spec.ts:813 › launchServer › should upload a folder `@tracing-firefox`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies `@firefox-macos-15-large`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:470 › top level 'Partitioned;' cookie and same origin iframe `@firefox-macos-15-large`
⚠️ [firefox-library] › library/inspector/cli-codegen-csharp.spec.ts:208 › should print context options method override in mstest if options were passed `@firefox-macos-15-large`
⚠️ [firefox-library] › library/inspector/cli-codegen-csharp.spec.ts:202 › should not print context options method override in xunit if no options were passed `@firefox-macos-15-large`
⚠️ [firefox-library] › library/inspector/cli-codegen-python-async.spec.ts:80 › should save the codegen output to a file if specified `@firefox-macos-15-large`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies `@firefox-windows-latest`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:470 › top level 'Partitioned;' cookie and same origin iframe `@firefox-windows-latest`
⚠️ [firefox-library] › library/signals.spec.ts:25 › should close the browser when the node process closes `@firefox-windows-latest`
⚠️ [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:470 › top level 'Partitioned;' cookie and same origin iframe `@firefox-macos-15-xlarge`
⚠️ [webkit-library] › library/trace-viewer.spec.ts:2016 › canvas clipping `@webkit-macos-15-xlarge`
⚠️ [webkit-page] › page/page-screenshot.spec.ts:356 › page screenshot › should work for canvas `@webkit-macos-15-xlarge`

107752 passed, 4646 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

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 unrelated

The two Firefox failures and page-set-content.spec.ts:57 on Android also fail on SHAs and PRs this PR can't have affected. locator-is-visible.spec.ts:93 on Android has no run history yet, so I can't call it a flake. The PR's code doesn't reach it either.

Details

The PR's product changes only run while connecting over CDP. The new code checks _skipCrashedPages, which is set only inside CRBrowser.connect and cleared right after. Regular test runs don't take that path on Chromium, Android, or any other browser. The shared page.ts and browserContext.ts edits are behind the same flag. The PR's own new test (connect-over-cdp.spec.ts:80) only flaked, on chromium-macos-14-xlarge, and passed on retry.

Pre-existing flake / infra

  • [firefox-library] › library/browsercontext-cookies-third-party.spec.ts:257 › third party 'Partitioned;' cookies (firefox-macos-15-xlarge): pre-existing flake. In the test-results DB it failed in 27 of 960 runs, on 27 other SHAs. Retries rescued it in another 656 runs. In this same report it also flaked on three other Firefox bots.
  • [firefox-library] › library/inspector/cli-codegen-aria.spec.ts:87 › should update aria snapshot highlight (firefox-macos-15-large): pre-existing flake. It failed in 17 of 959 runs, on 17 other SHAs, and retries rescued it in 44 more. This is recorder code on Firefox, which the PR doesn't touch.
  • [android-page] › page/page-set-content.spec.ts:57 › should include shadow roots: this test fails on every Android run. It failed 46 of 46 runs in the DB (43 main pushes and 3 other PRs). The Android job was also red on each of the last 4 main pushes I checked.

Uncertain

  • [android-page] › page/locator-is-visible.spec.ts:93 › isVisible and isHidden should work with list box options: the test was only added on 2026-09-28 (d67c16e), so the DB has no run history for it yet. The Android job's log was also unavailable, so I couldn't read the error. Android does go through crPage.ts, but the only changed lines there are gated on _skipCrashedPages, which is false outside connectOverCDP. A failure in <select multiple> / <optgroup> option visibility on Android WebView looks like a gap in that engine, not this PR. To be sure, check whether this test also fails on Android on a main push since d67c16e.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is just navigating slowly, it should not be marked as 'crashed', no?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually get a response if the tab is unloaded?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we get it from the browser process.

Pavel Feldman (pavelfeldman) pushed a commit to microsoft/playwright-cli that referenced this pull request Oct 31, 2026
## ✨ 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] playwright-cli: one discarded (Memory Saver) tab makes every command time out — tab header rendering awaits page.title() without timeout

2 participants