---
schema_version: 1
route: /t/playwright.md
tool: "playwright"
---

# sincecutoff.com /t/playwright — Playwright

- name: Playwright
- kind: library
- children: none
- homepage: <https://github.com/microsoft/playwright>

Changes to the tools coding agents drive, since a model's training cutoff, each linked to its first-party source. Check installed versions and limitations before acting; a cutoff date does not establish what a model knows.
Original editorial content: [Apache 2.0](https://sincecutoff.com/v1/data-license.txt), by [0xPatrick](https://0xpatrick.dev). Preserve applicable license and [NOTICE](https://sincecutoff.com/notice.txt) attribution when redistributing. Third-party source text and examples retain their own rights. [License scope and attribution](https://sincecutoff.com/v1/license.json).
To stay current, read the changes feed: [`/v1/changes.md?tool=playwright`](https://sincecutoff.com/v1/changes.md?tool=playwright) (or `.json`), adding `since=YYYY-MM-DD` for your training cutoff. Entries for registered children are included; the registry itself is `/v1/tools.json`. How to page and save your place: [llms.txt](https://sincecutoff.com/llms.txt).

### Playwright API request contexts gain cookie management (2026-10-07)
- slug: playwright-api-request-contexts-gain-cookie-management-ae377c96518e
- score: 0.98

How to use it:

When API-level tests need request-context cookie control, use `addCookies()` to add cookies, `cookies()` to inspect them, and `clearCookies()` to remove them.

Examples:

```
await request.addCookies([{ name: 'session-id', value: '42', url: 'https://example.com' }]);
console.log(await request.cookies('https://example.com'));
await request.clearCookies({ name: 'session-id' });
```

- why_it_matters: Manage cookies for an API request context during API-level testing.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/api/class-apirequestcontext>
- gotchas: "Version: v1.64.0"; "addCookies(cookies) — `cookies` (required): Array of cookie objects. Each needs `name` and `value`, plus either `url` or both `domain` and `path`."; "cookies(urls) — `urls`: URL or list of URLs; filters returned cookies to those affecting the specified URLs. Omit to return all cookies."; "clearCookies(options) — `options.name`: String or RegExp filter; only cookies with the given name are removed. The options object and its filters are optional."; "Prerequisite: The methods were added in Playwright v1.64. Use an `APIRequestContext`; `browserContext.request` and `page.request` share their BrowserContext cookie jar, while `apiRequest.newContext()` creates an isolated cookie store."; "The methods mirror the `BrowserContext` methods."

### Playwright locator scoping with `locator.within()` (2026-10-07)
- slug: playwright-locator-scoping-with-locator-within-98f84407f1b7
- score: 0.99

How to use it:

When an element must be located relative to a dialog or separately within each matching parent, combine existing locators with `locator.within()` and perform the action on the result.

Examples:

```
const saveButton = page.getByRole('button', { name: 'Save' });
const dialog = page.getByTestId('settings-dialog');
await saveButton.within(dialog).click();
```

```
const thirdColumn = page.getByRole('cell').nth(2).within(page.getByRole('row'));
await expect(thirdColumn).toHaveText(['Apple', 'Banana', 'Cherry']);
```

- why_it_matters: Locate and act on an element relative to a dialog or independently within each matching parent.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/api/class-locator#locator-within>, <https://playwright.dev/docs/api/class-locator#locator-nth>, <https://playwright.dev/docs/api/class-locator>
- gotchas: "Version: v1.64.0"; "locator.within(locator) (required): Returns a locator matching this locator's elements inside each element matched by the argument locator."; "locator.nth(index): Returns the zero-based n-th matching element; with `within()`, it resolves separately inside each matched parent."; "getByRole(role, options): Creates a locator by ARIA role; the example uses the `button` role and `name: 'Save'`."; "getByTestId(testId): Creates a locator by test id; the example uses `settings-dialog`."; "Prerequisite: Use Playwright v1.64 or later; `locator.within` was added in v1.64."

### Playwright page and frame content can include open shadow roots (2026-10-07)
- slug: playwright-page-and-frame-content-can-include-open-shadow-roots-1c579140290d
- score: 0.92

How to use it:

When serializing page or frame HTML and you need open shadow roots, call `content({ includeShadow: true })`; Playwright emits them as declarative shadow DOM, and closed roots are never included.

Examples:

```
const html = await page.content({ includeShadow: true });
```

```
const html = await frame.content({ includeShadow: true });
```

- why_it_matters: Serialize page or frame content including its open shadow roots.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/api/class-page>, <https://playwright.dev/docs/api/class-frame>
- gotchas: "Version: v1.64.0"; "includeShadow: Boolean option, added in v1.64; when true, includes open shadow root contents as nested `<template shadowrootmode=\"open\">`; defaults to false. Closed roots are never included."; "Open shadow roots are serialized as declarative shadow DOM."

### Playwright screenshot assertions can store unnamed screenshots as WebP (2026-10-07)
- slug: playwright-screenshot-assertions-can-store-unnamed-screenshots-as-webp-0249ba5d70d7
- score: 0.97

How to use it:

When you want unnamed `toHaveScreenshot` snapshots stored as WebP, set `expect.toHaveScreenshot.type` to `'webp'` in the Playwright test configuration.

Examples:

```
export default defineConfig({
  expect: {
    toHaveScreenshot: { type: 'webp' },
  },
});
```

- why_it_matters: Configure screenshot assertions to store unnamed screenshots as WebP.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/next/release-notes>
- gotchas: "Version: v1.64.0"; "expect.toHaveScreenshot.type: Set to `'webp'` to store unnamed screenshots as WebP."; "The option stores unnamed screenshots as WebP."

### Playwright test groups can configure test locks (2026-10-07)
- slug: playwright-test-groups-can-configure-test-locks-1c4331696554
- score: 0.93

How to use it:

When tests in a file or group access a shared resource that cannot be used concurrently, add a named lock with `test.describe.configure({ lock: 'user-settings' });`. Tests sharing that lock will not run at the same time.

Examples:

```
test.describe.configure({ lock: 'user-settings' });
```

- why_it_matters: Configure a test file or group to use a test lock while running tests.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/test-parallel>
- gotchas: "Version: v1.64.0"; "lock: A string or array of strings naming locks; tests sharing a lock name do not run concurrently. Repeated `test.describe.configure()` calls add locks without removing existing ones."; "Prerequisite: Use Playwright Test v1.64.0 or later; the release note introduces the `lock` option in that version."

### Playwright test runner selects default projects with `testProject.default` (2026-10-07)
- slug: playwright-test-runner-selects-default-projects-with-testproject-default-fd6abdc22c54
- score: 0.99

How to use it:

When a project should stay configured but be skipped by a plain test run, set `default: false`; run it with `--project=<name>` or select all projects with `--project="*"`.

Examples:

```
npx playwright test
```

```
npx playwright test --project=firefox
```

```
npx playwright test --project="*"
```

- why_it_matters: Run a default browser project locally while retaining additional browser projects for explicit or CI runs.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/api/class-testproject#test-project-default>, <https://playwright.dev/docs/test-cli>
- gotchas: "Version: v1.64.0"; "default: Boolean project option; defaults to `true`. Set `false` to skip the project when no `--project` option is passed."; "--project <project-name...>: Selects projects by name; supports `*` wildcard. A project with `default: false` can be selected explicitly."

### Playwright test runner shuffles test order with a reproducible seed (2026-10-07)
- slug: playwright-test-runner-shuffles-test-order-with-a-reproducible-seed-afcecc96245a
- score: 0.98

How to use it:

When investigating tests that may depend on execution order, run the suite with `--shuffle` to randomize its order. Re-run with the emitted seed to reproduce that order.

Examples:

```
npx playwright test --shuffle
```

```
npx playwright test --shuffle <seed>
```

- why_it_matters: Find tests that depend on execution order while debugging a test suite.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://github.com/microsoft/playwright/blob/v1.64.0/packages/playwright/src/program.ts>
- gotchas: "Version: v1.64.0"; "--shuffle [seed]: Randomizes test-file order and tests in parallel mode; pass a seed to reproduce a previous order."

### Playwright video recording adds frame-rate and CSS action styling options (2026-10-07)
- slug: playwright-video-recording-adds-frame-rate-and-css-action-styling-options-58c115ccc59b
- score: 0.95

How to use it:

When configuring Playwright video recordings, set `video.fps` and `video.show.actions.style` to choose the frame rate and CSS for the point, highlight, and title. Firefox and WebKit capture up to 25 fps; `style` replaces deprecated `fontSize`.

Examples:

```
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    video: {
      mode: 'on',
      fps: 60,
      show: {
        actions: {
          style: {
            point: 'width: 20px; height: 20px; border-radius: 50%; background: red',
            highlight: 'outline: 2px solid #333; background: rgba(0, 128, 255, .15)',
            title: 'font-size: 16px',
          },
        },
      },
    },
  },
});
```

- why_it_matters: Configure recorded test videos with a chosen frame rate and custom action decorations.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.64.0>, <https://playwright.dev/docs/next/release-notes>
- gotchas: "Version: v1.64.0"; "testOptions.video.fps: Sets the recorded video frame rate; Firefox and WebKit currently capture up to 25 frames per second."; "testOptions.video.show.actions.style: CSS declarations for the `point` marker, target `highlight`, and action `title`; replaces deprecated `fontSize`."; "recordVideo.fps: Sets the recorded video frame rate."; "screencast.start() `fps`: Sets the screencast recording frame rate."; "Firefox and WebKit currently capture up to 25 frames per second."; "The `fontSize` option is deprecated."

### APIRequestContext request methods type JSON responses (2026-09-04)
- slug: apirequestcontext-request-methods-type-json-responses-c36a0b59a523
- score: 0.98

How to use it:

For a typed API request in Playwright v1.63.0 or later, pass the response type to `request.get<T>(url)` and use `response.json()` as `T`.

Examples:

```
const response = await request.get<User>('/api/users/42');
const user = await response.json();
```

- why_it_matters: Make a typed API request in a test and use the typed JSON response.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-get>
- gotchas: "Version: v1.63.0"; "T (type argument) (required): Types the response from `json()`; use the expected response type, such as `User`."; "url (required): Target URL for the GET request."; "Prerequisite: Playwright v1.63.0 or later; the typed request method behavior was added in v1.63."

### Browser.newContext() accepts multiple HTTP credentials (2026-09-04)
- slug: browser-newcontext-accepts-multiple-http-credentials-0f0e3457b501
- score: 0.95

How to use it:

When browser tests need different HTTP credentials by request origin, pass an array of credential objects to `browser.newContext({ httpCredentials })`. The first entry matching the request origin is used; an entry without `origin` matches any request.

Examples:

```
const context = await browser.newContext({
  httpCredentials: [
    { username: "<user-1>", password: "<password-1>", origin: "https://<host-1>:<port>" },
    { username: "<user-2>", password: "<password-2>", origin: "https://<host-2>:<port>" },
  ],
});
```

- why_it_matters: Run browser tests against an application using different HTTP credentials for different request origins.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-browser>
- gotchas: "Version: v1.63.0"; "httpCredentials: An object or array of objects containing HTTP authentication credentials. For an array, the first entry matching the request origin is used; an entry without `origin` matches any request."; "httpCredentials[].username (required): Username for HTTP authentication."; "httpCredentials[].password (required): Password for HTTP authentication."; "httpCredentials[].origin: Restricts sending credentials to the specified origin (`scheme://host:port`)."; "httpCredentials[].send: For corresponding APIRequestContext requests, `always` sends credentials on each API request; `unauthorized` sends them after a 401 with `WWW-Authenticate`. Defaults to `unauthorized`."; "The first entry matching the request origin is used; entries without an origin match any request."

### Locator and page aria snapshots can return JSON (2026-09-04)
- slug: locator-and-page-aria-snapshots-can-return-json-df1a3f437bc7
- score: 0.97

How to use it:

When a test or inspection script needs a structured accessibility snapshot, call `locator.ariaSnapshotJSON()` or `page.ariaSnapshotJSON()`; pass optional `mode`, `depth`, or `boxes` options as needed. Both APIs were added in Playwright v1.63.0.

Examples:

```
const snapshot = await page.getByRole('list').ariaSnapshotJSON();
```

```
const snapshot = await page.ariaSnapshotJSON({ mode: 'ai', depth: 2, boxes: true });
```

- why_it_matters: Consume an aria snapshot as structured JSON in a test or inspection script.
- before: Use the aria snapshot API that returns YAML markup.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-locator#locator-aria-snapshot-json>, <https://playwright.dev/docs/api/class-page#page-aria-snapshot-json>
- gotchas: "Version: v1.63.0"; "mode: `\"ai\"` or `\"default\"`; `\"ai\"` returns a snapshot optimized for AI consumption. Defaults to `\"default\"`."; "depth: Number; limits the snapshot depth when specified."; "boxes: Boolean; when true, adds each element's bounding box as a `box` property (`x`, `y`, `width`, `height`), in viewport-relative CSS pixels. Defaults to false."; "Prerequisite: Use Playwright v1.63 or later; both methods were added in v1.63."

### Playwright codegen records against HTTP-authenticated pages (2026-09-04)
- slug: playwright-codegen-records-against-http-authenticated-pages-5e20cbcdaf4a
- score: 0.97

How to use it:

When recording tests for an HTTP Basic Authentication page, run `codegen` with `--http-credentials="username:password"` and the page URL. Credentials are sent to any origin that requests them during recording and are included in generated code.

Examples:

```
npx playwright codegen --http-credentials="<username>:<password>" <url>
```

- why_it_matters: Generate test code for a page protected by HTTP authentication.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://github.com/microsoft/playwright/blob/v1.63.0/docs/src/codegen.md>
- gotchas: "Version: v1.63.0"; "--http-credentials (required): HTTP Basic Authentication credentials in `username:password` form; sent to any origin that requests them during recording and included in generated code."; "<url>: Website URL to generate tests for; may be omitted and entered in the browser instead."

### Playwright emits dialogclosed events (2026-09-04)
- slug: playwright-emits-dialogclosed-events-fa32230cfb32
- score: 0.95

How to use it:

When a JavaScript dialog is accepted, dismissed, or closed by the user, listen for `dialogclosed` on the page or its browser context to receive the `Dialog` event data.

Examples:

```
page.on('dialogclosed', data => {});
```

```
browserContext.on('dialogclosed', data => {});
```

- why_it_matters: Observe when a JavaScript dialog is accepted, dismissed, or closed by the user during a browser test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-page#page-event-dialog-closed>, <https://playwright.dev/docs/api/class-browsercontext#browser-context-event-dialog-closed>
- gotchas: "Version: v1.63.0"; "event name: `dialogclosed` (required): Registers a listener for when a JavaScript dialog is closed."; "`data` listener argument (required): The `Dialog` event data."; "listener target: `page` or `browserContext` (required): A page listener covers that page; a context listener covers any page belonging to that context. The choices are alternatives."; "Prerequisite: Added in Playwright v1.63."

### Playwright frameLocator() searches across frames without a selector (2026-09-04)
- slug: playwright-framelocator-searches-across-frames-without-a-selector-72555e379b24
- score: 0.99

How to use it:

If the target may be in any frame in the page subtree, call `page.frameLocator()` without a selector, then chain the locator for the element and act on it. The locator resolves inside one frame; matches in multiple frames throw an error.

Examples:

```
const locator = page.frameLocator().getByRole('button');
await locator.click();
```

```
const locator = frame.frameLocator().getByRole('button');
await locator.click();
```

- why_it_matters: Locate an element that may appear in a frame anywhere in a page's frame subtree.
- before: Locate the iframe first, then use its frame locator to search within it.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-page#page-frame-locator>, <https://playwright.dev/docs/api/class-frame#frame-frame-locator>
- gotchas: "Version: v1.63.0"; "selector: Selector for the frame element. If omitted, search any frame on the page; for `frame.frameLocator()`, search this frame or any iframe inside it."; "getByRole(role) (required): Role used to locate the element; this usage example passes `button`."; "Prerequisite: `page.frameLocator` and `frame.frameLocator` were added in v1.17; use Playwright v1.17 or later."; "The rest of the locator resolves inside a single frame; an error is thrown when it matches elements in several frames."

### Playwright locator.visible() filters to visible elements (2026-09-04)
- slug: playwright-locator-visible-filters-to-visible-elements-f3a4c151c133
- score: 0.97

How to use it:

When clicking a matching button only if it is visible, use `await page.locator('button').visible().click();`. `visible()` returns a locator that filters out invisible elements and is the recommended replacement for `:visible`.

Examples:

```
await page.locator('button').visible().click();
```

- why_it_matters: Click a matching button only when it is visible.
- before: Use the `:visible` CSS pseudo-class to match visible elements.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-locator#locator-visible>, <https://playwright.dev/docs/api/class-locator>
- gotchas: "Version: v1.63.0"; "selector (`'button'`) (required): The selector passed to `page.locator()` to find matching elements."; "`visible()` (required): Takes no documented arguments; returns a locator matching only visible elements. Visibility is checked each time the locator is used."

### Playwright test runner adds reporters without replacing configured reporters (2026-09-04)
- slug: playwright-test-runner-adds-reporters-without-replacing-configured-reporters-3cac6590b8ef
- score: 0.97

How to use it:

When adding a reporter for one test run while keeping reporters configured in `playwright.config`, use `--add-reporter` with the reporter name or custom reporter path.

Examples:

```
npx playwright test --add-reporter=html
```

- why_it_matters: Add a reporter for one test run while retaining reporters configured in `playwright.config`.
- before: Use `--reporter` to select reporters; it replaces the reporters configured in `playwright.config`.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/test-cli>
- gotchas: "Version: v1.63.0"; "--add-reporter <reporter>: Reporter to add on top of configured reporters; accepts a built-in reporter name or custom reporter file path. Comma-separated values are supported."; "--reporter <reporter>: Replaces configured reporters, as stated in the v1.63.0 release note."

### Playwright test runner exposes standalone accessibility options (2026-09-04)
- slug: playwright-test-runner-exposes-standalone-accessibility-options-967e099951b6
- score: 0.92

How to use it:

When a test run needs a reduced-motion, forced-colors, or contrast preference, set the corresponding standalone option under `use` in the Playwright Test config.

Examples:

```
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    reducedMotion: 'reduce', // or 'no-preference'
    forcedColors: 'active', // or 'none'
    contrast: 'more', // or 'no-preference'
  },
});
```

- why_it_matters: Configure a test run's reduced motion, forced colors, or contrast setting independently.
- before: The v1.63.0 docs show `reducedMotion` nested under `use.contextOptions`.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://github.com/microsoft/playwright/blob/v1.63.0/docs/src/test-api/class-testoptions.md>
- gotchas: "Version: v1.63.0"; "reducedMotion: Emulates `prefers-reduced-motion`; accepts `reduce` or `no-preference`."; "forcedColors: Emulates `forced-colors`; accepts `active` or `none`."; "contrast: Emulates `prefers-contrast`; accepts `no-preference` or `more`."; "Docs conflict: The v1.63.0 docs mark each property as available since v1.50, while the release note calls these standalone options new in v1.63.0; the docs also show `reducedMotion` nested under `contextOptions`."

### Playwright test runner serializes tests sharing a named lock (2026-09-04)
- slug: playwright-test-runner-serializes-tests-sharing-a-named-lock-527d9fcf32e3
- score: 0.98

How to use it:

When tests access a shared resource that cannot be used concurrently, give them the same named lock. Use `test.describe()` details to apply a lock to every test in a group; tests sharing a lock wait for one another while other tests can run in parallel.

Examples:

```
import { test } from '@playwright/test';

test('update user settings', { lock: 'user-settings' }, async ({ page }) => {
  // ...
});
```

```
import { test } from '@playwright/test';

test.describe('settings tests', { lock: 'user-settings' }, () => {
  test('update settings', async ({ page }) => { /* ... */ });
  test('reset settings', async ({ page }) => { /* ... */ });
});
```

- why_it_matters: Keep tests that access the same shared resource from running concurrently.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/test-parallel#test-locks>, <https://playwright.dev/docs/api/class-test#test-describe>
- gotchas: "Version: v1.63.0"; "test lock (`details.lock`): A lock name, or an array of lock names. Tests with a shared lock name do not run concurrently; a test with multiple locks runs only when all are available."; "test.describe() `title`: The group title; the API allows omitting it when using the callback form."; "test.describe() `details.lock`: A lock name or array of lock names applied to the group's tests. The docs do not state that lock names are mutually exclusive; multiple locks are supported."; "test.describe() `callback` (required): Function whose declared tests belong to the group."; "Prerequisite: Use Playwright Test v1.63.0 or later for test locks."; "Docs conflict: Current API docs mark `test.describe.configure({ lock })` as added in v1.64. That scope-level form is newer than v1.63.0; use the documented `test.describe()` details form for a group lock in this card’s version."

### Playwright test steps support subtitles and params in reports (2026-09-04)
- slug: playwright-test-steps-support-subtitles-and-params-in-reports-b4bb39d564d5
- score: 0.97

How to use it:

When adding structured context to a test step, pass `subtitle` and `params` in the `test.step()` options; reporters expose them as `testStep.subtitle` and `testStep.params`, and the trace viewer and HTML report display step context.

Examples:

```
import { test } from '@playwright/test';

await test.step('Login', async () => {
  // ...
}, { subtitle: 'as admin', params: { user: 'admin' } });
```

- why_it_matters: Add structured context to a test step and inspect it in the trace viewer or HTML report.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/api/class-test#test-step>, <https://playwright.dev/docs/api/class-teststep#test-step-subtitle>, <https://playwright.dev/docs/api/class-teststep#test-step-params>
- gotchas: "Version: v1.63.0"; "title (required): Step name."; "body (required): Step callback."; "options: Optional object of step options."; "options.subtitle: String that complements the step title; reported as `testStep.subtitle`."; "options.params: Serializable object describing the step; reported as `testStep.params`."; "testStep.subtitle: Available subtitle; for Playwright API calls, the target locator or navigation URL; for `test.step()`, the author-provided subtitle."; "testStep.params: Available step parameters; API call steps may include a locator and call arguments, while `test.step()` steps contain author-provided parameters."; "Prerequisite: Use Playwright v1.63.0 or later; the docs mark `subtitle`, `params`, `testStep.subtitle`, and `testStep.params` as added in v1.63."

### Playwright traces can capture aria and screen snapshots (2026-09-04)
- slug: playwright-traces-can-capture-aria-and-screen-snapshots-0498f5693d71
- score: 0.96

How to use it:

When debugging tests with Playwright v1.63.0, configure trace snapshots to include `aria` and `screen` (and optionally `dom`) on every action. Open the trace and use Display Aria to view the action screenshot beside its aria snapshot and highlight nodes.

Examples:

```
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    trace: {
      mode: 'on',
      snapshots: { dom: true, aria: true, screen: true },
    },
  },
});
```

```
npx playwright show-trace <path-to-trace.zip>
```

- why_it_matters: Capture aria and screen state in traces to inspect UI actions during test debugging.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.63.0>, <https://playwright.dev/docs/trace-viewer>, <https://playwright.dev/docs/api/class-testoptions#test-options-trace>
- gotchas: "Version: v1.63.0"; "testOptions.trace.mode (required): Trace recording mode; `on` records and keeps a trace for every run."; "testOptions.trace.snapshots: Selects snapshots to capture on every action; may be an object or boolean."; "snapshots.dom: Captures a DOM snapshot on every action and records network activity."; "snapshots.aria: Captures an aria snapshot of the page on every action; needed for Display Aria mode."; "snapshots.screen: Captures a screenshot of the page on every action; needed for Display Aria mode."; "Display Aria mode behavior described requires aria and screen snapshots to be recorded."

### addInitScript() accepts functions as arguments (2026-07-24)
- slug: addinitscript-accepts-functions-as-arguments-3f8b9d21c097
- score: 0.93

How to use it:

When an init script needs a function in its argument, pass a function as the script and set `exposeFunctions: true`. The function is callable from the init script and returns a Promise.

Examples:

```
await page.addInitScript(({ callback }) => { window.result = callback(); }, { callback: async () => 'value' }, { exposeFunctions: true });
```

```
await browserContext.addInitScript(({ callback }) => { window.result = callback(); }, { callback: async () => 'value' }, { exposeFunctions: true });
```

- why_it_matters: Pass a function as an init-script argument when configuring page or context setup in a test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-page>, <https://playwright.dev/docs/api/class-browsercontext>
- gotchas: "Version: v1.62.0"; "script (required): Function, string, or object describing the init script; `arg` is supported only with a function."; "arg: Optional argument passed to the script function; with `exposeFunctions: true`, functions in it are exposed to the page."; "options.exposeFunctions: Boolean; set to `true` to expose functions passed inside `arg`. Calls return Promises. Defaults to `false`, when functions are silently dropped. No mutually exclusive sub-keys are documented."; "Prerequisite: Use Playwright v1.62.0 or later for `exposeFunctions`; it was added in v1.62."

### APIResponse exposes resource timing information (2026-07-24)
- slug: apiresponse-exposes-resource-timing-information-7fb4b13c9b1c
- score: 0.94

How to use it:

When debugging an API response in a test, call `apiResponse.timing()` to inspect its resource timing data.

Examples:

```
const timing = apiResponse.timing();
```

- why_it_matters: Inspect resource timing information while debugging an API response in a test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-apiresponse#api-response-timing>
- gotchas: "Version: v1.62.0"; "Prerequisite: `APIResponse.timing()` was added in Playwright v1.62."

### BrowserContext storage state includes virtual WebAuthn credentials (2026-07-24)
- slug: browsercontext-storage-state-includes-virtual-webauthn-credentials-9e9dd05ee06d
- score: 0.92

How to use it:

When saving a context that has virtual WebAuthn credentials, call `storageState({ credentials: true })` to include them. Restore that state in a later context with `storageState` or `setStorageState`; restoration installs the virtual authenticator and disables real authenticators in that context.

Examples:

```
await context.storageState({ credentials: true, path: 'state.json' });
```

```
const context = await browser.newContext({ storageState: 'state.json' });
```

```
await context.setStorageState('state.json');
```

- why_it_matters: Persist virtual WebAuthn credentials so a later browser context can be seeded with them.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state-option-credentials>, <https://playwright.dev/docs/auth#reuse-signed-in-state>, <https://playwright.dev/docs/api/class-browsercontext#browser-context-set-storage-state>, <https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state-option-path>, <https://playwright.dev/docs/api/class-browser#browser-new-context-option-storage-state>, <https://playwright.dev/docs/api/class-browsercontext#browser-context-set-storage-state-param-storage-state>
- gotchas: "Version: v1.62.0"; "credentials: Boolean option for `storageState`; set to `true` to include virtual WebAuthn credentials in the snapshot."; "path: File path for saving the state; if omitted, the state is returned but not saved to disk."; "storageState: `browser.newContext` option containing a state file path or state object to initialize the context."; "storageState (required): Argument to `setStorageState`; path or state object to apply to the existing context."; "Prerequisite: Use Playwright v1.62.0 or later for the release-note change."; "Prerequisite: Restoring state with credentials automatically installs the virtual WebAuthn authenticator; real authenticators will not work in that context."; "The option includes the context's virtual WebAuthn credentials (passkeys) in storage state."; "Docs conflict: Current API docs mark `credentials` as added in v1.61, while the v1.62.0 release note describes it as new in v1.62. The version attribution differs."

### HTML reporter supports mergeFiles configuration (2026-07-24)
- slug: html-reporter-supports-mergefiles-configuration-3bbad604857c
- score: 0.97

How to use it:

When using Playwright v1.62.0 or later, set the HTML reporter’s `mergeFiles` option to `true` in the config to group tests by their top-level `test.describe()` title.

Examples:

```
import { defineConfig } from '@playwright/test';
export default defineConfig({
  reporter: [['html', { mergeFiles: true }]],
});
```

- why_it_matters: Enable merged file grouping in the HTML report from the Playwright config.
- before: Merge files grouping was previously available only as a UI toggle.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/release-notes>, <https://playwright.dev/docs/test-reporters>
- gotchas: "Version: v1.62.0"; "reporter: [['html', { mergeFiles: true }]]: HTML reporter configuration; `mergeFiles` is an optional boolean that groups tests by their top-level `test.describe()` title instead of by file."; "Prerequisite: Playwright v1.62.0 or later; `mergeFiles` was introduced in v1.62.0."; "The Merge files grouping was previously only a UI toggle."

### Locator adds waitForFunction() (2026-07-24)
- slug: locator-adds-waitforfunction-0bf0d0baaedf
- score: 0.96

How to use it:

When a matching element must satisfy a custom condition, call `locator.waitForFunction()` with a page-context function; it waits until the function returns a truthy value.

Examples:

```
const status = page.getByTestId('status');
await status.waitForFunction((element, value) => element.textContent === value, 'Ready');
```

- why_it_matters: Wait for a condition on a matching element before continuing a test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-locator#locator-wait-for-function>
- gotchas: "Version: v1.62.0"; "pageFunction (required): Function evaluated in the page context; receives the matching element first and the optional `arg` second. Waiting ends when its result is truthy."; "arg: Optional argument passed to `pageFunction`."; "options.timeout: Maximum wait in milliseconds; defaults to 0 (no timeout)."; "Prerequisite: `locator.waitForFunction()` was added in Playwright v1.62."; "The function is called with the matching element and must return a truthy value for the wait to finish."

### Playwright actions accept a scroll option (2026-07-24)
- slug: playwright-actions-accept-a-scroll-option-e50ff82e1768
- score: 0.99

How to use it:

When an action must not scroll its target into view automatically, pass `scroll: "none"`; the action fails if the element is outside the viewport. Use `scroll: "auto"` to allow automatic scrolling.

Examples:

```
await page.getByRole('button', { name: '<button name>' }).click({ scroll: 'none' });
```

- why_it_matters: Run an action without Playwright automatically scrolling its target into view.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-page>
- gotchas: "Version: v1.62.0"; "scroll: Action option: `\"none\"` disables scrolling and the action fails if the element is not in the viewport; `\"auto\"` (the default) scrolls into view when needed, including nested scrollable containers."; "Prerequisite: Added in Playwright v1.62."; "The `scroll` option accepts `\"auto\"` or `\"none\"`."

### Playwright bundles MCP server and playwright-cli (2026-07-24)
- slug: playwright-bundles-mcp-server-and-playwright-cli-65203b30d317
- score: 0.97

How to use it:

When developing or inspecting a project with browser automation, run `npx playwright mcp` to start the MCP server or `npx playwright cli` to invoke the CLI. For CLI use, pass a documented command such as `open <url>`; use the release’s bundled entry points.

Examples:

```
npx playwright mcp
```

```
npx playwright cli --help
```

```
npx playwright cli open <url>
```

- why_it_matters: Use Playwright's bundled command line or MCP server while developing or inspecting a project.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/getting-started-cli>, <https://playwright.dev/docs/getting-started-mcp>
- gotchas: "Version: v1.62.0"; "Prerequisite: MCP docs list Node.js 20 or newer and an MCP client as prerequisites."; "Prerequisite: CLI docs list Node.js 20 or newer and a coding agent as prerequisites."; "The release says the server and CLI are bundled with Playwright."; "Docs conflict: Current MCP setup docs show `npx @playwright/mcp@latest`; current CLI setup docs show installing `@playwright/cli` and using `npx playwright cli`. These describe separate package setup; the v1.62.0 release says the Playwright package bundles both entry points."

### Playwright operations and assertions accept AbortSignal (2026-07-24)
- slug: playwright-operations-and-assertions-accept-abortsignal-72cc564804df
- score: 0.98

How to use it:

When a browser action or web-first assertion needs to be cancellable, pass an `AbortSignal` in its `signal` option. To disable the operation’s default timeout too, pass `timeout: 0`.

Examples:

```
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 });
```

```
await page.getByRole('button', { name: 'Submit' }).click({ signal: controller.signal, timeout: 0 });
```

- why_it_matters: Cancel a long-running browser action or assertion during a test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-locator>, <https://playwright.dev/docs/next/api/class-locatorassertions>
- gotchas: "Version: v1.62.0"; "signal: An `AbortSignal` that cancels the operation; for locator assertions, aborting fails the assertion like a timeout."; "timeout: Maximum time in milliseconds. For operations, `0` disables the timeout; assertion timeout defaults to `TestConfig.expect`."; "Prerequisite: The `signal` option was added in Playwright v1.62."; "Most operations and web-first assertions accept `signal`."; "Providing a signal does not disable the default timeout; pass `timeout: 0` to disable it."

### Playwright reporters can filter tests with reporter.preprocess() (2026-07-24)
- slug: playwright-reporters-can-filter-tests-with-reporter-preprocess-def815566117
- score: 0.98

How to use it:

When selected tests must be skipped before the run begins, implement `Reporter.preprocess()` and call `testRun.skip(test)` for each matching test in `suite.allTests()`.

Examples:

```
class MyReporter {
  async preprocess({ config, suite, testRun }) {
    for (const test of suite.allTests()) {
      if (shouldSkip(test)) // Replace with your selection condition.
        testRun.skip(test);
    }
  }
}
```

- why_it_matters: Skip selected tests in a reporter after configuration resolution and before the run begins.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-reporter>, <https://playwright.dev/docs/api/class-testrun>
- gotchas: "Version: v1.62.0"; "config (required): Resolved configuration passed to `preprocess`."; "suite (required): Root suite; `suite.allTests()` returns tests in it and its descendants. It reflects project, grep, and `.only` filtering; setup and dependency projects are read-only."; "testRun (required): Controls which tests run and their expected status."; "test (required): `TestCase` or `Suite` to skip; test bodies are not executed and tests are reported as skipped."; "reason: Optional explanation surfaced as the annotation description by `testRun.skip(test, reason)`."; "Prerequisite: Playwright v1.62 or later; `reporter.preprocess()` and `testRun.skip()` were added in v1.62."; "The hook runs after configuration is resolved and before `reporter.onBegin()`."; "The release says the hook lets reporters mark tests skipped, excluded, fixed, or failing through a `TestRun` object."

### Playwright screenshots support WebP snapshots (2026-07-24)
- slug: playwright-screenshots-support-webp-snapshots-0a3412526edd
- score: 0.97

How to use it:

When storing visual comparison snapshots or standalone screenshots as WebP in Playwright v1.62.0, use a `.webp` snapshot name or screenshot path; for standalone screenshots, optionally set `type: 'webp'` and `quality` below 100 for lossy compression.

Examples:

```
await expect(page).toHaveScreenshot('homepage.webp');
```

```
await expect(locator).toHaveScreenshot('image.webp');
```

```
await page.screenshot({ path: 'homepage.webp', quality: 50 });
```

- why_it_matters: Store visual comparison snapshots or standalone screenshots as WebP in a test workflow.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1>, <https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-screenshot-1>, <https://playwright.dev/docs/api/class-page#page-screenshot>
- gotchas: "Version: v1.62.0"; "name (required): Snapshot name; `.webp` selects WebP format. Both PNG and WebP snapshots are lossless."; "path: Output file path; screenshot type is inferred from its extension. A `.webp` path selects WebP."; "type: Screenshot type; accepts `png`, `jpeg`, or `webp`. Defaults to `png`."; "quality: Image quality from 0 to 100. For WebP, 100 (default) is lossless; lower values use lossy compression."; "Prerequisite: Screenshot assertions work only with the Playwright test runner."; "Visual comparisons store the golden snapshot as lossless WebP."; "Standalone screenshots can use lossy WebP; quality `100` is lossless by default and lower values use lossy compression."

### Playwright testConfig.retryStrategy supports isolated retries (2026-07-24)
- slug: playwright-testconfig-retrystrategy-supports-isolated-retries-58527b8c865b
- score: 0.98

How to use it:

When failed tests should run after the rest of the suite, set `retryStrategy: 'isolated'` in the Playwright config; retries then run one by one in a single worker. [Playwright TestConfig](https://playwright.dev/docs/api/class-testconfig#test-config-retry-strategy)

Examples:

```
import { defineConfig } from '@playwright/test';

export default defineConfig({
  retries: 2,
  retryStrategy: 'isolated',
});
```

- why_it_matters: Run failed test retries after the rest of the suite to minimize interference between retries and other tests.
- before: The default `'immediate'` strategy retries a failed test as soon as a worker is available, interleaved with the rest of the run.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.62.0>, <https://playwright.dev/docs/api/class-testconfig#test-config-retry-strategy>, <https://playwright.dev/docs/api/class-testconfig#test-config-retries>
- gotchas: "Version: v1.62.0"; "retryStrategy: Controls when failed tests are retried. `'isolated'` runs retries at the end, one by one in a single worker; the default is `'immediate'`."; "retries: Maximum number of retry attempts for failed tests; by default, failing tests are not retried."; "Prerequisite: `retryStrategy` was added in Playwright v1.62."; "`'immediate'` is the default strategy."; "`'isolated'` runs all retries at the end, one by one in a single worker."

### Playwright APIResponse exposes security details and server address (2026-06-15)
- slug: playwright-apiresponse-exposes-security-details-and-server-address-53a1754958b8
- score: 0.91

How to use it:

When inspecting an API response, call `await apiResponse.securityDetails()` for SSL/security information and `await apiResponse.serverAddr()` for the server IP and port; redirected responses report the last request in the chain.

Examples:

```
await apiResponse.securityDetails();
```

```
await apiResponse.serverAddr();
```

- why_it_matters: Inspect security and server connection details for API responses in a test or debugging workflow.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/api/class-apiresponse#api-response-security-details>, <https://playwright.dev/docs/api/class-apiresponse#api-response-server-addr>
- gotchas: "Version: v1.61.0"

### Playwright browserContext.credentials registers virtual passkeys (2026-06-15)
- slug: playwright-browsercontext-credentials-registers-virtual-passkeys-808561153626
- score: 0.99

How to use it:

When testing a passkey login without a physical key, seed a virtual credential in the browser context, install the authenticator before navigation, then open the login page.

Examples:

```
const context = await browser.newContext();
await context.credentials.create('example.com', {
  id: '<credentialId>',
  userHandle: '<userHandle>',
  privateKey: '<privateKey>',
  publicKey: '<publicKey>',
});
await context.credentials.install();
const page = await context.newPage();
await page.goto('https://example.com/login');
```

```
const context = await browser.newContext();
await context.credentials.install();
const page = await context.newPage();
await page.goto('https://example.com/register');
await page.getByRole('button', { name: 'Create a passkey' }).click();
const [credential] = await context.credentials.get({ rpId: 'example.com' });
```

```
const context = await browser.newContext();
await context.credentials.create('<rpId>', <credential>);
await context.credentials.install();
const page = await context.newPage();
await page.goto('https://example.com/login');
```

- why_it_matters: Test a passkey login flow in a browser context without a physical security key.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/api/class-credentials>
- gotchas: "Version: v1.61.0"; "rpId (required): Relying party ID, typically the site's effective domain."; "options.id: Base64url credential ID; auto-generated if omitted."; "options.userHandle: Base64url user handle; auto-generated if omitted."; "options.privateKey: Base64url PKCS#8 (DER) private key; auto-generated if omitted."; "options.publicKey: Base64url SPKI (DER) public key; auto-generated if omitted."; "credentials.install() (required): Takes no parameters; installs interception for page WebAuthn calls. Call before the page first uses WebAuthn."; "Prerequisite: Use Playwright v1.61 or later; the credentials API was added in v1.61."; "Prerequisite: Call credentials.install() before navigating to a page that uses WebAuthn; otherwise seeded credentials are not exposed to the page."; "No real hardware key is required."; "Works in all browsers."

### Playwright page.localStorage and page.sessionStorage read and write origin storage (2026-06-15)
- slug: playwright-page-localstorage-and-page-sessionstorage-read-and-write-origin-stora-fad96a56018a
- score: 0.99

How to use it:

When testing storage for a page’s current origin, use `page.localStorage` or `page.sessionStorage` to set, retrieve, or list items. Navigate the page to the target origin first.

Examples:

```
await page.goto('<origin-url>');
await page.localStorage.setItem('token', 'abc');
const token = await page.localStorage.getItem('token');
const items = await page.sessionStorage.items();
```

- why_it_matters: Set up or inspect browser storage while testing a page for its current origin.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/api/class-webstorage>
- gotchas: "Version: v1.61.0"; "name (required): Storage item name for `getItem` and `setItem`."; "value (required): New string value for `setItem`; overwrites the existing value for that name."; "Prerequisite: Use Playwright v1.61 or later; these WebStorage methods were added in v1.61. Navigate the page to the target origin before accessing its storage."; "Applies to the page's storage for the current origin."

### Playwright supports expect.soft.poll (2026-06-15)
- slug: playwright-supports-expect-soft-poll-fb8db8c68ed3
- score: 0.97

How to use it:

When a test needs to poll an assertion without stopping at the first failure, call `expect.soft.poll(...)` and chain the matcher, such as `.toBe(200)`.

Examples:

```
await expect.soft.poll(async () => { const response = await page.request.get('https://api.example.com'); return response.status(); }).toBe(200);
```

- why_it_matters: Poll an assertion in a test while keeping it soft.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/test-assertions>
- gotchas: "Version: v1.61.0"; "actual (callback) (required): Function polled until the chained matcher passes or polling times out."; "timeout: Polling timeout in milliseconds; default is 5 seconds. Set to 0 to disable timeout."; "intervals: Polling intervals in milliseconds; default is [100, 250, 500, 1000]."; "chained matcher (required): Assertion applied to the callback result, such as `.toBe(200)`."; "Prerequisite: Soft assertions work only with the Playwright test runner."

### Playwright test runner adds -G shorthand (2026-06-15)
- slug: playwright-test-runner-adds-g-shorthand-c3924906bde6
- score: 0.95

How to use it:

When you need to exclude tests matching a pattern, run `npx playwright test -G <grep>`. `-G` is shorthand for `--grep-invert` and runs tests that do not match the regular expression.

Examples:

```
npx playwright test -G "<grep>"
```

- why_it_matters: Exclude matching tests from a Playwright test run using the command line.
- before: Use `--grep-invert` to exclude matching tests.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/test-cli>
- gotchas: "Version: v1.61.0"; "-G <grep> (alias: --grep-invert <grep>) (required): Regular expression; only tests that do not match it run."

### Playwright testOptions.video adds trace-aligned recording modes (2026-06-15)
- slug: playwright-testoptions-video-adds-trace-aligned-recording-modes-66ea9ffee934
- score: 0.94

How to use it:

When configuring test video retention to follow a run’s recording policy, set `video` in the Playwright Test `use` config to one of the three modes below. Choose its recording and retention behavior from the video modes table.

Examples:

```
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    video: 'on-all-retries', // or 'retain-on-first-failure' or 'retain-on-failure-and-retries'
  },
});
```

- why_it_matters: Configure test video retention to match the trace recording and retention policy used by a test run.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.61.0>, <https://playwright.dev/docs/api/class-testoptions#test-options-video>, <https://playwright.dev/docs/test-use-options#video-modes>
- gotchas: "Version: v1.61.0"; "video: Recording mode. `on-all-retries` records and keeps video for every retry; `retain-on-first-failure` records only the first run and keeps it if that run failed; `retain-on-failure-and-retries` records every run and keeps it when that run failed or was a retry."

### Playwright ariaSnapshot() can include element bounding boxes (2026-05-11)
- slug: playwright-ariasnapshot-can-include-element-bounding-boxes-c5399393f041
- score: 0.92

How to use it:

When inspecting a page or locator, pass `{ boxes: true }` to `ariaSnapshot()` to append each element’s bounding box as `[box=x,y,width,height]`.

Examples:

```
await page.ariaSnapshot({ boxes: true });
```

```
await page.getByRole('<role>').ariaSnapshot({ boxes: true });
```

- why_it_matters: Include element geometry in an aria snapshot used to inspect a page or locator.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-page#page-aria-snapshot>, <https://playwright.dev/docs/api/class-locator#locator-aria-snapshot>
- gotchas: "Version: v1.60.0"; "boxes: Boolean option; when true, appends each element’s bounding box to the snapshot. Defaults to false. Coordinates are viewport-relative CSS pixels."; "Prerequisite: Use Playwright v1.60.0 or later; the `boxes` option was added in v1.60."

### Playwright BrowserContext mirrors page lifecycle events (2026-05-11)
- slug: playwright-browsercontext-mirrors-page-lifecycle-events-60080847de41
- score: 0.99

How to use it:

When monitoring lifecycle activity across every page in a browser context, register listeners on the `BrowserContext` for the events you need. Each callback receives a `Download`, `Frame`, or `Page`, as documented for that event.

Examples:

```
context.on('download', download => {});
context.on('frameattached', frame => {});
context.on('framedetached', frame => {});
context.on('framenavigated', frame => {});
context.on('pageclose', page => {});
context.on('pageload', page => {});
```

- why_it_matters: Monitor downloads, frame lifecycle, page closure, and page load across pages in a browser context.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-browsercontext>
- gotchas: "Version: v1.60.0"; "event name (`download`, `frameattached`, `framedetached`, `framenavigated`, `pageclose`, or `pageload`) (required): Selects which context event to listen for. The events report a download starting, a frame attaching/detaching/navigating, a page closing, or a page's JavaScript `load` event being dispatched, respectively."; "listener callback (`data => {}`) (required): Receives the event data: `Download` for `download`, `Frame` for the three frame events, and `Page` for `pageclose` and `pageload`."; "Prerequisite: Use Playwright v1.60.0 or later; the six context event APIs are documented as added in v1.60."

### Playwright getByRole() matches accessible descriptions (2026-05-11)
- slug: playwright-getbyrole-matches-accessible-descriptions-a2f5ba466ed9
- score: 0.97

How to use it:

When locating an element by role and accessible description, pass `description` in the `getByRole()` options. Playwright v1.60.0 added this option to page, locator, frame, and frame-locator methods.

Examples:

```
await page.getByRole('<role>', { description: '<accessible description>' });
```

```
await locator.getByRole('<role>', { description: '<accessible description>' });
```

```
await frame.getByRole('<role>', { description: '<accessible description>' });
```

- why_it_matters: Locate an element by its role and accessible description in a page, locator, frame, or frame locator.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-page#page-get-by-role>, <https://playwright.dev/docs/api/class-locator#locator-get-by-role>, <https://playwright.dev/docs/api/class-frame#frame-get-by-role>
- gotchas: "Version: v1.60.0"; "role (required): ARIA role to locate."; "description: String or RegExp matching the accessible description. String matching is case-insensitive substring matching by default."; "exact: Match the name and description exactly, case-sensitively and as whole strings; defaults to false. Ignored for RegExp values."; "Prerequisite: Use Playwright v1.60.0 or later for the `description` option."

### Playwright locator.drop() simulates external drag-and-drop (2026-05-11)
- slug: playwright-locator-drop-simulates-external-drag-and-drop-8cb857962ef8
- score: 0.98

How to use it:

When testing an element that accepts external file or clipboard-like drops, call `locator.drop()` with a `files` payload, a MIME-type-to-string `data` map, or both.

Examples:

```
await page.locator('<dropzone-selector>').drop({ files: { name: 'note.txt', mimeType: 'text/plain', buffer: Buffer.from('hello') } });
```

```
await page.locator('<dropzone-selector>').drop({ data: { 'text/plain': 'hello world', 'text/uri-list': 'https://example.com' } });
```

- why_it_matters: Test a page's file upload zone or other drag-and-drop target.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-locator#locator-drop>
- gotchas: "Version: v1.60.0"; "payload.files: File paths or in-memory buffers; file objects use `name` (file name), `mimeType` (file type), and `buffer` (file content)."; "payload.data: MIME-type-to-string map for clipboard-like content; may be used with `files` or by itself."; "options.position: Target point relative to the element’s padding-box top-left; defaults to a visible point."; "options.timeout: Maximum time in milliseconds; defaults to 0 (no timeout)."; "Prerequisite: `locator.drop()` was added in Playwright v1.60."; "Works cross-browser."

### Playwright locator highlights accept custom styles (2026-05-11)
- slug: playwright-locator-highlights-accept-custom-styles-d0ffac583d44
- score: 0.95

How to use it:

When visually inspecting a locator, call `locator.highlight({ style })` to add inline CSS to its overlay, then call `page.hideHighlight()` to clear all locator highlight overlays on that page.

Examples:

```
await page.locator('<selector>').highlight({ style: 'outline: 2px dashed red' });
await page.hideHighlight();
```

- why_it_matters: Visually inspect a highlighted locator and then clear page highlights.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-locator#locator-highlight>, <https://playwright.dev/docs/api/class-page#page-locator>
- gotchas: "Version: v1.60.0"; "options.style: Inline CSS for the highlight overlay. Accepts a CSS string or an object of string, string-or-number values. The docs do not state these forms are mutually exclusive."; "selector (required): Selector used by `page.locator()` to resolve the DOM element."; "Prerequisite: Use Playwright v1.60.0 or later; `style` and `page.hideHighlight()` were added in v1.60."

### Playwright test.abort() aborts the running test (2026-05-11)
- slug: playwright-test-abort-aborts-the-running-test-e180dae24c30
- score: 0.94

How to use it:

When a fixture, hook, or route handler detects unrecoverable misuse, call `test.abort()` to fail the running test immediately; in a route handler, also call `route.abort()` if the request should be stopped.

Examples:

```
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(); }); });
```

- why_it_matters: Stop a test immediately when a fixture, hook, or route handler detects unrecoverable misuse.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-test>, <https://github.com/microsoft/playwright/blob/main/docs/src/api/class-route.md>
- gotchas: "Version: v1.60.0"; "message (optional string): Describes the abort reason; included in the failure error."; "route.abort(): Aborts the intercepted request; the API also supports an optional error code."; "Prerequisite: `test.abort()` was added in Playwright v1.60."; "The optional message accompanies the abort."

### Playwright toHaveCSS() reads pseudo-element styles (2026-05-11)
- slug: playwright-tohavecss-reads-pseudo-element-styles-ae03dec5d9ec
- score: 0.90

How to use it:

When asserting a locator’s computed CSS for a `::before` or `::after` pseudo-element, pass `pseudo: 'before'` or `pseudo: 'after'` in the `toHaveCSS()` options.

Examples:

```
await expect(locator).toHaveCSS('content', '"New"', { pseudo: 'before' });
```

```
await expect(locator).toHaveCSS('content', '"New"', { pseudo: 'after' });
```

- why_it_matters: Assert the computed CSS style of a locator's `::before` or `::after` pseudo-element.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-css>
- gotchas: "Version: v1.60.0"; "name (required): CSS property name."; "value (required): Expected CSS property value; may be a string or RegExp."; "options.pseudo: Selects the pseudo-element to read computed styles from: `before` or `after`."; "The release names `::before` and `::after` as supported pseudo-elements."

### Playwright tracing adds scoped HAR recording (2026-05-11)
- slug: playwright-tracing-adds-scoped-har-recording-c51c15388e41
- score: 0.97

How to use it:

When recording network traffic for a browser workflow in Playwright v1.60.0 or later, call `context.tracing.startHar()` with the HAR path and any needed filters, then dispose its returned handle to save the HAR.

Examples:

```
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  await using har = await context.tracing.startHar('trace.har', {
    content: 'embed',
    mode: 'full',
    urlFilter: '**/*',
  });
  const page = await context.newPage();
  await page.goto('https://playwright.dev');
  await browser.close();
})();
```

- why_it_matters: Record network traffic while running a browser workflow for debugging or replay.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://playwright.dev/docs/api/class-tracing>
- gotchas: "Version: v1.60.0"; "path (required) (required): Filesystem path for the HAR. A .zip extension saves a ZIP archive with response bodies as separate files."; "options.content (optional): Resource content handling: omit, embed, or attach. Defaults to attach for .zip output and embed for other extensions."; "options.mode (optional): HAR detail level: full or minimal. Minimal keeps information needed for HAR routing; defaults to full."; "options.urlFilter (optional): Glob or regular expression filtering requests stored in the HAR; defaults to no filter."; "Prerequisite: Requires Playwright v1.60 or later; tracing.startHar was added in v1.60."

### Playwright WebSocket routes expose requested protocols (2026-05-11)
- slug: playwright-websocket-routes-expose-requested-protocols-1094a183ce10
- score: 0.96

How to use it:

When handling a routed WebSocket, call `ws.protocols()` to inspect the subprotocols requested by the page; it returns an empty array if none were specified.

Examples:

```
await page.routeWebSocket('wss://example.com/ws', ws => {
  const requestedProtocols = ws.protocols();
});
```

- why_it_matters: Inspect the subprotocols requested by a page when handling a WebSocket route.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.60.0>, <https://github.com/microsoft/playwright/blob/v1.60.0/docs/src/api/class-websocketroute.md>, <https://playwright.dev/docs/api/class-websocketroute>
- gotchas: "Version: v1.60.0"; "webSocketRoute.protocols() (required): No arguments; returns the requested subprotocols as an array of strings, or an empty array when none were specified."; "page.routeWebSocket(url, handler) (required): Sets up the WebSocket route whose handler receives the WebSocketRoute; replace the example URL with the target WebSocket URL or pattern."; "Prerequisite: Use Playwright v1.60 or later; `WebSocketRoute.protocols()` was added in v1.60."

### Playwright aria snapshots support page capture and locator depth and mode options (2026-04-01)
- slug: playwright-aria-snapshots-support-page-capture-and-locator-depth-and-mode-option-f41d0bd55096
- score: 0.96

How to use it:

When inspecting accessible structure in browser tests, capture a page snapshot with `page.ariaSnapshot()` or call `locator.ariaSnapshot({ depth, mode })` to limit snapshot depth or choose its mode.

Examples:

```
const snapshot = await page.ariaSnapshot();
```

```
const snapshot = await locator.ariaSnapshot({ depth: <depth>, mode: '<default-or-ai>' });
```

- why_it_matters: When inspecting accessible structure in browser tests, capture a page snapshot or set snapshot depth and mode on a locator.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/api/class-page#page-aria-snapshot>, <https://playwright.dev/docs/api/class-locator#locator-aria-snapshot>
- gotchas: "Version: v1.59.0"; "depth: Number; when specified, limits snapshot depth."; "mode: `\"ai\"` returns an AI-optimized snapshot; `\"default\"` is the default mode. The modes are alternatives."; "`page.ariaSnapshot()` is equivalent to `page.locator('body').ariaSnapshot()`."; "Docs conflict: Current API docs show `page.ariaSnapshot()` added in v1.59 and locator `depth`/`mode` added in v1.59; docs also describe features added in later versions, which are omitted here."

### Playwright browser.bind() lets CLI and other clients connect to a launched browser (2026-04-01)
- slug: playwright-browser-bind-lets-cli-and-other-clients-connect-to-a-launched-browser-6c03d7bb9873
- score: 0.98

How to use it:

When inspecting a launched browser session, bind it with a name, then attach a client using that name or the returned endpoint. Use `host` and `port` to bind over WebSocket; call `browser.unbind()` to stop accepting connections.

Examples:

```
const { endpoint } = await browser.bind('my-session', { workspaceDir: '<project-dir>' });
// In another terminal:
playwright-cli attach my-session
playwright-cli -s=my-session snapshot
```

```
const { endpoint } = await browser.bind('my-session', { host: 'localhost', port: 0 });
const client = await chromium.connect(endpoint);
```

```
@playwright/mcp --endpoint=my-session
```

- why_it_matters: When debugging or inspecting a repository's browser session from a coding agent, bind the launched browser and connect a client to it.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/api/class-browser>, <https://playwright.dev/docs/api/class-browsertype>
- gotchas: "Version: v1.59.0"; "title (required): Browser server name used for identification."; "workspaceDir: Working directory associated with the browser server."; "host: When specified, creates a WebSocket server instead of a named pipe."; "port: WebSocket port; `0` lets the OS choose an available port."; "endpoint (required): WebSocket endpoint string passed to `chromium.connect(endpoint)`."; "browser.unbind(): Unbinds the browser server previously bound with `browser.bind()`."; "Prerequisite: `browser.bind()` and `browser.unbind()` were added in Playwright v1.59."; "Prerequisite: The connecting Playwright instance’s major and minor versions must match the version that launched the browser."; "Multiple clients at a time are supported."; "Binding over WebSocket uses `host` and `port` options instead of a named pipe."

### Playwright browserType.launch() accepts artifactsDir (2026-04-01)
- slug: playwright-browsertype-launch-accepts-artifactsdir-63a9530b3817
- score: 0.97

How to use it:

When launching a browser and you want artifacts saved to a specific directory, pass `artifactsDir` in `browserType.launch()` options.

Examples:

```
const browser = await chromium.launch({ artifactsDir: '<artifacts-directory>' });
```

- why_it_matters: When launching a browser for a repository test run, set the directory used for artifacts.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/api/class-browsertype#browser-type-launch>
- gotchas: "Version: v1.59.0"; "options.artifactsDir: Directory for artifacts such as traces, videos, downloads, and HAR files. It is not cleaned up when the browser closes; without it, Playwright uses a temporary directory that is cleaned up on close."

### Playwright page.consoleMessages() and page.pageErrors() accept a filter option (2026-04-01)
- slug: playwright-page-consolemessages-and-page-pageerrors-accept-a-filter-option-0e11d98701a7
- score: 0.95

How to use it:

When a browser test retrieves console messages or page errors, pass `filter` in the options object to control which entries are returned.

Examples:

```
await page.consoleMessages({ filter: 'since-navigation' });
```

```
await page.pageErrors({ filter: 'since-navigation' });
```

- why_it_matters: When retrieving console messages or page errors in a browser test, filter the returned entries.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/api/class-page#page-console-messages>, <https://playwright.dev/docs/api/class-page#page-page-errors>
- gotchas: "Version: v1.59.0"; "filter: Optional value: `all` or `since-navigation`. Controls which messages or errors are returned; the docs do not define the individual values' behavior."; "Prerequisite: The filter option was added in Playwright v1.59."

### Playwright page.screencast records videos, streams frames and manages annotations (2026-04-01)
- slug: playwright-page-screencast-records-videos-streams-frames-and-manages-annotations-00eb8f27722c
- score: 0.93

How to use it:

When preparing browser workflow evidence, record activity or capture JPEG frames with `page.screencast.start()` and finish with `page.screencast.stop()`; add action annotations or overlays as needed. In Playwright Test fixtures, configure annotations under the `video` option.

Examples:

```
await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } });
// ... perform actions ...
await page.screencast.stop();
```

```
await page.screencast.start({
  onFrame: ({ data, timestamp, viewportWidth, viewportHeight }) => {
    processFrame(data, timestamp, viewportWidth, viewportHeight);
  },
  size: { width: 800, height: 600 },
});
// ... perform actions ...
await page.screencast.stop();
```

```
await page.screencast.start({ path: 'video.webm' });
await page.screencast.showActions({ position: 'top-right' });
await page.screencast.showChapter('Verification', { description: 'Browser workflow evidence' });
// ... perform actions ...
await page.screencast.stop();
```

- why_it_matters: When verifying a repository's browser workflow and preparing evidence for review, record the page activity with annotations or capture frames for processing.
- before: The v1.59 release note describes `page.screencast.start()` and `stop()` as an alternative to the `recordVideo` browser-context option.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/api/class-screencast>
- gotchas: "Version: v1.59.0"; "start({ path }): `path` is optional; when supplied, starts recording to that file. `size` optionally sets maximum frame width and height; `onFrame` optionally receives JPEG frame data and viewport dimensions."; "showActions({ position, duration, fontSize }): All options are optional. `position` selects the title overlay position; `duration` sets annotation display time in milliseconds (default 500); `fontSize` sets title size in pixels (default 24). Returns a disposable that stops annotations when disposed."; "showChapter(title, { description, duration }) (required): `title` is required. `description` and `duration` are optional; duration is milliseconds and defaults to 2000."; "showOverlay(html, { duration }) (required): `html` is required. Optional `duration` is milliseconds; without it, the overlay stays until dismissed or disposed."; "video.show.actions.position: In the Playwright Test `video` option, `show.actions.position` selects the annotation title position; `show.test.position` selects the test annotation position."; "Prerequisite: The screencast methods are documented as added in Playwright v1.59."; "Prerequisite: For Playwright Test fixture video annotations, configure the `video` option under `use`; the release-note example sets `mode: 'on'`."; "`showActions()` accepts `position` values `'top-left'`, `'top'`, `'top-right'`, `'bottom-left'`, `'bottom'`, and `'bottom-right'`, `duration` in milliseconds per annotation, and `fontSize` in pixels; it returns a disposable to stop showing actions."; "Docs conflict: The current API docs include later additions: `cursor` since v1.61 and `style` since v1.64; they also mark `fontSize` deprecated. Those later changes do not establish v1.59 behavior."

### playwright test --debug=cli attaches coding agents to paused tests (2026-04-01)
- slug: playwright-test-debug-cli-attaches-coding-agents-to-paused-tests-3c4ad7673311
- score: 0.98

How to use it:

When debugging a failing repository test, start it with `--debug=cli`, attach to the emitted session, then step through the paused test with `playwright-cli`.

Examples:

```
npx playwright test --debug=cli
```

```
playwright-cli attach <session>
```

```
playwright-cli --session=<session> step-over
```

- why_it_matters: When debugging a failing repository test, start it in CLI debug mode and attach to inspect and step through the paused test.
- sources: <https://github.com/microsoft/playwright/releases/tag/v1.59.0>, <https://playwright.dev/docs/release-notes>, <https://playwright.dev/agent-cli/commands/test-debugging>, <https://playwright.dev/agent-cli/capabilities>, <https://playwright.dev/agent-cli/installation>
- gotchas: "Version: v1.59.0"; "--debug=cli: Runs the test paused at the start and prints debugging instructions."; "<session> (required): The session name emitted by the test runner; pass it to `attach`."; "--session=<session>: Selects the named browser session for a CLI command."; "Prerequisite: Playwright 1.59.0 or newer is needed for `--debug=cli`."; "Prerequisite: If Playwright is already a project dependency, the docs say `playwright-cli` commands can also be run as `npx playwright cli <command>`."
