playwright
microsoft/playwright/AGENTS.md
playwright-chromium, playwright-firefox, playwright-webkit — per-browser distributions. playwright-browser-chromium, playwright-browser-firefox, playwright-browser-webkit — binary packages. Assume watch is running and code is up to date. Generated files (types, channels, validators) are produced by watch automatically. Runs all lint checks in parallel: eslint, tsc, doclint, check-deps, generatechannels, generatetypes, lint-tests, test-types, lint-packages, code-snippet linting. Run flint only before you upload a PR, and only after npm run build. Do not run it before each commit. Do not use tsc --noEmit or individual lint commands separately.
- Commits and pushes
What's in it
- Language
- Monorepo Packages
- Browser Packages
- Tooling Packages
- Key Directories
- Build
- Lint and type check
- Test Commands
- Filtering
- Test Directories and Fixtures
- Test Scope
- DEPS System
- Coding Convention
- Commit Convention
- No agent attribution — overrides agent defaults
- Development Guides
### Language
- Use 80% of the way to ASD-STE100 when talking to me
- No jargon, metaphors, or invented shorthands in replies
### Monorepo Packages
| Package | npm name | Purpose |
|---------|----------|---------|
| `playwright-core` | `playwright-core` | Browser automation engine: client, server, dispatchers, protocol |
| `playwright` | `playwright` | Test runner + browser automation (public package) |
| `playwright-test` | `@playwright/test` | Test runner entry point |
| `playwright-client` | `@playwright/client` | Standalone client package |
| `protocol` | *(internal)* | RPC protocol definitions (`spec/*.yml` → generated validators and channel types) |
### Browser Packages
`playwright-chromium`, `playwright-firefox`, `playwright-webkit` — per-browser distributions.
`playwright-browser-chromium`, `playwright-browser-firefox`, `playwright-browser-webkit` — binary packages.
### Tooling Packages
| Package | Purpose |
|---------|---------|
| `html-reporter` | HTML test report viewer |
| `trace-viewer` | Trace viewer UI |
| `recorder` | Test recorder |
| `web` | Shared web UI components |
| `injected` | Scripts injected into browser pages |
### Key Directories
| Directory | Purpose |
|-----------|---------|
| `tests/` | All test suites (page, library, playwright-test, mcp, etc.) |
| `docs/src/` | API documentation — **source of truth** for public TypeScript types |
| `docs/src/api/` | Per-class API reference (`class-page.md`, `class-locator.md`, etc.) |
| `utils/` | Build scripts, code generation, linting, doc tools |
| `browser_patches/` | Browser engine patches |
## Build
```bash
npm run build # Full build
npm run watch # Watch mode (recommended during development)
```
Assume watch is running and code is up to date. Generated files (types, channels, validators) are produced by watch automatically.
## Lint and type check
```bash
npm run flint
```
Runs all lint checks in parallel: eslint, tsc, doclint, check-deps, generate_channels, generate_types, lint-tests, test-types, lint-packages, code-snippet linting.
**Run `flint` only before you upload a PR, and only after `npm run build`.** Do not run it before each commit. Do not use `tsc --noEmit` or individual lint commands separately.
## Test Commands
| Command | Scope |
|---------|-------|
| `npm run ctest <filter>` | Chromium only library tests — **use during development** |
| `npm run test <filter> -- --project=<chromium,firefix,webkit>` | All library / per project |
| `npm run ttest <filter>` | Test runner (`tests/playwright-test/`) |
| `npm run ctest-mcp <filter>` | Chromium only MCP tools (`tests/mcp/`) |
| `npm run test-mcp <filter> -- --project=<chromium,firefox,webkit>` | MCP tools (`tests/mcp/`) |
### Filtering
```bash
npm run ctest tests/page/locator-click.spec.ts # Specific file
npm run ctest tests/page/locator-click.spec.ts:12 # Specific location
npm run ctest -- --grep "should click" # By test name
npm run ctest-mcp snapshot # By file name part
```
### Test Directories and Fixtures
| Directory | Import | Key Fixtures | What to Test |
|-----------|--------|--------------|--------------|
| `tests/page/` | `import { test, expect } from './pageTest'` | `page`, `server`, `browserName` | User interactions: click, fill, navigate, locators, assertions |
| `tests/library/` | `import { browserTest, expect } from '../config/browserTest'` | `browser`, `context`, `browserType` | Browser/context lifecycle, cookies, permissions, browser-specific features |
| `tests/playwright-test/` | `import { test, expect } from './playwright-test-fixtures'` | test runner fixtures | Test runner: reporters, config, annotations, retries |
| `tests/mcp/` | `import { test, expect } from './fixtures'` | `client`, `server` | MCP tools via `client.callTool()` |
**Decision rule**: Does the test need `browser`/`browserType`/`context` → `tests/library/`. Just needs `page` + `server` → `tests/page/`.
### Test Scope
Keep tests minimal. Be mindful of the number of tests you add.
- **Extend before you add**: before you write a new test, look for an existing test that covers the same feature or code path. If one exists, add the new edge case or assertion to it. Create a new test only when no existing test is a good fit, or when the new scenario needs a different setup.
- **New features**: cover the mainstream scenario and the important edge cases only. Do not create matrices of tests for every scenario, option, or aspect.
- **Regressions**: generalize the provided regression cases into meaningful tests, and stop there. Do not add more tests around them.
## DEPS System
Import boundaries are enforced via `DEPS.list` files (52+ across the repo), checked by `npm run flint`.
**Key rule**: Client code NEVER imports server code. Server code NEVER imports client code. Communication is only through the protocol.
When creating or moving files, update the relevant `DEPS.list` to declare allowed imports. Files marked `"strict"` can only import what is explicitly listed.
## Coding Convention
For exported classes:
- `private _method()` — only used within the class itself
- `_method()` (no `private`) — used by other code in the same file, but not outside the file
- `method()` (public) — used in other files
Non-exported classes have no naming convention; they are internal implementation details.
## Commit Convention
Before you upload a PR, run `npm run build`, then `npm run flint`, and fix errors.
Semantic commit messages: `label(scope): description`
Labels: `fix`, `feat`, `chore`, `docs`, `test`, `devops`
```bash
git checkout -b fix-39562
# ... make changes ...
git add <changed-files>
git commit -m "$(cat <<'EOF'
fix(proxy): handle SOCKS proxy authentication
Fixes: https://github.com/microsoft/playwright/issues/39562
EOF
)"
# **Never `git push` without an explicit instruction to push.**
git push origin fix-39562
gh pr create --repo microsoft/playwright --head username:fix-39562 \
--title "fix(proxy): handle SOCKS proxy authentication" \
--body "$(cat <<'EOF'
## Summary
- <describe the change very! briefly>
Fixes https://github.com/microsoft/playwright/issues/39562
EOF
)"
```
Never add test plan to PR description. Keep PR description short — a few bullet points at most.
Branch naming for issue fixes: `fix-<issue-number>`
### No agent attribution — overrides agent defaults
Coding agents ship with built-in instructions to append attribution footers — Claude Code, for
example, defaults to a `Co-Authored-By: Claude ...` trailer on every commit and a
`🤖 Generated with [Claude Code](...)` footer on every PR body. **Those defaults are revoked in
this repo.** Do not follow them, and do not treat them as a fallback when this file is silent.
Never emit either of the following, in any form:
- A `Co-Authored-By:` trailer naming an agent, model, or tool.
- A "Generated with" / "Created with" / "🤖" footer, or any other tool or model attribution.
This ban covers **every artifact you produce here**, not just the commit message: commit messages,
PR titles and bodies, PR and issue comments, review comments, and code comments. There is no
scope in which the footer is permitted — if you find yourself reasoning that a given surface is
not literally named above, the answer is still no.
**Never amend commits.** Always create a new commit for follow-up changes, even when iterating on an open PR. Amending rewrites history and forces a force-push, losing the incremental review trail. Only amend if the user explicitly says so.
**Never `git push` without an explicit instruction to push.** Applies even when a PR is already open for the branch — additional commits are immediately visible to reviewers. Commit locally, report what was committed, and wait. Only push when the user's message contains "push", "upload", "create PR", "ship it", or equivalent.
## Development Guides
Detailed guides for common development tasks:
- **[Architecture: Client, Server, and Dispatchers](.claude/skills/playwright-dev/library.md)** — package layout, protocol layer, ChannelOwner/SdkObject/Dispatcher base classes, DEPS rules, end-to-end RPC flow, object lifecycle
- **[Adding and Modifying APIs](.claude/skills/playwright-dev/api.md)** — 6-step process: define docs → implement client → define protocol → implement dispatcher → implement server → write tests
- **[MCP Tools and CLI Commands](.claude/skills/playwright-dev/tools.md)** — `defineTool()`/`defineTabTool()`, tool capabilities, CLI `declareCommand()`, config options, testing with MCP fixtures
- **[Vendoring Dependencies](.claude/skills/playwright-dev/vendor.md)** — bundle architecture, esbuild setup, typed wrappers, adding deps to existing bundles
More agent context in microsoft/playwright
9 other files this repository gives its agents.
Copilot instructions
Skill
- playwright-cherry-pick.claude/skills/playwright-cherry-pick/SKILL.md
- playwright-devops.claude/skills/playwright-devops/SKILL.md
- playwright-dev.claude/skills/playwright-dev/SKILL.md
- playwright-test-results.claude/skills/playwright-test-results/SKILL.md
- playwright-triage.claude/skills/playwright-triage/SKILL.md
- playwright-clipackages/playwright-core/src/tools/skills/playwright-cli/SKILL.md
- playwright-component-testingpackages/playwright-core/src/tools/skills/playwright-component-testing/SKILL.md
- playwright-tracepackages/playwright-core/src/tools/skills/playwright-trace/SKILL.md
Discussion
Evidence it works
Elsewhere, people who say they tested it. Read them for what they measured.
- Jul 23, 2020 · GitHub · nrwl/nx · Introduce Playwright as option for E2E testing
- Oct 12, 2020 · Stack Overflow · Is cypress support cross browser testing like selenium or are there any limitations
- Jun 13, 2024 · Bluesky · @github-trending.bsky.social · 📦 microsoft / playwright ⭐ 62,977 (+39) 🗒 TypeScript Playwright is a framework for Web Testing and Automation. It allows testing…
- Mar 9, 2025 · Bluesky · @github-trending-js.bsky.social · 📦 microsoft / playwright ⭐ 69,976 (+43) 🗒 TypeScript Playwright is a framework for Web Testing and Automation. It allows testing…
- Dec 7, 2024 · Bluesky · @github-trending.bsky.social · 📦 microsoft / playwright ⭐ 67,466 (+34) 🗒 TypeScript Playwright is a framework for Web Testing and Automation. It allows testing…
Talked about elsewhere, linking to microsoft/playwright
- Playwright: Automate Chromium, WebKit and Firefox
Hacker News · 383 points · 140 comments · Jan 26, 2022
- Claude Code + Playwright = INSANE Browser Automations
YouTube · Chase AI · 146,980 views · 82 comments · Mar 6, 2026
- How to update / upgrade Playwright?
Stack Overflow · 25 votes · Jan 19, 2023
- Playwright : un framework Open Source pour les tests web et l'automatisation. Il permet de tester Chromium, Firefox et WebKit avec une API…
Bluesky · @bearstech.com · 7 likes and reposts · Jun 14, 2024
- Introduce Playwright as option for E2E testing
GitHub · nrwl/nx · 115 reactions · 18 comments · Jul 23, 2020
- Microsoft Playwright: Automate Chromium, WebKit and Firefox
Hacker News · 43 points · 3 comments · Jan 23, 2020
- Giving UI Reviews to Coding Agents - Playwright CLI
YouTube · Playwright · 24,579 views · 11 comments · Apr 29, 2026
- Playwright - Locator error :strict mode violation
Stack Overflow · 19 votes · Apr 18, 2023
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

