Generate Playwright Test
Describe a scenario; get a runnable spec with page objects and real locators taken from the live DOM.
Playwright · MCP · AI Agents
Learn modern Playwright architecture from beginner to advanced — including MCP, AI Agents, Playwright Agents and Agentic Testing — with easy-to-understand visual diagrams.
Section 1
Forget the buzzword for a second. The fastest way to understand MCP is to watch one run happen — so that is exactly what this section starts with.
Not an AI model. Not an agent. Not a framework or a library.
An open protocol — one shared language between an AI app and your tools.
The model stops describing the work and starts doing it.
Pick a task, press Play, and follow the request travelling down the stack and the result coming back up. Every line on the right is the kind of message that really crosses the wire.
You:
Press Play to start the run…
now the same task — without MCP
Identical prompt, identical model. The only thing removed is access. Press Play and watch how far it gets.
You:
Press Play to start the run…
Same question, same intelligence, opposite outcome. The top run ends with a verified answer and a real locator. This one ends with a plausible guess and a homework list — because the model never got to look at anything.
It read the real page, the real console and the real test id. Without MCP it would
have invented a selector like .btn-checkout and hoped.
Lines like browser_click { ref: "add-to-cart-1" } are the protocol. The model
chooses which tool and what arguments; the server does the work and returns a structured result.
Call → read result → decide the next call. That repeated loop is what makes it feel agentic — and it is the bridge to Section 2.
The model did not get smarter. It got access. Same weights, same reasoning — the only new ingredient was a set of tools it was allowed to call.
MCP stops being abstract the moment you run it yourself. The official Playwright MCP server is one command.
npm init playwright@latest
npx playwright installclaude mcp add playwright npx @playwright/mcp@latestOne line. That is the whole integration.
For any other MCP client (Claude Desktop, VS Code, Cursor…), drop this into its MCP config file:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}Restart the client and ask it something that needs a browser — “open example.com and tell me the H1”. If it opens a real Chromium window, MCP is working. Point it at a practice app rather than production.
Not magic — a named list of callable tools. These are the ones you will see most:
| Tool | What it does | Why QA cares |
|---|---|---|
browser_navigate | Opens a URL in a real browser | Starts every journey |
browser_snapshot | Returns the accessibility tree — roles, names, test ids | The big one. Real locators instead of guesses |
browser_click | Clicks an element from that snapshot | Drives the flow |
browser_type | Fills inputs | Forms, search, login |
browser_console_messages | Reads console output | Catches the JS error behind a failure |
browser_network_requests | Lists requests and status codes | Spots the 500 the UI hid |
browser_take_screenshot | Captures the viewport | Evidence and visual checks |
Notice what is missing: there is no “look at the pixels” tool. Playwright MCP hands the model a
structured accessibility snapshot, which is why generated locators come out as
getByRole and getByTestId instead of brittle CSS chains.
Same protocol, different server. Click a tab to see what each one unlocks.
browser_navigatebrowser_snapshotbrowser_clickbrowser_typebrowser_console_messages“Walk through guest checkout on staging and tell me every field that has no label.”
What you get back: a real walkthrough, plus a list of unlabelled inputs with the exact locator for each — an accessibility bug report nobody had to write by hand.
list_issuescreate_branchcreate_or_update_filecreate_pull_requestget_workflow_run_logs“The nightly run failed. Read the CI log, fix the broken locator and open a PR.”
What you get back: a branch, a one-line diff in the page object, and a PR whose description quotes the exact CI error it fixes.
read_filewrite_filelist_directorysearch_files“Which of our 240 specs still use page.waitForTimeout?”
What you get back: the real file list with line numbers — and, if you ask, a refactor to web-first assertions across all of them.
querylist_tablesdescribe_table“I placed order #1042 in the UI. Did it actually persist?”
What you get back: the real row — status, total, timestamp. A green toast is not proof; a row in the table is. Keep this connection read-only.
search_issuesget_issueadd_commenttransition_issue“Read QA-318, turn its acceptance criteria into scenarios, then comment the result.”
What you get back: scenarios traceable to the criteria that produced them, and a comment on the ticket with pass/fail evidence.
http_requestdescribe_endpoint“Seed a user with 3 items in the cart, then start the UI test from there.”
What you get back: state created in one API call instead of six UI clicks — faster and far less flaky than driving setup through the interface.
Before MCP, every AI app needed a bespoke connector for every tool: M apps × N tools = M×N integrations, each with its own auth and format. Anthropic open-sourced MCP in late 2024 to collapse that into M+N — one server per tool, one client per app, everything interoperable. That is why Microsoft, OpenAI, Google, JetBrains and GitHub all ship MCP servers today.
Section 1.1
The fastest way to understand MCP is to look at what an AI model can and cannot do without it.
Section 1.2
Hover (or tap) any block to see what it does. The dotted lines show live protocol traffic.
Section 1.3
What actually happens, step by step, when you type a prompt like “open the shop, add a product to the cart and tell me the badge count”.
Request → Response round trip
The loop can repeat many times before you see an answer. The model calls a tool, reads the result, decides the next tool, and only replies to you once the goal is met. That loop is what makes it feel agentic.
Section 1.4
The same loop, told from a QA engineer’s chair — from prompt to a committed, passing test.
Prompt → Green build → repeat
Section 1.5
Same goal, two very different loops. On the left you do every step. On the right you supervise.
Every iteration costs human time. Flaky locators mean the loop runs again tomorrow, and the day after.
You stay the reviewer and the decision-maker. The repetitive middle of the loop is automated.
Section 1.6
Ten things teams are genuinely doing today with Playwright plus MCP.
Describe a scenario; get a runnable spec with page objects and real locators taken from the live DOM.
Run the suite, a project, a single spec or a single --grep tag, and read the output.
Capture and compare screenshots, then explain what changed instead of just failing a diff.
Probe endpoints, learn the schema, and generate request/response assertions that match reality.
Run axe checks through the browser tool and get prioritised, human-readable remediation steps.
Create a branch, commit the new specs, open a PR and summarise the change for reviewers.
Turn acceptance criteria into scenarios, and post pass/fail evidence back onto the ticket.
Assert the UI action produced the right row, status and audit entry — not just the right toast message.
When a selector breaks, find an equivalent element in the current DOM and propose a stronger locator.
Read the trace, the console errors and the network log together, then explain the root cause in one paragraph.
Section 2
MCP gave the model hands. Agents give it a plan. This section explains what an agent really is — without any jargon.
An AI agent is a model that is given a goal, a set of tools, and permission to keep working until the
goal is met.
Think of the difference between asking a colleague “how do I book a flight?” (they explain) and saying
“book me a flight to Bangalore next Tuesday” (they open the site, compare options, pick one, and come back
with a confirmation). The second one is an agent.
An agent is a loop: observe → think → act → observe again. The model looks at the current state, decides on an action, calls a tool (very often through MCP), reads the result, and repeats. It stops when the goal is achieved, when it hits a guardrail, or when it needs a human decision.
| Aspect | AI Assistant | AI Agent |
|---|---|---|
| What you give it | A question | A goal |
| What it returns | An answer or a code snippet | A completed outcome |
| Tools | None — text only | Browser, files, GitHub, DB, APIs |
| Number of steps | One turn | Many turns, self-directed |
| Memory of progress | Just the chat history | Tracks a task list and its own state |
| Failure handling | You debug it | It re-plans and retries |
| QA analogy | “Show me a login test example” | “Cover the whole login module and open a PR” |
MCP made “plug a model into a real system” a five-minute config change instead of a project.
Modern models can decompose a fuzzy goal into ordered, verifiable steps — the hard part of automation.
Running a test and reading the output is fast, so the agent can self-correct instead of guessing.
Scaffolding, locator hunting, fixture wiring and report chasing are exactly what agents are good at.
Crawls an unfamiliar app, maps the pages and forms, and proposes a coverage matrix before a line of code exists.
Runs nightly, finds the three specs that broke after a UI refactor, and opens a PR with fixed locators.
Groups 40 CI failures into 3 root causes and tells you which one is a real product bug.
Compares the test suite against the requirements doc and lists the scenarios nobody wrote.
Section 2.1
Traditional automation is one long human loop. Agentic testing splits that loop into specialists.
Section 2.2
A single “super agent” is hard to control. Real systems use a planner, a task manager, and a team of narrow specialists. Hover any agent to see its job.
Section 3
A Playwright Agent is not one big robot. It is a multi-agent architecture in which different agents own different responsibilities in the test lifecycle — planning, generating and healing.
The three roles map cleanly onto how a good QA team already works: someone decides what to test (Planner), someone writes the code (Generator), and someone keeps the suite green when the UI moves (Healer). The agents just do it faster, and never get bored.
Explores the app and turns a requirement into a structured test plan. It never writes or runs code.
Turns the plan into real Playwright code — page objects, specs, fixtures, assertions.
Wakes up only when a test fails, finds why, repairs the locator or wait, and re-runs to prove it.
Section 3.1
The Planner is the analyst of the team. Give it a requirement and a URL; it gives you back a test plan a human can review before a single line of code is written.
Planner flow
Prompt: “Create a test plan for the checkout flow on shop.qaautomationlabs.com.”
# Test Plan — Checkout Module
Under test: shop.qaautomationlabs.com
Pages found: /cart.php, /checkout.php, /order-confirm.php
TC-01 Guest checkout — happy path [P1]
add product → cart → checkout → pay → confirmation id shown
TC-02 Checkout with empty cart is blocked [P1]
TC-03 Required address fields validated [P2]
TC-04 Cart total = sum(line items) [P1]
TC-05 Quantity update recalculates total [P2]
TC-06 Cart survives a page reload [P2]
Test data: demo@demo.com / demo · product ids 1–20
Order: TC-01 first (seeds state), rest independent
Not in scope: real payment gateway, email delivery
Notice there is no code here at all. That is deliberate — a plan is cheap to review and cheap to change. Fixing scope at this stage costs seconds; fixing it after 600 lines of specs costs an afternoon.
Section 3.2
The Generator is the developer of the team. It takes the approved plan and writes real, runnable Playwright code — using locators read from the live DOM, not invented from memory.
getByRole / getByTestId over CSS chainsexpect()Generator flow
TC-01 to runnable code// pages/CartPage.ts — generated page object
import { Page, Locator, expect } from '@playwright/test';
export class CartPage {
readonly badge: Locator;
readonly checkoutBtn: Locator;
constructor(private readonly page: Page) {
// locators read from the live DOM via Playwright MCP
this.badge = page.getByTestId('cart-count');
this.checkoutBtn = page.getByRole('button', { name: 'Proceed to Checkout' });
}
async expectItemCount(n: number) {
await expect(this.badge).toHaveText(String(n));
}
}
// tests/checkout.spec.ts — generated spec
test('TC-01 guest checkout happy path', async ({ page }) => {
const cart = new CartPage(page);
await page.goto('/womens-wear.php');
await page.getByTestId('add-to-cart-1').click();
await cart.expectItemCount(1);
await cart.checkoutBtn.click();
await expect(page.getByTestId('order-id')).toBeVisible();
});
Why this is better than a hand-guessed test: the agent read
data-testid="cart-count" from the real page. It did not guess
.cart > span.badge:nth-child(2) and hope.
Section 3.3
The Healer is the maintainer — and for most teams it is the agent that saves the most time. Suites rarely fail because the test logic is wrong; they fail because the UI moved.
When a test fails, the Healer does what an experienced engineer does: read the error, look at the page as it is now, compare it with what the test expected, find the element that clearly corresponds, and switch to a locator that will not break again. Then it re-runs the test — because a fix you have not verified is just a guess.
Self-healing must never hide a real defect. If the “Checkout” button is missing because the feature is broken, the correct behaviour is to fail loudly — not to find something else to click. A good Healer proves the element still exists and still means the same thing before it repairs anything.
Healer flow
✗ TC-01 guest checkout happy path
TimeoutError: locator.click: Timeout 30000ms exceeded.
waiting for locator('.btn-checkout')
— Healer: reading the current accessibility snapshot …
button "Proceed to Checkout" [data-testid="checkout-btn"]
→ same text, same position, class renamed by the UI refactor
— Healer: proposed patch
- checkoutBtn = page.locator('.btn-checkout');
+ checkoutBtn = page.getByRole('button', { name: 'Proceed to Checkout' });
— Healer: re-running TC-01 …
✓ TC-01 guest checkout happy path (4.1s)
The fix also made the test better: a CSS class is an implementation detail, while the button’s role and accessible name are what the user actually perceives.
Section 3.4
All three agents together, including the failure branch that loops back through the Healer. Hover any node for detail.
Section 3.5
Same framework, same browsers, same assertions — a very different day-to-day.
| Activity | Traditional Playwright | Playwright Agent |
|---|---|---|
| Writing tests | Manual you type every line | AI-assisted generated from a reviewed plan |
| Debugging | Manual open the trace, bisect by hand | Automatic failure analysed and explained |
| Execution | Manual you decide what to run, when | Autonomous scoped runs triggered by the agent |
| Reporting | Manual read the HTML report yourself | AI-generated summarised, grouped, prioritised |
| Maintenance | Manual fix every broken selector by hand | Self-healing repaired and re-verified, diff for review |
| Coverage discovery | Manual depends on who remembers what | Explored the app is crawled and mapped |
| Who reviews | A human writes and a human reviews | A human reviews — and that stays non-negotiable |
Section 3.6
How the pieces sit inside a normal delivery pipeline, from a requirement landing in the backlog to a dashboard the whole team watches.
Track 3
There is a second way to hand a coding agent a browser — not through MCP tool schemas, but
through a shell command it already knows how to run. That is
@playwright/cli.
Short command output instead of large tool schemas sitting in the model’s context.
Every command returns an accessibility snapshot with element refs like e21.
A persistent browser process, so there is no start-up cost on every command.
The agent runs playwright-cli click e21 the same way it runs
git commit. No protocol, no JSON-RPC — just a command and its output. That is the
whole idea: agents are already excellent at using a terminal.
The real TodoMVC walkthrough from the Playwright docs. Press Play and watch each command return a fresh snapshot that the next command depends on.
Goal: Add two todos to TodoMVC and tick the first one off.
Press Play to start the session…
Notice check e21. The agent never invented that reference — it
read it from the snapshot the previous command returned. Refs are what make the interaction
deterministic instead of a guess at a CSS selector.
Track 3.1
Two doors into the same browser. They are not rivals — they suit different jobs.
| Playwright CLI | Playwright MCP | |
|---|---|---|
| Best for | Coding agents (Claude Code, Copilot) working inside a large codebase | Specialised agentic loops and exploratory automation |
| How it works | The agent runs shell commands | The model calls MCP tools with structured parameters |
| Token cost | Lower concise output, skills loaded on demand | Higher tool schemas plus snapshots in context |
| Default mode | Headless | Headed |
| Setup | npm install -g @playwright/cli |
JSON config in the MCP client |
Rule of thumb. If the agent is already living in your repo and context is precious, reach for the CLI. If you are building a dedicated automation loop where a model should reason over rich structured tool results, reach for MCP. Plenty of teams use both.
Track 3.2
Node.js 20+ and a coding agent (Claude Code, Copilot, Cursor…) are the only prerequisites.
npm install -g @playwright/cli@latest
playwright-cli --helpPrefer not to install globally? npx playwright-cli --help works too.
One is downloaded automatically on first use, but you can be explicit:
playwright-cli install-browser # chromium (default)
playwright-cli install-browser firefox # a specific browser
playwright-cli install-browser --with-deps # + Linux system depsplaywright-cli install --skillsThis drops skill files locally so your agent gets structured reference docs for the CLI instead of
guessing from --help.
PLAYWRIGHT_CLI_SESSION=todo-app claude .Keeps one agent’s browser state isolated from another’s.
| Flag | What it does |
|---|---|
--with-deps | Also install Linux system dependencies |
--dry-run | Preview what would be installed |
--list | List available browsers across installations |
--force | Reinstall even if already present |
--only-shell | Only the Chromium headless shell |
--no-shell | Skip the Chromium headless shell |
The CLI drives a real browser with real cookies and real storage. Point it at a test environment or a practice app such as the QA Automation Labs demo shop — never at production with live credentials.
Track 3.3
Every CLI interaction follows the same four beats. Once this clicks, the whole command set makes sense.
The core workflow
e21 — a stable handle on one element### Page
- Page URL: https://demo.playwright.dev/todomvc/#/
- Page Title: React - TodoMVC
### Snapshot
[Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
Short by design. The heavy accessibility tree lives in the .yml file; only the
pointer goes into the agent’s context. That is the token trick.
Track 3.4
The full surface, grouped the way the docs group it. Click a category.
open [url]goto <url>closeclick <ref>dblclick <ref>fill <ref> <text>type <text>select <ref> <val>check <ref>uncheck <ref>hover <ref>drag <start> <end>upload <file>snapshotscreenshot [ref]pdfeval <func> [ref]resize <w> <h>dialog-acceptdialog-dismissQA angle: snapshot is your best friend when writing
tests — it is the same accessibility view Playwright’s getByRole uses,
so whatever you see there is what you should assert on.
go-backgo-forwardreloadQA angle: perfect for the checks people forget — does the cart survive a
reload? Does go-back from checkout keep the basket intact?
press <key>keydown <key>keyup <key>mousemove <x> <y>mousedown [btn]mouseup [btn]mousewheel <dx> <dy>QA angle: keyboard-only journeys are an accessibility requirement.
press Tab repeatedly and read each snapshot to verify a sane focus order.
tab-listtab-new [url]tab-select <idx>tab-close [idx]QA angle: anything that opens a new window — OAuth pop-ups, payment redirects, “open in new tab” links, PDF previews.
state-save [file]state-load <file>cookie-listcookie-get <name>cookie-set <name> <val>cookie-delete <name>cookie-clearlocalstorage-listlocalstorage-get <key>localstorage-set <k> <v>localstorage-clearsessionstorage-*QA angle: state-save once after logging in, then
state-load before every run — the CLI equivalent of Playwright’s
storageState. It is the single biggest speed-up for authenticated suites.
networkroute <pattern> [opts]route-listunroute [pattern]QA angle: the fastest way to test the unhappy paths. Route the cart API to a
500 and check the UI degrades honestly instead of showing an empty basket.
console [min-level]run-code <code>tracing-starttracing-stopvideo-start [file]video-chapter <title>video-stopshowQA angle: wrap a flaky journey in
tracing-start / tracing-stop and hand the trace to
a human. console error often explains a failure in one line.
-s=<name> <cmd>listclose-allQA angle: two sessions, two logged-in users, one shared document — the simplest way to exercise real multi-user behaviour. Also how you stop parallel agents fighting over one browser.
--headed watch it happen
--browser=firefox switch engine
--persistent keep the profile
--profile named profile
-s=<name> pick a session
Track 3.5
Running playwright-cli install --skills gives the agent structured
reference guides it can pull in on demand — instead of you pasting instructions into every prompt.
How to run, debug and manage a Playwright test suite from the command line.
Intercepting and mocking network requests to force the paths you cannot trigger by hand.
Executing arbitrary Playwright snippets when a single command is not enough.
Juggling several isolated browser sessions at once.
Persisting and restoring cookies and localStorage so tests start logged in.
Turning a recorded interaction into an actual Playwright test.
Recording and inspecting execution traces for post-mortem debugging.
Capturing a session as video — useful evidence on a bug ticket.
Reading element attributes that the accessibility snapshot does not expose.
You can point an agent at the CLI and let it discover the commands itself:
Test the "add todo" flow on https://demo.playwright.dev/todomvc
using playwright-cli. Check playwright-cli --help for available commands.Skills work with Claude Code, GitHub Copilot, Cursor and any agent that supports locally installed skills.
Track 3.6
Honest answer: learn both. They share the same mental model — snapshot the page, target an element by its accessible identity, act, re-snapshot. Master that loop and switching between CLI and MCP is a matter of syntax, not concepts. See Track 1 for the MCP side.
Section 4
Everything above, compressed into answers you can quiz yourself with. Open one, cover the text, and try to explain it out loud first.
MCP (Model Context Protocol) is an open standard that lets an AI model talk to external tools and data sources through one common language. The AI app runs an MCP client; each tool runs an MCP server.
It is not a model and not an agent — it is the wiring. Without MCP a model can only describe what you should do; with MCP it can open the browser, read your repo, query the database and run your tests. Anthropic open-sourced it in late 2024 to replace M×N custom integrations with M+N.
An AI agent is a model that is given a goal, a set of tools, and permission to keep working until the goal is met. It runs a loop: observe → think → act → observe.
An assistant answers a question in one turn. An agent completes an outcome over many turns, tracks its own progress, and re-plans when something fails.
A Playwright Agent is a multi-agent architecture for the test lifecycle. Instead of one model doing everything, specialised agents each own one responsibility — most commonly Planner (what to test), Generator (write the code) and Healer (keep it green).
Underneath it is still ordinary Playwright: the same runner, the same browsers, the same
expect() assertions. The agents write and maintain the code; Playwright executes it.
It converts a requirement into a reviewable test plan: understand the requirement, explore the application, identify pages, identify scenarios, set priorities and test data, and state what is out of scope.
The Planner does not execute tests and does not write code. That separation is the whole point — a plan is cheap to review and cheap to correct, and catching a scope mistake here saves rewriting hundreds of lines later.
It turns the approved plan into runnable Playwright code: page objects, spec files, locators, web-first assertions, fixtures, test data and reporter configuration.
Its key advantage over a hand-written first draft is that it reads locators from the live DOM through
the browser tool, so it can prefer getByRole and
getByTestId instead of guessing a fragile CSS chain.
It reacts to failures: analyse the error and trace, compare the expected DOM with the current one, find a better locator, patch the page object, and re-run to prove the fix.
The critical rule: a Healer must never mask a real product bug. If an element is genuinely missing because the feature is broken, the test has to fail loudly. Healing applies to how we find an element, never to whether the behaviour is correct.
data-testid. Good locators make agents dramatically more reliable.expect(locator).toBeVisible()) over manual sleeps — for humans and agents alike.A realistic first week:
npm init playwright@latestPractise against a site built for it — try the
QA Automation Labs demo shop, where every element
already carries a data-testid.
Section 5
The seven sentences that clear up almost every beginner misconception.
MCP is not an AI model.
MCP is a communication protocol.
Agents are task executors.
Playwright Agent combines AI with Playwright automation.
The Planner does not execute tests.
The Generator creates automation code.
The Healer repairs failing tests — it never hides real bugs.
One last thing. None of this removes the need to understand testing. An agent can write a hundred assertions; deciding which hundred are worth writing is still the QA engineer’s job — and it is the part of the role that is getting more valuable, not less.
Want more? Explore the courses, practise on the demo shop and the UI testing playground, or read the blog.