Free resource · AI in Testing

Playwright MCP & AI Agents: The Practical Guide for Testers

What MCP actually is, how to connect Playwright to an AI assistant, the workflows that save real time, where it falls apart — and how to talk about it in an interview.

By Vaibhav Sumbe, Senior SDET · ~15 min read + hands-on lab

Section 1Why testers should care

For years, "AI in testing" meant a tool that recorded clicks or guessed locators. MCP changes the shape of it. Instead of a separate AI product, your everyday assistant — Claude, Copilot in VS Code, Cursor — gets a real browser it can open, read and operate. You describe what you want in plain English; the agent navigates, clicks, fills forms, reads the page and reports back. Then it can turn what it did into a proper Playwright test.

That does not replace an automation engineer. It removes the boring middle: inspecting the DOM for a locator, writing the first rough version of a spec, figuring out why a test broke after a UI change. The engineer still decides what to test, reviews the code and owns the framework.

The one-line versionPlaywright MCP lets an AI assistant drive a real browser through Playwright, so you can explore, debug and generate tests by talking to it.

Section 2MCP in plain words

MCP (Model Context Protocol) is an open standard for connecting AI applications to outside tools and data. Think of it the way you think of a USB port: the AI app is the laptop, an MCP server is a device, and the protocol is the plug shape that lets any device work with any laptop.

Host

The AI app you type into — VS Code with Copilot, Claude Desktop, Claude Code, Cursor.

Client

The part inside the host that speaks MCP and keeps a connection to each server.

Server

A small program that exposes "tools" the model can call. Playwright MCP is one such server.

Tools

Named actions with inputs — navigate, click, type, take a snapshot. The model decides which to call.

Before MCP, every AI tool needed its own custom integration for every service. With MCP, Microsoft wrote one Playwright server and it works in every MCP-capable assistant.

Section 3How Playwright MCP works

You: "Log in and add a laptop to the cart"
→
AI model plans the steps
→
Playwright MCP server
→
Real Chromium / Firefox / WebKit
→
Page snapshot back to the model

The important design choice: the agent reads the page through the accessibility tree, not screenshots. After each action, the server returns a structured text snapshot of the page — roles, names, states — with a short reference (ref) for every element. The model says "click ref e42" and Playwright clicks exactly that element.

Snapshot mode (default)

Fast, cheap in tokens, deterministic. Works with any text model. Mirrors how getByRole sees the page.

Vision mode (opt-in)

Uses screenshots and x/y coordinates. Useful for canvas, charts or badly built UIs with no accessible names.

Why this matters for youIf your app has poor accessibility — buttons with no names, divs pretending to be links — the agent struggles exactly the way getByRole does. Good a11y makes both your tests and your AI tooling better.

Section 4Setup in 5 minutes

Prerequisite: Node.js 18 or newer. That is it — the server is downloaded on demand with npx.

VS Code (GitHub Copilot agent mode)

Add this to .vscode/mcp.json in your project (or your user settings), then switch Copilot Chat to Agent mode:

