Automated Testing Playwright

Playwright 1.61 Release Update: New Features, Benefits, and Upgrade Tips

Playwright 1.61 is one of those releases that may look small at first, but for test automation teams, it solves some very real day-to-day problems. If your team works with passkey login, browser storage, live UI updates, flaky retries, or CI debugging, this release is more useful than it looks in a quick changelog scan.

What makes this update interesting is not only the new APIs. It is the fact that they reduce common testing workarounds. Instead of adding more helper code, more page.evaluate() calls, or more custom debugging logic, Playwright 1.61 gives cleaner built-in ways to handle these situations.

In this blog, we will go through the Playwright 1.61 release update in a practical way. We will cover the new features, proper code examples, benefits for test automation teams, limitations, browser version updates, upgrade considerations, best practices after upgrading, and a quick comparison with alternatives like Selenium and Cypress where it makes sense.

Why Playwright 1.61 release update matters

Many automation issues do not come from normal click and type scenarios. They usually come from the parts that are harder to automate properly, like password less login, token setup, session handling, live updates, and retry-only CI failures. Playwright 1.61 focuses on exactly these areas, which is why it feels practical for real QA teams.

This release is also important because it reduces custom framework code. Teams often spend a lot of time maintaining helpers for login bypass, storage setup, socket debugging, and flaky test evidence collection. Playwright 1.61 moves several of those needs into first-class APIs and runner options.

New features in Playwright 1.61 

The Playwright 1.61 release update includes a set of changes that improve both test authoring and test debugging. The main additions are WebAuthn passkey testing, direct Web Storage APIs, new network response details, better video retention modes, WebSocket support in trace and HAR recordings, Ubuntu 26.04 support, and updated browser engines. 

Here is the short version of what changed:

  • browserContext.credentials for passkey and WebAuthn flows.
  • page.localStorage and page.sessionStorage APIs for browser storage access.
  • apiResponse.securityDetails() and apiResponse.serverAddr() for deeper network visibility.
  • New video retention modes like retain-on-first-failure and retain-on-failure-and-retries.
  • WebSocket requests added to HAR and trace recordings.
  • Ubuntu 26.04 support and newer browser versions.

Now let us go through each change with actual examples.

Playwright passkey testing with WebAuthn

Passkey testing is one of the most important additions in Playwright 1.61. Modern apps are moving toward passwordless login because it improves security and user experience, but it has always been harder to automate than standard username-password flows. Playwright now adds a virtual authenticator through browserContext.credentials, which makes passkey-based testing much more realistic in CI and local automation.

Why this feature matters

Before this change, many teams handled passkey testing in one of three weak ways. They either skipped the real flow, mocked the flow too much, or created a hidden backdoor login only for automation. All three options reduce confidence because the test no longer matches the real user path.

With Playwright 1.61, you can keep the automation much closer to the real login behavior. That makes it more useful for fintech apps, healthcare portals, admin platforms, and any product where secure authentication is an important part of the user journey.

Example of Playwright passkey testing

For a real, publicly usable passkey test, you can use webauthn.io, a public demo site built specifically for testing the WebAuthn specification, including passkey registration and login. This is the same kind of site QA teams use to try out virtual authenticator behavior.

Note: `browserContext.credentials` in Playwright 1.61 wraps this same CDP-based virtual authenticator flow into a simpler API. The example above shows the underlying mechanics using webauthn.io, a site made specifically for testing this behavior, so you can run it and see a real registration succeed without a physical security key.

import { test, expect } from '@playwright/test';

test('Register and verify a passkey using virtual authenticator', async ({ page, context }) => {

    const client = await context.newCDPSession(page);
    await client.send('WebAuthn.enable');
    const result = await client.send('WebAuthn.addVirtualAuthenticator', {

        options: {

            protocol: 'ctap2',
            transport: 'internal',
            hasResidentKey: true,
            hasUserVerification: true,
            isUserVerified: true,
        },
    });

    await page.goto('https://webauthn.io/');
    await page.getByPlaceholder('Username').fill('playwright-test-user');
    await page.getByRole('button', { name: 'Register' }).click();

    // The virtual authenticator answers the browser's WebAuthn prompt automatically

    await expect(page.getByText('Success!')).toBeVisible({ timeout: 10000 });
    await client.send('WebAuthn.removeVirtualAuthenticator', {
        authenticatorId: result.authenticatorId,
    });
});

Real project example

