Packages

playwright

1.64.1Apache-2.0
  • 1.64.1 is the latest, published 14 October 2026.
  • 1 security advisory, all fixed.
  • 1.x: 155 releases since 6 May 2020, 5 in the last 90 days.

Security advisories

Grouped by the version that fixes them, so one upgrade reads as one step.

Releases in the last 90 days

Feed of releases and advisories

Every stable release, newest first. Notes are quoted as the maintainers published them.

  1. 1.64.1

    14 October 2026
    [Bug]: _electron.launch intermittently loses a packaged app's first window since 1.64.0

    Bug Fixes

    • [Bug]: _electron.launch intermittently loses a packaged app's first window since 1.64.0

    • [Regression]: Chromium 155+ aborts a preflighted cross-origin redirect whenever any route is registered (net::ERR_ABORTED)

  2. 1.64.0

    7 October 2026
    New page.webmcp and frame.webmcp give access to the tools that a page registers through the experimental WebMCP browser API, so you can test them like any other part of your app:

    WebMCP

    New page.webmcp and frame.webmcp give access to the tools that a page registers through the experimental WebMCP browser API, so you can test them like any other part of your app:

    const browser = await chromium.launch({ args: ['--enable-features=WebMCP'] });
    const page = await browser.newPage();
    await page.goto('https://example.com');
    
    for (const tool of await page.webmcp.tools())
      console.log(tool.name, tool.description);
    
    const result = await page.webmcp.callTool('add', { a: 2, b: 40 });
    console.log(result.content[0].text); // "42"

    Playwright MCP also supports WebMCP by default, with page-defined tools offered to the agent as webmcp_<tool>. Pass --no-webmcp to opt out.

    playwright-cli exposes them as well:

    playwright-cli webmcp-list
    playwright-cli webmcp-call search_catalog --params '{"query":"cats"}'

    Better videos

    Videos can now be recorded at a custom frame rate, and the decorations for actions are styled with plain CSS:

    // playwright.config.ts
    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      use: {
        video: {
          mode: 'on',
          size: { width: 1920, height: 1080 },
          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',
              },
            },
          },
        },
      },
    });
    • New fps option in testOptions.video, recordVideo and screencast.start(). Firefox and WebKit currently capture up to 25 frames per second.

    • New style option takes CSS declarations for the point marker, the target highlight and the action title. It replaces the fontSize option, which is now deprecated.

    • The cursor stays visible at the last action point, survives navigations and travels along a natural, eased path.

    • Videos are encoded with VP9 instead of VP8, which takes less CPU and produces smaller files of the same or better quality.

    • All video options are also available in Playwright MCP and playwright-cli.

    Locator.within()

    New locator.within() combines two locators that you already have, reading in the natural order "this button, within that dialog":

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

    Relative locators such as locator.nth() or locator.first() are resolved inside each parent separately, which makes column-like queries straightforward:

    // The third cell of every row, not the third cell in the table.
    const thirdColumn = page.getByRole('cell').nth(2).within(page.getByRole('row'));
    await expect(thirdColumn).toHaveText(['Apple', 'Banana', 'Cherry']);

    New APIs

    Breaking changes

    • breaking

      screen property is now forwarded from the device descriptors. If you use ...devices['Desktop Chrome'] and alike, window.screen and media queries now see the emulated screen size. You can opt-out by explicitly setting screen to undefined:

      // playwright.config.ts
      export default defineConfig({
        use: {
          ...devices['Desktop Chrome'],
          screen: undefined,
        },
      });
    • breaking

      JSX in your test files now follows your tsconfig.json. Playwright compiles JSX in test files according to the jsx, jsxFactory, jsxFragmentFactory and jsxImportSource tsconfig options, and defaults to the automatic runtime from react/jsx-runtime.

    • breaking

      --update-snapshots=missing now passes the test run. Tests that only create missing snapshots now pass in the 'missing' mode of testConfig.updateSnapshots, so that CI can generate new snapshots and verify the existing ones in a single run. The mode used when the option is not specified is now called 'default' and behaves as before: missing snapshots are written and the test fails.

    • breaking

      Elements inside hidden iframes are considered hidden. Elements inside an iframe that is not visible, for example with visibility: hidden, are now considered hidden by actions, locator.isVisible() and expect(locator).toBeVisible().

  3. 1.63.0

    4 September 2026
    Tests that access a shared resource — an external service, a global account setting — can now declare a named lock.

    Test locks

    Tests that access a shared resource — an external service, a global account setting — can now declare a named lock. Tests that share a lock name never run concurrently, across files, workers and projects, while everything else keeps running in parallel:

    test('update user settings', { lock: 'user-settings' }, async ({ page }) => {
      // never runs at the same time as other tests holding 'user-settings'
    });

    A test can hold multiple locks, and test.describe() accepts a lock for the whole group. Learn more about test locks.

    Locate across frames

    page.frameLocator() and frame.frameLocator() called without a selector search in any frame of the subtree, so you no longer need to locate the iframe first:

    // Finds the button in any frame on the page.
    await page.frameLocator().getByRole('button').click();

    The rest of the locator resolves inside a single frame, just like a regular locator, and an error is thrown when it matches elements in several frames.

    Visible-only locators

    New locator.visible() returns a locator that matches only visible elements. It is the recommended replacement for the :visible CSS pseudo-class:

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

    Step params and subtitles

    Steps now carry structured data for reporters. Playwright API steps report the target locator and call arguments, and test.step() accepts subtitle and params options for your own steps:

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

    Reporters receive them via testStep.subtitle and testStep.params. For Playwright API steps, the subtitle is the locator or the navigation url — for example, Click with subtitle getByRole('button'). Both are rendered next to the step title in the trace viewer and the HTML report.

    Aria and screen snapshots in traces

    The snapshots option of tracing.start() and the testOptions.trace fixture option now accept an object selecting what to capture on every action:

    // playwright.config.ts
    export default defineConfig({
      use: {
        trace: {
          mode: 'on',
          snapshots: { dom: true, aria: true, screen: true }
        },
      },
    });

    With aria and screen snapshots recorded, the new Display Aria mode in the trace viewer shows the action screenshot side by side with the aria snapshot, and hovering an aria node highlights it on the screenshot.

    New APIs

    Browser and Context

    Locators

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

    Command line

    • npx playwright install --no-remove keeps the browsers of other Playwright installations instead of removing them.

  4. 1.62.1

    30 July 2026
    [Regression]: tsconfig "extends" bare specifier isn't resolved via node_modules walk-up like tsc (fatal since 1.62)

    Bug Fixes

    • [Regression]: tsconfig "extends" bare specifier isn't resolved via node_modules walk-up like tsc (fatal since 1.62)

    • [Regression]: directory-form tsconfig project references ("path": "../pkg") fail to resolve (fatal since 1.62)

    • Accessibility snapshot drops button name when text is nested inside spans with aria-hidden SVG

    • [Regression]: page.evaluate() arg of a branded primitive type (string & { brand }) no longer type-checks since 1.62

    • [BUG]Image-type actionable elements are not presented in the snapshot.

  5. 1.62.0

    24 July 2026
    Component testing moves to a stories and galleries model.

    New component testing model

    Component testing moves to a stories and galleries model. A story wraps your component in one specific scenario — hard-coded props, mock data, providers — and a gallery page that you serve renders stories on demand. The new fixtures.mount() fixture navigates to the gallery, mounts a story by id, and returns a Locator scoped to the story's root element:

    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, letting you cancel long-running actions, navigations, waits, and assertions:

    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() and expect(locator).toHaveScreenshot() can now store snapshots in the WebP format — just give the snapshot a .webp name:

    // 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() and [locator.screenshot() (playwright.dev/docs/api/class-locator) 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() hook runs after the configuration is resolved and before reporter.onBegin(), letting a reporter mark individual tests as skipped, excluded, fixed, or failing through a TestRun object:

    class MyReporter {
      async preprocess({ config, suite, testRun }) {
        for (const test of suite.allTests()) {
          if (shouldSkip(test))
            testRun.skip(test);
        }
      }
    }

    Isolated retries

    New testConfig.retryStrategy controls when failed tests are retried. The default 'immediate' retries as soon as a worker is free; 'isolated' runs all retries at the end, one by one in a single worker, to minimize interference with the rest of the suite:

    // playwright.config.ts
    export default defineConfig({
      retries: 2,
      retryStrategy: 'isolated',
    });

    New APIs

    Browser and Context

    • New option credentials includes the context's virtual WebAuthn Credentials (passkeys) in the storage state, so they can be persisted and re-seeded into later contexts.

    Actions

    • New scroll option ("auto" | "none") on actions to opt out of Playwright's automatic scroll-into-view.

    Network

    Evaluation

    Command line & MCP

All 191 releases

Major versions

  • 1.xsince 6 May 2020 · latest 1.64.1 · 155 releases
  • 0.xsince 23 January 2015 · latest 0.18.0 · 36 releases

Quality and security signals

What npm and deps.dev say about the latest release. Signals, not a verdict.

Reading npm and deps.dev…

Registry facts last checked 15 October 2026. Releases and advisories last read 15 October 2026.

Know when your own dependencies move

Inlinr tracks your coding time automatically. Switch dependency tracking on for a project and it reads that repository's manifest to show what is behind and what has been deprecated — off by default, one project at a time.