CONCEPT · TUTORIALS
Your first E2E flow with an agent
Pick one critical flow of your project, have an agent plan it, generate the Playwright test, and report the result, so that you decide what gets fixed.
30 min · updated 2026-10
BEFORE READING
Goal
By the end you'll have one end-to-end (E2E) test of a critical flow of your project, written by your agent from a plan you reviewed, passing, and proven to fail when the app breaks.
The working rule of this guide: the agent runs the test and reports; you decide what gets fixed.
Prerequisites
- Playwright installed in your project (see the install guide), with
baseURLandwebServerset. - A coding agent connected to your project. This guide uses Claude Code.
- A place where the flow can write data safely: a local database or a development branch of your database. Never your production data.
This guide covers Playwright as of October 2026.
Steps
1. Pick one critical flow
Choose a flow that is short, important to the business, and stable. Examples: sign up, log in, book an appointment, complete a purchase. Write its expected result in one sentence, for example: "a visitor can book an appointment and sees a confirmation".
One flow is enough for this guide. E2E tests are slow and costly to maintain, so they are kept for what must never break.
2. Ask the agent for a plan, not code
I want an E2E test for this flow: a visitor books an appointment
from the booking page.
Do not write code yet. Explore the app and write a plan in plain
language: the starting state, each step the user takes, what they
should see at the end, and what data the flow creates.
Wait for my approval.Read the plan carefully. Correct it if a step is wrong or a result is missing. This is your review point: it is much cheaper to fix a plan than a test.
3. Generate the test from the approved plan
Write the Playwright test from the approved plan.
Use locators by role and visible text, assertions that wait on
their own, no fixed sleeps, and one flow in one test.
Then run it.The result should look like this (illustrative, your labels will differ):
import { test, expect } from '@playwright/test';
test('a visitor can book an appointment', async ({ page }) => {
await page.goto('/booking');
await page.getByRole('button', { name: 'Bath' }).click();
await page.getByLabel('Name').fill('Ana');
await page.getByRole('button', { name: 'Confirm' }).click();
await expect(page.getByText('Your appointment is confirmed')).toBeVisible();
});4. Run the test and make the agent report
Run `npx playwright test`.
If it fails, do not change any file. Report: which step failed,
what the screenshot and the trace show, whether you think the
test is outdated or the app has a bug, and the fix you would propose.The agent only reports. You decide what happens next.
5. Decide what to fix
When a test fails, there are two possible diagnoses:
- The test is outdated (a text, a label, or a step changed on purpose): update the test, after confirming that the intention really changed.
- The app has a bug: fix the application code and do not touch the test. The test is the judge. If you edit it to make it pass, it stops protecting you.
Then run the test again.
6. Prove that the test catches a bug
A test that always passes is worthless. Break the app on purpose, for example by renaming a field in the request your frontend sends to the API, and run the test: it must fail. Then revert the change and check that it passes again.
Expected result
- One E2E test of a critical flow of your project, passing.
- The same test failing when you break the app on purpose, with a clear report from the agent.
- A plan in plain language saved in your project or your notes.
Troubleshooting
Common issues
- The test passes the first time and fails the second: the flow creates data (for example a booked time slot) that collides on the next run. Use different data on every run, or clean up after the test. Run against a test database, not a real one.
- The agent edited the test to make it pass: reject the change and review the diff. A test that was "fixed" without you deciding that the intention changed may be hiding a real bug.
- The test never fails, even when you break the app: its assertions are too weak. Ask the agent to assert on what the user must see at the end of the flow.
- The test fails randomly: look for fixed waits and fragile locators. Prefer locators by role and visible text, and assertions that wait on their own.
- The app does not start for the test: check
webServerandbaseURLinplaywright.config.ts.
Next step
Add a second flow, once the first one is stable. If you want to go further, Playwright (since v1.56) ships three agent definitions you can generate for Claude Code with npx playwright init-agents --loop=claude: a planner that explores the app and writes a Markdown plan, a generator that turns the plan into tests, and a healer that repairs failing tests. Regenerate them whenever you update Playwright. Keep in mind that the healer works in a loop until the test passes, so review every change it makes.