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

8
cli.js
View File

@@ -15,4 +15,10 @@
* 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;
/**
* CDP headers to send with the connect request.
*/
cdpHeaders?: Record<string, string>;
/**
* Remote endpoint to connect to an existing Playwright server.
*/
@@ -95,6 +100,13 @@ export type Config = {
*/
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.
*/
@@ -112,6 +124,18 @@ export type Config = {
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.
*/

72
package-lock.json generated
View File

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

View File

@@ -17,10 +17,12 @@
"scripts": {
"lint": "npm run update-readme",
"update-readme": "node update-readme.js",
"docker-build": "docker build --no-cache -t playwright-mcp-dev:latest .",
"test": "playwright test",
"ctest": "playwright test --project=chrome",
"ftest": "playwright test --project=firefox",
"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"
},
"exports": {
@@ -31,15 +33,16 @@
}
},
"dependencies": {
"playwright": "1.56.0-alpha-1756945786000",
"zod-to-json-schema": "^3.24.6"
"playwright": "1.56.0-alpha-1757090131000",
"playwright-core": "1.56.0-alpha-1757090131000"
},
"bin": {
"mcp-server-playwright": "cli.js"
},
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.17.5",
"@playwright/test": "1.56.0-alpha-1756945786000",
"@types/node": "^24.3.0"
"@playwright/test": "1.56.0-alpha-1757090131000",
"@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>
`, 'text/html');
await client.callTool({
expect(await client.callTool({
name: 'browser_navigate',
arguments: { url: server.PREFIX },
})).toHaveResponse({
code: `await page.goto('${server.PREFIX}');`,
pageState: expect.stringContaining(`- button \"Submit\" [ref=e2]`),
});
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))]));
/**
* @param {any} tool
* @returns {string[]}
*/
function formatToolForReadme(tool) {
const lines = /** @type {string[]} */ ([]);
lines.push(`<!-- NOTE: This has been generated via ${path.basename(__filename)} -->`);