{
  "servers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Claude Desktop / Cursor

Same idea, under the mcpServers key of the app's MCP config file:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Claude Code (terminal)

claude mcp add playwright npx @playwright/mcp@latest

Check it works

Ask the assistant: "Open https://demo.opencart.com and tell me what the main navigation menu contains." A browser window should open and the answer should come back from the live page.

Common first-run problems
  • Browser not installed — run npx playwright install chromium.
  • Tools not showing — restart the host app after editing config; check the JSON has no trailing commas.
  • Corporate proxy — npx needs registry access; set your npm proxy or install the package globally once.

Section 5Tools the agent gets

The server exposes a set of tools. You never call them yourself — the model does — but knowing them helps you write better prompts and read the agent's log.

ToolWhat it does
browser_navigateOpen a URL
browser_snapshotReturn the accessibility snapshot with element refs
browser_click / browser_hoverClick or hover an element by ref
browser_type / browser_fill_formType into one field, or fill several at once
browser_select_optionChoose from a dropdown
browser_press_keyPress Enter, Tab, Escape, etc.
browser_wait_forWait for text to appear/disappear or for time
browser_handle_dialogAccept or dismiss alerts and confirms
browser_file_uploadUpload files to a file input
browser_tabsList, open, switch and close tabs
browser_take_screenshotCapture the page or an element
browser_console_messagesRead the browser console — great for debugging
browser_network_requestsList network calls the page made
browser_evaluateRun JavaScript on the page
browser_closeClose the browser

Tool names evolve between releases — check the server's README for the current list.

Section 6Useful config flags

Pass flags through the args array, e.g. ["@playwright/mcp@latest", "--headless", "--browser=firefox"].

FlagUse it when
--headlessYou don't need to watch, or you're on CI / a server
--browser=firefox|webkit|msedgeChecking behaviour in another engine
--isolatedEach session should start with a clean profile (no leftover cookies)
--user-data-dir=<path>You want to stay logged in between sessions
--storage-state=<file>Reuse a saved login state, same as in your test suite
--viewport-size=1280,720Testing a specific screen size
--caps=visionTurn on screenshot/coordinate tools
--save-traceKeep a Playwright trace of what the agent did — open it in Trace Viewer
--allowed-origins=<list>Restrict which sites the agent may visit

Section 7Real workflows that save time

Workflow 1 — Exploratory testing by conversation

// Prompt
Go to https://demo.opencart.com. Search for "MacBook", open the first result,
add it to the cart and open the cart. Report: product name, unit price,
quantity and total. Flag anything that looks wrong.

The agent performs every step and reports what it saw. You get a quick smoke check of a flow without writing a line of code — useful on a fresh build or a ticket you're picking up for the first time.

Workflow 2 — Explore first, then generate the test

// Prompt, after the exploration above
Now write a Playwright Test in TypeScript for the flow you just did.
Use getByRole / getByLabel locators only, web-first assertions,
and put it in tests/cart.spec.ts.

Because the agent actually walked the page, its locators come from the real accessibility tree instead of guesses. A typical result:

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

test('add MacBook to cart from search', async ({ page }) => {
  await page.goto('https://demo.opencart.com/');
  await page.getByRole('textbox', { name: 'Search' }).fill('MacBook');
  await page.getByRole('button', { name: /search/i }).click();

  await page.getByRole('link', { name: 'MacBook', exact: true }).first().click();
  await page.getByRole('button', { name: 'Add to Cart' }).click();
  await expect(page.getByText(/success: you have added/i)).toBeVisible();

  await page.getByRole('link', { name: /shopping cart/i }).first().click();
  await expect(page.getByRole('link', { name: 'MacBook', exact: true })).toBeVisible();
});
Review it like a junior's PRGenerated tests often hard-code data, skip the page objects your framework uses, or assert too little. Ask the agent to refactor into your POM structure, then read every line before merging.

Workflow 3 — Debug a failing test

tests/checkout.spec.ts fails at the "Place order" step with a timeout.
Open the app, repeat the steps manually, check the console and network
requests, and tell me why. Then propose the smallest fix.

The agent can see what your CI log can't: a cookie banner covering the button, a 500 from an API, a renamed label. Combine with --save-trace to keep evidence.

Workflow 4 — Locator hunting

On the registration page, give me the most stable Playwright locator
for every input and button. Prefer role + accessible name. Output a table.

Workflow 5 — Quick accessibility pass

Take a snapshot of the checkout page and list every interactive element
that has no accessible name, or whose name is unclear.

Section 8Playwright test agents: planner, generator, healer

Newer Playwright releases (1.56+) ship ready-made agent definitions built on top of MCP. Instead of writing prompts from scratch, you get three specialised agents:

🧭 Planner

Explores the app from a seed test and writes a human-readable test plan in Markdown under specs/.

⚙️ Generator

Turns the plan into Playwright test files, checking selectors and assertions live as it writes.

🩹 Healer

Runs failing tests, replays the steps, finds what changed in the UI and patches the test — or marks it skipped if the feature is genuinely broken.

Initialise them for your assistant of choice:

npx playwright init-agents --loop=vscode     # or --loop=claude / --loop=opencode

This adds the agent definitions plus a seed test — a small spec that sets up the starting state (base URL, login, fixtures). Every agent starts from it, so get it right first.

Seed test
→
Planner
→
specs/*.md
→
Generator
→
tests/*.spec.ts
→
Healer
Where the healer helps — and where it shouldn'tA renamed button or moved element? Let it patch. A real bug where the button no longer works? The healer should not "fix" the test to pass. Always review healer diffs — a test that was healed into passing against a broken feature is worse than a red test.

Section 9Prompts that work

Be specific about the goal

"Verify a guest can check out with COD" beats "test the checkout".

State your standards

Locator strategy, folder, naming, POM usage, assertion style — say it once, upfront.

Ask for evidence

"Report console errors and failed network calls" turns a click-through into a real check.

Break big flows up

Login, then search, then cart. Long single prompts drift and burn tokens.

Give test data

Provide the user, product and expected values — don't let the agent invent them.

Keep project rules in a file

Put conventions in CLAUDE.md or Copilot instructions so every session follows them.

Section 10Limits & best practices

What it is not good at (yet)

Safety on real projects

Section 11Interview questions on Playwright MCP

This topic now comes up in SDET interviews, usually as "Have you used AI in your automation work?" Here's how to answer at the level it's asked.

What is MCP and why is it useful for test automation?

Model Context Protocol is an open standard that lets AI assistants call external tools in a uniform way. For automation, the Playwright MCP server gives an assistant a real browser, so it can explore an application, find stable locators, generate test code and debug failures — all from natural-language instructions.

How does Playwright MCP "see" the page?

By default through accessibility snapshots — a structured text view of the page with roles, names and element references. It's faster and more reliable than screenshots and works with text-only models. Vision mode with screenshots can be switched on with --caps=vision when needed.

Can Playwright MCP replace your regression suite?

No. Agent runs are non-deterministic and cost tokens. MCP helps write, maintain and debug tests; the suite itself still runs as normal Playwright tests in CI, giving repeatable results.

Explain the planner, generator and healer agents.

The planner explores the app from a seed test and writes a Markdown test plan. The generator converts that plan into executable Playwright tests, verifying locators live. The healer runs failing tests, works out what changed, and repairs the test or skips it if the feature itself is broken.

What risks do you watch for with AI-generated tests?
  • Weak or missing assertions — a test that clicks but proves nothing.
  • Hard-coded data and brittle waits.
  • Ignoring the framework's POM and utilities.
  • A healer "fixing" a test to pass against a real bug.
  • Sending sensitive application data to an external model.

Mitigation: code review, clear project instructions, test environments only, and keeping humans responsible for what gets merged.

How did you use it in a real project? (frame your own answer)

Structure: situation (e.g. 40 new screens, tight sprint) → what you did (used MCP to explore and draft specs, refactored into the POM, reviewed every assertion) → result (authoring time cut, flaky locators reduced) → what you'd watch for. Only claim what you actually did — interviewers follow up.

Snapshot mode vs vision mode — when do you pick which?

Snapshot mode by default: cheaper, deterministic, matches role-based locators. Vision mode for canvas, charts, maps, or legacy UIs without accessible names, accepting more cost and less precision.

Hands-on lab: build it yourself, step by stepSections 12 to 17 are the exact steps from our live session. Every code block has a Copy button. Do this in a fresh demo folder, not in your main framework.

Section 12 · Hands-onInstall Copilot, Playwright MCP and the agents

Most agent setup failures are version problems. Check these four first.

ToolMinimumCheck with
Node.js18+ (20+ recommended)node --version
VS Code1.105+Help → About
GitHub Copilot ChatSigned in, Agent modeChat panel opens
Playwright1.56+npx playwright --version

Step 1 · Create an empty project

mkdir app-mcp-demo
cd app-mcp-demo
npm init -y

Step 2 · Install GitHub Copilot

Extensions → search GitHub Copilot → Install → restart VS Code → sign in with GitHub. In the chat panel switch to Agent mode and pick a model.

Copilot is the MCP client, not the modelThe model (Claude, GPT, Gemini) is whatever you choose in the model dropdown. Copilot is only the window you type the prompt into.

Step 3 · Install Playwright MCP (method A: standalone)

Official repo: github.com/microsoft/playwright-mcp. Click Install Server → VS Code, or run:

code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'

Expected output: Added MCP servers: playwright. If code is not found, open the Command Palette → Shell Command: Install 'code' command in PATH, or jump to method B.

Step 4 · Initialise Playwright

npm init playwright@latest

Choose TypeScript, tests folder tests, GitHub Actions workflow: yes, install browsers: yes.

Step 5 · Add the three agents (method B: bundled)

npx playwright init-agents --loop=vscode
One command does bothIt creates the Planner, Generator and Healer files and registers the Playwright test MCP server for VS Code. If step 3 failed, this alone is enough. Other options: --loop=claude, --loop=opencode.

Section 13 · Hands-onWhat init-agents creates

Seven new files appear. Know what each one does before you edit anything.

FilePurpose
.github/agents/playwright-test-planner.agent.mdPlanner agent
.github/agents/playwright-test-generator.agent.mdGenerator agent
.github/agents/playwright-test-healer.agent.mdHealer agent
.vscode/mcp.jsonRegisters the Playwright test MCP server
specs/README.mdFolder for the Planner's test plans
tests/seed.spec.tsSeed test every agent starts from
.github/workflows/copilot-setup-steps.ymlCloud Copilot coding-agent setup (ignore for now)

.vscode/mcp.json (generated)

{
  "servers": {
    "playwright-test": {
      "type": "stdio",
      "command": "npx",
      "args": ["playwright", "run-test-mcp-server"]
    }
  },
  "inputs": []
}

Open mcp.json and click Start above "playwright-test". It turns into Running | Stop | Restart | N tools. That tool count is your proof the server is installed. Think of mcp.json as the package.json of MCP servers: add Jira or GitHub MCP later and they appear here too.

Never rename the agent filesEach .agent.md has front matter between --- lines (description, tools, model, mcp-servers) and then a plain-English body. Change the content, never the file name.

Section 14 · Hands-onOur three agent files (copy and paste)

Keep the generated front matter. Replace only the body below the closing --- with these AutomateWithUs rules.

Why keep the front matter?Tool names change between Playwright releases. A hand-typed tool list with one wrong name silently removes that ability from the agent.

🧭 Planner body

.github/agents/playwright-test-planner.agent.md

# Planner (AutomateWithUs rules)

You are the Planner. You explore a running web app and write a numbered
test plan in Markdown. You never write test code.

## Read first
1. AGENTS.md at the project root (if a rule here conflicts, AGENTS.md wins)
2. tests/seed.spec.ts for the base URL and starting state

## Allowed
- Navigate, hover, wait, press keys, switch tabs
- Take accessibility snapshots (your main way of seeing the page)
- Read console and network messages for context
- Create or edit files only inside specs/

## Not allowed
- Clicking destructive actions (delete, remove, cancel order, pay)
- Typing real-looking personal data into forms
- Writing or editing any file outside specs/
- Exploring production URLs: staging, local or public demo sites only

## Output: specs/<feature-name>.md (kebab-case)
# Test Plan: <Feature>
Target: <URL> | Seed: tests/seed.spec.ts | Date: <YYYY-MM-DD>

## Preconditions
## Scenarios
### 1.1 <short title>
- Priority: P0 | P1 | P2
- Tags: @smoke | @regression | @critical
- Steps: numbered, each with "expected: <what the user sees>"
- Assertions: at least one real check, not just "page loaded"
- Edge cases considered
## Not covered (and why)

## Rules
- Numbering is <feature>.<scenario>: 1.1, 1.2, 2.1. The Generator uses these numbers.
- Every scenario is independent and has explicit preconditions.
- If the plan file already exists, ask before overwriting it.

⚙️ Generator body

.github/agents/playwright-test-generator.agent.md

# Generator (AutomateWithUs rules)

You turn ONE scenario from specs/*.md into a runnable Playwright
TypeScript test that follows our framework.

## Read first
1. AGENTS.md
2. tests/seed.spec.ts
3. The plan file and scenario number the user gave you
4. Existing page objects in src/pages/ (reuse before creating)

## Framework rules
- Import test and expect from src/fixtures/base.ts, never from @playwright/test
- Test data comes from tests/data/*.json, never hard-coded in the spec
- One page object class per page in src/pages/, extending BasePage
- Locators are readonly properties set in the constructor
- Page objects contain no expect(); assertions live in the spec
- Spec files are kebab-case and end with .spec.ts
- Ask before creating a new page object

## Locator priority (stop at the first one that is unique)
1. getByRole(role, { name })
2. getByLabel(text)
3. getByPlaceholder(text)
4. getByTestId(id)
5. getByText(text) for static copy only
CSS or XPath only with a code comment explaining why.
If nothing is unique, stop and ask the user.

## Assertions
- Web-first only: toBeVisible, toHaveText, toHaveURL, toHaveCount
- Never page.waitForTimeout or waitForSelector

## Before you finish
- Verify every locator in the live browser before writing it
- Run the test; report pass or fail honestly

🩹 Healer body

.github/agents/playwright-test-healer.agent.md

# Healer (AutomateWithUs rules)

You diagnose a failing test and make the smallest correct fix.
A test that passes for the wrong reason is worse than a red test.

## Read first
AGENTS.md, the failing spec, its page objects, the last error and trace.

## Classify the failure first
A  Locator changed (element still there)   -> fix the locator
B  UI flow changed (element moved)         -> update the steps
C  Text on screen changed                  -> update the text after checking
D  Real bug in the app                     -> REPORT it, do not touch the test
E  Environment down / seed broken          -> REPORT it, do not touch the test
F  Flaky timing                            -> wait for a real state, never a fixed sleep

Check console errors and failed network calls BEFORE assuming A.

## Never
- Weaken an assertion (toHaveText -> toContainText, toHaveCount(6) -> toBeVisible)
- Add test.skip, test.fixme or bigger timeouts without approval
- Use page.waitForTimeout
- Edit page objects, fixtures, test data or playwright.config.ts without approval
- Delete a test, comment out an assertion, or wrap it in try/catch

## Stop and ask when
- The failure looks like category D or E
- The fix needs a page object or fixture change
- You cannot classify the failure with confidence

## Two-attempt limit
After 2 failed fix attempts: stop, report both attempts, ask what next.

## Report format
Category | Root cause | Files changed | Ready to merge / Needs review / Real bug
The Healer is the most dangerous agentAn over-helpful AI "fixes" a real bug by loosening the test. A red test is better than a test that is green for the wrong reason.

Section 15 · Hands-onAGENTS.md: the global rulebook

Every agent file says "read AGENTS.md first", but init-agents does not create it. Create it once, by hand, at the project root. Each AI tool auto-loads a different file name:

ToolFile it reads automatically
GitHub Copilot (VS Code).github/copilot-instructions.md
Claude CodeCLAUDE.md or AGENTS.md
Cursor.cursorrules or .cursor/rules/*.mdc
Codex CLIAGENTS.md

Keep the real file at .github/copilot-instructions.md and make AGENTS.md a symlink to it. Edit either one and both change.

macOS / Linux / Git Bash

mkdir -p .github
touch .github/copilot-instructions.md
ln -s .github/copilot-instructions.md AGENTS.md

Windows PowerShell (Admin or Developer Mode)

New-Item -ItemType File -Force .github/copilot-instructions.md
New-Item -ItemType SymbolicLink -Path AGENTS.md -Target .github/copilot-instructions.md

Now paste the template into .github/copilot-instructions.md and adjust it to your project:

.github/copilot-instructions.md

# Project rules for AI agents

This is a Playwright + TypeScript automation project.
Follow these rules for every change.

## Stack
- Playwright 1.56+ with TypeScript, Node 20+
- Runner: @playwright/test | Reports: HTML + Allure
- CI: GitHub Actions with sharding

## Folder structure
- src/pages/     page object classes, one file per page
- src/fixtures/  custom fixtures (base.ts)
- src/utils/     pure helpers, no test logic
- tests/         spec files, mirroring the app's URL structure
- tests/data/    JSON test data
- specs/         Markdown test plans from the Planner

## Coding conventions
- Classes PascalCase, methods camelCase, spec files kebab-case.spec.ts
- Import test/expect only from src/fixtures/base.ts
- No hard-coded test data in specs

## Locators (in this order)
getByRole > getByLabel > getByPlaceholder > getByTestId > getByText
CSS/XPath only with a comment saying why.

## Page objects
- Extend BasePage, constructor takes page: Page
- Locators are readonly, set in the constructor
- Methods return Promise<void> or the next page object
- No expect() inside page objects

## Assertions and waits
- Web-first assertions only (expect(locator).toBeVisible())
- No page.waitForTimeout, no waitForSelector
- Custom timeouts only with a comment explaining why

## Adding a new test
- Reuse existing page objects; do not create parallel ones
- Tag every test: @smoke, @regression or @critical

## Forbidden
- Skipping or commenting out failing tests to make CI green
- page.evaluate when an MCP tool can do the job
- Committing .env, credentials, storage-state.json or tokens
- Changing playwright.config.ts or adding npm packages without asking
- page.pause() in committed code

## When unsure
- Ask a question before writing code
- Prefer a small, focused change over a big refactor
- If a needed file does not exist, ask before creating it
Agent did something surprising?Check the rules in this order: your prompt → the .agent.md body → AGENTS.md → the agent's defaults.

Section 16 · Hands-onStarter project structure

Agents copy what they see. Give them a small, clean skeleton and they follow it; give them an empty folder and they invent their own.

Terminal

mkdir -p src/pages src/fixtures src/utils tests/data specs

src/fixtures/base.ts

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

export const test = base.extend<{}>({});

export { expect };

src/pages/BasePage.ts

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

export abstract class BasePage {
  readonly page: Page;

  constructor(page: Page) {
    this.page = page;
  }

  abstract goto(): Promise<void>;

  async waitForReady(): Promise<void> {
    await this.page.waitForLoadState('domcontentloaded');
  }
}

tests/seed.spec.ts (replace the generated one)

import { test, expect } from '../src/fixtures/base';

test.describe('Seed - environment baseline @smoke', () => {
  test('SauceDemo login page loads', async ({ page }) => {
    await page.goto('https://www.saucedemo.com');
    await expect(page.getByRole('textbox', { name: 'Username' })).toBeVisible();
    await expect(page.getByRole('textbox', { name: 'Password' })).toBeVisible();
  });
});

tests/data/users.json

{
  "standard": { "username": "standard_user", "password": "secret_sauce" },
  "locked":   { "username": "locked_out_user", "password": "secret_sauce" }
}

These are SauceDemo's public demo users, shown on its own login page.

Verify before using any agent

npx playwright test tests/seed.spec.ts
Expected: 1 passed (per browser project)If it fails, fix the setup first. An agent built on a broken seed builds broken tests.

Final folder tree

app-mcp-demo/
├── .github/
│   ├── agents/            planner, generator, healer .agent.md
│   └── copilot-instructions.md
├── .vscode/mcp.json
├── AGENTS.md -> .github/copilot-instructions.md
├── specs/                 test plans (Planner output)
├── src/
│   ├── fixtures/base.ts
│   ├── pages/BasePage.ts
│   └── utils/
├── tests/
│   ├── data/users.json
│   └── seed.spec.ts
└── playwright.config.ts

Section 17 · Hands-onRun Planner → Generator → Healer

The order is fixed: plan → review the plan → generate one scenario → review the code → heal only when a test fails. In Copilot Chat, pick the agent from the agent dropdown first, and check that mcp.json shows Running.

Seed test
→
Planner
→
You review the plan
→
Generator
→
You review the code
→
Healer

Step 1 · Planner prompt

Explore https://www.saucedemo.com starting from tests/seed.spec.ts.
Cover: login (valid, locked-out, empty fields), add to cart, remove from cart,
and checkout until the overview page. Do not place the order.
Save the plan as specs/saucedemo-checkout.md.
Review the plan before moving onNumbered scenarios (1.1, 1.2…), each with tags, priority, expected results and at least one real assertion, plus a "Not covered" section. Nothing outside specs/ should change. A bad plan gives bad code.

Step 2 · Generator prompt (one scenario at a time)

Generate scenario 1.1 from specs/saucedemo-checkout.md.
Use users.standard from tests/data/users.json.
Create LoginPage and InventoryPage in src/pages/ if they do not exist (ask first).
Save the test as tests/login/standard-user-login.spec.ts and run it.

What a good result looks like

import { test, expect } from '../../src/fixtures/base';
import { LoginPage } from '../../src/pages/LoginPage';
import users from '../data/users.json';

test.describe('Login', () => {
  test('standard user lands on inventory @smoke @critical', async ({ page }) => {
    const login = new LoginPage(page);
    await login.goto();
    const inventory = await login.loginAs(users.standard.username, users.standard.password);
    await expect(page).toHaveURL(/inventory/);
    await expect(inventory.items).toHaveCount(6);
  });
});

Step 3 · Healer prompt (only on a red test)

Class exercise: in LoginPage, change the login button's name to a wrong value, run the test so it fails, then ask:

The test tests/login/standard-user-login.spec.ts is failing.
Diagnose it, classify the failure (A to F), and propose the smallest fix.
Do not change any assertion.

Expected: category A (locator drift), a one-line locator fix and a short report. Then try the trap: change the expected count to toHaveCount(7). A well-guarded Healer reports it as a test or data question instead of quietly changing it.

Review checklist for AI-written code

Learn Playwright properly — then let AI speed you up

AI agents are only as good as the engineer reviewing them. Our live Playwright with TypeScript course gets you to framework level, with real projects and mock interviews included.

See the Playwright course Book a mock interview