From 8f3c1edb9dccfeb35b03422ae4bdd7b9a2db4c79 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 16 Apr 2026 16:37:17 -0700 Subject: [PATCH 1/4] chore(mcp): rename Playwright MCP Bridge to Playwright Extension (#40259) --- docs/src/getting-started-cli.md | 2 +- docs/src/getting-started-mcp.md | 2 +- packages/playwright-core/src/tools/mcp/cdpRelay.ts | 2 +- packages/playwright-core/src/tools/mcp/config.d.ts | 2 +- packages/playwright-core/src/tools/mcp/program.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/getting-started-cli.md b/docs/src/getting-started-cli.md index e5256fa2ec943..272f93a94add8 100644 --- a/docs/src/getting-started-cli.md +++ b/docs/src/getting-started-cli.md @@ -283,7 +283,7 @@ Connect to your existing browser tabs instead of launching a new browser: playwright-cli attach --extension ``` -This requires the [Playwright MCP Bridge browser extension](https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md) to be installed. +This requires the [Playwright Extension](https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md) to be installed. ## Quick Reference diff --git a/docs/src/getting-started-mcp.md b/docs/src/getting-started-mcp.md index 2cc735876ead3..72a26421405a8 100644 --- a/docs/src/getting-started-mcp.md +++ b/docs/src/getting-started-mcp.md @@ -175,7 +175,7 @@ Playwright MCP supports three profile modes: - **Persistent (default)**: Login state and cookies are preserved between sessions. The profile is stored in `ms-playwright/mcp-{channel}-{workspace-hash}` in your platform's cache directory, so different projects get separate profiles automatically. Override with `--user-data-dir`. - **Isolated**: Each session starts fresh. Pass `--isolated` to enable. You can load initial state with `--storage-state`. -- **Browser extension**: Connect to your existing browser tabs with the [Playwright MCP Bridge extension](https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md). Pass `--extension` to enable. +- **Browser extension**: Connect to your existing browser tabs with the [Playwright Extension](https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md). Pass `--extension` to enable. ### Configuration file diff --git a/packages/playwright-core/src/tools/mcp/cdpRelay.ts b/packages/playwright-core/src/tools/mcp/cdpRelay.ts index 3b2f54597e7fd..20275e3a3128f 100644 --- a/packages/playwright-core/src/tools/mcp/cdpRelay.ts +++ b/packages/playwright-core/src/tools/mcp/cdpRelay.ts @@ -117,7 +117,7 @@ export class CDPRelayServer { await Promise.race([ this._extensionConnectionPromise, new Promise((_, reject) => setTimeout(() => { - reject(new Error(`Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed. See https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md for installation instructions.`)); + reject(new Error(`Extension connection timeout. Make sure the "Playwright Extension" is installed. See https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md for installation instructions.`)); }, process.env.PWMCP_TEST_CONNECTION_TIMEOUT ? parseInt(process.env.PWMCP_TEST_CONNECTION_TIMEOUT, 10) : 5_000)), ]); debugLogger('Extension connection established'); diff --git a/packages/playwright-core/src/tools/mcp/config.d.ts b/packages/playwright-core/src/tools/mcp/config.d.ts index 26cc07518d02b..6756d9a731650 100644 --- a/packages/playwright-core/src/tools/mcp/config.d.ts +++ b/packages/playwright-core/src/tools/mcp/config.d.ts @@ -101,7 +101,7 @@ export type Config = { /** * Connect to a running browser instance (Edge/Chrome only). If specified, `browser` * config is ignored. - * Requires the "Playwright MCP Bridge" browser extension to be installed. + * Requires the "Playwright Extension" to be installed. */ extension?: boolean; diff --git a/packages/playwright-core/src/tools/mcp/program.ts b/packages/playwright-core/src/tools/mcp/program.ts index 126fcb6f20bd6..e6157cb1a8c4e 100644 --- a/packages/playwright-core/src/tools/mcp/program.ts +++ b/packages/playwright-core/src/tools/mcp/program.ts @@ -47,7 +47,7 @@ export function decorateMCPCommand(command: Command) { .option('--console-level ', 'level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels.', enumParser.bind(null, '--console-level', ['error', 'warning', 'info', 'debug'])) .option('--device ', 'device to emulate, for example: "iPhone 15"') .option('--executable-path ', 'path to the browser executable.') - .option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.') + .option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright Extension" to be installed.') .option('--endpoint ', 'Bound browser endpoint to connect to.') .option('--grant-permissions ', 'List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write".', commaSeparatedList) .option('--headless', 'run browser in headless mode, headed by default') From 2fb4b68f4180bcc9ac10ac77f77cfcb811805205 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 16 Apr 2026 17:25:43 -0700 Subject: [PATCH 2/4] fix(mcp): throw clear error for tab creation in extension protocol v1 (#40261) --- packages/playwright-core/src/tools/mcp/cdpRelayV1.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/playwright-core/src/tools/mcp/cdpRelayV1.ts b/packages/playwright-core/src/tools/mcp/cdpRelayV1.ts index aa9201ef0ff86..3aff2addae28e 100644 --- a/packages/playwright-core/src/tools/mcp/cdpRelayV1.ts +++ b/packages/playwright-core/src/tools/mcp/cdpRelayV1.ts @@ -74,6 +74,9 @@ export class ExtensionProtocolV1 implements ExtensionProtocolHandler { case 'Target.getTargetInfo': { return { result: this._connectedTabInfo?.targetInfo }; } + case 'Target.createTarget': { + throw new Error('Tab creation is not supported yet.'); + } } return undefined; } From 9dd27f85f8abbf3db2590fc3dbc5f48e8c5a5ae0 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 16 Apr 2026 17:33:23 -0700 Subject: [PATCH 3/4] test: add regression test for Response.formData() in WebKit (#40251) --- tests/page/page-network-response.spec.ts | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/page/page-network-response.spec.ts b/tests/page/page-network-response.spec.ts index 849d7c22cbe2f..3be69f7082639 100644 --- a/tests/page/page-network-response.spec.ts +++ b/tests/page/page-network-response.spec.ts @@ -426,3 +426,37 @@ it('should return http version', async ({ page, server }) => { const response = await page.goto(server.EMPTY_PAGE); expect(await response.httpVersion()).toBe('HTTP/1.1'); }); + +it('Response.formData() should parse multipart/form-data in page context', async ({ page, server, browserName }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/40244' }); + it.fail(browserName === 'webkit', 'WebKit 26.4 upstream regression: rejects multipart body without trailing CRLF after closing boundary'); + await page.goto(server.EMPTY_PAGE); + const result = await page.evaluate(async () => { + const boundary = '----WebKitFormBoundary1234'; + const body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="test.txt"', + 'Content-Type: text/plain', + '', + 'hello', + `--${boundary}--`, + ].join('\r\n'); + const response = new Response(body, { + headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}` }, + }); + const fd = await response.formData(); + const file = fd.get('file1') as File; + return { + field1: fd.get('field1'), + filename: file instanceof File ? file.name : null, + fileContent: file instanceof File ? await file.text() : null, + }; + }); + expect(result.field1).toBe('value1'); + expect(result.filename).toBe('test.txt'); + expect(result.fileContent).toBe('hello'); +}); From be9f921c2bd0013a79317467fd403c98f995f3dd Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 16 Apr 2026 17:59:38 -0700 Subject: [PATCH 4/4] docs(claude): forbid pushing without explicit instruction (#40260) --- CLAUDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 6d46cb16929f1..9110c0b092916 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -138,6 +138,8 @@ Never add "Generated with" in commit message. Never add test plan to PR description. Keep PR description short — a few bullet points at most. Branch naming for issue fixes: `fix-` +**Never `git push` without an explicit instruction to push.** Applies even when a PR is already open for the branch — additional commits are immediately visible to reviewers. Commit locally, report what was committed, and wait. Only push when the user's message contains "push", "upload", "create PR", "ship it", or equivalent. + ## Development Guides Detailed guides for common development tasks: