The Testing Academy · AI for QA

Playwright 1.62 for QA

The densest tester-facing release in a long while. Isolated retries that tell flake from failure, virtual passkeys that make WebAuthn login testable, a new component testing model, and the MCP server bundled into the runner you already install. Feature by feature, then the adoption order.

Flake control Passkey testing Component model npx playwright mcp

Playwright 1.62 is the densest tester-facing release in a long while: flake control, passkey testing, a new component model, and the MCP server now in the box.

1.62_

Playwright 1.62 for QA

the release where the runner grew agent hands

One minor version, four tester-sized gifts: isolated retries that separate flake from failure, virtual passkeys that make WebAuthn login testable, a new component testing model, and the MCP server bundled into the package you already install.

Isolated retries

retry at the end, alone

Passkeys

WebAuthn, finally testable

Component model

stories, galleries, mount()

MCP in the box

npx playwright mcp

The upgrade-and-adopt path

1. Upgrade
Two commands
npm i -D @playwright/test@latest

Then npx playwright install

2. Stabilize
Isolated retries
retryStrategy: 'isolated'

Retries run at the end, sequentially

3. Cover
Passkey login
context.credentials.create()

Virtual authenticator per context

4. Filter
Quarantine hook
Reporter.preprocess()

Skip lists as reporter code

5. Shrink
WebP snapshots
toHaveScreenshot('x.webp')

Comparisons stay lossless

6. Connect
Agent hands
npx playwright mcp

Bundled server for agent browser control

Adopt one feature at a time and measure; the release is additive, no breaking changes called out.

Release RadarIllustration

what ships in 1.62

retryStrategy: 'isolated'flake
context.credentials.*auth
fixtures.mount()ct
signal: AbortSignaldx
Reporter.preprocess()dx
npx playwright mcpagent

browser builds

Chromium 151

also inside

Firefox 153WebKit 26.5

upgrade › run suite › compare › adopt next

Which 1.62 feature do we roll out first on the flaky checkout suite?
Radaradoption order
  • Suite retries pass inline on quiet machines: classic contention flake
  • Start with retryStrategy: 'isolated', one config line
  • Next payoff: passkey spec, login is WebAuthn-only for new users
  • WebP snapshots later: assertions unchanged, repo just shrinks

reasoning traced to

[1]flakeretries pass when run alone1st
[2]authpasskey flow untested today2nd
[3]sizesnapshot repo growth4th
adopt one feature, measure a week...

The release in six tokens

isolated

retries without neighbors

passkeys

virtual authenticators

mount()

stories and galleries

signal

cancel anything

webp

lighter snapshots

mcp

bundled agent server

What this page settles

  • When isolated retries beat inline retries
  • The passkey recipe, create() to storage state
  • What stories and galleries actually are
  • Quarantine lists as Reporter.preprocess() code
  • What npx playwright mcp replaces
  • A one-week, one-variable-at-a-time rollout

Quickstart (local)

# 1. upgrade the runner
npm i -D @playwright/test@latest
npx playwright install

# 2. first adoption, one line
retryStrategy: 'isolated'

# 3. give your agent the browser
npx playwright mcp

Why testers should care

Flake diagnosis, passkey coverage, and agent plumbing all landed in one minor version of the tool you already run. Our one-week rollout below is a proposal: adopt one feature at a time and the flaky suites and agent setups feel it first.

13features covered
7tabs
14diagrams
3browser builds
2upgrade commands

The headline features

FeatureWhat it gives you
Isolated retriesOpt-in retryStrategy: 'isolated' runs every retry at the end of the run, sequentially, in a single worker, so a retry pass finally means something.
WebAuthn passkeysVirtual authenticators through context.credentials, plus a credentials storage state option: log in once, reseed the passkey everywhere.
Component testing modelmount() opens a gallery page, mounts a story by ID, and returns a scoped locator, so component tests reuse your e2e locator and web-first assertion skills.
AbortSignal supportMost operations (actions, navigations, waits, assertions) accept a signal option, the standard web AbortController pattern, no custom API.
WebP screenshotsLossless .webp visual comparisons plus a quality knob on standalone shots, shrinking heavy snapshot repos.
Reporter.preprocess()A reporter hook that can mark tests skipped or excluded before the run, turning quarantine lists and sharding policies into reporter code instead of grep and CLI gymnastics.
Bundled MCP + CLInpx playwright mcp and npx playwright cli ship inside the package, no separate @playwright/mcp install needed (the standalone package still exists).
Smaller DX batchscroll option on actions, apiResponse.timing(), locator.waitForFunction(), functions as arguments to evaluate and init scripts, HTML report merge grouping, headless clipboard isolation.
npm i -D@playwright/test@latestpull the new runnernpx playwright installfetch the browser buildsNew builds readyChromium 151, Firefox 153, WebKit26.5
The whole upgrade is two commands

Upgrade in two commands

Nothing exotic about the move, it is the usual pair:

npm i -D @playwright/test@latest
npx playwright install
BrowserBuild in 1.62
Chromium151.0.7922.34
Mozilla Firefox153.0
WebKit26.5
Flake controlisolated retries, scroll opt-out, clipboard isolationAuth coveragevirtual passkeys + credentials storage stateNew surfacescomponent stories, WebP snapshotsAgent plumbingMCP server and CLI bundled in
The release in four themes
Tip. Version numbers are the topic here, and they keep moving: treat the official release notes page as the living reference and this guide as the QA reading of it.

Next up: the Flake killers tab, where isolated retries and the two quiet stability fixes earn their keep.

Three features in 1.62 aim straight at the noise that makes suites lie: isolated retries, an opt-out for auto scrolling, and clipboard isolation in headless mode.

Isolated retries: retry without the neighbors

One config line turns retries from a reflex into a controlled experiment:

export default defineConfig({
  retries: 2,
  retryStrategy: 'isolated',
});
  1. Fail during the run. A test fails while the suite is running in parallel as usual; nothing retries yet.
  2. Retry deferred. The retry is queued instead of firing immediately next to the workers that were hammering the machine.
  3. End of run, single worker. All queued retries execute sequentially in one worker, with no parallel neighbors competing for resources.
  4. Verdict. A pass on the quiet machine is strong evidence of neighbor noise; a repeat failure is strong evidence of a real bug worth a ticket.
Inline retries (default)Retry fires immediatelySame busy machine, same contentionFlake often repeatsFast feedback, noisy signalIsolated retriesRetries queue to the endSingle worker, sequentialSeparates failure from neighbor noiseOpt-in: retryStrategy 'isolated'VS
Same retry budget, two very different signals

The two quiet stability fixes

Suite runs in parallelfull speed, fullcontentionA test failscould be real, could benoiseRetry queued for theendnot re-run inlineSequential re-rundecidessingle worker, quietmachineflaky or truly broken?
The isolated-retry loop turns retries into a diagnosis
SymptomWhich 1.62 feature helps
The retry passes whenever the machine is quietIsolated retries (retryStrategy: 'isolated')
A click scrolls a sticky header over the targetscroll: "none" on the action
Clipboard tests fight the host machineHeadless clipboard isolation
Note. Retries hide bugs when they are used as a green button; use isolated retries to diagnose which failures are contention and which are code, then fix the root cause instead of raising the count.

Next up: the Passkeys tab, where virtual authenticators turn WebAuthn login into a spec you can actually write.

Passkey login flows stop being the untestable corner of the suite. Playwright 1.62 adds a Credentials API that spins up virtual WebAuthn authenticators per browser context, so the login your users actually perform becomes a spec you can write, run, and reuse like any other.

Virtual authenticators, per context

The whole setup is a fresh context plus two credentials calls.

