chore: roll to the latest Playwright (#1003)

This commit is contained in:
Pavel Feldman
2025-09-05 12:31:08 -07:00
committed by GitHub
parent 971489536e
commit 3d6a66fd08
7 changed files with 152 additions and 78 deletions

106
README.md
View File

@@ -180,52 +180,65 @@ Playwright MCP server supports following arguments. They can be provided in the
``` ```
> npx @playwright/mcp@latest --help > npx @playwright/mcp@latest --help
--allowed-origins <origins> semicolon-separated list of origins to allow the --allowed-origins <origins> semicolon-separated list of origins to allow
browser to request. Default is to allow all. the browser to request. Default is to allow
--blocked-origins <origins> semicolon-separated list of origins to block the all.
browser from requesting. Blocklist is evaluated --blocked-origins <origins> semicolon-separated list of origins to block
before allowlist. If used without the allowlist, the browser from requesting. Blocklist is
requests not matching the blocklist are still evaluated before allowlist. If used without
allowed. the allowlist, requests not matching the
--block-service-workers block service workers blocklist are still allowed.
--browser <browser> browser or chrome channel to use, possible --block-service-workers block service workers
values: chrome, firefox, webkit, msedge. --browser <browser> browser or chrome channel to use, possible
--caps <caps> comma-separated list of additional capabilities values: chrome, firefox, webkit, msedge.
to enable, possible values: vision, pdf. --caps <caps> comma-separated list of additional
--cdp-endpoint <endpoint> CDP endpoint to connect to. capabilities to enable, possible values:
--config <path> path to the configuration file. vision, pdf.
--device <device> device to emulate, for example: "iPhone 15" --cdp-endpoint <endpoint> CDP endpoint to connect to.
--executable-path <path> path to the browser executable. --cdp-header <headers...> CDP headers to send with the connect request,
--extension Connect to a running browser instance multiple can be specified.
(Edge/Chrome only). Requires the "Playwright MCP --config <path> path to the configuration file.
Bridge" browser extension to be installed. --device <device> device to emulate, for example: "iPhone 15"
--headless run browser in headless mode, headed by default --executable-path <path> path to the browser executable.
--host <host> host to bind server to. Default is localhost. Use --extension Connect to a running browser instance
0.0.0.0 to bind to all interfaces. (Edge/Chrome only). Requires the "Playwright
--ignore-https-errors ignore https errors MCP Bridge" browser extension to be installed.
--isolated keep the browser profile in memory, do not save --headless run browser in headless mode, headed by
it to disk. default
--image-responses <mode> whether to send image responses to the client. --host <host> host to bind server to. Default is localhost.
Can be "allow" or "omit", Defaults to "allow". Use 0.0.0.0 to bind to all interfaces.
--no-sandbox disable the sandbox for all process types that --ignore-https-errors ignore https errors
are normally sandboxed. --isolated keep the browser profile in memory, do not
--output-dir <path> path to the directory for output files. save it to disk.
--port <port> port to listen on for SSE transport. --image-responses <mode> whether to send image responses to the client.
--proxy-bypass <bypass> comma-separated domains to bypass proxy, for Can be "allow" or "omit", Defaults to "allow".
example ".com,chromium.org,.domain.com" --no-sandbox disable the sandbox for all process types that
--proxy-server <proxy> specify proxy server, for example are normally sandboxed.
"http://myproxy:3128" or "socks5://myproxy:8080" --output-dir <path> path to the directory for output files.
--save-session Whether to save the Playwright MCP session into --port <port> port to listen on for SSE transport.
the output directory. --proxy-bypass <bypass> comma-separated domains to bypass proxy, for
--save-trace Whether to save the Playwright Trace of the example ".com,chromium.org,.domain.com"
session into the output directory. --proxy-server <proxy> specify proxy server, for example
--storage-state <path> path to the storage state file for isolated "http://myproxy:3128" or
sessions. "socks5://myproxy:8080"
--user-agent <ua string> specify user agent string --save-session Whether to save the Playwright MCP session
--user-data-dir <path> path to the user data directory. If not into the output directory.
specified, a temporary directory will be created. --save-trace Whether to save the Playwright Trace of the
--viewport-size <size> specify browser viewport size in pixels, for session into the output directory.
example "1280, 720" --secrets <path> path to a file containing secrets in the
dotenv format
--storage-state <path> path to the storage state file for isolated
sessions.
--timeout-action <timeout> specify action timeout in milliseconds,
defaults to 5000ms
--timeout-navigation <timeout> specify navigation timeout in milliseconds,
defaults to 60000ms
--user-agent <ua string> specify user agent string
--user-data-dir <path> path to the user data directory. If not
specified, a temporary directory will be
created.
--viewport-size <size> specify browser viewport size in pixels, for
example "1280, 720"
``` ```
<!--- End of options generated section --> <!--- End of options generated section -->
@@ -442,6 +455,7 @@ http.createServer(async (req, res) => {
- `ref` (string): Exact target element reference from the page snapshot - `ref` (string): Exact target element reference from the page snapshot
- `doubleClick` (boolean, optional): Whether to perform a double click instead of a single click - `doubleClick` (boolean, optional): Whether to perform a double click instead of a single click
- `button` (string, optional): Button to click, defaults to left - `button` (string, optional): Button to click, defaults to left
- `modifiers` (array, optional): Modifier keys to press
- Read-only: **false** - Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js --> <!-- NOTE: This has been generated via update-readme.js -->

8
cli.js
View File

@@ -15,4 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
require('playwright/lib/mcp/program'); const { program } = require('playwright-core/lib/utilsBundle');
const { decorateCommand } = require('playwright/lib/mcp/program');
const packageJSON = require('./package.json');
const p = program.version('Version ' + packageJSON.version).name('Playwright MCP');
decorateCommand(p, packageJSON.version)
void program.parseAsync(process.argv);

24
config.d.ts vendored
View File

@@ -59,6 +59,11 @@ export type Config = {
*/ */
cdpEndpoint?: string; cdpEndpoint?: string;
/**
* CDP headers to send with the connect request.
*/
cdpHeaders?: Record<string, string>;
/** /**
* Remote endpoint to connect to an existing Playwright server. * Remote endpoint to connect to an existing Playwright server.
*/ */
@@ -95,6 +100,13 @@ export type Config = {
*/ */
saveTrace?: boolean; saveTrace?: boolean;
/**
* Secrets are used to prevent LLM from getting sensitive data while
* automating scenarios such as authentication.
* Prefer the browser.contextOptions.storageState over secrets file as a more secure alternative.
*/
secrets?: Record<string, string>;
/** /**
* The directory to save output files. * The directory to save output files.
*/ */
@@ -112,6 +124,18 @@ export type Config = {
blockedOrigins?: string[]; blockedOrigins?: string[];
}; };
timeouts?: {
/*
* Configures default action timeout: https://playwright.dev/docs/api/class-page#page-set-default-timeout. Defaults to 5000ms.
*/
action?: number;
/*
* Configures default navigation timeout: https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout. Defaults to 60000ms.
*/
navigation?: number;
};
/** /**
* Whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them. * Whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.
*/ */

72
package-lock.json generated
View File

@@ -9,16 +9,17 @@
"version": "0.0.36", "version": "0.0.36",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright": "1.56.0-alpha-1756945786000", "playwright": "1.56.0-alpha-1757090131000",
"zod-to-json-schema": "^3.24.6" "playwright-core": "1.56.0-alpha-1757090131000"
}, },
"bin": { "bin": {
"mcp-server-playwright": "cli.js" "mcp-server-playwright": "cli.js"
}, },
"devDependencies": { "devDependencies": {
"@modelcontextprotocol/sdk": "^1.17.5", "@modelcontextprotocol/sdk": "^1.17.5",
"@playwright/test": "1.56.0-alpha-1756945786000", "@playwright/test": "1.56.0-alpha-1757090131000",
"@types/node": "^24.3.0" "@types/node": "^24.3.0",
"zod-to-json-schema": "^3.24.6"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -49,13 +50,13 @@
} }
}, },
"node_modules/@playwright/test": { "node_modules/@playwright/test": {
"version": "1.56.0-alpha-1756945786000", "version": "1.56.0-alpha-1757090131000",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.0-alpha-1756945786000.tgz", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.0-alpha-1757090131000.tgz",
"integrity": "sha512-I4+J2BnzDO2KLMhafHmVw8gPzWA0R4niu+tDHwD+YaJzaxj4lH/nxSvqSRZJ5lCEBrt/zbDbEyzNpBdqBy4/Wg==", "integrity": "sha512-DVyN8ScyBMPasnrcIN7RjltZl7YkJlFZcz9otXe4TwUMo6JYt98MMmcsGXWbKCe+sk4KsgUNx3gYZtAWRBfIzw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright": "1.56.0-alpha-1756945786000" "playwright": "1.56.0-alpha-1757090131000"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@@ -65,9 +66,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "24.3.0", "version": "24.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz",
"integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -824,12 +825,12 @@
} }
}, },
"node_modules/playwright": { "node_modules/playwright": {
"version": "1.56.0-alpha-1756945786000", "version": "1.56.0-alpha-1757090131000",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.0-alpha-1756945786000.tgz", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.0-alpha-1757090131000.tgz",
"integrity": "sha512-Y07i9m/hZOQ8lLb4XDYAO24V1+qy+OCgxsW66fSlJJ064p8N4KjwKL5OJpVZofhf3EP8vp0adGePjBOjSwhVeA==", "integrity": "sha512-3G5jTso8FKB8iiha0aRsZy7T/oanxL7Hx/D3oK3FzM0K3fS0eUXPetzQk8elYz/ZwNPCpfYvXbzGzdaRiBKLFw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright-core": "1.56.0-alpha-1756945786000" "playwright-core": "1.56.0-alpha-1757090131000"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@@ -842,9 +843,9 @@
} }
}, },
"node_modules/playwright-core": { "node_modules/playwright-core": {
"version": "1.56.0-alpha-1756945786000", "version": "1.56.0-alpha-1757090131000",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.0-alpha-1756945786000.tgz", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.0-alpha-1757090131000.tgz",
"integrity": "sha512-692W77VRoV2hq1bNwrZXsRBVOY8z5DDjV5jacB5det4v8rUcvOAGTqNUhoV17acP4mfbItM34VOPYOMtlJxjXg==", "integrity": "sha512-kj4hYkv79zIqUjepNun3homv1h9jkn4CHUNyfV8tJotj6X1ypmIiox/smLm7Lcjg9wLexk4N/Sxx1mglrXlQeg==",
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"playwright-core": "cli.js" "playwright-core": "cli.js"
@@ -904,19 +905,36 @@
} }
}, },
"node_modules/raw-body": { "node_modules/raw-body": {
"version": "3.0.0", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz",
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"bytes": "3.1.2", "bytes": "3.1.2",
"http-errors": "2.0.0", "http-errors": "2.0.0",
"iconv-lite": "0.6.3", "iconv-lite": "0.7.0",
"unpipe": "1.0.0" "unpipe": "1.0.0"
}, },
"engines": { "engines": {
"node": ">= 0.8" "node": ">= 0.10"
}
},
"node_modules/raw-body/node_modules/iconv-lite": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
} }
}, },
"node_modules/router": { "node_modules/router": {
@@ -1205,9 +1223,10 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.24.2", "version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
@@ -1217,6 +1236,7 @@
"version": "3.24.6", "version": "3.24.6",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
"integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
"dev": true,
"license": "ISC", "license": "ISC",
"peerDependencies": { "peerDependencies": {
"zod": "^3.24.1" "zod": "^3.24.1"

View File

@@ -17,10 +17,12 @@
"scripts": { "scripts": {
"lint": "npm run update-readme", "lint": "npm run update-readme",
"update-readme": "node update-readme.js", "update-readme": "node update-readme.js",
"docker-build": "docker build --no-cache -t playwright-mcp-dev:latest .",
"test": "playwright test", "test": "playwright test",
"ctest": "playwright test --project=chrome", "ctest": "playwright test --project=chrome",
"ftest": "playwright test --project=firefox", "ftest": "playwright test --project=firefox",
"wtest": "playwright test --project=webkit", "wtest": "playwright test --project=webkit",
"dtest": "MCP_IN_DOCKER=1 playwright test --project=chromium-docker",
"npm-publish": "npm run clean && npm run build && npm run test && npm publish" "npm-publish": "npm run clean && npm run build && npm run test && npm publish"
}, },
"exports": { "exports": {
@@ -31,15 +33,16 @@
} }
}, },
"dependencies": { "dependencies": {
"playwright": "1.56.0-alpha-1756945786000", "playwright": "1.56.0-alpha-1757090131000",
"zod-to-json-schema": "^3.24.6" "playwright-core": "1.56.0-alpha-1757090131000"
}, },
"bin": { "bin": {
"mcp-server-playwright": "cli.js" "mcp-server-playwright": "cli.js"
}, },
"devDependencies": { "devDependencies": {
"@modelcontextprotocol/sdk": "^1.17.5", "@modelcontextprotocol/sdk": "^1.17.5",
"@playwright/test": "1.56.0-alpha-1756945786000", "@playwright/test": "1.56.0-alpha-1757090131000",
"@types/node": "^24.3.0" "@types/node": "^24.3.0",
"zod-to-json-schema": "^3.24.6"
} }
} }

