Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/getting-started-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Playwright comes with `playwright-cli`, a command-line interface for browser aut
## Prerequisites

Before you begin, make sure you have the following installed:
- [Node.js](https://nodejs.org/) 18 or newer
- [Node.js](https://nodejs.org/) 20 or newer
- A coding agent: Claude Code, GitHub Copilot, or similar

## Installation
Expand Down
2 changes: 1 addition & 1 deletion docs/src/getting-started-mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The Playwright MCP server provides browser automation capabilities through the [
## Prerequisites

Before you begin, make sure you have the following installed:
- [Node.js](https://nodejs.org/) 18 or newer
- [Node.js](https://nodejs.org/) 20 or newer
- An MCP client: VS Code, Cursor, Windsurf, Claude Code, Claude Desktop, or similar

## Getting Started
Expand Down
4,625 changes: 2,904 additions & 1,721 deletions package-lock.json

Large diffs are not rendered by default.

208 changes: 103 additions & 105 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down Expand Up @@ -54,117 +54,115 @@
"packages/*"
],
"devDependencies": {
"@actions/core": "^3.0.0",
"@actions/github": "^9.0.0",
"@babel/code-frame": "^7.27.1",
"@babel/core": "^7.28.0",
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/parser": "^7.28.0",
"@babel/plugin-proposal-decorators": "^7.28.0",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-import-attributes": "^7.27.1",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-transform-class-properties": "^7.27.1",
"@babel/plugin-transform-class-static-block": "^7.27.1",
"@babel/plugin-transform-explicit-resource-management": "^7.28.0",
"@babel/plugin-transform-export-namespace-from": "^7.27.1",
"@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
"@babel/plugin-transform-numeric-separator": "^7.27.1",
"@babel/plugin-transform-optional-chaining": "^7.27.1",
"@babel/plugin-transform-private-methods": "^7.27.1",
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
"@babel/plugin-transform-react-jsx": "^7.27.1",
"@babel/preset-typescript": "^7.27.1",
"@eslint/compat": "^1.3.2",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.34.0",
"@jest/expect-utils": "30.2.0",
"@modelcontextprotocol/sdk": "^1.28.0",
"@octokit/graphql-schema": "^15.26.0",
"@stylistic/eslint-plugin": "^5.2.3",
"@types/babel__code-frame": "^7.0.6",
"@types/babel__core": "^7.20.5",
"@types/babel__helper-plugin-utils": "^7.10.3",
"@types/babel__traverse": "^7.20.6",
"@types/chrome": "^0.0.315",
"@types/codemirror": "^5.60.7",
"@types/debug": "^4.1.7",
"@types/diff": "^5.2.3",
"@types/formidable": "^2.0.4",
"@types/ini": "^4.1.1",
"@types/mime": "^2.0.3",
"@types/minimatch": "^3.0.5",
"@types/node": "18.19.76",
"@types/pngjs": "^6.0.1",
"@types/progress": "^2.0.5",
"@types/proxy-from-env": "^1.0.1",
"@types/react": "^19.2.1",
"@types/react-dom": "^19.2.1",
"@types/retry": "^0.12.5",
"@types/source-map-support": "^0.5.4",
"@actions/core": "3.0.1",
"@actions/github": "9.1.1",
"@babel/code-frame": "7.29.7",
"@babel/core": "7.29.7",
"@babel/helper-plugin-utils": "7.29.7",
"@babel/parser": "7.29.7",
"@babel/plugin-proposal-decorators": "7.29.7",
"@babel/plugin-syntax-async-generators": "7.8.4",
"@babel/plugin-syntax-import-attributes": "7.29.7",
"@babel/plugin-syntax-json-strings": "7.8.3",
"@babel/plugin-syntax-object-rest-spread": "7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "7.8.3",
"@babel/plugin-transform-class-properties": "7.29.7",
"@babel/plugin-transform-class-static-block": "7.29.7",
"@babel/plugin-transform-explicit-resource-management": "7.29.7",
"@babel/plugin-transform-export-namespace-from": "7.29.7",
"@babel/plugin-transform-logical-assignment-operators": "7.29.7",
"@babel/plugin-transform-modules-commonjs": "7.29.7",
"@babel/plugin-transform-nullish-coalescing-operator": "7.29.7",
"@babel/plugin-transform-numeric-separator": "7.29.7",
"@babel/plugin-transform-optional-chaining": "7.29.7",
"@babel/plugin-transform-private-methods": "7.29.7",
"@babel/plugin-transform-private-property-in-object": "7.29.7",
"@babel/plugin-transform-react-jsx": "7.29.7",
"@babel/preset-typescript": "7.29.7",
"@eslint/compat": "2.1.0",
"@eslint/eslintrc": "3.3.5",
"@eslint/js": "9.39.4",
"@jest/expect-utils": "30.4.1",
"@modelcontextprotocol/sdk": "1.29.0",
"@octokit/graphql-schema": "15.26.1",
"@stylistic/eslint-plugin": "5.10.0",
"@types/babel__code-frame": "7.27.0",
"@types/babel__core": "7.20.5",
"@types/babel__helper-plugin-utils": "7.10.3",
"@types/babel__traverse": "7.28.0",
"@types/chrome": "0.2.0",
"@types/codemirror": "5.60.17",
"@types/debug": "4.1.13",
"@types/diff": "7.0.2",
"@types/formidable": "2.0.6",
"@types/ini": "4.1.1",
"@types/node": "20.19.43",
"@types/pngjs": "6.0.5",
"@types/progress": "2.0.7",
"@types/proxy-from-env": "1.0.4",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@types/retry": "0.12.5",
"@types/source-map-support": "0.5.10",
"@types/ws": "8.18.1",
"@types/xml2js": "^0.4.9",
"@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.2",
"@typescript-eslint/eslint-plugin": "^8.59.0",
"@typescript-eslint/parser": "^8.59.0",
"@typescript-eslint/utils": "^8.59.0",
"@vitejs/plugin-basic-ssl": "^1.1.0",
"@vitejs/plugin-react": "^4.2.1",
"@zip.js/zip.js": "^2.7.29",
"@types/xml2js": "0.4.14",
"@types/yauzl": "3.4.0",
"@types/yazl": "3.3.1",
"@typescript-eslint/eslint-plugin": "8.62.0",
"@typescript-eslint/parser": "8.62.0",
"@typescript-eslint/utils": "8.62.0",
"@vitejs/plugin-basic-ssl": "2.3.0",
"@vitejs/plugin-react": "6.0.3",
"@zip.js/zip.js": "2.7.73",
"chokidar": "3.6.0",
"chromium-bidi": "^12.0.0",
"chromium-bidi": "12.1.0",
"colors": "1.4.0",
"commander": "^13.0.0",
"cross-env": "^7.0.3",
"debug": "^4.3.4",
"diff": "^8.0.3",
"dotenv": "^16.4.5",
"electron": "^42.3.3",
"enquirer": "2.3.6",
"esbuild": "^0.25.0",
"eslint": "^9.34.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-notice": "^1.0.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"formidable": "^2.1.1",
"get-east-asian-width": "1.3.0",
"get-stream": "^5.1.0",
"graceful-fs": "4.2.10",
"https-proxy-agent": "7.0.6",
"ini": "^6.0.0",
"jest-matcher-utils": "30.2.0",
"jest-message-util": "30.2.0",
"commander": "15.0.0",
"cross-env": "10.1.0",
"debug": "4.4.3",
"diff": "9.0.0",
"dotenv": "17.4.2",
"electron": "42.5.0",
"enquirer": "2.4.1",
"esbuild": "0.28.1",
"eslint": "9.39.4",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-notice": "1.0.0",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "5.2.0",
"formidable": "2.1.5",
"get-east-asian-width": "1.6.0",
"get-stream": "9.0.1",
"graceful-fs": "4.2.11",
"https-proxy-agent": "9.1.0",
"ini": "7.0.0",
"jest-matcher-utils": "30.4.1",
"jest-message-util": "30.4.1",
"jpeg-js": "0.4.4",
"json5": "2.2.3",
"license-checker": "^25.0.1",
"mime": "^3.0.0",
"minimatch": "^3.1.4",
"open": "8.4.0",
"pngjs": "6.0.0",
"license-checker": "25.0.1",
"mime": "4.1.0",
"minimatch": "10.2.5",
"open": "11.0.0",
"pngjs": "7.0.0",
"progress": "2.0.3",
"proxy-from-env": "2.0.0",
"react": "^19.2.1",
"react-dom": "^19.2.1",
"retry": "0.12.0",
"signal-exit": "3.0.7",
"socks-proxy-agent": "8.0.5",
"proxy-from-env": "2.1.0",
"react": "19.2.7",
"react-dom": "19.2.7",
"retry": "0.13.1",
"signal-exit": "4.1.0",
"socks-proxy-agent": "10.1.0",
"source-map-support": "0.5.21",
"ssim.js": "^3.5.0",
"typescript": "^6.0.3",
"vite": "^6.4.3",
"vite-plugin-static-copy": "^3.1.1",
"ssim.js": "3.5.0",
"typescript": "6.0.3",
"vite": "8.1.0",
"vite-plugin-static-copy": "3.4.0",
"ws": "8.21.0",
"xml2js": "^0.5.0",
"yaml": "^2.8.3",
"yauzl": "3.3.2",
"yazl": "2.5.1",
"zod": "^4.3.6",
"zod-to-json-schema": "^3.25.1"
"xml2js": "0.6.2",
"yaml": "2.9.0",
"yauzl": "3.4.0",
"yazl": "3.3.1",
"zod": "4.4.3",
"zod-to-json-schema": "3.25.2"
}
}
2 changes: 1 addition & 1 deletion packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-browser-chromium/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-browser-firefox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-browser-webkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-chromium/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"homepage": "https://playwright.dev",
"engines": {
"node": ">=18"
"node": ">=20"
},
"author": {
"name": "Microsoft Corporation"
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

const minimumMajorNodeVersion = 18;
const minimumMajorNodeVersion = 20;
const currentNodeVersion = process.versions.node;
const major = +currentNodeVersion.split('.')[0];

Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/cli/browserActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export async function codegen(options: Options & { target: string, output?: stri
});
const donePromise = new ManualPromise<void>();
maybeSetupTestHooks(browser, closeBrowser, donePromise);
dotenv.config({ path: 'playwright.env' });
dotenv.config({ path: 'playwright.env', quiet: true });
await context._enableRecorder({
language,
launchOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class ArtifactDispatcher extends Dispatcher<Artifact, channels.ArtifactCh
await new Promise<void>(resolve => {
readable.on('close', resolve);
readable.on('end', resolve);
readable.on('error', resolve);
readable.on('error', () => resolve());
});
} catch (e) {
reject(e);
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/server/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,10 @@ export abstract class APIRequestContext extends SdkObject {
const peerCertificate = socket.getPeerCertificate();
securityDetails = {
protocol: socket.getProtocol() ?? undefined,
subjectName: peerCertificate.subject.CN,
subjectName: peerCertificate.subject.CN as string,
validFrom: new Date(peerCertificate.valid_from).getTime() / 1000,
validTo: new Date(peerCertificate.valid_to).getTime() / 1000,
issuer: peerCertificate.issuer.CN
issuer: peerCertificate.issuer.CN as string
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ class SocksProxyConnection {
if (browserDecrypted.alpnProtocol === 'h2') {
// This method is available only in Node.js 20+
if ('performServerHandshake' in http2) {
// @ts-expect-error
const session: http2.ServerHttp2Session = http2.performServerHandshake(browserDecrypted);
session.on('error', error => {
this._browserEncrypted.destroy(error);
Expand Down
9 changes: 4 additions & 5 deletions packages/playwright-core/src/utilsBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const jpegjs = jpegLibrary;
import mimeLibrary from 'mime';
export const mime = mimeLibrary;

import minimatchLibrary from 'minimatch';
import { minimatch as minimatchLibrary } from 'minimatch';
export const minimatch = minimatchLibrary;

import openLibrary from 'open';
Expand Down Expand Up @@ -90,17 +90,16 @@ export const gracefulFs = gracefulFsLibrary;
import retryLibrary from 'retry';
export const retry = retryLibrary;

// @ts-expect-error untyped vendored module
import onExitLibrary from 'signal-exit';
import { onExit as onExitLibrary } from 'signal-exit';
export const onExit = onExitLibrary;

import getStreamLibrary from 'get-stream';
export const getStream = getStreamLibrary;

import httpProxyAgentLibrary from 'https-proxy-agent';
import { HttpsProxyAgent as httpProxyAgentLibrary } from 'https-proxy-agent';
export const httpProxyAgent = httpProxyAgentLibrary;

import socksProxyAgentLibrary from 'socks-proxy-agent';
import { SocksProxyAgent as socksProxyAgentLibrary } from 'socks-proxy-agent';
export const socksProxyAgent = socksProxyAgentLibrary;

export * as z from 'zod';
Expand Down
Loading
Loading