Suppose your team is testing an employee portal where admins must use passkeys before accessing payroll details. In older automation, the team may have bypassed this step completely using a pre-created session token. With Playwright 1.61, the same team can automate the proper authentication flow using the same virtual authenticator pattern shown above, applied to their own app’s registration and login endpoints. 

Playwright Web Storage API for localStorage and sessionStorage 

Playwright 1.61 introduces direct Web Storage APIs through page.localStorage and page.sessionStorage. This is a simple but very useful improvement because many test suites rely on storage setup for auth tokens, feature flags, user preferences, and onboarding states. 

Why this feature matters

Earlier, most teams used page.evaluate() to read or write storage values. That works, but it spreads small browser-side scripts across the suite. Over time, those helpers become harder to read and maintain, especially for new team members. 

The new storage APIs make the intent much clearer. Instead of injecting JavaScript, the test directly says that it wants to set or read local or session storage.

Example of Playwright Web Storage API

We will use Sauce Labs’ public demo site, saucedemo.com, which is a real, stable practice site built for test automation. After a successful login, Sauce Demo stores the logged-in username in `sessionStorage` under the key `session-username`, which makes it a perfect real example for this feature. 

import { test, expect } from '@playwright/test';

test('Login and read session storage using Web Storage API', async ({ page }) => {

    await page.goto('https://www.saucedemo.com/');
    await page.locator('#user-name').fill('standard_user');
    await page.locator('#password').fill('secret_sauce');
    await page.locator('#login-button').click();
    await expect(page.locator('.inventory_list')).toBeVisible();

    // Playwright 1.61 Web Storage API - read sessionStorage directly, no page.evaluate() needed 

    const loggedInUser = await page.sessionStorage.getItem('session-username');
    expect(loggedInUser).toBe('standard_user');

});

Here is a second example that writes to `localStorage` before the page loads, using Sauce Demo's cart page: 

import { test, expect } from '@playwright/test';

test('Set a local storage value before visiting the page', async ({ page }) => {
    await page.goto('https://www.saucedemo.com/');

    // Playwright 1.61 Web Storage API - write to localStorage directly 

    await page.localStorage.setItem('qa-note', 'seeded-by-playwright-1-61');
    const savedValue = await page.localStorage.getItem('qa-note');
    expect(savedValue).toBe('seeded-by-playwright-1-61');
});

Real project example

In e-commerce projects, QA teams often need to verify session tokens, region settings, or feature flags stored in the browser. The Sauce Demo example above shows the exact same pattern: log in, then read the value the app already stores in session storage, without writing a single line of `page.evaluate()`.

Playwright network and trace improvements

Playwright 1.61 adds more useful debugging data with apiResponse.securityDetails(), apiResponse.serverAddr(), and WebSocket requests inside HAR and trace recordings. These changes are especially useful for modern apps that depend on live updates or are deployed behind multiple infrastructure layers.

Why this feature matters

When tests fail in CI, the biggest problem is often not the failure itself. The biggest problem is missing context. If your app uses sockets or staging-only network routes, incomplete traces make debugging slow.

The new response metadata and WebSocket trace support help reduce that gap. Teams can see more of what happened between the browser and the backend during the failing run.

Practical example of trace capture with a real UI flow

This example runs a real Sauce Demo checkout flow with tracing turned on, so you can open the trace afterward and inspect every network request, including any WebSocket traffic your own app might use: 

import { test, expect } from '@playwright/test';

test('Add item to cart with trace enabled', async ({ page, context }) => {

    await context.tracing.start({ screenshots: true, snapshots: true });
    await page.goto('https://www.saucedemo.com/');
    await page.locator('#user-name').fill('standard_user');
    await page.locator('#password').fill('secret_sauce');
    await page.locator('#login-button').click();
    await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
    await expect(page.locator('.shopping_cart_badge')).toHaveText('1');
    await context.tracing.stop({ path: 'trace.zip' });

});

Run `npx playwright show-trace trace.zip` after the test finishes to open the trace viewer and inspect the full network activity. 

Practical example of network response details

This example uses JSONPlaceholder, a free public REST API commonly used for testing, to show the new response metadata methods in action:

import { test, expect } from '@playwright/test';

test('Check response security and server details on a real API', async ({ request }) => {

    const response = await request.get('https://jsonplaceholder.typicode.com/posts/1');
    expect(response.ok()).toBeTruthy();

    // Playwright 1.61 network enhancements 

    const securityDetails = await response.securityDetails();
    const serverAddress = await response.serverAddr();
    console.log('securityDetails:', securityDetails);
    console.log('serverAddress:', serverAddress);
    const body = await response.json();
    expect(body.id).toBe(1);

});

