Agents.md for Playwright: A 7-Section File That Makes AI-Written Tests Reliable
AI tools write Playwright tests fast but break your conventions. Here is the agents.md file that keeps them in line.

Every AI coding tool now reads one plain text file in your repository before it writes anything, and most Playwright projects still do not have one. The AGENTS.md format is used by more than 60,000 open-source projects, and an agents.md for Playwright is quickly becoming the line between AI-written Playwright tests a team keeps and tests it throws away.
The pain is familiar. The agent writes a login test in 30 seconds, but it uses a CSS class, sleeps for 3 seconds, and logs in through the UI in every test, so the reviewer leaves the same 4 comments they left last week.
This guide shows what belongs in the file, gives you a template to copy, explains how it fits with the built-in Playwright test agents, and covers how to make the rules stick instead of staying polite suggestions.
What agents.md for Playwright actually is
An agents.md for Playwright is a Markdown file, usually named AGENTS.md at the repository root, that tells AI coding agents how tests are organized, how to run them, which locator and waiting rules to follow, and when a generated test counts as done. The official agents.md project describes the format as "a README for agents."
A README written for machines, not people
Your README explains the project to a new teammate. The agents file explains it to Codex, Copilot, Cursor, or Claude Code before they touch a spec file. According to the official agents.md site, the format emerged from work across OpenAI Codex, Amp, Google's Jules, Cursor, and Factory, and it is now stewarded by the Agentic AI Foundation under the Linux Foundation.
There is nothing clever about the format. It is standard Markdown with no required fields, and the project states that agents read "the nearest file in the directory tree." You can write one in 10 minutes. The hard part is deciding what to say, which is most of this article.
Which coding tools read it
The reason one file is worth writing is that nearly every tool your team might use reads it. The table below is based on each vendor's own documentation.
| Tool | Reads AGENTS.md? | Where it looks | Documented detail |
|---|---|---|---|
| OpenAI Codex | ~/.codex/AGENTS.md, then repo root down to the current folder | Files are concatenated root-down; combined size capped at 32 KiB by default | |
| GitHub Copilot | Anywhere in the repo | "The nearest AGENTS.md file in the directory tree will take precedence"; a root CLAUDE.md or GEMINI.md is also accepted | |
| Cursor | Project root, with nested files in subdirectories | Documented as a "simple alternative to .cursor/rules" | |
| Claude Code | Working directory and parents | Read directly from v2.1.277 when no CLAUDE.md exists, or imported with @AGENTS.md |
That coverage matters when a team mixes tools. One engineer writes Playwright tests with Codex in the cloud, another runs Claude Code with Playwright in the terminal, and both pull the same rules.
Agents.md vs Playwright Test Agents: not the same thing
The naming collision trips people up, so it is worth separating the two early. Playwright 1.56 introduced Playwright Test Agents, which the release notes describe as "three custom agent definitions designed to guide LLMs through the core process of building a Playwright test." Those are the planner, generator, and healer, created by running npx playwright init-agents.
Your agents.md is different. It is your team's rulebook, written by you, and it applies to every agent and every task, not just the three Playwright ships. The two work well together, and a later section shows exactly how, but first you need to know how tools actually load the file.
How coding agents find and apply the file
The behavior is consistent in spirit across tools and different in the details. Getting the details right is what stops a rule from silently never loading.
Nearest file wins
The agents.md specification puts it in one line: "The closest AGENTS.md to the edited file wins; explicit user chat prompts override everything." So a root file sets the baseline, and a file in tests/e2e/ can tighten it for that folder.
Codex documents the mechanics most precisely. It walks from the Git root to the current directory, picks at most one file per directory, and joins them with blank lines so closer files appear later in the prompt. An AGENTS.override.md at any level beats the plain file at that level, and empty files are skipped.
Claude Code, Copilot, and Cursor differences
Claude Code has one rule you must know. By default it reads AGENTS.md only when there is no CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md in the working directory or above it. If you want both, the documented options are to put @AGENTS.md inside CLAUDE.md, or to set the project instructions option to claude-md-and-agents-md.
Note: Claude Code's documentation states that instruction files are treated "as context, not enforced configuration." The same is true for every tool in the table above. A rule in the file raises the odds of compliance; it does not guarantee it, which is why a later section covers lint and hooks.
Copilot accepts AGENTS.md files "stored anywhere within the repository" and adds path-specific .instructions.md files with an applyTo glob. Cursor reads a root AGENTS.md and nested ones "in any subdirectory," merged with its own .cursor/rules. If your team writes Playwright tests with Copilot or Playwright tests with Cursor, the same root file serves both.
Why size matters more than you expect
Codex stops adding files once the combined size reaches 32 KiB. Claude Code's guidance is to target under 200 lines per instruction file, because "longer files consume more context and reduce adherence." A Playwright rulebook that tries to be a wiki gets truncated or ignored.
That constraint shapes the rest of this guide. The goal is a short file where every line is a rule a reviewer could check, which brings us to what those lines should be.
What to put in an agents.md for Playwright: 7 sections
Here is the shortest useful structure. Each section answers one question an agent would otherwise guess at.
- Project map: where specs, fixtures, page objects, and config live.
- Commands: how to run all tests, one file, UI mode, and lint.
- Locator rules: the priority order and what is banned.
- Waits and assertions: web-first assertions only, no fixed sleeps.
- Isolation and test data: how auth, seeding, and cleanup happen.
- Network boundaries: what to mock and what never to mock.
Definition of done and out of scope: when the agent stops and what it must not touch.

