# Playwright changelog > Fast and reliable end-to-end testing for modern web apps. - Vendor: Microsoft - Category: Developer Tools - Official site: https://playwright.dev - Tracked by: What's New (https://whatsnew.fyi/product/playwright) - Harvested from: GitHub (microsoft/playwright) - Entries below: 10 (newest first) What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. ## Releases ### v1.62.0 - Date: 2026-07-24 - Version: v1.62.0 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.62.0 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.62.0 - **added** — New component testing model with stories and galleries, including fixtures.mount() fixture that navigates to gallery, mounts a story by id, and returns a Locator scoped to the story's root element - **added** — Most operations and web-first assertions now accept a signal option that takes an AbortSignal to cancel long-running actions, navigations, waits, and assertions - **added** — expect(page).toHaveScreenshot() and expect(locator).toHaveScreenshot() can now store snapshots in WebP format - **added** — page.screenshot() and locator.screenshot() accept webp as a type, with quality 100 as lossless and lower values using lossy compression - **added** — New reporter.preprocess() hook runs after configuration is resolved and before reporter.onBegin() to mark individual tests as skipped, excluded, fixed, or failing - **added** — New testConfig.retryStrategy option controls when failed tests are retried, with 'isolated' running all retries at the end in a single worker - **added** — New credentials option includes the context's virtual WebAuthn Credentials in the storage state for persistence and re-seeding - **added** — New scroll option on actions to opt out of Playwright's automatic scroll-into-view - **added** — New apiResponse.timing() returns resource timing information for an API response - **added** — New locator.waitForFunction() waits until a function called with the matching element returns a truthy value - **added** — page.evaluate() and related methods now accept functions as evaluate arguments - **added** — page.addInitScript() and browserContext.addInitScript() now accept functions as init-script arguments - **added** — Playwright now bundles the Playwright MCP server and playwright-cli, runnable via npx playwright mcp and npx playwright cli - **added** — HTML report's Merge files grouping can now be enabled from config with the new mergeFiles reporter option - **removed** — Debian 11 is no longer supported ##### 🧱 New component testing model [Component testing](https://playwright.dev/docs/test-components) 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()](https://playwright.dev/docs/api/class-fixtures#fixtures-mount) fixture navigates to the gallery, mounts a story by id, and returns a [Locator](https://playwright.dev/docs/api/class-locator) scoped to the story's root element: ```js test('click should expand', async ({ mount }) => { const component = await mount('components/Expandable/Stateful'); await component.getByRole('button').click(); await expect(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`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal), letting you cancel long-running actions, navigations, waits, and assertions: ```js const controller = new AbortController(); setTimeout(() => controller.abort(), 1000); await page.getByRole('button', { name: 'Submit' }).click({ signal: controller.signal }); await expect(page.getByText('Done')).toBeVisible({ signal: controller.signal }); ``` Providing a signal does not disable the default timeout; pass `timeout: 0` to disable it. ##### 🖼️ WebP screenshots [expect(page).toHaveScreenshot()](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1) and [expect(locator).toHaveScreenshot()](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-screenshot-1) can now store snapshots in the WebP format — just give the snapshot a `.webp` name: ```js // Visual comparisons store the golden snapshot as lossless WebP. await expect(page).toHaveScreenshot('homepage.webp'); // Standalone screenshots can trade quality for size with lossy WebP. await page.screenshot({ path: 'homepage.webp', quality: 50 }); ``` [page.screenshot()](https://playwright.dev/docs/api/class-page#page-screenshot) and [locator.screenshot() (https://playwright.dev/docs/api/class-locator#locator-screenshot) also accept `webp` as a `type`, where quality `100` (the default) is lossless and lower values use lossy compression. ##### 🧩 Custom test filtering with Reporter.preprocess() New [reporter.preprocess()](https://playwright.dev/docs/api/class-reporter#reporter-preprocess) hook runs after the configuration is resolved and before [reporter.onBegin()](https://playwright.dev/docs/api/class-reporter#reporter-on-begin), letting a reporter mark individual tests as skipped, excluded, fixed, or failing through a [TestRun](https://playwright.dev/docs/api/class-testrun) object: ```js class MyReporter { async preprocess({ config, suite, testRun }) { for (const test of suite.allTests()) { if (shouldSkip(test)) testRun.skip(test); } } } ``` ##### 🔁 Isolated retries New [testConfig.retryStrategy](https://playwright.dev/docs/api/class-testconfig#test-config-retry-strategy) 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: ```js // playwright.config.ts export default defineConfig({ retries: 2, retryStrategy: 'isolated', }); ``` ##### New APIs ###### Browser and Context - New option [`credentials`](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state-option-credentials) includes the context's virtual WebAuthn [Credentials](https: _[Truncated at 4000 characters — full notes: https://github.com/microsoft/playwright/releases/tag/v1.62.0]_ ### v1.61.1 - Date: 2026-06-23 - Version: v1.61.1 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.61.1 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.61.1 - **fixed** — Expect.extend matcher with same name as default matcher in same expect instance no longer overrides default matchers implementation - **fixed** — Playwright UI mode apiRequestContext._wrapApiCall reporting unexpected number of bytes - **fixed** — Trace viewer message times in websockets no longer downscaled by 1000 - **fixed** — Sync loader throwing context.conditions?.includes is not a function on Node 22.15 - **fixed** — Sync ESM loader registerHooks failing to resolve extensionless .ts subpath imports across pnpm workspace symlinks ###### Bug Fixes - #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 ### v1.61.0 - Date: 2026-06-15 - Version: v1.61.0 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.61.0 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.61.0 - **added** — Add Credentials virtual authenticator API via browserContext.credentials for registering passkeys and handling navigator.credentials ceremonies without hardware keys - **added** — Add WebStorage API via page.localStorage and page.sessionStorage for reading and writing page storage - **added** — Add apiResponse.securityDetails() and apiResponse.serverAddr() methods to mirror browser-side response methods - **added** — Add artifactsDir option in browserType.connectOverCDP() to control where artifacts are stored when attached to an existing browser - **added** — Add cursor option in screencast.showActions() to control cursor decoration for pointer actions - **added** — Add timestamp parameter to onFrame callback in screencast.start() indicating when the frame was presented by the browser - **added** — Add 'on-all-retries', 'retain-on-first-failure', and 'retain-on-failure-and-retries' modes to testOptions.video option - **added** — Add support for expect.soft.poll() - **added** — Add fullConfig.argv providing a snapshot of process.argv from the runner process - **added** — Add fullConfig.failOnFlakyTests to mirror the config option for reporters - **added** — Add -G command line shorthand for --grep-invert - **changed** — testInfo.errors now lists each sub-error of an AggregateError as a separate entry - **changed** — HAR and trace recordings now include WebSocket requests - **added** — Add support for Ubuntu 26.04 ##### 🔑 WebAuthn passkeys New [Credentials](https://playwright.dev/docs/api/class-credentials) virtual authenticator, available via [browserContext.credentials](https://playwright.dev/docs/api/class-browsercontext#browser-context-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: ```js const context = await browser.newContext(); // Seed a passkey your backend provisioned for a test user. await context.credentials.create('example.com', { id: credentialId, userHandle, privateKey, publicKey, }); await context.credentials.install(); const page = await context.newPage(); await page.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()](https://playwright.dev/docs/api/class-credentials#credentials-get), and seed it into later tests — see [Credentials](https://playwright.dev/docs/api/class-credentials) for details. ##### 🗃️ Web Storage New [WebStorage](https://playwright.dev/docs/api/class-webstorage) API, available via [page.localStorage](https://playwright.dev/docs/api/class-page#page-local-storage) and [page.sessionStorage](https://playwright.dev/docs/api/class-page#page-session-storage), reads and writes the page's storage for the current origin: ```js await page.localStorage.setItem('token', 'abc'); const token = await page.localStorage.getItem('token'); const items = await page.sessionStorage.items(); ``` ##### New APIs ###### Network - [apiResponse.securityDetails()](https://playwright.dev/docs/api/class-apiresponse#api-response-security-details) and [apiResponse.serverAddr()](https://playwright.dev/docs/api/class-apiresponse#api-response-server-addr) mirror the browser-side [response.securityDetails()](https://playwright.dev/docs/api/class-response#response-security-details) and [response.serverAddr()](https://playwright.dev/docs/api/class-response#response-server-addr). ###### Browser and Screencast - New option `artifactsDir` in [browserType.connectOverCDP()](https://playwright.dev/docs/api/class-browsertype#browser-type-connect-over-cdp) controls where artifacts such as traces and downloads are stored when attached to an existing browser. - New option `cursor` in [screencast.showActions()](https://playwright.dev/docs/api/class-screencast#screencast-show-actions) controls the cursor decoration rendered for pointer actions. - The `onFrame` callback in [screencast.start()](https://playwright.dev/docs/api/class-screencast#screencast-start) now receives a `timestamp` of when the frame was presented by the browser. ###### Test runner - The [testOptions.video](https://playwright.dev/docs/api/class-testoptions#test-options-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](https://playwright.dev/docs/test-use-options#video-modes) for which runs are recorded and kept in each mode. - Supported `expect.soft.poll(...)`. - New [fullConfig.argv](https://playwright.dev/docs/api/class-fullconfig#full-config-argv) — a snapshot of `process.argv` from the runner process, handy for reading custom arguments passed after the `--` separator. - New [fullConfig.failOnFlakyTests](https://playwright.dev/docs/api/class-fullconfig#full-config-fail-on-flaky-tests) mirrors the config option, so reporters can explain why a flaky run failed. - [testInfo.errors](https://playwright.dev/docs/api/class-testinfo#test-info-errors) now lists each sub-error of an `AggregateError` as a separate entry. - New `-G` command line shorthand for `--grep-invert`. ##### 🛠️ Other improvements - Playwright now supports Ubuntu 26.04. - HAR and trace recording _[Truncated at 4000 characters — full notes: https://github.com/microsoft/playwright/releases/tag/v1.61.0]_ ### v1.60.0 - Date: 2026-05-11 - Version: v1.60.0 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.60.0 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.60.0 - **added** — Add tracing.startHar() and tracing.stopHar() to expose HAR recording as a first-class tracing API - **added** — Add locator.drop() to simulate external drag-and-drop of files or clipboard-like data onto an element - **added** — Add expect(page).toMatchAriaSnapshot() to work on a Page in addition to a Locator - **added** — Add boxes option on locator.ariaSnapshot() and page.ariaSnapshot() to append each element's bounding box - **added** — Add test.abort() to abort the currently running test from a fixture, hook, or route handler - **added** — Add browser.on('context') event fired when a new context is created on the browser - **added** — Add lifecycle events to BrowserContext: browserContext.on('download'), browserContext.on('frameattached'), browserContext.on('framedetached'), browserContext.on('framenavigated'), browserContext.on('pageclose'), browserContext.on('pageload') - **added** — Add description option in page.getByRole(), locator.getByRole(), frame.getByRole(), and frameLocator.getByRole() - **added** — Add pseudo option in expect(locator).toHaveCSS() to read computed styles from ::before or ::after - **added** — Add style option in locator.highlight() to apply extra inline CSS to the highlight overlay - **added** — Add page.hideHighlight() to clear all highlights - **added** — Add webSocketRoute.protocols() to return the WebSocket subprotocols requested by the page - **added** — Add noDefaults option in browserType.connectOverCDP() to disable Playwright's default overrides on the default context - **added** — Add webError.location() to mirror consoleMessage.location() - **added** — Add testInfoError.errorContext to surface additional diagnostic context such as the aria snapshot of the receiver at the time of an expect(...) matcher failure - **changed** — consoleMessage.location() now exposes line and column properties - **deprecated** — consoleMessage.location() properties lineNumber and columnNumber are deprecated ##### 🌐 HAR recording on Tracing [tracing.startHar()](https://playwright.dev/docs/api/class-tracing#tracing-start-har) / [tracing.stopHar()](https://playwright.dev/docs/api/class-tracing#tracing-stop-har) expose HAR recording as a first-class tracing API, with the same `content`, `mode` and `urlFilter` options as `recordHar`. The returned [Disposable](https://playwright.dev/docs/api/class-disposable) makes it easy to scope a recording with `await using`: ```js await using har = await context.tracing.startHar('trace.har'); const page = await context.newPage(); await page.goto('https://playwright.dev'); // HAR is finalized when `har` goes out of scope. ``` ##### 🪝 Drop API New [locator.drop()](https://playwright.dev/docs/api/class-locator#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: ```js await page.locator('#dropzone').drop({ files: { name: 'note.txt', mimeType: 'text/plain', buffer: Buffer.from('hello') }, }); await page.locator('#dropzone').drop({ data: { 'text/plain': 'hello world', 'text/uri-list': 'https://example.com', }, }); ``` ##### 🎯 Aria snapshots - [expect(page).toMatchAriaSnapshot()](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-match-aria-snapshot) now works on a [Page](https://playwright.dev/docs/api/class-page), in addition to a [Locator](https://playwright.dev/docs/api/class-locator) — equivalent to asserting against `page.locator('body')`. - New `boxes` option on [locator.ariaSnapshot()](https://playwright.dev/docs/api/class-locator#locator-aria-snapshot) / [page.ariaSnapshot()](https://playwright.dev/docs/api/class-page#page-aria-snapshot) appends each element's bounding box as `[box=x,y,width,height]`, useful for AI consumption. ##### 🛑 test.abort() New [test.abort()](https://playwright.dev/docs/api/class-test#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: ```js test('does not publish to the shared page', async ({ page }) => { await page.route('**/publish', route => { test.abort('Tests must not publish to the shared page. Use the `clone` option.'); return route.abort(); }); // ... }); ``` ##### New APIs ###### Browser, Context and Page - Event [browser.on('context')](https://playwright.dev/docs/api/class-browser#browser-event-context) — fired when a new context is created on the browser. - [BrowserContext](https://playwright.dev/docs/api/class-browsercontext) now mirrors lifecycle events from its pages: [browserContext.on('download')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-download), [browserContext.on('frameattached')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-attached), [browserContext.on('framedetached')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-detached), [browserContext.on('framenavigated')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-navigated), [browserContext.on('pageclose')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-page-close), [browserContext.on('pageload')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-page-load). ###### Locators and Assertions - New option `description` in [page.getByRole()](https://playwright.dev/docs/api/class-page#page-get-by-role) / [locator.getByRole()](https://playwright.dev/docs/api/class-locator#locator-get-by-role) / [frame.getByRole()](https://playwright.dev/docs/api/class-frame#frame-get-by-role) / [frameLocator.getByRole()](https://playwright.dev/docs/api/class- _[Truncated at 4000 characters — full notes: https://github.com/microsoft/playwright/releases/tag/v1.60.0]_ ### v1.59.1 - Date: 2026-04-01 - Version: v1.59.1 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.59.1 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.59.1 - **fixed** — Reverted hiding console window when spawning browser processes to fix regressions in codegen, --ui and show commands on Windows ###### Bug Fixes - **[Windows]** Reverted hiding console window when spawning browser processes, which caused regressions including broken `codegen`, `--ui` and `show` commands ([#39990](https://github.com/microsoft/playwright/issues/39990)) ### v1.59.0 - Date: 2026-04-01 - Version: v1.59.0 - Original notes: https://github.com/microsoft/playwright/releases/tag/v1.59.0 - Permalink: https://whatsnew.fyi/product/playwright/releases/v1.59.0 - **added** — Add page.screencast API for capturing page content with screencast recordings, action annotations, visual overlays, real-time frame capture, and agentic video receipts - **added** — Add screencast.start() method to record video with precise start/stop control as an alternative to recordVideo option - **added** — Add screencast.stop() method to stop video recording - **added** — Add screencast.showActions() method to enable visual annotations that highlight interacted elements and display action titles during recording with configurable position, duration, and fontSize - **added** — Add screencast.showChapter() method to add chapter titles and descriptions to recorded video - **added** — Add screencast.showOverlay() method to add custom HTML overlays on top of the page during recording - **added** — Add onFrame callback to screencast.start() for real-time JPEG-encoded frame capture for custom processing - **added** — Add video option to test fixtures configuration to enable action and test annotations during video recording - **added** — Add browser.bind() API to make a launched browser available for playwright-cli, @playwright/mcp, and other clients to connect to - **added** — Add browser.unbind() method to stop accepting new connections - **added** — Add support for multiple Playwright clients to connect to the same bound browser - **added** — Add host and port options to browser.bind() for WebSocket-based connections - **added** — Add playwright-cli show command to open Dashboard listing all bound browsers, their statuses, and allow interaction with them - **added** — Add support for PLAYWRIGHT_DASHBOARD environment variable to see all @playwright/test browsers in the dashboard - **added** — Add --debug=cli flag to npx playwright test for attaching and debugging tests over playwright-cli - **added** — Add playwright-cli attach command to attach to running test sessions ##### 🎬 Screencast New [page.screencast](https://playwright.dev/docs/api/class-page#page-screencast) API provides a unified interface for capturing page content with: - Screencast recordings - Action annotations - Visual overlays - Real-time frame capture - Agentic video receipts