โ ๏ธ 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:
โก 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
Newer Version โ
Latest Tracked Version โ