Project map and commands
Agents waste tokens and make wrong guesses when they have to discover layout. State where specs live, which file exports the extended test object, and where page objects go. Then list the exact commands, including the one for a single file and the one for lint.
This section also tells the agent what not to invent. If you say fixtures live in tests/fixtures.ts, it stops creating a second helper file with a slightly different name every time.
Locator rules the agent cannot bend
Playwright's official best practices say to "prefer user-facing attributes to XPath or CSS selectors" and warn that "your DOM can easily change so having your tests depend on your DOM structure can lead to failing tests." Put that priority order in writing: role, then label or text, then test id, with CSS and XPath banned unless a comment explains why.
The payoff is consistency. Agents are good at following a ranked list and bad at inferring one from 40 existing spec files with mixed habits. A deeper walkthrough of each strategy lives in the guide to Playwright locators.
Waits, assertions, and the no-sleep rule
The single most common AI mistake in Playwright is a hard wait. The official docs are blunt: with web-first assertions "Playwright will wait until the expected condition is met," while a plain isVisible() check "won't wait a single second." Your file should name the banned call, page.waitForTimeout(), and the replacement pattern.
Spell out navigation too. An agent that reads "wait for navigation with await expect(page).toHaveURL(/dashboard/)" produces that line. One that reads "avoid flakiness" produces a sleep. The reference on Playwright assertions covers the retrying matchers worth naming.
Tip: Write every rule in your agents.md for Playwright as a check someone could fail in code review. "Never call page.waitForTimeout()" is checkable. "Write robust tests" is not, and agents treat it as noise.
Isolation, fixtures, and test data
Playwright's guidance is that "each test should be completely isolated from another test and should run independently with its own local storage, session storage, data, cookies etc." Agents routinely break this by logging in through the UI in every test or reusing a record another test created.
The fix is to name the mechanism. Say that login happens through a fixture backed by storageState, that data is created through an API helper, and that cleanup lives in fixture teardown. The patterns are documented in depth under Playwright fixtures and Playwright authentication.
Definition of done and what not to touch
Agents stop when they think they are finished, so define finished. A good bar is that the file passes 3 repeated runs, lint is clean, and the diff contains only test code. Then list the forbidden moves: no edits to config or CI files, no new dependencies, and no test.skip to make a run green.
Network boundaries fit here too. The official advice is "don't try to test links to external sites or third party servers that you do not control," so mock those with the patterns from Playwright network mocking and never mock your own app in end-to-end tests. With the sections settled, you can see them assembled into one file.
A copy-paste AGENTS.md template for Playwright projects
The template below is deliberately short. It fits comfortably under Codex's 32 KiB limit and Claude Code's 200-line guidance, and it uses paths you should change to match your repository.
# Playwright test guide for AI agents
## Project map
- End-to-end specs: `tests/e2e/**/*.spec.ts`
- Shared fixtures: `tests/fixtures.ts` (import `test` and `expect` from here, never from `@playwright/test` directly)
- Page objects: `tests/pages/*.page.ts`
- Config: `playwright.config.ts` (do not edit without asking)
## Commands
- Run all tests: `npx playwright test`
- Run one file: `npx playwright test tests/e2e/login.spec.ts`
- Debug in UI mode: `npx playwright test --ui`
- Lint: `npm run lint`
## Locators
- Priority: `getByRole` > `getByLabel` / `getByText` > `getByTestId`.
- Never use CSS classes, XPath, or `nth()` unless no accessible attribute exists. Leave a comment explaining why.
- Test ids use the `data-testid` attribute in kebab-case.
## Waits and assertions
- Never call `page.waitForTimeout()`.
- Use web-first assertions: `await expect(locator).toBeVisible()`, not `if (await locator.isVisible())`.
- Wait for navigation with `await expect(page).toHaveURL(/dashboard/)`.
## Isolation and data
- Every test must pass alone and in any order. No shared mutable state between tests.
- Log in through the `authenticatedPage` fixture, never through the UI in a test body.
- Create test data with `tests/helpers/api.ts` and clean it up in fixture teardown.
- Use `baseURL` from config. No hardcoded hosts or ports.
## Network
- Mock third-party services with `page.route()`. Never mock our own API in end-to-end tests.
## Definition of done
- `npx playwright test <file> --repeat-each=3` passes.
- `npm run lint` is clean.
- One scenario per `test()`, titled as a user outcome, e.g. "shows an error for a wrong password".
- The diff contains test code only. No changes to snapshots, config, or CI files.
## Out of scope
- Do not add dependencies.
- Do not use `test.skip` or `test.fixme` to make a run green. Report the failure instead.
Two things make this template work. Every bullet is a concrete instruction with a file path or a function name, and every section maps to a question the agent would otherwise answer on its own. The locator and assertion rules are lifted straight from Playwright best practices, so you are not asking the agent to follow house style, you are asking it to follow the framework's own advice.
Adjust the structure to your repo rather than the other way round. If you use a Playwright page object model, add a line on when to create a new page class versus extending one. If your playwright.config.ts is not yet settled, the free Config Generator among TestDino's free Playwright tools produces a starting point you can then describe in the file.
Keep the first version small and let review comments feed it. The documented trigger in Claude Code's guidance applies to every tool: add a rule when the agent "makes the same mistake a second time." That habit keeps the file honest and short.
How agents.md for Playwright works with Playwright Test Agents
Once the rulebook exists, the next question is how it relates to the planner, generator, and healer that Playwright generates for you. The short answer is that they sit at different layers.
What init-agents generates
Running the init command writes agent definitions for the tool you pick. The official docs list the loops below, and the generator source in the Playwright repository shows where each one writes its files.
npx playwright init-agents --loop=vscode
npx playwright init-agents --loop=claude
npx playwright init-agents --loop=codex
npx playwright init-agents --loop=opencode
| Loop | Agent definitions | Tool configuration |
|---|---|---|
| claude | .claude/agents/<name>.md | .mcp.json |
| vscode | .github/chatmodes/<name>.chatmode.md | .vscode/mcp.json |
| copilot | .github/agents/<name>.agent.md | .github/workflows/copilot-setup-steps.yml |
| codex | .codex/agents/<name>.toml | Embedded in the agent files |
| opencode | .opencode/prompts/<name>.md | opencode.json |
Those files are not yours to edit. The docs say the definitions "should be regenerated whenever Playwright is updated to pick up new tools," so any rule you add inside them disappears on the next upgrade. The generator's own definition already instructs it to write a single test per file inside a describe block that matches the plan's category. What it does not know is your fixture name, your test id convention, or your definition of done.
Where your file fits in the planner, generator, healer loop
That gap is exactly what agents.md fills. The host tool, whether Claude Code, Copilot, or Codex, loads your project instructions as context, and the Playwright agents run inside that host. Your file supplies the repository-specific rules, the generated definitions supply the browser tools and workflow, and the Playwright MCP server underneath supplies the live browser.
The workflow in the docs has three artifacts: a seed.spec.ts that "sets up the environment necessary to interact with your app," Markdown plans in specs/, and generated tests in tests/. Your agents.md should name the seed file and the fixtures it imports, so the planner starts from your setup rather than a blank page.
Note: The healer "re-runs the test until it passes or until guardrails stop the loop," according to the Playwright docs. Your "out of scope" section is one of those guardrails. Without a written ban, a healer can reach for test.fixme() as a repair, which the generated definition itself allows when a test cannot be fixed.
The healer is where the rules pay off most. It is designed to replay failing steps, inspect the UI, and patch the test. Give it the locator priority and the no-sleep rule and it repairs toward your conventions instead of away from them. The broader playbook for fixing Playwright tests with AI covers how to review those patches. Either way, the file is only context, so the next step is turning context into enforcement.
Make the rules enforceable, not just readable
Every vendor says the same thing in different words: instruction files guide the model, they do not constrain it. Claude Code's docs recommend a PreToolUse hook "to block an action regardless of what Claude decides." The practical reading is that the file sets expectations and tooling catches the misses.
That gap between expectation and output is not a small one. The data below comes from the Stack Overflow 2025 Developer Survey, which gathered responses from more than 49,000 developers.

