What's new in Playwright 1.62: MCP in the box, isolated retries, and a patch you should not skip

The agent tooling moves into core, retries get a diagnostic mode, and 1.62.0 shipped three regressions that 1.62.1 fixes.

Cover image for What's new in Playwright 1.62: MCP in the box, isolated retries, and a patch you should not skip

tldr: The MCP server and a CLI now ship inside the Playwright package, so npx playwright mcp runs with nothing else installed. Retries get an 'isolated' strategy that separates a flaky test from a test with a concurrency bug. Component testing is rebuilt on stories and galleries. And 1.62.0 shipped three regressions, two of them in TypeScript config resolution, so install 1.62.1 instead.


The release that folds the agent stack into the box

Playwright 1.62.0 shipped on 24 July. The patch, 1.62.1, landed on 30 July and is the version you want. Browsers are Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5. Debian 11 support is gone.

Most coverage will lead with component testing, because it is the largest API change. For a suite that already exists, the more consequential change is smaller and easier to miss: the Model Context Protocol server and a command-line interface are now part of the core package rather than things you install alongside it.

The pattern across the last few releases has been steady. 1.59 built the agentic primitives. 1.61 retired the setup hacks around passkeys, storage, and video retention. 1.62 stops treating the agent tooling as an add-on. Read the sections below in that order of importance, not in the order the changelog lists them.


MCP and the CLI ship in core

Both run straight out of the package:

npx playwright mcp
npx playwright cli

Until now, driving a browser from an agent over MCP meant a separate package whose version you kept in step with your Playwright install by hand. Those are one artifact now. The MCP server moves with the browser builds that ship beside it.

That kills a specific and irritating class of bug. When the agent's browser and the runner's browser were different builds, the two disagreed about what the page contained, and the failure surfaced as a mystery in the agent's reasoning rather than as a version error. There was nothing in the stack trace pointing at the real cause.

If you are deciding whether to drive tests through the CLI or through MCP, the tradeoffs in Playwright CLI vs. Playwright MCP still hold. What changed is that the setup cost for both is now zero.


Isolated retries turn a pass rate into a diagnosis

testConfig.retryStrategy is new, and the 'isolated' mode defers every retry to the end of the run, executing them sequentially in a single worker.

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

That reads like a scheduling detail, but what it actually gives you is a debugging instrument.

Default retries re-run a failed test immediately, inside the same parallel context that just produced the failure. When it passes on attempt two, you have learned almost nothing. The test might be flaky on its own terms. It might have collided with a neighbouring worker over a shared record, a session, or a port, and simply got luckier. Both outcomes render as the same green tick.

Isolated retries split those cases apart. A test that fails under parallelism and passes alone at the end is not a flaky test. It has a concurrency bug, and the shared resource is what needs fixing. A test that fails in both conditions is flaky for real reasons. One config line separates a category most teams have been tracking as a single number.

This matters because retry counts are the metric teams most often use to declare a suite healthy, and they are the metric that conceals the most. We put numbers on what that concealment costs in the true cost of flaky tests.


AbortSignal is not another timeout

Most operations now take a signal option carrying an AbortSignal. It cancels long-running actions, navigations, waits, and assertions, and it does so without touching your default timeouts.

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

The two mechanisms look alike and solve different problems. A timeout is a policy fixed before the run starts: this action gets eight seconds. An abort is a decision made mid-run, by something outside the test, that the remaining work no longer needs to finish. CI cancels the job. An upstream service goes down and every remaining assertion is doomed anyway. A run blows its time budget.

Expressing that before 1.62 meant tightening timeouts until they doubled as a kill switch, which made the suite brittle on slow infrastructure. The two concerns are now separate, which is how they should have been all along.


Component testing moves to stories and galleries

This is the big API change, and it will cost you time if you have an existing component suite.

A story is a named export that wraps a component in one scenario, with hard-coded props, mock data, and whatever providers it needs. Stories live in *.story.tsx files:

// src/components/Button.story.tsx
import { Button } from './Button';

export const Primary = () => <Button title='Submit' />;
export const Disabled = () => <Button title='Submit' disabled />;

A gallery is a page served by your dev server that renders stories on demand. It exposes window.mount({ story, props }) and window.unmount(), lives at playwright/gallery/, and the mount fixture finds it automatically.

