Playwright: From Test Runner to AI Agent Interface
In 2017, Google built Puppeteer to automate Chrome. In 2020, the two lead developers left Google, joined Microsoft, and built Playwright, which follows the same idea but supports several browsers from day one. By April 2025, Playwright had overtaken Cypress in npm downloads.
In March 2025, Microsoft released Playwright MCP, an MCP server that lets AI agents control a browser using the same API you write tests with. Within a year the repository had 25,000+ GitHub stars, with integrations for tools including Claude Code, Cursor, VS Code, and GitHub Copilot. Playwright had become an important browser-automation option for AI agents.
With getByRole, you test whether Playwright can locate the UI through roles and accessible names. Those signals also support Playwright MCP and other snapshot-dependent agents, without proving complete interaction or task success.
Playwright in Numbers
What started as a Puppeteer alternative now has more weekly npm downloads than Cypress, Puppeteer, and Selenium:
Weekly npm downloads in millions. Source: npm registry. Playwright went from 56K weekly downloads in 2020 to 34M+ in 2026. More than 12,400 companies use it, including Amazon, Apple, Microsoft, and NVIDIA.
The 25,000+ stars on the Playwright MCP repository point to a second audience. That separate project lets AI agents drive Playwright, so it reaches beyond test suites.
What Is Playwright MCP?
MCP (Model Context Protocol) is the open standard for connecting AI assistants to external tools. Playwright MCP is Microsoft's official MCP server that gives AI agents a browser they can control. It was released in March 2025 as an open-source browser-automation option for compatible agents.
It exposes 70+ tools
organized into capability groups: navigation, clicking, typing, form filling, tab management, PDF generation, and more. For this article, the most relevant tool is browser_snapshot.
browser_snapshot: How Agents Read a Page
Within Playwright MCP, browser_snapshot exposes the browser's accessibility tree as a YAML-serialized representation of semantically meaningful elements. Other browser-agent systems may also use the DOM, screenshots, or a combination of modalities.
# browser_snapshot output for a login form
- heading "Welcome back" [level=2]
- textbox "Email" [required] (ref=1)
- textbox "Password" [required] (ref=2)
- button "Sign in" (ref=3)
- link "Forgot password?" (ref=4)
- link "Create account" (ref=5)
The snapshot contains no CSS classes, layout divs, or inline styles. It lists what the page contains and what you can do with it. Each interactive element gets a reference number, and the agent sends "click ref 3" to sign in. The output is predictable and small in tokens.
Playwright MCP runs in two modes:
Snapshot Mode (Default)
Playwright MCP's default snapshot mode uses the accessibility tree for structured interaction. It is fast and token-efficient, while other browser-agent systems may combine DOM data and screenshots.
Vision Mode (Opt-in)
Falls back to screenshots for visually complex pages. Adds mouse coordinate tools (click_xy, move_xy, drag_xy). Used when the accessibility tree doesn't capture enough context.
Snapshot mode is the default, and vision mode is opt-in.
Who's Using Playwright MCP?
Playwright MCP works with several widely used developer tools:
Claude Code
One command to add: claude mcp add playwright -- npx @playwright/mcp@latest. Opens a visible Chrome window. You can log in yourself while the agent watches, and cookies persist for the session.
Cursor
Global MCP config in ~/.cursor/mcp.json. Cursor uses Playwright MCP to preview changes, verify UI behavior, and navigate documentation sites.
VS Code Copilot
MCP support added in VS Code 1.99 (March 2025). Agent Mode uses Playwright MCP to verify code changes directly in the browser.
GitHub Copilot Coding Agent
Built-in, zero configuration. The coding agent uses Playwright MCP to open your app, navigate, and verify its own changes. Works through the same Playwright framework as your test suite.
Several AI coding tools can now access a browser through Playwright MCP. In those workflows, an agent navigates your website using the same automation framework you test with.
data-testid vs getByRole: What Each Locator Tests
With data-testid,
you test whether your own label still matches. The test can pass without showing that a user can find the button or that a screen reader can announce it. It also says nothing about whether the element appears in a Playwright MCP snapshot.
data-testid
Tests whether your own label still matches. Stable, but doesn't validate that users, screen readers, or AI agents can actually find the element.
getByRole / getByLabel
Tests whether Playwright can find an element by role or label. Those roles and names are also available to screen readers and Playwright MCP snapshots, but finding them does not prove complete interaction or task success.
With getByRole,
your test fails when the button is not a real button, so you fix the markup. The fixed markup then appears in the accessibility tree that Playwright MCP reads through browser_snapshot.
The accessibility tree doesn't include test attributes. When Playwright MCP calls browser_snapshot, your carefully placed
data-testid="submit-btn"
does not appear. The snapshot contains roles, labels, and names, which are exactly what
getByRole
and getByLabel
query.
// Your Playwright test
await page.getByRole('button', { name: 'Add to cart' }).click();
await page.getByLabel('Email').fill('user@example.com');
await page.getByRole('link', { name: 'Checkout' }).click();
// What an AI agent sees via Playwright MCP browser_snapshot
// - button "Add to cart" (ref=12)
// - textbox "Email" (ref=15)
// - link "Checkout" (ref=18)
// Same selectors. Same elements. Same accessibility tree.
A getByRole
locator and a snapshot entry read the same
roles and accessible names. With getByRole
you test UI semantics and confirm that roles and names are available to snapshot-dependent agents such as Playwright MCP. That does not by itself prove complete navigation or task success. With
data-testid
you test a string you chose yourself.
Playwright's own
locator priority guide
recommends getByRole
as the first choice and data-testid
as a last resort. The guide's reasoning is to "test like a user." The same locators also match what Playwright MCP snapshots expose.
The Flywheel: How Testing, Accessibility, and Agent Readiness Connect
Using Playwright with semantic selectors works like this:
-
You write Playwright tests with accessibility-first selectors
like
getByRole,getByLabel, andgetByText - This pushes you toward accessible HTML. If your getByRole selector cannot find the element, it is not a proper button. Your test fails, so you fix the markup
- Accessible HTML produces a fuller accessibility tree, the same tree that Playwright MCP reads
- Snapshot-dependent agents receive useful targets. Roles and accessible names expose controls to the accessibility tree, but do not prove navigation or task success
-
Your tests validate the semantics Playwright MCP exposes.
If your test suite passes with
getByRoleselectors, you've verified the relevant roles and accessible names
A Playwright suite that uses semantic selectors verifies roles and accessible names that snapshot-dependent agents can also consume. That overlap is useful evidence, but it does not make a website agent-ready or prove that an agent can complete a task.
ARIA Snapshots: Testing the Tree Itself
Playwright also offers ARIA snapshot testing, which lets you write assertions directly against an accessibility representation. Instead of checking only whether an element exists in the DOM, you verify the semantic structure that Playwright exposes to tests and snapshots.
// ARIA snapshot test — validates the accessibility tree directly
await expect(page.getByRole('navigation')).toMatchAriaSnapshot(`
- link "Home"
- link "Products"
- link "Pricing"
- link "Contact"
`);
// This validates:
// 1. A navigation landmark exists
// 2. It contains four links with these exact names
// 3. The accessibility tree is correct for both screen readers and AI agents
If your ARIA snapshot test passes, you have verified the YAML structure Playwright MCP returns when it calls browser_snapshot. This covers that structured snapshot only. The agent may still use other context such as screenshots or DOM data.
Playwright also introduced Test Agents, built-in AI that uses the accessibility tree to plan, generate, and heal tests. The planner explores your app through accessibility snapshots, the generator writes tests with
getByRole
selectors, and the healer fixes broken tests after UI changes by reading the accessibility tree again.
Beyond Playwright MCP: Other Browser Agents
Playwright MCP is not the only way AI agents browse the web. This table compares it with other browser agents and frameworks:
| Agent / Framework | Approach | Uses Accessibility Tree | Built on Playwright |
|---|---|---|---|
| Playwright MCP | Accessibility snapshots (YAML) | Yes (primary) | Yes |
| browser-use | Snapshot + numbered refs | Yes (primary) | Yes |
| Amazon Nova Act | Direct Playwright integration | Yes | Yes |
| Vercel Agent Browser | Streamlined accessibility refs | Yes (primary) | Yes |
| OpenAI CUA / Operator | Hybrid (screenshots + tree) | Yes (supplementary) | Partial |
| Claude Computer Use | Hybrid (screenshots + read_page) | Yes (supplementary) | No |
Several tools in this comparison build on Playwright or expose accessibility snapshots, while others combine screenshots with structured browser data. The framework you chose for testing may also support an agent's browser workflow.
What This Means for Your Team
If you already use Playwright, part of the groundwork may be done. It depends on how you write your locators:
Good signs if...
Your tests use getByRole, getByLabel, and getByText as primary locators. Your UI uses semantic HTML. Form fields have proper labels. Buttons have accessible names.
Work to do if...
Your tests rely on data-testid, CSS selectors, or XPath. Your UI uses generic div elements patched with ARIA attributes. Form fields use placeholder text instead of labels.
Practical Steps
-
Audit your locator strategy.
Grep your test suite for
data-testidvsgetByRole. The ratio shows how many of your locators depend on roles and names -
Migrate critical paths first.
Start with your most important user flows: login, search, checkout, signup. Rewrite those tests to use
getByRoleselectors. Fix the HTML where tests fail - Add ARIA snapshot tests. For key pages, add snapshot tests that validate the accessibility tree structure. A passing snapshot confirms roles, names, and states. It does not prove complete navigation or task success
- Try Playwright MCP yourself. Install it in Claude Code or Cursor and point an agent at your own site. Compare what it sees with what you expect on the page
- Scan for AI agent readiness. Use our free scanner to check semantic HTML, form labels, heading hierarchy, and interactive surface coverage across 77 checkpoints
The Bigger Picture: Tests as a Contract for Roles and Names
Playwright tests written with accessibility selectors provide a contract for the roles, names, and states Playwright MCP can reference. If your test finds the "Add to cart" button by role and name, that semantic target can also appear in a Playwright MCP snapshot. The test does not define everything an agent can do.
Compare this to WebMCP , the W3C proposal where websites explicitly register tools for AI agents. WebMCP uses tool definitions. Playwright MCP exposes semantic browser targets through accessibility snapshots. These mechanisms offer different levels of structure and neither guarantees task completion.
Teams that already test with semantic selectors expose useful roles and names to Playwright MCP and other snapshot-dependent agents. That supports one interaction modality, alongside DOM access, screenshots, and explicit agent protocols.
Conclusion
Playwright started as a Puppeteer alternative, became a popular testing framework, and is now a browser runtime that AI agents can use through MCP. Each step built on the last: cross-browser automation, accessibility-first selectors, and MCP-based agent control.
A data-testid locator tests whether your own label still matches. A locator like
getByRole tests localization through roles and names and supports snapshot-dependent agents, but it does not prove complete interaction or task success. It also keeps your tests aligned with how users and screen readers identify controls.
Sources
- Playwright: Microsoft's Browser Automation Framework (80,000+ GitHub stars, 33M weekly npm downloads)
- Playwright MCP: Browser Automation for AI Agents (25,000+ GitHub stars, 70+ tools, released March 2025)
- Playwright Locators Documentation (Recommended locator priority: getByRole first, data-testid as last resort)
- Playwright ARIA Snapshots (Testing accessibility tree structure directly)
- Playwright Test Agents (AI-powered test planning, generation, and healing)
- Simon Willison: Playwright MCP with Claude Code (Practical usage guide and authentication patterns)
- GitHub Blog: Debug Web Apps with Playwright MCP and Copilot
- GitHub Docs: MCP and Copilot Coding Agent (Playwright MCP auto-configured for Copilot's coding agent)
- TestDino: Playwright Market Share 2025 (45.1% QA adoption rate, 235% YoY growth)
- Fastly: AI Crawlers Make Up 80% of AI Bot Traffic
- IsAgentReady: How AI Agents See Your Website: The Accessibility Tree Explained
- IsAgentReady: What Is MCP? The Model Context Protocol for AI Agents
- IsAgentReady: What Is WebMCP and Why Your Website Needs It