Real project example

This is useful when a test fails only in staging, only behind a proxy, or only for one geographic environment. QA engineers can collect more useful evidence before sending the issue to developers or DevOps teams.

Playwright test runner updates for flaky test debugging

Playwright 1.61 also improves the test runner. The release adds new video retention modes, better AggregateError reporting in testInfo.errors, support for expect.soft.poll(…), fullConfig.argv, and a -G shorthand for –grep-invert.

Why this feature matters

Flaky tests are not only about failure. They are about poor evidence. If your runner stores too much data, you drown in artifacts. If it stores too little, you lose the one piece of evidence that could explain the issue. 

The new retention modes give a better balance. Teams can keep useful retry and failure recordings without keeping everything.

Practical example of video retention settings

This `playwright.config.ts` example keeps videos only for failures and retries, which you can test directly against Sauce Demo:

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

export default defineConfig({
    retries: 2,
    use: {

        baseURL: 'https://www.saucedemo.com/',
        video: 'retain-on-failure-and-retries',
        trace: 'retain-on-failure',
    },
});

Practical example of soft polling 

This example waits for the Sauce Demo cart badge to update without failing the test too early:

import { test, expect } from '@playwright/test';

test('Wait for cart badge to update using soft polling', async ({ page }) => {

    await page.goto('https://www.saucedemo.com/');
    await page.locator('#user-name').fill('standard_user');
    await page.locator('#password').fill('secret_sauce');
    await page.locator('#login-button').click();
    await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
    await expect.soft.poll(async () => {
        return await page.locator('.shopping_cart_badge').textContent();
    }).toBe('1');

});

Example of grep-invert shorthand

This is a small change, but still useful in CI when you want to skip a tagged group of tests: 

npx playwright test -G @visual

This command excludes tests matching the grep pattern instead of including them.

Real project example

Suppose your checkout test fails only on the first retry in CI. With the new retention modes, your team can keep the first failure video and retry evidence, exactly as configured in the example above.

Playwright browser and platform support

Playwright 1.61 adds support for Ubuntu 26.04 and includes other browser and screencast improvements such as an `artifactsDir` option for `connectOverCDP()`, better screencast cursor visibility, and frame timestamps in `screencast.start()`.

Example of platform upgrade use

If your CI image is moving to Ubuntu 26.04, the rollout can be simple: 

  1. Upgrade Playwright to 1.61.
  1. Update the Docker or Runner image. 
  1. Run smoke tests first, for example, the Sauce Demo login test shown earlier. 
  1. Run cross-browser and flaky suites next. 
  1. Review screenshots, traces, and videos for any browser-related differences.

Example Docker base image

FROM ubuntu:26.04
RUN apt-get update && apt-get install -y curl git
RUN npm install -D @playwright/test
RUN npx playwright install --with-deps

This is not a full production Dockerfile, but it shows the typical direction teams follow when refreshing CI images.

Updated browser versions in Playwright 1.61

Playwright 1.61 ships with updated browser engines. Release coverage for this version lists Chromium 149.0.7827.55, Mozilla Firefox 151.0, and WebKit 26.5.

These version updates matter because browser changes can surface issues in test timing, rendering, focus behavior, or animations. Even when the Playwright APIs themselves do not break, newer browser engines can still reveal assumptions in an older test suite.

Browser Version in Playwright 1.61 
Chromium 149.0.7827.55 
Firefox 151.0 
WebKit 26.5 

Benefits for test automation teams

Playwright 1.61 gives several benefits that matter in daily QA work, not just in release note summaries.

Cleaner test code

The Web Storage API reduces page.evaluate() usage for storage work. That makes tests easier to read, easier to review, and easier to maintain over time.

Better support for modern authentication

Passkey support means teams can automate secure login flows more realistically. This is especially useful for apps that want stronger authentication without relying on test-only shortcuts.

Better debugging evidence

WebSocket trace coverage, response metadata, and smarter video retention all improve the quality of failure investigation. This helps teams reduce time spent reproducing issues manually.

Better CI alignment

Ubuntu 26.04 support and updated browser versions help teams keep their test stack current. That reduces long-term maintenance pain when environments need to be refreshed.

Limitations of Playwright 1.61 changes

Even though Playwright 1.61 is useful, it is not magic. There are still limits and teams should be aware of them. 

Passkey testing still needs app-specific setup

The new virtual authenticator support is powerful, but WebAuthn flows still depend on how your app is implemented. Teams will still need to understand their authentication flow properly before writing stable tests.

Better APIs do not fix weak test design