View File

@@ -22,9 +22,12 @@ test('browser_click', async ({ client, server, mcpBrowser }) => {
<button>Submit</button> <button>Submit</button>
`, 'text/html'); `, 'text/html');
await client.callTool({ expect(await client.callTool({
name: 'browser_navigate', name: 'browser_navigate',
arguments: { url: server.PREFIX }, arguments: { url: server.PREFIX },
})).toHaveResponse({
code: `await page.goto('${server.PREFIX}');`,
pageState: expect.stringContaining(`- button \"Submit\" [ref=e2]`),
}); });
expect(await client.callTool({ expect(await client.callTool({

View File

@@ -34,6 +34,10 @@ const capabilities = {
const toolsByCapability = Object.fromEntries(Object.entries(capabilities).map(([capability, title]) => [title, allTools.filter(tool => tool.capability === capability).sort((a, b) => a.schema.name.localeCompare(b.schema.name))])); const toolsByCapability = Object.fromEntries(Object.entries(capabilities).map(([capability, title]) => [title, allTools.filter(tool => tool.capability === capability).sort((a, b) => a.schema.name.localeCompare(b.schema.name))]));
/**
* @param {any} tool
* @returns {string[]}
*/
function formatToolForReadme(tool) { function formatToolForReadme(tool) {
const lines = /** @type {string[]} */ ([]); const lines = /** @type {string[]} */ ([]);
lines.push(`<!-- NOTE: This has been generated via ${path.basename(__filename)} -->`); lines.push(`<!-- NOTE: This has been generated via ${path.basename(__filename)} -->`);