Playwright 1.65 New Features Explained: Bun Test Runner, Failure-Only Reports and the Breaking Changes

Playwright 1.65 new features explained — the official Playwright logo

Image: Microsoft — the official Playwright logo (Apache 2.0, via Wikimedia Commons).

TL;DR — Playwright 1.65 new features explained in one line: Microsoft's browser-testing framework, released 5 November 2026, can now run its test runner under Bun with a --bun flag, adds failure-only reports and exclusive test locks — but it also drops Node.js 20 and ships breaking changes that can fail existing suites, so upgrade on a branch first.

📌 KEY HIGHLIGHTS

  • Run tests with Bun: bunx --bun playwright test runs the test runner under Bun, which transpiles your TypeScript test files itself — no Babel, no compilation cache.
  • Failure-only reporting: a new failures reporter and an onlyFailures option for the HTML, JSON and JUnit reporters keep CI logs short.
  • Exclusive test locks: a built-in -exclusive- lock runs a test only when nothing else is running; test.skip(), test.fixme(), test.fail() and test.slow() now take only a description.
  • Breaking changes to check first: TypeScript class fields now follow useDefineForClassFields (some page objects throw), actions wait for non-inert elements, sharded runs fail when no tests match, and cookie matching follows RFC 6265.
  • Node.js 20 is out: Playwright 1.65 is tested only on Node.js 22, 24 and 26; the Docker images now ship Node.js 26. Browsers pinned: Chromium 158, Firefox 159, WebKit 27.2.

What happened?

Microsoft's Playwright — the open-source framework teams use to test web apps across Chromium, Firefox and WebKit — shipped version 1.65.0 on 5 November 2026. It follows 1.64, released on 8 October, which added WebMCP testing and a --shuffle flag. This release is really two stories at once: a genuinely useful new runtime option, and a list of breaking changes long enough that the upgrade deserves a branch and a full test run rather than a Friday-afternoon version bump.

The timing also matters. Days before the release, a viral post claimed Playwright was a security risk because it "bundles browsers". On 3 November the official Playwright account pushed back on X: no Playwright package bundles a browser at all — npx playwright install downloads pinned Chrome for Testing builds on request, into a cache folder, and the test runner uses those pinned builds by design. An independent fact-check by Codecaf in November 2026 concluded the official response holds up. The 1.65 release notes carry no security fix for that claim, because there was nothing to fix — but the episode is a useful reminder to check what a testing tool actually installs before repeating a scare post.

Playwright 1.65 new features explained

Run tests with Bun

The headline feature is Bun support. The test runner now runs under Bun — the fast JavaScript runtime — instead of Node.js. Pass the --bun flag, because without it bunx playwright test still runs on Node.js:

bunx --bun playwright test

Bun transpiles your TypeScript test files itself, so Playwright does not use Babel or its compilation cache. That removes a whole layer of tooling from the test path, which is the point: fewer moving parts between your test files and the browser. Microsoft's own CI runs the test-runner tests under Bun 1.4.3 on Linux, so the mode is tested — but it is not yet a full replacement for the Node.js path, and the release notes are honest about the gaps. There is no watch mode. UI mode does not run tests again when files change, and --only-changed does not follow imports. Because Bun loads modules itself, --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 lose their class name — click instead of locator.click — which changes some step locations, step titles and error messages. Console output from a test does not get into the trace or UI mode. If your workflow leans on watch mode or UI mode, stay on Node.js for now and try Bun mode on a side branch.

Reports with only failures

Big suites produce big logs, and most of the lines are passes nobody reads. Playwright 1.65 adds a failures reporter that prints failures and successful retries as they occur, followed by a summary, without progress output. The same idea reaches the existing reporters through a new onlyFailures option for the HTML, JSON and JUnit reporters, which keeps only tests with unexpected outcomes, flaky tests and interrupted tests. For CI pipelines where the interesting output is buried under thousands of passing lines, this is the most immediately useful change in the release.

Test runner: exclusive locks and new APIs

Some tests cannot share: restarting a server, flipping a global account setting, touching a shared external service. Playwright 1.63 added named test locks for that; 1.65 adds a built-in -exclusive- lock that runs a test only when no other tests are running, while all other tests keep running in parallel with each other. Also in the runner: test.skip(), test.fixme(), test.fail() and test.slow() now accept only a description, recorded in the test annotation; and a new PLAYWRIGHT_TRANSFORM_CACHE_DIR environment variable sets the directory for transpiled test files — useful on a Linux machine shared between users. Two new APIs land as well: timeout and signal options in cdpSession.send(), and testRun.mode(), which returns the execution mode of a suite during reporter.preprocess().

The breaking changes — what fails and how to fix it

An independent tester ran every breaking change below on Playwright 1.64.1 and 1.65.0 with the same spec files, so each row shows what actually changed rather than what the notes promise. Check your suite against this table before upgrading.