The fixture navigates to the gallery and hands back a Locator scoped to the story's root:

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

Stories take props, and the returned component can be updated or torn down in place:

const component = await mount<typeof WithTitle>('Button/WithTitle', { title: 'Hello' });
await component.update({ title: 'Updated' });
await component.unmount();

If you have been running component tests in Storybook and end-to-end tests in Playwright, these two stacks now look almost the same. Consolidating on one of them is a more reasonable conversation than it was a month ago. End-to-end tests are untouched by any of this.


Install 1.62.1, not 1.62.0

The changelog will not tell you this part, because it happened after the changelog was written.

Version 1.62.1 shipped on 30 July, six days after the minor, and fixed five issues. Three were regressions that 1.62.0 introduced:

  • #41989, tsconfig extends with a bare specifier failing to resolve through a node_modules walk-up
  • #41998, directory-form tsconfig project references failing to resolve
  • #42000, page.evaluate() arguments of a branded primitive type no longer type-checking

Two of those three are TypeScript configuration resolution. If your project uses extends with a package specifier, or directory-form project references, and a great many monorepos use both, 1.62.0 may not resolve your config at all.

The patch fixed two more issues that are not regressions and matter more than their numbers suggest:

  • #41985, accessibility snapshots dropping button names when the text sat inside a span beside an aria-hidden SVG
  • #42013, image-type actionable elements missing from snapshots

Both land on the same surface. Aria snapshots are what agent-driven execution reads to decide what is on the page, and 1.60 added bounding boxes to those snapshots specifically for AI consumption. When a button loses its name in the snapshot, an agent does not see a slightly degraded page. It sees a page with no button, and then reasons confidently from that. Passmark, our open-source Playwright-based engine, resolves natural-language steps against exactly this representation, which makes snapshot fidelity a correctness property rather than a cosmetic one.

Six days from minor to patch is a fast turnaround and a credit to the team. It is also the argument for letting a minor settle before it goes near a suite that gates your releases.


Smaller wins worth knowing

WebP arrives for screenshots, lossless by default in visual comparison, lossy in standalone captures:

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

Reporters get a preprocess() hook that runs after config resolution and before onBegin(), with the power to mark tests skipped, excluded, fixed, or failing:

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

The rest, briefly. Storage state now carries credentials, so WebAuthn passkeys persist across contexts, finishing what the 1.61 virtual authenticator started. A scroll option set to 'auto' or 'none' lets actions opt out of scrolling the target into view. apiResponse.timing() returns resource timing. locator.waitForFunction() waits for a function to return truthy. page.evaluate() and addInitScript() now accept functions in their argument payloads, not only as the code they run. The HTML reporter's mergeFiles option can now be set in config instead of only on the command line. Headless mode no longer shares the operating system clipboard.


What is overhyped, what is underrated

The changelog gives every line equal weight. They are not equal.

Underrated: bundled MCP and CLI. No new API to learn, no migration, and it removes a whole failure mode from agent-driven runs. The least glamorous item in the release and the one most likely to save you a bad afternoon.

Underrated: retryStrategy: 'isolated'. One line of config that converts your flakiest tests from a number into a diagnosis. Nothing else in this release changes what you understand about your own suite.

Properly hyped, but narrow: stories and galleries. A real improvement, and irrelevant if you do not run component tests. If you do, it is the only item here that costs you a migration.

Overhyped: WebP screenshots. Smaller artifacts are pleasant. Nobody upgrades for this.

Skip the excitement: mergeFiles in config, apiResponse.timing(), clipboard isolation. Reach for them when a specific problem calls, not as a reason to move.


What to adopt first

Today: pin 1.62.1. If you already installed 1.62.0, this is the whole task. Two TypeScript regressions are not worth living with for a week.

This week: retryStrategy: 'isolated'. One line, and the next flaky failure arrives already classified.

This week, if you run agents: drop the standalone MCP package. Switch to npx playwright mcp and delete a version you were pinning by hand.

When you have a clear afternoon: the component testing migration. Structural, not mechanical. Do not start it the day before a release.


If you are upgrading from 1.61

