Playwright v1.65.0stable Released Nov 05, 2026
โš ๏ธ Breaking Change Impact Score: 7/10

Playwright v1.65.0 โ€” Release Notes & Engineering Impact

Source available โ€” automated, not human-reviewed

Component: playwright ยท Channel: stable. Automated analysis, not a compatibility certification. How this works.

Analysis updated: 2026-11-05.

Breaking-change evidence from the source

  • Breaking Changes โš ๏ธ - TypeScript class fields now follow [`useDefineForClassFields`](https://playwright.dev/docs/test-typescript#tsconfig-class-fields) from your `tsconfig.json`, the same as `tsc`. It is enabled for `ES2022` and later targets, and when `target` is not specified. A field initializer that reads a constructor parameter property now fails, because the initializer runs first:
Read the original context โ†—
Source flags breaking changes โ€” review applicability
๐Ÿ“„ .MD
โšก Executive Summary (TL;DR)

Playwright v1.65.0. Source highlight: ๐ŸฅŸ Run tests with Bun

Who Does This Impact? (Role-Based Analysis)

๐Ÿ’ป Software Engineers & Devs

Check the source notes against the package and APIs you use before upgrading.

๐Ÿ“Š Product & Engineering Leads

Use the documented changes to assess relevance to your product; release frequency alone is not a quality measure.

โš™๏ธ DevOps & Security

Verify the target version, runtime requirements and rollback procedure in the official documentation.

โš ๏ธ Breaking Changes & Deprecations (1)

  • Breaking Changes โš ๏ธ - TypeScript class fields now follow [`useDefineForClassFields`](https://playwright.dev/docs/test-typescript#tsconfig-class-fields) from your `tsconfig.json`, the same as `tsc`. It is enabled for `ES2022` and later targets, and when `target` is not specified. A field initializer that reads a constructor parameter property now fails, because the initializer runs first:

๐Ÿ”ง Bug Fixes & Patches (1)

  • ๐Ÿณ Docker images now include Node.js 26 instead of Node.js 24, and the latest patch of Chromium on the same branch.
๐Ÿ“„ View Raw Release Notes (Original Developer Log)
## ๐ŸฅŸ Run tests with Bun The test runner now runs under [Bun](https://bun.com). Bun transpiles your TypeScript test files itself, so Playwright does not use Babel or its compilation cache. Pass the `--bun` flag, because without it `bunx playwright test` runs on Node.js: ```bash bunx --bun playwright test ``` Our CI runs the test runner tests under Bun 1.4.3 on Linux. Some features work differently under Bun: - There is no watch mode. UI mode does not run tests again when files change, and `--only-changed` does not follow imports. - Bun loads modules itself, so `--tsconfig` and the JSX options in `tsconfig.json` have no effect, and custom ESM loaders are not supported. - Stack traces do not include async frames, and API names do not include the class name: `click` instead of `locator.click`. This changes some step locations, step titles and error messages. - Console output of a test does not get into the trace and UI mode. ## ๐Ÿšจ Reports with only failures New [`failures`](https://playwright.dev/docs/test-reporters#failures-reporter) reporter prints failures and successful retries as they occur, followed by a summary, without progress output. New `onlyFailures` option of the HTML, JSON and JUnit reporters [keeps only](https://playwright.dev/docs/test-reporters#report-only-failures) tests with unexpected outcomes, flaky tests and interrupted tests: ```js // playwright.config.ts import { defineConfig } from '@playwright/test'; export default defineConfig({ reporter: [ ['failures'], ['html', { onlyFailures: true }], ], }); ``` ## ๐ŸŽฏ Test runner - New built-in `-exclusive-` [test lock](https://playwright.dev/docs/test-parallel#test-locks) runs a test only when no other tests are running. All other tests continue to run in parallel with each other: ```js test('restart the server', { lock: '-exclusive-' }, async () => { // No other test runs while this one is running. }); ``` - [test.skip()](https://playwright.dev/docs/api/class-test#test-skip), [test.fixme()](https://playwright.dev/docs/api/class-test#test-fixme), [test.fail()](https://playwright.dev/docs/api/class-test#test-fail) and [test.slow()](https://playwright.dev/docs/api/class-test#test-slow) now accept only a description. It is recorded in the test annotation: ```js test('upload a file', async ({ page }) => { test.skip('Not implemented yet'); }); ``` - New `PLAYWRIGHT_TRANSFORM_CACHE_DIR` environment variable sets the directory for transpiled test files, for example on a Linux machine shared with other users. ## New APIs - New options [`timeout`](https://playwright.dev/docs/api/class-cdpsession#cdp-session-send-option-timeout) and [`signal`](https://playwright.dev/docs/api/class-cdpsession#cdp-session-send-option-signal) in [cdpSession.send()](https://playwright.dev/docs/api/class-cdpsession#cdp-session-send). - New [testRun.mode()](https://playwright.dev/docs/api/class-testrun#test-run-mode) returns the execution mode of a suite during [reporter.preprocess()](https://playwright.dev/docs/api/class-reporter#reporter-preprocess). ## Breaking Changes โš ๏ธ - TypeScript class fields now follow [`useDefineForClassFields`](https://playwright.dev/docs/test-typescript#tsconfig-class-fields) from your `tsconfig.json`, the same as `tsc`. It is enabled for `ES2022` and later targets, and when `target` is not specified. A field initializer that reads a constructor parameter property now fails, because the initializer runs first: ```js class LoginPage { // TypeError: Cannot read properties of undefined (reading 'getByRole') readonly submit = this.page.getByRole('button', { name: 'Submit' }); constructor(private readonly page: Page) {} } ``` Move the initialization to the constructor, or set `"useDefineForClassFields": false` in your `tsconfig.json`. - Actions such as [locator.click()](https://playwright.dev/docs/api/class-locator#locator-click), [locator.check()](https://playwright.dev/docs/api/class-locator#locator-check), [locator.tap()](https://playwright.dev/docs/api/class-locator#locator-tap), [locator.fill()](https://playwright.dev/docs/api/class-locator#locator-fill), [locator.clear()](https://playwright.dev/docs/api/class-locator#locator-clear) and [locator.selectOption()](https://playwright.dev/docs/api/class-locator#locator-select-option) now wait for the element to be [not inert](https://playwright.dev/docs/actionability#not-inert). An action on an element with the `inert` attribute, or inside such an element, now times out if the element stays inert. - A sharded run now fails with "No tests found" when no tests match across all shards. Pass `--pass-with-no-tests` to allow this. An empty shard still passes when other shards have tests. - Cookie matching now follows RFC 6265. With a URL, [browserContext.cookies()](https://playwright.dev/docs/api/class-browsercontext#browser-context-cookies) and [apiRequestContext.cookies()](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-cookies) no longer return host-only cookies for subdomains or `Path=/api` cookies for `/apiv2`, and a `Path=/foo/` cookie does not match `/foo`. [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext) sends a cookie without a name as `Cookie: x` instead of `Cookie: =x`, and stores `Set-Cookie: token` as a cookie without a name. - Proxy credentials are no longer sent to websites. The credentials in the [`proxy`](https://playwright.dev/docs/api/class-browsertype#browser-type-launch-option-proxy) option now answer only proxy challenges. To authenticate on a website, use [`httpCredentials`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-http-credentials). - Text that the browser does not render, such as text that is not assigned to a slot or text directly inside a closed `<details>`, is no longer part of accessible names and aria snapshots. This can change the results of [page.getByRole()](https://playwright.dev/docs/api/class-page#page-get-by-role) with a name, [locator.ariaSnapshot()](https://playwright.dev/docs/api/class-locator#locator-aria-snapshot) and [expect(locator).toMatchAriaSnapshot()](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot). - String and `URLSearchParams` values of the `params` option in [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext) requests are now appended to the query that the URL already has, instead of replacing it. - `.css`, `.less` and `.scss` imports in test files now load as empty modules instead of being removed, so the imported file must exist. - The blob reporter again deletes the content of its output directory before it writes the report. Playwright 1.64 kept reports with other names. - Test locations of imported calls such as `test(` in CommonJS output now point to the start of the callee, for example `a.spec.ts:3:7` instead of `a.spec.ts:3:11`. This is the same as in ESM. ## Announcements * โš ๏ธ Playwright no longer tests on Node.js 20. Use Node.js 22, 24 or 26, as listed in the [system requirements](https://playwright.dev/docs/intro#system-requirements). * ๐Ÿณ [Docker images](https://playwright.dev/docs/docker) now include Node.js 26 instead of Node.js 24, and the latest patch of Chromium on the same branch. ## Browser Versions - Chromium 158.0.8127.18 - Mozilla Firefox 159.0 - WebKit 27.2 This version was also tested against the following stable channels: - Google Chrome 157 - Microsoft Edge 156
โ† Older Version Playwright v1.64.1