const context = await browser.newContext();
await context.credentials.create('example.com', {
  id: credentialId,
  userHandle,
  privateKey,
  publicKey,
});
await context.credentials.install();
credentials.create()register the passkeymaterialcredentials.install()arm the virtualauthenticatorApp login via passkeythe real WebAuthn flowrunsSave storage statecredentials persist forreseeding
One passkey login, then reuse it everywhere

Passkeys in storage state

Password flow testingType into fieldsState is cookiesEasy to automateIncreasingly not the real flowPasskey flow testingVirtual authenticator answersState is credentials + cookiesFirst-class in the runner nowMatches where auth is goingVS
The auth your users actually use is now testable

A pragmatic first passkey spec

  1. In a setup project, call credentials.create() with your test credential material, then credentials.install() to arm the authenticator.
  2. Drive the app's passkey registration flow once with that context, so the app enrolls the virtual credential.
  3. Save storage state with the credentials option, so the passkey persists alongside the cookies.
  4. In a dependent project, load that state and assert one protected page renders. That single check tells you passkey auth holds before you invest in deeper flows.
Tip. Keep passkey specs separate from password specs. They fail for different reasons: a challenge that never gets answered is a different bug from a form that will not submit, and mixing them muddies triage.

Auth sorted. Next, the Components tab: the new stories-and-galleries model that points your existing locator skills at a much faster layer.

Component tests that reuse your e2e muscle memory: the same locators, the same web-first assertions, pointed at a mounted component instead of a deployed app. If your team writes Playwright e2e today, the new concepts are the story, the gallery, and the mount line; everything after mount is familiar.

Stories, galleries, and mount

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');
});
Write a storycomponent in one scenarioCollect in a gallerystories grouped on a pagemount('path/Story')fixture returns a scopedlocatorAssert as usualgetByRole and web-firstexpects
After mount(), everything is standard Playwright

Where component tests fit for a QA team

E2E testsuser journeys, few and stableComponent storieswidget states, many and fastUnit testspure logic, no browser
The middle layer gets a first-class runner model
QuestionLayer
Does checkout work end to end?E2E test
Does the dropdown render all 12 states?Component story
Does the price rounding function work?Unit test
Note. The component testing model is new in this release, so expect the shape to evolve. Keep stories small and single-purpose, and any future adjustments stay cheap.

That is the component story. Next, the DX + API tab: cancelling stuck operations with AbortSignal, WebP snapshots, and Reporter.preprocess() filtering.

None of these headline a release on their own; together they remove a dozen daily papercuts from writing, running, and maintaining tests. This is the batch you feel one sprint after upgrading.

Cancel operations with AbortSignal

Most operations now accept a signal option, wired to the same AbortController the web platform already gave you.

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

Quarantine as code: Reporter.preprocess()

Reporters get a hook that reshapes the run before a single worker starts.

class MyReporter {
  async preprocess({ config, suite, testRun }) {
    for (const test of suite.allTests()) {
      if (shouldSkip(test))
        testRun.skip(test);
    }
  }
}
Config resolvedprojects, shards, filtersknownReporter.preprocess()your policy runsTestRun filteredskip and exclude appliedSuite executesonly what your policyallows
One hook, your own filtering policy

WebP snapshots and the rest

Visual comparisons speak lossless WebP by naming the snapshot .webp; standalone screenshots add a quality knob (100 is lossless, lower values are lossy).

await expect(page).toHaveScreenshot('homepage.webp');
await page.screenshot({ path: 'homepage.webp', quality: 50 });
CallWhat you get
toHaveScreenshot('homepage.webp')Comparison snapshot, lossless
page.screenshot({ path, quality: 50 })Standalone capture, lossy at 50
quality: 100Lossless capture
PNG snapshotsLossless onlyBigger filesHeavier snapshot reposSame assertionsWebP snapshotsComparisons stay losslessquality knob on standalone shotsSmaller reposSame assertionsVS
Same visual checks, lighter git history
Tip. Adopt WebP on your heaviest visual suite first and watch the repo size; the assertion workflow does not change, it is the same toHaveScreenshot() call with a different file extension.