If a suite already has unstable selectors, poor waits, or weak test data handling, new release features will not solve those core issues. The release improves tools, but it does not replace good automation design.

Browser updates can surface old assumptions

Updated browser versions are a benefit, but they can also expose hidden test flakiness. A test that relied on timing luck may start failing after the browser upgrade even if the app is unchanged.

Playwright 1.61 comparison with Selenium and Cypress

Playwright 1.61 does not replace Selenium or Cypress for every team, but this release strengthens Playwright in some areas where modern apps need more built-in support.

Area Playwright 1.61 Selenium Cypress 
Passkey testing Built-in virtual authenticator support in this release Often requires separate setup or browser-specific handling More limited for full browser-level auth flows compared with Playwright’s newer support 
Web storage access Direct localStorage and sessionStorage API Usually handled with script execution or custom logic Commonly possible, but different model and limitations apply 
Trace and debugging Strong trace tools, HAR, WebSocket visibility in this release Depends more on external tooling and framework layers Good runner experience, but different architecture and browser scope 
Browser coverage Chromium, Firefox, WebKit with one API Broad ecosystem support, especially enterprise setups Strong for web app testing, but not the same multi-engine model as Playwright 

The practical takeaway is simple. If your team is already on Playwright, version 1.61 adds useful features without changing your whole workflow. If your team is comparing tools, this release makes Playwright even more attractive for modern authentication, state-heavy front ends, and built-in debugging.

Things to consider before upgrading to Playwright 1.61

Before upgrading, teams should review a few practical points.

Check authentication complexity

If your app uses WebAuthn or passkeys, identify the exact flows first. Registration, login, and re-authentication may all behave differently, so it is better to map them before rewriting tests.

Review old helper utilities

If your framework already has storage helpers, auth bypass helpers, or custom trace setup, decide which parts should be replaced and which parts should stay. Upgrading is a good time to remove unnecessary framework debt. 

Re-run browser-sensitive tests

Visual tests, animation-heavy tests, and timing-sensitive tests should be validated after the browser update. Browser engine changes are one of the most common reasons a safe-looking upgrade still needs a few test fixes.

Plan CI artifact usage

If you enable more retention, make sure your CI storage policy is still sensible. Better artifacts are useful, but uncontrolled artifact growth creates a different maintenance problem.

Best practices after upgrading to Playwright 1.61

Once the team upgrades, the next step is using the new features properly instead of just keeping the old test style on the new version. 

Replace storage workarounds gradually

Do not rewrite the whole suite in one go. Start by replacing the most repeated and most confusing storage helpers with the new Web Storage API.

Use passkey automation only where it adds value

Not every test needs to cover the full auth ceremony. Keep a few strong passkey end-to-end flows, then use good session reuse where appropriate to keep the suite fast.

Tune artifacts for signal, not volume

Use trace and video retention settings based on real debugging needs. Keep enough evidence to investigate flaky failures, but avoid storing artifacts for every passing run.

Validate cross-browser behavior early 

Since browser versions are updated, run smoke tests across Chromium, Firefox, and WebKit after the upgrade. Catching browser-specific issues early is much cheaper than finding them later in a full regression cycle.

How to use Playwright 1.61 in real projects 

If this upgrade is planned for a real product, the best path is to adopt it in stages.

A practical rollout looks like this:

  1. Upgrade Playwright on a branch. 
  1. Run smoke tests across all configured browsers. 
  1. Test passkey and authentication flows next. 
  1. Replace a few old storage helpers with the new APIs. 
  1. Tune trace and video settings for flaky CI suites. 
  1. Roll out to the full regression pipeline after confidence improves. 

This staged approach works well because it reduces risk while still letting the team get quick value from the new features.

Conclusion 

Playwright 1.61 is a practical release for modern test automation teams. The biggest improvements are passkey testing, direct Web Storage access, better trace coverage for WebSocket traffic, stronger flaky test evidence, Ubuntu 26.04 support, and updated browser engines. 

The release is especially valuable for teams that test secure login flows, state-heavy front-end apps, and real-time user experiences. It also gives a good chance to clean up older helper code and improve CI debugging without changing the whole framework design. 

For teams already using Playwright, version 1.61 is not just another update. It is a very usable improvement in the parts of automation that usually become painful first.

Witness how our meticulous approach and cutting-edge solutions elevated quality and performance to new heights. Begin your journey into the world of software testing excellence. To know more refer to Tools & Technologies & QA Services.

If you would like to learn more about the awesome services we provide,  be sure to reach out.

Happy Testing 🙂