You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(deps): update dependency @playwright/test to v1.65.0 in package.json - #118
The test runner now runs under Bun. 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:
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 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 tests with unexpected outcomes, flaky tests and interrupted tests:
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.
TypeScript class fields now follow useDefineForClassFields 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:
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() and apiRequestContext.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 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 option now answer only proxy challenges. To authenticate on a website, use httpCredentials.
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() with a name, locator.ariaSnapshot() and expect(locator).toMatchAriaSnapshot().
String and URLSearchParams values of the params option in 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.
🐳 Docker images 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:
New page.webmcp and frame.webmcp give access to the tools that a page registers through the experimental WebMCP browser API, so you can test them like any other part of your app:
New style option takes CSS declarations for the point marker, the target highlight and the action title. It replaces the fontSize option, which is now deprecated.
The cursor stays visible at the last action point, survives navigations and travels along a natural, eased path.
Videos are encoded with VP9 instead of VP8, which takes less CPU and produces smaller files of the same or better
quality.
New testProject.default option keeps a project in the config without running it by default. You can configure every browser you care about, and let a plain npx playwright test run just your favourite one:
npx playwright test# runs chromium only
npx playwright test --project=firefox # runs firefox
npx playwright test --project="*"# runs all three, for example on CI
New --shuffle command line option schedules tests in a random order, which helps to find tests that accidentally depend on each other.
npx playwright test --shuffle
# Running 42 tests using 4 workers, shuffle seed 271828182# ...# Pass the seed to reproduce the same order.
npx playwright test --shuffle 271828182
Relative locators such as locator.nth() or locator.first() are resolved inside each parent
separately, which makes column-like queries straightforward:
// The third cell of every row, not the third cell in the table.constthirdColumn=page.getByRole('cell').nth(2).within(page.getByRole('row'));awaitexpect(thirdColumn).toHaveText(['Apple','Banana','Cherry']);
New option signCount sets the initial signature counter of a virtual credential. credentials.create() and credentials.get() return the current signCount, and it is saved and restored together with the credentials in the storage state.
New fullConfig.filteredProjects lists the projects that were selected to run after applying the --project filter. It is available in global setup and reporters.
screen property is now forwarded from the device descriptors. If you use ...devices['Desktop Chrome'] and alike, window.screen and media queries now see the emulated screen size. You can opt-out by explicitly setting screen to undefined:
JSX in your test files now follows your tsconfig.json. Playwright compiles JSX in test files according to the jsx, jsxFactory, jsxFragmentFactory and jsxImportSourcetsconfig options, and defaults to the automatic runtime from react/jsx-runtime.
--update-snapshots=missing now passes the test run. Tests that only create missing snapshots now pass in the 'missing' mode of testConfig.updateSnapshots, so that CI can generate new snapshots and verify the existing ones in a single run. The mode used when the option is not specified is now called 'default' and behaves as before: missing snapshots are written and the test fails.
Elements inside hidden iframes are considered hidden. Elements inside an iframe that is not visible, for example with visibility: hidden, are now considered hidden by actions, locator.isVisible() and expect(locator).toBeVisible().
Browser Versions
Chromium 156.0.8078.4
Mozilla Firefox 157.0
WebKit 27.2
This version was also tested against the following stable channels:
Tests that access a shared resource — an external service, a global account setting — can now declare a named lock.
Tests that share a lock name never run concurrently, across files, workers and projects, while
everything else keeps running in parallel:
test('update user settings',{lock: 'user-settings'},async({ page })=>{// never runs at the same time as other tests holding 'user-settings'});
A test can hold multiple locks, and test.describe() accepts a lock for the whole group.
Learn more about test locks.
🪟 Locate across frames
page.frameLocator() and frame.frameLocator() called without a selector search in any frame of the
subtree, so you no longer need to locate the iframe first:
// Finds the button in any frame on the page.awaitpage.frameLocator().getByRole('button').click();
The rest of the locator resolves inside a single frame, just like a regular locator, and an error is thrown when it
matches elements in several frames.
👁️ Visible-only locators
New locator.visible() returns a locator that matches only visible elements. It is the recommended
replacement for the :visible CSS pseudo-class:
awaitpage.locator('button').visible().click();
🧾 Step params and subtitles
Steps now carry structured data for reporters. Playwright API steps report the target locator and call arguments,
and test.step() accepts subtitle and params options for your own steps:
Reporters receive them via testStep.subtitle and testStep.params. For Playwright API
steps, the subtitle is the locator or the navigation url — for example, Click with subtitle getByRole('button').
Both are rendered next to the step title in the trace viewer and the HTML report.
🖼️ Aria and screen snapshots in traces
The snapshots option of tracing.start() and the testOptions.trace fixture option now accept an
object selecting what to capture on every action:
With aria and screen snapshots recorded, the new Display Aria mode in the trace viewer shows the action screenshot
side by side with the aria snapshot, and hovering an aria node highlights it on the screenshot.
New APIs
Browser and Context
httpCredentials now also accepts an array of credentials. The first entry matching the request origin is used, and entries without an origin match any request.
New option opfs includes the origin private file system in the storage state, so it can be persisted and restored into later contexts.
New --add-reporter command line option appends a reporter on top of the ones configured in playwright.config, instead of replacing them like --reporter does.
New omitTags option for the list, line, dot, github and junit reporters suppresses the tags that are automatically appended to test titles.
Command line
npx playwright install --no-remove keeps the browsers of other Playwright installations instead of removing them.
npx playwright codegen --http-credentials records against pages behind HTTP authentication.
Miscellaneous
New built-in perfetto reporter writes a Trace Event Format file for the Perfetto UI or chrome://tracing, rendering the test run as a timeline with a lane per worker.
The HTML report renders a duration waterfall next to test steps.
Announcements
⚠️ The experimental @playwright/experimental-ct-react, @playwright/experimental-ct-react17 and @playwright/experimental-ct-vue packages will no longer be updated. Follow the migration guide to move to the stories model introduced in 1.62. Story ids passed to fixtures.mount() can now be typed through the generated Stories registry.
⚠️ Ubuntu 20.04 is not supported anymore.
🐧 On Linux arm64, Playwright now downloads the Chrome for Testing build of Chromium, the same build used on all other platforms.
Browser Versions
Chromium 153.0.8010.12
Mozilla Firefox 155.0
WebKit 26.6
This version was also tested against the following stable channels:
Component testing moves to a stories and galleries model.
A story wraps your component in one specific scenario — hard-coded props, mock data, providers — and a gallery page that you serve renders stories on demand.
The new fixtures.mount() fixture navigates to the gallery, mounts a story by id, and returns a Locator scoped to the story's root element:
test('click should expand',async({ mount })=>{constcomponent=awaitmount('components/Expandable/Stateful');awaitcomponent.getByRole('button').click();awaitexpect(component.getByTestId('expanded')).toHaveValue('true');});
Pass a story type as a template argument to type-check its props, and use update(props) / unmount() on the returned locator to re-render or tear down within a test.
🛑 Cancel operations with AbortSignal
Most operations and web-first assertions now accept a signal option that takes an AbortSignal, letting you cancel long-running actions, navigations, waits, and assertions:
// Visual comparisons store the golden snapshot as lossless WebP.awaitexpect(page).toHaveScreenshot('homepage.webp');// Standalone screenshots can trade quality for size with lossy WebP.awaitpage.screenshot({path: 'homepage.webp',quality: 50});
🧩 Custom test filtering with Reporter.preprocess()
New reporter.preprocess() hook runs after the configuration is resolved and before reporter.onBegin(), letting a reporter mark individual tests as skipped, excluded, fixed, or failing through a TestRun object:
New testConfig.retryStrategy controls when failed tests are retried.
The default 'immediate' retries as soon as a worker is free; 'isolated' runs all retries at the end, one by one in a single worker, to minimize interference with the rest of the suite:
New option credentials includes the context's virtual WebAuthn Credentials (passkeys) in the storage state, so they can be persisted and re-seeded into later contexts.
Actions
New scroll option ("auto" | "none") on actions to opt out of Playwright's automatic scroll-into-view.
Network
New apiResponse.timing() returns resource timing information for an API response.
Evaluation
New locator.waitForFunction() waits until a function — called with the matching element — returns a truthy value.
page.evaluate() and related methods now accept functions as evaluate arguments.
#41365 [Bug]: Expect.Extend matcher with same name as default matcher in same expect instance overrides default matchers implementation to custom matcher
#41351 [Bug]: Playwright UI mode: apiRequestContext._wrapApiCall reports unexpected number of bytes (same test passes in headed mode)
#41360 [Bug]: Trace viewer: message times in websockets are downscaled by 1000
#41311 [Bug]: [Regression]: Sync loader throws "context.conditions?.includes is not a function" on Node 22.15
#41371 [Regression]: Sync ESM loader (registerHooks) fails to resolve extensionless .ts subpath imports across pnpm workspace symlinks
New Credentials virtual authenticator, available via browserContext.credentials, lets tests register passkeys and answer navigator.credentials.create() / navigator.credentials.get() ceremonies in the page — no real hardware key required, works in all browsers:
constcontext=awaitbrowser.newContext();// Seed a passkey your backend provisioned for a test user.awaitcontext.credentials.create('example.com',{id: credentialId,
userHandle,
privateKey,
publicKey,});awaitcontext.credentials.install();constpage=awaitcontext.newPage();awaitpage.goto('https://example.com/login');// The page's navigator.credentials.get() is answered with the seeded passkey.
You can also let the app register a passkey once in a setup test, read it back with credentials.get(), and seed it into later tests — see Credentials for details.
New option artifactsDir in browserType.connectOverCDP() controls where artifacts such as traces and downloads are stored when attached to an existing browser.
New option cursor in screencast.showActions() controls the cursor decoration rendered for pointer actions.
The onFrame callback in screencast.start() now receives a timestamp of when the frame was presented by the browser.
Test runner
The testOptions.video option now supports the same set of modes as trace: new 'on-all-retries', 'retain-on-first-failure' and 'retain-on-failure-and-retries' values. See the video modes table for which runs are recorded and kept in each mode.
Supported expect.soft.poll(...).
New fullConfig.argv — a snapshot of process.argv from the runner process, handy for reading custom arguments passed after the -- separator.
tracing.startHar() / tracing.stopHar() expose HAR recording as a first-class tracing API, with the same content, mode and urlFilter options as recordHar. The returned Disposable makes it easy to scope a recording with await using:
await using har=awaitcontext.tracing.startHar('trace.har');constpage=awaitcontext.newPage();awaitpage.goto('https://playwright.dev');// HAR is finalized when `har` goes out of scope.
🪝 Drop API
New locator.drop() simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches dragenter, dragover, and drop with a synthetic [DataTransfer] in the page context — works cross-browser and is great for testing upload zones:
New test.abort() aborts the currently running test from a fixture, hook, or route handler with an optional message. Use it when you have detected an unrecoverable misuse and want to fail the test right away:
test('does not publish to the shared page',async({ page })=>{awaitpage.route('**/publish',route=>{test.abort('Tests must not publish to the shared page. Use the `clone` option.');returnroute.abort();});// ...});
New option noDefaults in browserType.connectOverCDP() disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state.
consoleMessage.location() now exposes line / column properties (lineNumber / columnNumber are deprecated).
New testInfoError.errorContext surfaces additional diagnostic context, such as the aria snapshot of the receiver at the time of an expect(...) matcher failure.
reporter.onError() now receives a workerInfo argument with details about the worker for fixture teardown errors.
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.60.0 in package.json
fix(deps): update playwright monorepo to v1.60.0 in package.json
Jun 2, 2026
renovateBot
changed the title
fix(deps): update playwright monorepo to v1.60.0 in package.json
fix(deps): update playwright monorepo to v1.61.0 in package.json
Jun 18, 2026
renovateBot
changed the title
fix(deps): update playwright monorepo to v1.61.0 in package.json
fix(deps): update playwright monorepo in package.json
Jun 22, 2026
renovateBot
changed the title
fix(deps): update playwright monorepo in package.json
fix(deps): update dependency @playwright/test to v1.61.0 in package.json
Jun 25, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.61.0 in package.json
fix(deps): update dependency @playwright/test to v1.61.1 in package.json
Jun 26, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.61.1 in package.json
fix(deps): update dependency @playwright/test to v1.62.0 in package.json
Jul 27, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.62.0 in package.json
fix(deps): update dependency @playwright/test to v1.62.1 in package.json
Aug 3, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.62.1 in package.json
fix(deps): update dependency @playwright/test to v1.63.0 in package.json
Sep 8, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.63.0 in package.json
fix(deps): update dependency @playwright/test to v1.64.0 in package.json
Oct 12, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.64.0 in package.json
fix(deps): update dependency @playwright/test to v1.64.1 in package.json
Oct 19, 2026
renovateBot
changed the title
fix(deps): update dependency @playwright/test to v1.64.1 in package.json
fix(deps): update dependency @playwright/test to v1.65.0 in package.json
Nov 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
1.59.1→1.65.0Release Notes
microsoft/playwright (@playwright/test)
v1.65.0Compare Source
🥟 Run tests with Bun
The test runner now runs under Bun. Bun transpiles your TypeScript test files itself, so Playwright does not use Babel or its compilation cache. Pass the
--bunflag, because without itbunx playwright testruns on Node.js:bunx --bun playwright testOur CI runs the test runner tests under Bun 1.4.3 on Linux. Some features work differently under Bun:
--only-changeddoes not follow imports.--tsconfigand the JSX options intsconfig.jsonhave no effect, and custom ESM loaders are not supported.clickinstead oflocator.click. This changes some step locations, step titles and error messages.🚨 Reports with only failures
New
failuresreporter prints failures and successful retries as they occur, followed by a summary, without progress output.New
onlyFailuresoption of the HTML, JSON and JUnit reporters keeps only tests with unexpected outcomes, flaky tests and interrupted tests:🎯 Test runner
New built-in
-exclusive-test lock runs a test only when no other tests are running. All other tests continue to run in parallel with each other:test.skip(), test.fixme(), test.fail() and test.slow() now accept only a description. It is recorded in the test annotation:
New
PLAYWRIGHT_TRANSFORM_CACHE_DIRenvironment variable sets the directory for transpiled test files, for example on a Linux machine shared with other users.New APIs
timeoutandsignalin cdpSession.send().Notable Changes⚠️
TypeScript class fields now follow
useDefineForClassFieldsfrom yourtsconfig.json, the same astsc. It is enabled forES2022and later targets, and whentargetis not specified. A field initializer that reads a constructor parameter property now fails, because the initializer runs first:Move the initialization to the constructor, or set
"useDefineForClassFields": falsein yourtsconfig.json.Actions such as locator.click(), locator.check(), locator.tap(), locator.fill(), locator.clear() and locator.selectOption() now wait for the element to be not inert. An action on an element with the
inertattribute, 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-teststo allow this. An empty shard still passes when other shards have tests.Cookie matching now follows RFC 6265. With a URL, browserContext.cookies() and apiRequestContext.cookies() no longer return host-only cookies for subdomains or
Path=/apicookies for/apiv2, and aPath=/foo/cookie does not match/foo. APIRequestContext sends a cookie without a name asCookie: xinstead ofCookie: =x, and storesSet-Cookie: tokenas a cookie without a name.Proxy credentials are no longer sent to websites. The credentials in the
proxyoption now answer only proxy challenges. To authenticate on a website, usehttpCredentials.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() with a name, locator.ariaSnapshot() and expect(locator).toMatchAriaSnapshot().String and
URLSearchParamsvalues of theparamsoption in APIRequestContext requests are now appended to the query that the URL already has, instead of replacing it..css,.lessand.scssimports 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 examplea.spec.ts:3:7instead ofa.spec.ts:3:11. This is the same as in ESM.Announcements
Browser Versions
This version was also tested against the following stable channels:
v1.64.1Compare Source
Bug Fixes
v1.64.0Compare Source
🧰 WebMCP
New page.webmcp and frame.webmcp give access to the tools that a page registers through the experimental WebMCP browser API, so you can test them like any other part of your app:
Playwright MCP also supports WebMCP by default, with page-defined tools offered to the agent as
webmcp_<tool>. Pass--no-webmcpto opt out.playwright-cliexposes them as well:playwright-cli webmcp-list playwright-cli webmcp-call search_catalog --params '{"query":"cats"}'🎬 Better videos
Videos can now be recorded at a custom frame rate, and the decorations for actions are styled with plain CSS:
fpsoption in testOptions.video,recordVideoandscreencast.start(). Firefox and WebKit currently capture up to 25 frames per second.
styleoption takes CSS declarations for thepointmarker, the targethighlightand the actiontitle. It replaces thefontSizeoption, which is now deprecated.quality.
playwright-cli.🎯 Test runner
New testProject.default option keeps a project in the config without running it by default. You can configure every browser you care about, and let a plain
npx playwright testrun just your favourite one:New
--shufflecommand line option schedules tests in a random order, which helps to find tests that accidentally depend on each other.New
lockoption in test.describe.configure() adds test locks to all tests in a file or a group:New
typeoption oftoHaveScreenshotin testConfig.expect stores all unnamed screenshots as WebP:🪆 Locator.within()
New locator.within() combines two locators that you already have, reading in the natural order —
"this button, within that dialog":
Relative locators such as locator.nth() or locator.first() are resolved inside each parent
separately, which makes column-like queries straightforward:
New APIs
New page.getByRef() locates an element by its aria ref, such as
e2, reported by page.ariaSnapshot() in the'ai'mode.New option
includeShadowin page.content() and frame.content() serializes open shadow roots as declarative shadow DOM.New option
signCountsets the initial signature counter of a virtual credential. credentials.create() and credentials.get() return the currentsignCount, and it is saved and restored together with the credentials in the storage state.New fullConfig.filteredProjects lists the projects that were selected to run after applying the
--projectfilter. It is available in global setup and reporters.New apiRequestContext.addCookies(), apiRequestContext.cookies() and apiRequestContext.clearCookies() manage cookies of a request context, mirroring the BrowserContext methods:
Breaking changes⚠️
screenproperty is now forwarded from the device descriptors. If you use...devices['Desktop Chrome']and alike,window.screenand media queries now see the emulated screen size. You can opt-out by explicitly settingscreentoundefined:JSX in your test files now follows your
tsconfig.json. Playwright compiles JSX in test files according to thejsx,jsxFactory,jsxFragmentFactoryandjsxImportSourcetsconfig options, and defaults to the automatic runtime fromreact/jsx-runtime.--update-snapshots=missingnow passes the test run. Tests that only create missing snapshots now pass in the'missing'mode of testConfig.updateSnapshots, so that CI can generate new snapshots and verify the existing ones in a single run. The mode used when the option is not specified is now called'default'and behaves as before: missing snapshots are written and the test fails.Elements inside hidden iframes are considered hidden. Elements inside an iframe that is not visible, for example with
visibility: hidden, are now considered hidden by actions, locator.isVisible() and expect(locator).toBeVisible().Browser Versions
This version was also tested against the following stable channels:
v1.63.0Compare Source
🔒 Test locks
Tests that access a shared resource — an external service, a global account setting — can now declare a named
lock.Tests that share a lock name never run concurrently, across files, workers and projects, while
everything else keeps running in parallel:
A test can hold multiple locks, and test.describe() accepts a
lockfor the whole group.Learn more about test locks.
🪟 Locate across frames
page.frameLocator() and frame.frameLocator() called without a selector search in any frame of the
subtree, so you no longer need to locate the iframe first:
The rest of the locator resolves inside a single frame, just like a regular locator, and an error is thrown when it
matches elements in several frames.
👁️ Visible-only locators
New locator.visible() returns a locator that matches only visible elements. It is the recommended
replacement for the
:visibleCSS pseudo-class:🧾 Step params and subtitles
Steps now carry structured data for reporters. Playwright API steps report the target locator and call arguments,
and test.step() accepts
subtitleandparamsoptions for your own steps:Reporters receive them via testStep.subtitle and testStep.params. For Playwright API
steps, the subtitle is the locator or the navigation url — for example,
Clickwith subtitlegetByRole('button').Both are rendered next to the step title in the trace viewer and the HTML report.
🖼️ Aria and screen snapshots in traces
The
snapshotsoption of tracing.start() and the testOptions.trace fixture option now accept anobject selecting what to capture on every action:
With aria and screen snapshots recorded, the new Display Aria mode in the trace viewer shows the action screenshot
side by side with the aria snapshot, and hovering an aria node highlights it on the screenshot.
New APIs
Browser and Context
httpCredentialsnow also accepts an array of credentials. The first entry matching the request origin is used, and entries without an origin match any request.opfsincludes the origin private file system in the storage state, so it can be persisted and restored into later contexts.Locators
mode,depthandboxesoptions.json():Test runner
--add-reportercommand line option appends a reporter on top of the ones configured inplaywright.config, instead of replacing them like--reporterdoes.omitTagsoption for thelist,line,dot,githubandjunitreporters suppresses the tags that are automatically appended to test titles.Command line
npx playwright install --no-removekeeps the browsers of other Playwright installations instead of removing them.npx playwright codegen --http-credentialsrecords against pages behind HTTP authentication.Miscellaneous
perfettoreporter writes a Trace Event Format file for the Perfetto UI orchrome://tracing, rendering the test run as a timeline with a lane per worker.Announcements
@playwright/experimental-ct-react,@playwright/experimental-ct-react17and@playwright/experimental-ct-vuepackages will no longer be updated. Follow the migration guide to move to the stories model introduced in 1.62. Story ids passed to fixtures.mount() can now be typed through the generatedStoriesregistry.Browser Versions
This version was also tested against the following stable channels:
v1.62.1Compare Source
Bug Fixes
v1.62.0Compare Source
🧱 New component testing model
Component testing moves to a stories and galleries model.
A story wraps your component in one specific scenario — hard-coded props, mock data, providers — and a gallery page that you serve renders stories on demand.
The new fixtures.mount() fixture navigates to the gallery, mounts a story by id, and returns a Locator scoped to the story's root element:
Pass a story type as a template argument to type-check its props, and use
update(props)/unmount()on the returned locator to re-render or tear down within a test.🛑 Cancel operations with AbortSignal
Most operations and web-first assertions now accept a
signaloption that takes anAbortSignal, letting you cancel long-running actions, navigations, waits, and assertions:Providing a signal does not disable the default timeout; pass
timeout: 0to disable it.🖼️ WebP screenshots
expect(page).toHaveScreenshot() and expect(locator).toHaveScreenshot() can now store snapshots in the WebP format — just give the snapshot a
.webpname:page.screenshot() and [locator.screenshot() (https://playwright.dev/docs/api/class-locator#locator-screenshot) also accept
webpas atype, where quality100(the default) is lossless and lower values use lossy compression.🧩 Custom test filtering with Reporter.preprocess()
New reporter.preprocess() hook runs after the configuration is resolved and before reporter.onBegin(), letting a reporter mark individual tests as skipped, excluded, fixed, or failing through a TestRun object:
🔁 Isolated retries
New testConfig.retryStrategy controls when failed tests are retried.
The default
'immediate'retries as soon as a worker is free;'isolated'runs all retries at the end, one by one in a single worker, to minimize interference with the rest of the suite:New APIs
Browser and Context
credentialsincludes the context's virtual WebAuthn Credentials (passkeys) in the storage state, so they can be persisted and re-seeded into later contexts.Actions
scrolloption ("auto"|"none") on actions to opt out of Playwright's automatic scroll-into-view.Network
Evaluation
Command line & MCP
playwright-cli, runnable vianpx playwright mcpandnpx playwright cli.Reporters
mergeFilesreporter option:Announcements
Browser Versions
This version was also tested against the following stable channels:
v1.61.1Compare Source
Bug Fixes
v1.61.0Compare Source
🔑 WebAuthn passkeys
New Credentials virtual authenticator, available via browserContext.credentials, lets tests register passkeys and answer
navigator.credentials.create()/navigator.credentials.get()ceremonies in the page — no real hardware key required, works in all browsers:You can also let the app register a passkey once in a setup test, read it back with credentials.get(), and seed it into later tests — see Credentials for details.
🗃️ Web Storage
New WebStorage API, available via page.localStorage and page.sessionStorage, reads and writes the page's storage for the current origin:
New APIs
Network
Browser and Screencast
artifactsDirin browserType.connectOverCDP() controls where artifacts such as traces and downloads are stored when attached to an existing browser.cursorin screencast.showActions() controls the cursor decoration rendered for pointer actions.onFramecallback in screencast.start() now receives atimestampof when the frame was presented by the browser.Test runner
trace: new'on-all-retries','retain-on-first-failure'and'retain-on-failure-and-retries'values. See the video modes table for which runs are recorded and kept in each mode.expect.soft.poll(...).process.argvfrom the runner process, handy for reading custom arguments passed after the--separator.AggregateErroras a separate entry.-Gcommand line shorthand for--grep-invert.🛠️ Other improvements
Browser Versions
This version was also tested against the following stable channels:
v1.60.0Compare Source
🌐 HAR recording on Tracing
tracing.startHar() / tracing.stopHar() expose HAR recording as a first-class tracing API, with the same
content,modeandurlFilteroptions asrecordHar. The returned Disposable makes it easy to scope a recording withawait using:🪝 Drop API
New locator.drop() simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches
dragenter,dragover, anddropwith a synthetic [DataTransfer] in the page context — works cross-browser and is great for testing upload zones:🎯 Aria snapshots
page.locator('body').boxesoption on locator.ariaSnapshot() / page.ariaSnapshot() appends each element's bounding box as[box=x,y,width,height], useful for AI consumption.🛑 test.abort()
New test.abort() aborts the currently running test from a fixture, hook, or route handler with an optional message. Use it when you have detected an unrecoverable misuse and want to fail the test right away:
New APIs
Browser, Context and Page
Locators and Assertions
descriptionin page.getByRole() / locator.getByRole() / frame.getByRole() / frameLocator.getByRole() for matching the accessible description.pseudoin expect(locator).toHaveCSS() reads computed styles from::beforeor::after.stylein locator.highlight() applies extra inline CSS to the highlight overlay, plus new page.hideHighlight() to clear all highlights.Network
noDefaultsin browserType.connectOverCDP() disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state.Errors and Reporting
line/columnproperties (lineNumber/columnNumberare deprecated).expect(...)matcher failure.workerInfoargument with details about the worker for fixture teardown errors.Test runner
{testFileBaseName}token in testProject.snapshotPathTemplate — file name without extension.workers: 0or negative values.🛠️ Other improvements
npx playwright show-reportaccepts.zipfiles directly — no need to unzip first.repeatEachIndexis shown in the test header when non-zero.Breaking Changes⚠️
Locator.ariaRef()— use the standard locator.ariaSnapshot() pipeline.handleoption onBrowserContext.exposeBindingandPage.exposeBinding.loggeroption onBrowserType.connectandBrowserType.connectOverCDP— use tracing instead.videosPath/videoSize— userecordVideoinstead.Browser Versions
This version was also tested against the following stable channels:
Configuration
📅 Schedule: (UTC)
* * * * 1-5)🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.