Those are the papercuts. The structural change is bigger: the MCP server and the CLI now ship inside the runner itself, and that is the whole next tab, MCP + agents.

The line between your test runner and your AI tooling just got shorter: the agent plumbing now ships in the box you already install.

MCP server and CLI, bundled

The release notes put it in one sentence: "Playwright now bundles the Playwright MCP server and playwright-cli, runnable via npx playwright mcp and npx playwright cli."

npx playwright mcp
npx playwright cli

Wiring an agent to it is three moves.

  1. Confirm the repo is on @playwright/test 1.62; the MCP server travels with it.
  2. Run npx playwright mcp, nothing extra to install.
  3. Point the agent setup, Copilot or Claude Code, at that command.
Agent (Copilot /Claude)asks for a browsernpx playwright mcpthe bundled serveranswersReal browser sessionnavigate, snapshot, actEvidence back to theagentaccessibility tree +results
The bundled MCP server gives compatible agents browser control from the install you already have

Companion release: the standalone server

Alongside the runner, the standalone Playwright MCP server reaches 0.0.79 with its own set of upgrades.

Test runner@playwright/test, the part you hadCLInpx playwright cli, scriptable controlMCP servernpx playwright mcp, the agent's hands
One install, three surfaces

What this unlocks for QA agents

Heads up. GitHub's Copilot code review runs its MCP tool calls read-only by design, so PR-side verification is inspect-only there; the local agent-mode session is where the full toolset lives.

That covers what 1.62 puts on the table. The Upgrade plan tab turns it into an order of operations: what to switch on first, and how to tell it paid off.

You do not adopt a release, you adopt features in the order they pay off. Playwright 1.62 hands a QA team five features worth real hours, and the order below is ours: flake control first because it pays on every single run, agent workflows last because they build on everything else.

Upgrade first, adopt in order

npm i -D @playwright/test@latest
npx playwright install
  1. Isolated retries on the flakiest suite. Set retries with retryStrategy: 'isolated' so retries run at the end of the run, sequentially, in a single worker, then compare retry pass rates against your old inline retries.
  2. One passkey login spec. Cover WebAuthn with context.credentials.create() plus context.credentials.install(), and persist it through the credentials storage state option so you log in once and reseed everywhere.
  3. Quarantine list via Reporter.preprocess(). Move the flaky-test list into a reporter hook that calls testRun.skip(test), replacing grep-based skips scattered across CI scripts.
  4. WebP on the heaviest visual suite. Point toHaveScreenshot() at .webp names and watch the repo size; comparisons stay lossless.
  5. Agent workflows through MCP. Run npx playwright mcp, bundled with the runner since 1.62, and wire your agent skills to it.
Isolated retriesone config linePasskey specone setup projectQuarantine hookone reporter fileWebP snapshotsone suite at a timeAgent MCPone command
Five adoptions, ordered by payoff per hour invested

The one-week rollout table

DayMoveSuccess signal
Day 1Flip retryStrategy: 'isolated' on the flakiest projectFlake report shows which retries pass in isolation and which fail everywhere
Day 2Add one WebAuthn login spec with credentials storage statePasskey spec is green in CI with no manual hacks
Day 3Move skips into a Reporter.preprocess() quarantine hookQuarantine list is one file, zero grep flags in CI scripts
Day 4Switch the heaviest visual suite to WebP snapshotsSnapshot repo shrinks while comparisons stay lossless
Day 5Point an agent at npx playwright mcpAgent drives the app through npx playwright mcp
Adopt one featurea single variableRun the suite a weeklet the data arriveCompare the signalflake rate, repo size,coverageKeep or revertthen move onnext feature
Adopt like a tester: one variable at a time

Keep learning

Pin it. Lock the runner version in package.json and upgrade deliberately, one minor at a time. Nightly alphas of the next minor exist, but they are not for course repos or CI.

That is the whole plan: two commands, five adoptions, one signal per day, and anything that does not move a number gets reverted. For the rest of this series and every other guide, head back to the /ai hub.