Change in 1.65What happensFix or workaround
TypeScript class fields follow useDefineForClassFieldsA page-object field that reads a constructor parameter property — for example readonly submit = this.page.getByRole('button', {name: 'Submit'}) — now throws TypeError: Cannot read properties of undefined before the test body runsMove the initialisation into the constructor, or set "useDefineForClassFields": false in tsconfig.json
Actions wait for non-inert elementsclick, check, tap, fill, clear and selectOption on an element with the inert attribute — or inside one — now time out if the element stays inertRemove the inert attribute before acting, or fix the app code that leaves elements inert
Sharded run with no tests now failsA sharded run where no tests match on any shard used to exit 0; it now fails with "No tests found"Pass --pass-with-no-tests to allow it; an empty shard still passes when other shards have tests
Cookie matching follows RFC 6265With a URL, browserContext.cookies() no longer returns host-only cookies for subdomains or Path=/api cookies for /apiv2; a Path=/foo/ cookie does not match /fooTighten cookie paths and domains in test setup to match the standard
Proxy credentials no longer reach websitesCredentials in the proxy option now answer only proxy challengesAuthenticate on a website with httpCredentials instead
API params appended, not replacedString and URLSearchParams values in API request params are now appended to the query the URL already has, instead of replacing itAn API call that used to send a different URL may now send a merged query — check request assertions
Node.js 20 no longer testedPlaywright 1.65 is tested only on Node.js 22, 24 and 26; Docker images now ship Node.js 26Upgrade CI images to Node.js 22 or newer before upgrading Playwright

Three smaller breaks round out the list: text the browser does not render — such as text not assigned to a slot, or text directly inside a closed <details> — is no longer part of accessible names and aria snapshots, which can change getByRole() results; .css, .less and .scss imports in test files now load as empty modules instead of being removed, so the imported file must exist; and the blob reporter again deletes the contents of its output directory before writing the report.

Playwright 1.65 new features explained — the Bun JavaScript runtime logo, the headline feature of this release

Image: Jarred Sumner / Oven — the Bun logo (MIT licence, via Wikimedia Commons). Bun is the headline runtime option in Playwright 1.65.

Why it matters for Indian developers

Playwright is the default end-to-end testing choice for a large share of Indian product teams and service companies, and its upgrades land in CI pipelines that run thousands of tests a day. The Bun mode matters here because Indian startups adopted Bun early — it replaces runtime, bundler, test runner and package manager in one binary — and a Bun-native Playwright run removes the Babel step those teams never wanted. The breaking changes matter more: page-object patterns are the standard way Indian QA teams structure suites, so the useDefineForClassFields change is the one most likely to turn a routine upgrade red on Monday morning. The Node.js 20 drop matters too, because plenty of CI images still pin it. And the failure-only reporters are a quiet win for teams whose CI logs are already too long to read: the signal — what failed and why — is now the default view instead of something you scroll to find. Chrome 157 is the stable channel this release was tested against, so teams on the current Chrome get the tested combination.

Should you care?

✅ Yes, if you run Playwright in CI or maintain a large suite — the failure-only reporters and the exclusive lock are immediate wins, and the Bun mode is worth a trial on a branch. ⏳ Wait on a production upgrade if your suite uses page objects with field initialisers, runs on Node.js 20, or relies on UI mode or watch mode — fix those first, then upgrade.

How to upgrade

Playwright is free and open source under the Apache 2.0 licence. Upgrade on a branch, not on main: check your version with npx playwright --version, then run npm i -D @playwright/[email protected] followed by npx playwright install to fetch the pinned browsers — Chromium 158.0.8127.2, Firefox 159.0 and WebKit 27.2. Run the whole suite, and use the breaking-changes table above to explain what fails. If you are on Node.js 20, move to 22, 24 or 26 first. To try Bun mode, run bunx --bun playwright test and compare the run against your Node.js baseline before committing to it. Like the Go 1.27 release earlier this week, this is a developer-tooling upgrade where the migration notes matter as much as the features.

FAQs

What is new in Playwright 1.65?
Released 5 November 2026, it adds native Bun test execution with the --bun flag, a failures reporter and an onlyFailures reporter option, a built-in -exclusive- test lock, and new cdpSession.send() options — plus breaking changes around class fields, inert elements, cookies and Node.js 20.

How do I run Playwright tests with Bun?
Run bunx --bun playwright test. Bun transpiles your TypeScript test files itself, so Playwright skips Babel and its compilation cache. Without the --bun flag, bunx playwright test still runs on Node.js. Note the limits: no watch mode, no test re-runs in UI mode, and --tsconfig and JSX options have no effect under Bun.

Does Playwright 1.65 still support Node.js 20?
No. Playwright 1.65 is tested only on Node.js 22, 24 and 26, and the Docker images now ship Node.js 26 instead of 24. Upgrade your Node.js version — in CI images as well as locally — before upgrading Playwright.

What breaks when upgrading to Playwright 1.65?
The most common break is a page-object field that reads a constructor parameter, which now throws a TypeError because class fields follow useDefineForClassFields. Other breaks: actions on inert elements time out, sharded runs with no matching tests fail, cookie matching follows RFC 6265, and proxy credentials no longer authenticate on websites — use httpCredentials instead.

Takeaway: Playwright 1.65 is a useful release with a sharp edge — Bun mode and failure-only reports genuinely improve the daily workflow, but the breaking changes will fail suites that upgrade blindly. Upgrade on a branch, run the full suite, and work through the table above before merging.

Try the Bun mode on a copy of your own suite this week and compare its run time against your Node.js baseline — that comparison, not the release notes, will tell you whether to switch.

Sources

Comments