The headline numbers explain why review alone does not scale. Among respondents, 84% use or plan to use AI tools, yet 46% actively distrust their accuracy against 33% who trust it. The single biggest frustration, cited by 66%, is "AI solutions that are almost right, but not quite," and 45.2% say debugging AI-generated code is more time-consuming.
An almost-right Playwright test is the expensive kind. It passes locally, flakes in CI, and burns reruns. The cost pattern is laid out in the guide to Playwright flaky tests, and the Flaky Cost Calculator on the TestDino tools page puts a yearly dollar figure on it for your team.
Lint what the file says
Any rule you can express as a lint check should also exist as one. An ESLint plugin for Playwright can flag hard waits, missing awaits on assertions, and skipped tests. When the agent runs npm run lint as part of its definition of done, the rule enforces itself before a human sees the diff.
Gate the merge in CI
Make the Playwright job a required check, and run new or changed spec files with --repeat-each so a flaky test fails before it merges. The setup for Playwright in GitHub Actions shows how to shard that job so the extra repeats do not stretch the pipeline.
Review the output against the file
Treat the agents file as the review checklist for AI pull requests. If a reviewer finds a violation, the fix is a line in the file plus, where possible, a lint rule, not a one-off comment. Over time the Playwright test reporting you already collect shows whether the flake rate on agent-written specs is falling, which is the real measure that the file is working. Before that number moves, though, most teams hit the same handful of writing mistakes.
Common mistakes when writing agents.md for Playwright
The failures below show up in nearly every first draft. Each one has a cheap fix.
Writing wishes instead of rules
"Follow best practices" and "keep tests maintainable" are the most common lines in weak files and the least useful. Vendor guidance converges on the same advice: write instructions "concrete enough to verify." If a line could not fail a code review, cut it or make it specific.
Letting the file grow into a wiki
Each extra paragraph competes for the model's attention with the rules that matter. The documented limits are real: Codex truncates at 32 KiB combined, and Claude Code recommends under 200 lines. Move long explanations into linked docs or path-scoped rules, and keep the root file to commands and constraints.
Contradicting your own config
If the file says tests must pass without retries but playwright.config.ts sets 2 retries on CI, the agent gets a mixed signal and the human gets a false sense of stability. Keep the file and the config in agreement, especially on retries, timeouts, and baseURL. The reasoning behind sensible timeout defaults is covered under Playwright timeout.
Tip: Add a short "last reviewed" line with the Playwright version at the top of the file. When you upgrade, rerun init-agents to refresh the generated definitions and reread your own rules against the release notes. Playwright is on 1.63 at the time of writing, and APIs the file mentions do change.
Pointing at files that no longer exist
A rule that says "use the login helper in tests/utils/auth.ts" is worse than no rule once that file moves, because the agent either hunts for it or recreates it. Claude Code's audit command checks for "references to files or commands that don't exist," and a quick manual pass after any refactor does the same job in other tools.
Banning things without naming the replacement
"No hard waits" on its own leaves the agent to guess the alternative. Pair every ban with the pattern you want instead, as the template does. The wider list of Playwright mistakes is a good source of bans worth pairing this way. When the root file is clean and short, the remaining question is what to do when one file cannot cover a whole codebase.
When 1 file is not enough: nested files, rules, and skills
Large repositories need more than a single root file, and every major tool provides a way to layer guidance without bloating it.
Nested files for monorepos
The agents.md spec, Codex, Copilot, and Cursor all support nested files with the nearest one taking precedence. A root file can hold commands and locator rules, while apps/checkout/AGENTS.md adds the checkout fixtures and the payment sandbox rules only when an agent works there.
Path-scoped rules
Claude Code's .claude/rules/ directory accepts Markdown files with a paths field so a rule loads only for matching files, and Copilot's .instructions.md files use applyTo globs the same way. A rule like "visual tests under tests/visual must call toHaveScreenshot with maxDiffPixelRatio set" belongs here, not in the root.
Skills for deep how-to guidance
Some knowledge is too long for any instruction file: how to set up auth across 3 roles, how to mock a paginated API, how to shard in GitLab. That is what skills are for. The open-source Playwright skill on GitHub packages 70 Markdown guides across core testing, CI, the Playwright CLI, page objects, and migration, installed with one command.
npx skills add testdino-hq/playwright-skill

The three layers complement each other. The root file states the rules, skills carry the long explanations the agent pulls in only when the task matches, and the generated Playwright agents handle the plan, write, and repair loop. The setup for the Playwright skill in Claude Code shows the install and first run in detail.
A small but useful habit is to keep the request itself precise. A good file plus a vague prompt still yields a vague test. The structure for Playwright prompts that work, with a role, context, task, constraints, and verification step, pairs naturally with an agents file because the constraints are already written down.
With the file, the rules directory, and a skill pack in place, the agent has what it needs. What remains is watching the results over time so the rulebook keeps earning its place.
Conclusion
An agents.md for Playwright is a small file with an outsized effect. It replaces the comments reviewers repeat on every AI pull request with rules the agent reads before it starts, and because Codex, Copilot, Cursor, and Claude Code all read the same file, one rulebook covers the whole team.
Keep it short, keep it concrete, and keep it in agreement with your config. Pair each ban with a replacement, back the important rules with lint and CI gates, and regenerate the Playwright agent definitions on upgrade while leaving your own rules where they belong. When a test still fails, structured test failure analysis tells you whether the rulebook needs another line or the app needs a fix.
FAQs

Savan Vaghani
Product Developer