1.62 documents no breaking changes of its own beyond dropping Debian 11. If you are on Debian 11, move the OS before you move Playwright.

Pin the patch rather than the minor:

npm install -D @playwright/test@1.62.1
npx playwright install

Yarn users run yarn add -D @playwright/test@1.62.1 and then npx playwright install. Run the suite afterwards. If your build fails on config resolution, you are on 1.62.0.


FAQs

What's new in Playwright 1.62?

Playwright 1.62 bundles an MCP server and CLI into the core package, adds testConfig.retryStrategy with an 'isolated' mode, adds AbortSignal cancellation through a signal option on most operations, rebuilds component testing around stories and galleries with a new mount fixture, and adds WebP screenshots, a reporter.preprocess() hook, credentials in storage state, a scroll option, apiResponse.timing(), and locator.waitForFunction(). It bundles Chromium 151.0.7922.34, Firefox 153.0, and WebKit 26.5, and drops Debian 11.

Should I install 1.62.0 or 1.62.1?

1.62.1. The 1.62.0 release introduced three regressions, two of them in TypeScript config resolution, which can stop a monorepo from resolving its config at all. The patch shipped on 30 July, six days later. There is no reason to install the minor now.

How do I upgrade to Playwright 1.62?

Run npm install -D @playwright/test@1.62.1 followed by npx playwright install to fetch the matching browser builds. Pin the patch version explicitly. Upgrade off Debian 11 first, since 1.62 no longer supports it.

Does Playwright 1.62 break existing component tests?

Almost certainly. Component testing was rebuilt around stories in *.story.tsx files and a gallery served by your dev server, with mount returning a Locator scoped to the story root. Existing component suites need reworking rather than a find and replace. End-to-end tests are unaffected.

Do I still need a separate Playwright MCP server?

No. Playwright 1.62 ships the MCP server in the core package, and npx playwright mcp runs it with no extra install. The server version now tracks your Playwright version and its browser builds, so the agent and the runner cannot drift apart.

What is retryStrategy: 'isolated' for?

Diagnosis rather than pass rates. It defers every retry to the end of the run in a single worker, so a test that only fails under parallel execution becomes distinguishable from one that is flaky on its own. The first is a concurrency bug in your suite or fixtures. The second is a real test defect. Default retries make them look identical.

How does Bug0 keep tests current across Playwright releases?

When Playwright ships a release like 1.62, a suite written against older APIs starts to drift, and the drift is invisible until something fails. With Bug0, a forward-deployed engineer plans your coverage and builds the suite on Passmark, our open-source Playwright-based engine. The engine runs the suite on every deploy and self-heals it when your UI moves, and the engineer verifies every result before it reaches your team. You get each release's new capabilities without owning the upgrade work. That is what Bug0 Managed covers.


Playwright keeps moving in one direction: fewer things you have to bolt on, more first-party APIs for what teams already do. 1.62 takes the agent tooling off the side of the plate and puts it in the package. Pin 1.62.1, turn on isolated retries, and leave the component migration for a week when nothing is shipping.

playwrightTestingautomationAI
About the author
Sandeep Panda
Sandeep PandaCo-founder & CTO, Bug0

Sandeep Panda is the CTO and Co-founder of Bug0, where he leads engineering and architects Passmark, the open-source AI regression testing framework that powers the platform. He previously co-founded Hashnode and served as its CTO, scaling the developer blogging platform to millions of users. A software engineer with a Computer Science background, he is the author of AngularJS: Novice to Ninja and co-author of Jump Start HTML5 for SitePoint. He writes about Playwright, agentic testing, and building reliable AI-powered test infrastructure.

Ship every deploy with confidence.

Bug0 gives you a dedicated AI QA engineer that tests every critical flow, on every PR, with zero test code to maintain. 200+ engineering teams already made the switch.

From $2,500/mo. Full coverage in 7 days.

Go on vacation. Bug0 never sleeps. The AI tests every commit, every deploy, every schedule. Your forward-deployed engineer reviews every failure and files the bugs. Coverage holds while you're off the grid.

Go on vacation.
Bug0 never sleeps.

The AI tests every commit, every deploy, every schedule. Your forward-deployed engineer reviews every failure and files the bugs. Coverage holds while you're off the grid.