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. Same idea, but cross-browser from day one. By April 2025, Playwright had overtaken Cypress in npm downloads. Just another testing tool winning the framework wars. Or so it seemed.
Then 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: 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 by the Numbers
What started as a Puppeteer alternative has become the dominant browser automation framework. The numbers are hard to argue with:
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.
But the number that matters most isn't on npm. It's the 25,000+ stars on the Playwright MCP repository, a separate project that turned Playwright from a testing tool into an AI agent runtime.
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. But the most important 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)
That's it. No CSS classes, no layout divs, no inline styles. Just what the page contains and what you can do with it. Each interactive element gets a reference number. The agent says "click ref 3" to sign in. Clean, predictable, cheap 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.
The default is snapshot mode. Not vision. Apparently screenshots of websites are not the best way for AI to understand them. Who knew.
Who's Using Playwright MCP?
Playwright MCP isn't a niche experiment. It's integrated into the tools most developers use daily:
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. Uses the exact same selectors 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 Is a Code Smell (You Just Can't Smell It Yet)
With data-testid
you're testing whether your own label still matches. The test passes, sure. But you haven't verified that a user can actually find that button, that a screen reader can announce it, or that an AI agent knows it exists. You're testing your own bookkeeping.
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 isn't a real button. That forces you to fix the markup. And that fixed markup shows up in the accessibility tree, the same tree that AI agents read via Playwright MCP's browser_snapshot.
The accessibility tree doesn't include test attributes. When Playwright MCP calls browser_snapshot, your carefully placed
data-testid="submit-btn"
simply doesn't exist. What does exist are roles, labels, and names, 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.
The test selector and the agent selector are the same thing. With
getByRole
you're testing UI semantics and confirming 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're testing a string you made up yourself.
Playwright's own documentation has been nudging teams in this direction for years. Their
locator priority guide
explicitly recommends getByRole
as the first choice and data-testid
as a last resort. At the time, the reasoning was "test like a user." Now the reasoning extends to "build for agents."
The Flywheel: Testing, Accessibility, Agent Readiness
Here's what happens when you use Playwright with semantic selectors:
-
You write Playwright tests with accessibility-first selectors
like
getByRole,getByLabel, andgetByText - This forces accessible HTML. If your getByRole selector can't find the element, it's not a proper button. Your test fails, so you fix the markup
- Accessible HTML produces a rich accessibility tree, the same tree that AI agents consume via Playwright MCP
- AI agents can navigate your site. They find buttons, fill forms, follow links, and complete tasks
-
Your tests validate the semantics Playwright MCP exposes.
If your test suite passes with
getByRoleselectors, you've verified the relevant roles and accessible names
Teams with a solid Playwright test suite using semantic selectors already have two things they didn't know they had: accessible interfaces and AI-agent-ready websites. Teams that skipped testing, or relied on visual regression tests and testid's? Neither.
ARIA Snapshots: Testing the Tree Itself
Playwright took this connection even further with ARIA snapshot testing, a feature that lets you write assertions directly against an accessibility representation. Instead of checking only if 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
via Playwright MCP. This covers that structured snapshot, while 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 automatically plan, generate, and heal tests. The planner explores your app via accessibility snapshots, the generator writes tests using
getByRole
selectors, and the healer fixes broken tests when the UI changes by re-reading the accessibility tree. It's agents all the way down.
Beyond Playwright MCP: The Browser Agent Landscape
Playwright MCP isn't the only way AI agents browse the web, but it set the pattern that others follow. Here's how the broader landscape looks:
| 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're already using Playwright, you're closer to AI agent readiness than you think. But the specifics of how you use it matter:
You're ready 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.
You have work to do if...
Your tests rely on data-testid, CSS selectors, or XPath. Your UI is div-soup with ARIA band-aids. Form fields use placeholder text instead of labels.
Practical Steps
-
Audit your locator strategy.
Grep your test suite for
data-testidvsgetByRole. The ratio tells you how agent-ready your tests (and your UI) are -
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. Watch what it sees. The gaps become obvious immediately
- Scan for AI agent readiness. Use our free scanner to check semantic HTML, form labels, heading hierarchy, and interactive surface coverage across 65 checkpoints
The Bigger Picture: Testing as an AI Agent Contract
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.
Organizations that invested in Playwright testing with semantic selectors already expose useful roles and names to Playwright MCP and other snapshot-dependent agents. That strengthens one interaction modality, alongside DOM access, screenshots, and explicit agent protocols.
Conclusion
Playwright went from Puppeteer alternative to a popular testing framework and then to a browser runtime available to AI agents through MCP. Each step followed logically from the last: cross-browser automation, accessibility-first selectors, and now MCP-based agent control.
With data-testid
you test whether your own label still matches. With getByRole
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.
Test like a user, build for an agent. Same selector.
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