> Where AI agents help with end-to-end tests: Playwright planner, generator and healer, MCP or CLI, and the guardrails that keep healed tests honest.
>
> Web page: https://balazscsorba.com/blog/browser-agents-e2e-testing-playwright · Language: English · Also available in: [Deutsch](https://balazscsorba.com/de/blog/browser-agents-e2e-testing-playwright.md) · [Magyar](https://balazscsorba.com/hu/blog/browser-agents-e2e-testing-playwright.md)
> Author: Balázs Csorba · Published: 2026-10-16 · Keywords: playwright test agents, playwright planner generator healer, ai e2e testing, playwright mcp, llm generated playwright tests, self-healing tests, browser agent testing, playwright init-agents, ai test automation 2026, playwright cli skills

[Blog](https://balazscsorba.com/blog)/AI agents

# Browser agents for E2E testing: let agents write Playwright tests, not run them

Where AI agents help with end-to-end tests: Playwright planner, generator and healer, MCP or CLI, and the guardrails that keep healed tests honest.

[Balázs Csorba](https://balazscsorba.com/about)·October 16, 2026·7 min read

-   Playwright
-   E2E testing
-   Coding agents
-   MCP
-   Test automation

![An agent explores a web app, writes a Markdown test plan, turns it into Playwright tests, and a healer repairs locators while assertions stay under review.](https://balazscsorba.com/images/blog/browser-agents-e2e-testing-playwright/cover.webp?v=0ad9b19637)

## Key takeaways

-   Use agents to write and maintain deterministic Playwright tests; CI should run plain test files, not an LLM deciding what passed.
-   Playwright ships planner, generator and healer agents that turn a seed test and a request into a Markdown plan and then into test files.
-   For coding agents, Playwright's own docs now point to the CLI with skills as more token-efficient than the MCP server.
-   A healer may update locators and waits on its own; any change to an assertion or a skipped test needs a human review.
-   Accessible markup is the contract: role-based locators are what both agents and resilient tests rely on.

On this page

1.  [What are the three ways to use agents in E2E testing?](https://balazscsorba.com/#three-ways-agents-meet-e2e)
2.  [How do Playwright's test agents work?](https://balazscsorba.com/#playwright-test-agents)
3.  [Should coding agents use Playwright MCP or the CLI?](https://balazscsorba.com/#mcp-or-cli)
4.  [Why is accessible markup the contract for agents and tests?](https://balazscsorba.com/#accessibility-is-the-contract)
5.  [How do you keep self-healing tests honest?](https://balazscsorba.com/#healer-guardrails)
6.  [When does a runtime browser agent still make sense?](https://balazscsorba.com/#runtime-agents)
7.  [What does a practical setup look like?](https://balazscsorba.com/#setup-checklist)
8.  [Sources](https://balazscsorba.com/#sources)

Listen to this article

0:000:00

Browser agents can now open an app, read the page, click through a checkout and tell you whether it worked. It is tempting to turn that into the test suite: describe the flows in plain language and let a model check them on every pull request. I think that is the wrong place for the model. The better split is to let agents do the expensive human work, exploring the app, writing tests and fixing broken locators, and let CI run plain Playwright tests that give the same answer every time.

This article compares the three ways agents meet E2E testing, walks through Playwright's own test agents, covers MCP versus CLI for coding agents, and sets the guardrails I use so that a self-healing test cannot quietly heal away a real bug.

## What are the three ways to use agents in E2E testing?

Approach

What the agent does

Runs in CI?

Main risk

Agent writes tests

Explores the app, writes a plan and Playwright test files

No, the tests do

Tests that assert the wrong thing

Agent repairs tests

Runs failing tests, inspects the UI, patches locators and waits

Optional, as a separate job

Healing away a real regression

Agent is the test

Follows natural-language steps in a live browser and judges the result

Yes

Slow, costly, non-deterministic verdicts

A test is useful because it is a fixed oracle: the same code, the same data and the same assertion give the same result. A model judging a screenshot is a second opinion, not an oracle. It is useful for exploration, but a red build should mean the product changed, not that the model changed its mind.

## How do Playwright's test agents work?

Playwright ships three [test agents](https://playwright.dev/docs/test-agents) as agent definitions you add to the repository with `npx playwright init-agents`, with loops for VS Code, Claude Code, Codex and OpenCode. The docs say to regenerate them whenever Playwright is updated, so they pick up new tools and instructions.

Every agent output is a file in the repository: plans, tests and patches all go through normal code review.

-   **Planner:** takes a request such as "plan guest checkout", a seed test that sets up fixtures and login, and optionally a requirements document. It runs the seed test, explores the app and writes a Markdown plan into `specs/`.
-   **Generator:** turns the plan into Playwright tests under `tests/`, verifying selectors and assertions live while it performs the scenarios. The docs note that generated tests may include initial errors.
-   **Healer:** given a failing test, it replays the steps, inspects the current UI for equivalent elements, suggests a patch such as a locator update, a wait adjustment or a data fix, and re-runs until the test passes or guardrails stop it. Its output is a passing test, or a skipped test if it believes the functionality is broken.

```
# Add the agent definitions for your coding agent (regenerate after Playwright upgrades)
npx playwright init-agents --loop=claude

# tests/seed.spec.ts: everything the agents need to reach a logged-in state
import { test, expect } from './fixtures'
test('seed', async ({ page }) => {
  await page.goto('/')
  await expect(page.getByRole('navigation')).toBeVisible()
})
```

## Should coding agents use Playwright MCP or the CLI?

[Playwright MCP](https://github.com/microsoft/playwright-mcp) lets a model drive a browser through structured accessibility snapshots instead of screenshots, so it needs no vision model and avoids the ambiguity of clicking on pixels. Its own README now draws a line, though: for coding agents it recommends the Playwright CLI with skills, because CLI calls avoid loading large tool schemas and verbose accessibility trees into the context. MCP remains the better fit for loops that benefit from a persistent browser session, such as exploratory automation and self-healing tests.

That matches the general trade-off in [AGENTS.md, skills, MCP or CLI](https://balazscsorba.com/blog/agents-md-skills-mcp-cli-decision-matrix): every resident tool schema and every page snapshot costs context on each turn. If a test session needs only a few page reads, the CLI is cheaper; the techniques in [cutting coding-agent tokens](https://balazscsorba.com/blog/token-saving-tools-coding-agents-top-20) apply here too.

## Why is accessible markup the contract for agents and tests?

Playwright's [best practices](https://playwright.dev/docs/best-practices) recommend user-facing locators such as `getByRole('button', { name: 'Submit' })` over CSS classes and XPath, because the DOM structure changes more often than what users see. Playwright MCP reads the same accessibility tree. So the work that makes a site usable with a screen reader also makes it easier for an agent to explore and produces tests that survive redesigns. A button that is a styled `div` without a role is invisible to all three.

For shops in the EU this is not optional anyway; see [the European Accessibility Act for B2B shops](https://balazscsorba.com/blog/european-accessibility-act-b2b-shop). Fixing roles and labels pays for compliance, agents and test stability at once.

## How do you keep self-healing tests honest?

The healer's job description contains the risk: it re-runs until the test passes, and if it believes the feature is broken, it marks the test skipped. Both outcomes are fine when a button was renamed. Both are bad when the button disappeared because of a real bug. The rule I use is simple: the healer may change how a test finds things, never what a test checks.

**A healed test that no longer fails is not a fixed test**

Treat every healer patch that touches an `expect(...)` line, removes a step, or adds `test.skip` or `test.fixme` as a possible product bug. Route it to a person, with the failing trace attached.

```
#!/usr/bin/env bash
# CI gate for agent-made test changes: locator and wait edits pass, assertion edits need review
set -euo pipefail
changed=$(git diff --unified=0 origin/main -- 'tests/**/*.spec.ts' | grep -E '^[-+][^-+]' || true)
if echo "$changed" | grep -Eq 'expect\(|test\.(skip|fixme)\(|\.toHave|\.toBe'; then
  echo "Assertions or skips changed in tests/: needs a human reviewer (label: test-assertions)"
  exit 1
fi
```

The same applies to tests an agent writes for a bug fix. A regression test is only worth something if it fails when the fix is reverted; I check that in every bug-fix PR, as described in [the agent loop](https://balazscsorba.com/blog/agent-loop-explained) and in my [bug-to-PR workflow](https://balazscsorba.com/blog/coding-agent-skills-workflow).

## When does a runtime browser agent still make sense?

There are cases where fixed selectors are the wrong tool. Exploratory testing before a release, where an agent tries unusual paths and reports what looked wrong. Smoke checks on third-party pages you do not control, such as a payment provider's redirect. Internal back-office flows that change weekly. For these, libraries like [Stagehand](https://github.com/browserbase/stagehand) combine natural-language `act`, `extract` and `observe` calls with Playwright-style page and locator APIs, so a script can be mostly deterministic with a few flexible steps. I compare it in more detail in the [Stagehand review](https://balazscsorba.com/tools/browserbase-stagehand).

Keep these runs out of the merge gate. Report their findings as issues or as new deterministic tests, and keep the pass or fail decision on code you can read.

## What does a practical setup look like?

1.  A seed test with fixtures for login and test data, so agents start from a known state.
2.  Plans in `specs/` reviewed like requirements: a wrong plan produces correct-looking tests for the wrong behavior.
3.  Generated tests use role-based locators only; CSS selectors fail lint.
4.  CI runs plain `npx playwright test` with traces on failure; no model in the merge gate.
5.  The healer runs as a separate job that opens a PR; assertion changes and skips are blocked for review.

This is [harness engineering](https://balazscsorba.com/blog/harness-engineering-coding-agents) applied to testing: the agent gets guides (seed test, plans, locator rules) and sensors (the test run, the assertion gate), and the human review sits where the decisions are, not on every line.

## Sources

1.  [Playwright docs: Test agents (planner, generator, healer)](https://playwright.dev/docs/test-agents)
2.  [Microsoft: Playwright MCP README (MCP vs CLI, accessibility snapshots)](https://github.com/microsoft/playwright-mcp)
3.  [Playwright docs: Best practices](https://playwright.dev/docs/best-practices)
4.  [Playwright docs: Locators](https://playwright.dev/docs/locators)
5.  [Browserbase: Stagehand README (act, extract, observe)](https://github.com/browserbase/stagehand)

## Frequently asked questions

Can an AI agent replace my E2E test suite?

Not as the thing that runs in CI. An agent that clicks through the app at test time is slower, costs tokens on every run and can judge the same result differently twice. Use agents to write, extend and repair a normal Playwright suite, and run that suite deterministically.

What are Playwright test agents?

Playwright ships three agent definitions: a planner that explores the app and writes a Markdown test plan, a generator that turns the plan into Playwright test files while verifying selectors live, and a healer that runs failing tests and suggests patches. You add them with npx playwright init-agents for VS Code, Claude Code, Codex or OpenCode.

Should I use Playwright MCP or the Playwright CLI?

For coding agents working in a repository, the Playwright MCP README recommends the CLI with skills, because it avoids loading large tool schemas and accessibility trees into the context. MCP fits long-running exploratory or self-healing loops that benefit from a persistent browser session.

Are self-healing tests safe?

Only with limits. Fixing a renamed button locator is fine. Changing what a test asserts, or marking it skipped because the feature seems broken, can hide a real regression. Let the healer change locators and waits, and send assertion changes and skips to review.

When does a runtime browser agent make sense?

For exploratory testing, quick smoke checks on pages you do not control, and tasks where the UI changes too often for fixed selectors. Tools like Stagehand mix natural-language actions with Playwright-style code for these cases.

Written by Balázs Csorba

Senior fullstack & AI engineer in Styria, Austria – 10+ years of Vue, Nuxt, Node.js and PHP, now building tooling for AI agents.

[AI engineering & MCP servers →](https://balazscsorba.com/expertise/ai-engineer)[About me →](https://balazscsorba.com/about)

## More articles

-   [Context rot in long-running agents: clearing, compaction, memory and sub-agents](https://balazscsorba.com/blog/context-rot-compaction-long-running-agents)
-   [The A2A protocol explained: agent cards, tasks, and where it fits next to MCP](https://balazscsorba.com/blog/a2a-protocol-agent-interoperability)
-   [One senior with coding agents versus a team: what the evidence says](https://balazscsorba.com/blog/ai-assisted-development-economics)
-   [Spec-driven development for coding agents: agree the plan before the code](https://balazscsorba.com/blog/spec-driven-development-coding-agents)

## Sounds like what you need?

Tell me about your project or role – I’d love to hear from you.

[Get in touch](mailto:contact@balazscsorba.com) [Connect on LinkedIn](https://www.linkedin.com/in/balazs-csorba)
