playwright-e2e-mcp 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,196 @@
1
+ ---
2
+ name: playwright-e2e-mcp
3
+ description: Runs, debugs and fixes Playwright end-to-end tests through the playwright-e2e-mcp server, using structured run results, trace-based failure diagnostics, verified locators, self-healing fixes that re-run and revert if still red, per-test flaky verdicts that separate parallelism bugs from races, signed-in page inspection and local run history. Use when the user asks to run Playwright tests, fix a failing or broken e2e test, find out why a test is flaky or which tests are unstable, repair a selector that no longer matches, write a new Playwright test, or check a page for visual regressions.
4
+ ---
5
+
6
+ # Playwright E2E with playwright-e2e-mcp
7
+
8
+ This skill drives the `playwright-e2e-mcp` MCP server. The server runs Playwright
9
+ for you and returns structured results instead of raw terminal output: pass/fail
10
+ stats, each failure with `file:line`, a failure kind, the DOM at the moment of
11
+ failure (read from the Playwright trace), failed network requests, console errors
12
+ and concrete next steps. It can also propose and apply a verified fix for a broken
13
+ locator, inspect pages behind a login, run long suites in the background and keep
14
+ a local history of every run.
15
+
16
+ This skill is written for playwright-e2e-mcp 0.3.0 and works with 0.2.0 or
17
+ newer. If `suggest-fix`, `get-run-status` or `analyze-history` is missing, the
18
+ server is older than 0.2.0: use the steps that do not need those tools and tell
19
+ the user to update it. `diagnose-flaky`'s per-test table and `isolate` option
20
+ arrived in 0.3.0.
21
+
22
+ ## Before you start
23
+
24
+ 1. Check that the server's tools are available. They are named `run-test`,
25
+ `get-run-status`, `get-failure`, `suggest-fix`, `inspect-page`,
26
+ `validate-selector`, `list-tests`, `generate-e2e-test`,
27
+ `compare-visual-state`, `diagnose-flaky` and `analyze-history` (your client
28
+ may prefix them, e.g. `mcp__playwright-e2e__run-test`).
29
+ 2. If they are all missing, stop and tell the user the MCP server is not
30
+ connected. Point them to `references/setup.md` for the one-line install for
31
+ their client. Do not fall back to shelling out to `npx playwright test` unless
32
+ the user asks. If only some are missing, the server may run a smaller tool
33
+ profile (`--tools=core` exposes `run-test`, `get-run-status`, `get-failure`,
34
+ `suggest-fix`, `diagnose-flaky` and `list-tests`); work with what is there and
35
+ mention the profile when a task needs a page tool.
36
+ 3. Every tool except `get-run-status` takes an optional `projectRoot`. Leave it
37
+ out unless the user works in a sub-project; the server defaults to `PW_MCP_PROJECT_ROOT` or its working
38
+ directory, and rejects any root outside its allowed roots.
39
+ 4. If the client offers the server's prompts as slash commands,
40
+ `/fix-failing-test` and `/triage-flaky-tests` start the two main workflows
41
+ below.
42
+
43
+ ## The core loop: fix a failing test
44
+
45
+ Follow these steps in order. Do not edit code before step 3.
46
+
47
+ 1. **Run.** Call `run-test` with the narrowest scope you know:
48
+ `{ "testFiles": ["tests/checkout.spec.ts"] }`, or `file:line`, or `grep`.
49
+ Omit `testFiles` only when the user asks for the whole suite. Failing tests are
50
+ retried once by default, so a test that passes on retry is reported as
51
+ **flaky**, not failed. For a long suite pass `background: true` and poll
52
+ `get-run-status` with `waitSeconds: 30`.
53
+ 2. **Read the failure.** For each failure, call `get-failure` with its 1-based
54
+ `index`. Read the message and code frame, expected vs actual, the failure kind,
55
+ the DOM snapshot at failure, the failed action and its selector, failed network
56
+ requests and console errors.
57
+ 3. **Decide what is wrong** using the failure kind (see
58
+ `references/failure-kinds.md`):
59
+ - `server-unreachable` / `SERVER_NOT_RUNNING`: the app is not running. Tell the
60
+ user to start the dev server, or suggest `webServer` in the Playwright config.
61
+ Do not edit tests.
62
+ - A locator or selector in the message, or "0 elements": call `suggest-fix`
63
+ with the same `index`. If it returns a diff with `high` confidence, call it
64
+ again with `apply: true`; it re-runs the test and reverts if still red. If it
65
+ says the element is missing, treat it as an app bug and report the evidence.
66
+ Otherwise go to the selector loop below.
67
+ - `assertion` with a sensible selector: compare expected vs actual and the DOM
68
+ snapshot. Decide whether the app regressed or the test expectation is stale,
69
+ and say which before changing anything.
70
+ - `timeout`: check the DOM snapshot and failed requests for a slow or failed
71
+ API call before raising any timeout.
72
+ - Failed network request (4xx/5xx/no response) right before the failure: the
73
+ backend is the likely cause; report it.
74
+ 4. **Fix** the spec or the app code, the smallest change that addresses the cause.
75
+ 5. **Re-run only what failed:** `run-test` with `{ "lastFailed": true }`. Repeat
76
+ from step 2 until green.
77
+
78
+ ## Selector loop: a locator no longer matches
79
+
80
+ 1. `inspect-page` with the page URL and `view: "locators"`
81
+ (e.g. `{ "url": "http://localhost:3000/checkout", "view": "locators" }`).
82
+ Behind a login, pass `storageState` (the project's saved auth file); to reach a
83
+ modal or later step, pass `actions`. Every locator listed was checked to match
84
+ exactly one element.
85
+ 2. Pick a replacement. Prefer, in order: role + accessible name (`getByRole`),
86
+ `getByTestId`, label/placeholder, then a short stable CSS selector. Avoid
87
+ positional selectors such as `:nth-child` and generated class names.
88
+ 3. `validate-selector` with `{ "url": ..., "selector": ... }` before editing the
89
+ spec. It accepts locator expressions as written in the spec. Only use one that
90
+ comes back `✅ VALID` with exactly 1 match.
91
+ 4. Update the spec and re-run with `lastFailed: true`.
92
+
93
+ ## Pages behind a login
94
+
95
+ `inspect-page`, `validate-selector` and `compare-visual-state` open the page in a
96
+ fresh browser, so a signed-in page shows the login screen unless you pass state:
97
+
98
+ - `storageState`: path inside the project to a Playwright storageState JSON, such
99
+ as `playwright/.auth/user.json` written by the project's setup project. Look for
100
+ it in `playwright.config.*` before asking the user. The server can default to
101
+ `PW_MCP_STORAGE_STATE`.
102
+ - `headers`: extra HTTP headers, e.g. an API token the user gave you. Never invent
103
+ or log credentials.
104
+ - `actions`: up to 20 steps after load (`click`, `fill`, `press`, `check`,
105
+ `select`, `hover`, `wait`, `goto`, ...) to open a modal or reach a later step.
106
+ - `viewport`: `{ "width": 390, "height": 844 }` for mobile layouts.
107
+
108
+ When a response says the page landed on a login screen, retry with
109
+ `storageState`. `suggest-fix` takes `storageState` and `headers` too when you heal
110
+ against a live `url`.
111
+
112
+ ## Flaky or intermittent failures
113
+
114
+ Start with `analyze-history` (default view `flaky`) to see which tests flip
115
+ between pass and fail across recorded runs, which regressed, and which are simply
116
+ broken; `view: "patterns"` groups failures that share a cause. Then call
117
+ `diagnose-flaky` on the worst ones (optionally `{ "testFiles": [...], "runs": 5 }`;
118
+ with no `testFiles` it takes the tests that failed in the last run). It repeats
119
+ them with retries disabled, in one Playwright process, and returns a table with
120
+ one verdict **per test** (passes, failures, duration spread, first error):
121
+
122
+ - **CONSISTENTLY FAILING**: not flaky; treat it as a real failure (core loop).
123
+ - **FLAKY**: some runs passed. Same error signature each time points to a real
124
+ race in the app or test; varying errors point to timing or environment. Look for
125
+ missing awaits, assertions without auto-waiting, shared state between tests and
126
+ fixed `waitForTimeout` sleeps. Never "fix" flakiness by only adding retries or
127
+ sleeps.
128
+ - **NOT REPRODUCING**: passed every run. Report that the failure was one-off.
129
+
130
+ When a test is FLAKY and the suite runs in parallel, call `diagnose-flaky` again
131
+ with `isolate: true`. It repeats the tests fully parallel, then repeats the
132
+ failing ones with one worker, and reads each one:
133
+
134
+ - **fails only in parallel**: the test shares state with others (same user or
135
+ account, DB rows, files, ports, a global fixture). Fix the data isolation, for
136
+ example per-worker data from `testInfo.workerIndex`; do not just serialize the
137
+ whole suite.
138
+ - **flaky even alone**: the race is inside the test or the app.
139
+ - **fails alone too**: a real bug, not parallelism.
140
+
141
+ Pass `separateProcesses: true` only when the flake seems tied to global setup or
142
+ a cold start, since one process per run is slower. `get-failure` works on the
143
+ last failing diagnose run straight after, and each repetition is recorded in the
144
+ history, so `diagnose-flaky` with `runs: 5` is also the quickest way to seed
145
+ history for `analyze-history`.
146
+
147
+ Every `run-test`, `diagnose-flaky` and `suggest-fix` run is recorded in
148
+ `<project>/.playwright-e2e-mcp/history.jsonl` on the user's machine;
149
+ `analyze-history` with `view: "test"` and a `test` filter shows one test's
150
+ pass/fail timeline.
151
+
152
+ ## Other tasks
153
+
154
+ - **List tests:** `list-tests`, with `filter` for a substring of `file › title`.
155
+ - **Write a new test:** `generate-e2e-test` with a `description` (and `pageUrl` if
156
+ there is no `baseURL`). It scaffolds a spec from selectors the project actually
157
+ declares, from recent git changes, and reports each selector's source. Review the
158
+ file it writes, then `run-test` it. Pass `write: false` to preview without
159
+ writing.
160
+ - **Set up CI:** when the user wants the same diagnosis on every pull request,
161
+ point them to the GitHub Action (`uses: xsignon-secure/E2E@v0.3.0`) or the
162
+ `npx -y playwright-e2e-mcp ci` command in `references/setup.md`. It writes the
163
+ run, flaky verdicts and fix diffs to the job summary and one PR comment.
164
+ - **Visual regression:** `compare-visual-state` with `url` and a `name`. The first
165
+ call saves a baseline under `.pw-mcp/visual/`; later calls report changed
166
+ regions and color shifts and write a diff image. Use `action: "baseline"` only
167
+ when the user confirms the new look is intended.
168
+
169
+ ## Reporting back
170
+
171
+ When you finish, tell the user, in this order:
172
+
173
+ 1. The result: which tests now pass, fail or are flaky (counts from the last
174
+ `run-test`).
175
+ 2. The cause of each failure you fixed, with the `file:line` you changed.
176
+ 3. Anything you did not fix and why (app bug, server down, needs a decision).
177
+
178
+ ## Things to avoid
179
+
180
+ - Do not raise timeouts, add retries, add `waitForTimeout`, or delete or
181
+ `test.skip` a test to make a run green, unless the user explicitly asks.
182
+ - Do not accept a new visual baseline without the user's confirmation.
183
+ - Do not pass `allowExpectationUpdate: true` to `suggest-fix` unless the user
184
+ confirms the new text is intended; a changed expected value can be a real bug.
185
+ - Do not point `inspect-page` or `validate-selector` at sites the user did not
186
+ name; they open real pages in a headless browser.
187
+ - `run-test` executes the project's own test code. Run it only in projects the
188
+ user has asked you to work on.
189
+
190
+ ## References
191
+
192
+ - `references/setup.md`: install and client configuration, environment variables.
193
+ - `references/tools.md`: every tool's arguments.
194
+ - `references/failure-kinds.md`: failure kinds and error codes, and what to do.
195
+ - `references/example-session.md`: a worked fix-a-failing-test session with
196
+ `suggest-fix`.
@@ -0,0 +1,53 @@
1
+ # Example session: fixing a failing checkout test
2
+
3
+ **User:** The checkout test started failing after the redesign. Can you fix it?
4
+
5
+ 1. Agent calls `run-test` with `{ "testFiles": ["tests/checkout.spec.ts"] }`.
6
+
7
+ ```
8
+ ## Playwright run — ❌ FAILED
9
+ | passed | failed | flaky | skipped |
10
+ | 2 | 1 | 0 | 0 |
11
+ ### 1 of 1. checkout.spec.ts › pays with card
12
+ File: checkout.spec.ts:18 | failed · timeout
13
+ ```
14
+
15
+ 2. Agent calls `get-failure` with `{ "index": 1 }`. The failed action is
16
+ `locator('#pay-now').click()`. The DOM snapshot at failure has no `#pay-now`,
17
+ but it does have a `Pay now` button. No network requests failed and the console
18
+ is clean, so the app itself looks healthy.
19
+
20
+ 3. The failure kind is `timeout`, but the cause is a locator that no longer
21
+ matches, so the agent calls `suggest-fix` with `{ "index": 1 }`:
22
+
23
+ ```
24
+ ### Proposed locator fix — confidence **high**
25
+ The button's accessible name matches "pay", and
26
+ `getByRole('button', { name: 'Pay now' })` is proven to resolve to exactly
27
+ that element.
28
+ - await page.locator('#pay-now').click();
29
+ + await page.getByRole('button', { name: 'Pay now' }).click();
30
+ ```
31
+
32
+ 4. Confidence is high, so the agent calls `suggest-fix` with
33
+ `{ "index": 1, "apply": true }`. The server writes the change, re-runs the test
34
+ with retries off, and reports `✅ Verified — the test passes with the fix`.
35
+ Had the test still failed, the server would have restored the original file.
36
+
37
+ 5. Agent calls `run-test` with `{ "lastFailed": true }` to confirm, then
38
+ `{ "testFiles": ["tests/checkout.spec.ts"] }` for the whole file: 3 passed.
39
+
40
+ **Agent's reply:**
41
+
42
+ > All 3 checkout tests pass now. "pays with card" failed because the redesign
43
+ > removed the `#pay-now` id from the pay button. I changed the locator at
44
+ > `tests/checkout.spec.ts:18` to `getByRole('button', { name: 'Pay now' })`,
45
+ > which matches exactly one element, and the server re-ran the test to confirm
46
+ > the fix.
47
+
48
+ ## When suggest-fix refuses
49
+
50
+ If `suggest-fix` says the element is most likely missing, do not weaken the test.
51
+ Read `get-failure` again for failed network requests and console errors, check the
52
+ page with `inspect-page` (with `storageState` if it needs a login), and report it
53
+ to the user as a probable app bug with that evidence.
@@ -0,0 +1,32 @@
1
+ # Failure kinds and error codes
2
+
3
+ ## Per-test failure kinds (from `run-test` and `get-failure`)
4
+
5
+ | Kind | Meaning | What to do |
6
+ | --- | --- | --- |
7
+ | `assertion` | An `expect` did not hold | Compare expected vs actual and the DOM snapshot; decide whether the app regressed or the expectation is stale, and say which before editing |
8
+ | `timeout` | An action or the test ran out of time | Check the DOM snapshot and failed network requests for the real cause (element never appeared, API failed) before touching timeouts |
9
+ | `server-unreachable` | The app under test did not respond | Ask the user to start the dev server, or configure `webServer` in the Playwright config; do not edit tests |
10
+ | `browser-crash` | The browser or page closed unexpectedly | Re-run once; if it repeats, suggest `npx playwright install` to repair browsers |
11
+ | `syntax` | The spec or config does not compile | Fix the reported `file:line` first; nothing else will run until it does |
12
+ | `config` | The Playwright config is invalid | Read the message and fix the config |
13
+ | `unknown` | Not classified | Read the message, stack and DOM snapshot directly |
14
+
15
+ A test reported as **flaky** passed on the automatic retry. Run
16
+ `diagnose-flaky` before deciding how to treat it.
17
+
18
+ ## Tool error codes
19
+
20
+ | Code | Meaning | What to do |
21
+ | --- | --- | --- |
22
+ | `NO_PLAYWRIGHT` | `@playwright/test` is not installed in the project | Show the user the install command the error includes |
23
+ | `NO_CONFIG` | No `playwright.config.*` found | Ask where the config is, or pass `projectRoot` / `config` |
24
+ | `MULTIPLE_CONFIGS` | Several configs found; the error lists them numbered | Ask the user which one, or pick the obvious one, and pass `config: "2"` or its path |
25
+ | `INVALID_PATH` | A path or `projectRoot` leaves the allowed roots | Use a path inside the project; to allow another root the user must set `PW_MCP_ALLOWED_ROOTS` |
26
+ | `SERVER_NOT_RUNNING` | The app is not reachable | As `server-unreachable` above |
27
+ | `TIMEOUT` | The whole run hit `timeoutMs`; results are partial | Narrow the run (`testFiles`, `grep`) or raise `timeoutMs` for this call |
28
+ | `BROWSER_CRASH` | Browser failed | As `browser-crash` above |
29
+ | `SYNTAX_ERROR` | A spec has a syntax error | Fix the reported file; `list-tests` still works via a source scan |
30
+ | `DISK_FULL` | No space left on device | Ask the user to free disk space |
31
+ | `SPAWN_FAILED` / `REPORT_MISSING` | Playwright could not start or wrote no report | Check Node and Playwright are installed; re-run with `LOG_LEVEL=debug` |
32
+ | `CLIENT_DISCONNECT` | The run was cancelled | Re-run if still needed |
@@ -0,0 +1,120 @@
1
+ # Setup: connecting the playwright-e2e-mcp server
2
+
3
+ This skill only gives the agent instructions. The tools come from the
4
+ `playwright-e2e-mcp` MCP server, which must be connected to the agent.
5
+
6
+ ## Requirements
7
+
8
+ - playwright-e2e-mcp **0.2.0 or newer**, 0.3.0 recommended. `suggest-fix`,
9
+ `get-run-status`, `analyze-history`, verified locators and signed-in page
10
+ inspection arrived in 0.2.0; per-test flaky verdicts, `isolate`, tool profiles
11
+ and the `ci` command in 0.3.0. Check with
12
+ `npx -y playwright-e2e-mcp --version`.
13
+
14
+ - Node.js 20 or newer.
15
+ - A project with `@playwright/test` installed and a browser available:
16
+ `npx playwright install chromium`.
17
+
18
+ ## Install the server
19
+
20
+ The server is published on npm as `playwright-e2e-mcp` and in the official MCP
21
+ Registry as `io.github.xsignon-secure/E2E`. Pin a version in shared configs
22
+ (`playwright-e2e-mcp@<version>`) so every machine runs the same build.
23
+
24
+ **Claude Code**
25
+
26
+ ```bash
27
+ claude mcp add playwright-e2e -- npx -y playwright-e2e-mcp
28
+ ```
29
+
30
+ **Claude Desktop, Cursor, Windsurf, Gemini CLI, Qwen Code and other JSON-config clients**
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "playwright-e2e": {
36
+ "command": "npx",
37
+ "args": ["-y", "playwright-e2e-mcp"],
38
+ "env": { "PW_MCP_PROJECT_ROOT": "/absolute/path/to/your/project" }
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ Claude Desktop also has a one-click `.mcpb` extension on the project's
45
+ [GitHub releases](https://github.com/xsignon-secure/E2E/releases); it asks for the
46
+ project root on install.
47
+
48
+ **Codex CLI**
49
+
50
+ ```toml
51
+ # ~/.codex/config.toml
52
+ [mcp_servers.playwright-e2e]
53
+ command = "npx"
54
+ args = ["-y", "playwright-e2e-mcp"]
55
+ startup_timeout_sec = 60
56
+ tool_timeout_sec = 600
57
+ ```
58
+
59
+ Raise the timeouts as shown: a Playwright run with retries takes longer than
60
+ Codex's 60-second default tool timeout.
61
+
62
+ ## Install the skill
63
+
64
+ Copy the `playwright-e2e-mcp/` folder (the one holding `SKILL.md`) into your
65
+ agent's skills directory, for example:
66
+
67
+ - Claude Code: `~/.claude/skills/` (personal) or `.claude/skills/` (project)
68
+ - Codex CLI: `~/.codex/skills/`
69
+ - Other agents: their documented skills folder
70
+
71
+ ## Environment variables
72
+
73
+ Set these in the server's `env` block. None of them are secrets except
74
+ `PW_MCP_HTTP_TOKEN`; never put a token in a committed config file.
75
+
76
+ | Variable | Default | Purpose |
77
+ | --- | --- | --- |
78
+ | `PW_MCP_PROJECT_ROOT` | server working directory | Default project root for every tool |
79
+ | `PW_MCP_TOOLS` | all | Tools to expose: names and/or profiles `core`, `triage`, `inspect`, `author` (same as the `--tools=` flag). `core` halves the tool-definition context |
80
+ | `PW_MCP_ALLOWED_ROOTS` | none | Extra directories allowed as `projectRoot` (`:`-separated, `;` on Windows) |
81
+ | `PW_MCP_BLOCK_PRIVATE_URLS` | off for stdio | `1` makes the URL tools refuse loopback, private-network and cloud-metadata addresses |
82
+ | `PW_MCP_STORAGE_STATE` | none | Default Playwright storageState JSON (inside the project) for the page tools, so signed-in pages open logged in |
83
+ | `PW_MCP_HISTORY` | on | `0` stops recording runs to `<project>/.playwright-e2e-mcp/history.jsonl` (this turns off `analyze-history`) |
84
+ | `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` or `silent` |
85
+ | `PW_MCP_HTTP_TOKEN` | none | HTTP bridge only: bearer token that unlocks all tools |
86
+
87
+ ## Hosted endpoint
88
+
89
+ Clients that only accept remote MCP servers can use the Streamable HTTP bridge
90
+ (`https://playwright-e2e-mcp.vercel.app/api/mcp`, or your own deployment of the
91
+ repo). Without a bearer token the bridge serves only `list-tests`,
92
+ `get-failure` and `analyze-history`, so the core loop in `SKILL.md` needs a local install or a token.
93
+
94
+ ## Check it works
95
+
96
+ Ask the agent to "list my Playwright tests". It should call `list-tests` and
97
+ return files and titles. Clients that show MCP prompts also list
98
+ `/fix-failing-test` and `/triage-flaky-tests`. If it says the tools are missing, the server is not
99
+ connected: restart the client after editing its config.
100
+
101
+ ## CI (0.3.0+)
102
+
103
+ The same diagnosis runs without an agent:
104
+
105
+ ```bash
106
+ npx -y playwright-e2e-mcp ci --flaky-runs 3 --suggest 2 --output report.md
107
+ ```
108
+
109
+ Exit code 0 means passed, 1 tests failed, 2 the run itself failed. On GitHub
110
+ Actions it also writes to the job summary. As an Action:
111
+
112
+ ```yaml
113
+ - uses: xsignon-secure/E2E@v0.3.0
114
+ with:
115
+ flaky-runs: 3
116
+ suggest: 2
117
+ ```
118
+
119
+ It keeps one PR comment up to date when the run fails (needs
120
+ `pull-requests: write`).
@@ -0,0 +1,161 @@
1
+ # Tool reference
2
+
3
+ All paths are relative to the project root. Every tool except `get-run-status`
4
+ accepts an optional `projectRoot`, which must sit inside the server's allowed roots.
5
+
6
+ ## run-test
7
+
8
+ Runs Playwright and returns stats, failures, failure kinds and fix hints.
9
+
10
+ | Argument | Type | Notes |
11
+ | --- | --- | --- |
12
+ | `testFiles` | string[] | Files or directories; `file:line` supported. Omit to run everything |
13
+ | `grep` | string | Only tests whose title matches this regex |
14
+ | `browser` | `chromium` \| `firefox` \| `webkit` | Matched against config project names |
15
+ | `background` | boolean | Return a run id at once and keep running; follow it with `get-run-status` |
16
+ | `headed` | boolean | Visible browser window |
17
+ | `timeoutMs` | number | Wall-clock limit for the run (default 120000); partial results are returned past it |
18
+ | `testTimeoutMs` | number | Per-test timeout |
19
+ | `workers`, `retries` | number | Passed to Playwright |
20
+ | `config` | string | Config path, or 1-based index when there are several |
21
+ | `retryOnFailure` | boolean | Retry failures once before reporting (default true; ignored when `retries` is set) |
22
+ | `lastFailed` | boolean | Re-run only the tests that failed last time |
23
+ | `args` | string[] | Allowlisted Playwright flags such as `--repeat-each=N`, `--max-failures=N`, `--update-snapshots`, `--shard=1/3`, `--trace=on`; path-taking flags are rejected |
24
+
25
+ Traces are captured on failure automatically so `get-failure` can show the DOM.
26
+ Clients that send a progress token get live progress while the run goes.
27
+
28
+ ## get-failure
29
+
30
+ | Argument | Type | Notes |
31
+ | --- | --- | --- |
32
+ | `index` | number | 1-based failure index from the last run (default 1) |
33
+
34
+ Returns the message and code frame, expected vs actual, stack, failure kind and
35
+ diagnosis, console output, the DOM snapshot at failure with the failed action and
36
+ its selector, failed network requests, console errors and warnings, and next steps.
37
+
38
+ ## inspect-page
39
+
40
+ | Argument | Type | Notes |
41
+ | --- | --- | --- |
42
+ | `url` | string | Required, full http(s) URL |
43
+ | `selector` | string | Inspect only matches of this CSS selector |
44
+ | `waitFor` | string | Wait for a selector (CSS or `text=...`) first |
45
+ | `waitUntil` | `load` \| `domcontentloaded` \| `networkidle` | Navigation wait |
46
+ | `includeHtml` | boolean | Include rendered HTML (capped by `maxHtmlChars`, default 20000) |
47
+ | `timeoutMs` | number | Default 45000 |
48
+ | `view` | `elements` \| `locators` | `locators`: compact map of interactive elements with verified locators |
49
+ | `storageState` | string | Playwright storageState JSON inside the project (signed-in session); defaults to `PW_MCP_STORAGE_STATE` |
50
+ | `headers` | object | Extra HTTP headers |
51
+ | `actions` | array | Up to 20 steps after load: `{ type: click\|dblclick\|fill\|press\|check\|uncheck\|select\|hover\|wait\|goto, locator?, value?, url?, ms? }` |
52
+ | `viewport` | object | `{ width, height }` |
53
+
54
+ Returns each element's Playwright locators proven unique on the page (role +
55
+ name first), unique CSS selector, tag, visibility, box, text and attributes,
56
+ plus console messages. `validate-selector` and `compare-visual-state` take the
57
+ same `storageState`, `headers`, `actions` and `viewport`.
58
+
59
+ ## validate-selector
60
+
61
+ | Argument | Type | Notes |
62
+ | --- | --- | --- |
63
+ | `url` | string | Required |
64
+ | `selector` | string | Required: CSS, a Playwright selector, or a locator such as `getByRole('button', { name: 'Save' })` |
65
+ | `timeoutMs` | number | Default 45000 |
66
+
67
+ Verdicts: `✅ VALID — N matches` with samples and a unique locator for each,
68
+ a strict-mode warning when more than one matches, `✅ VALID — 0 matches` with
69
+ advice, or `❌ INVALID` with the parse error.
70
+
71
+ ## list-tests
72
+
73
+ | Argument | Type | Notes |
74
+ | --- | --- | --- |
75
+ | `config` | string | Config path or index |
76
+ | `testDir` | string | Restrict to a directory |
77
+ | `filter` | string | Case-insensitive substring of `file › title` |
78
+ | `limit` | number | Default 500 |
79
+
80
+ Falls back to a source scan when Playwright cannot list (broken install or spec).
81
+
82
+ ## generate-e2e-test
83
+
84
+ | Argument | Type | Notes |
85
+ | --- | --- | --- |
86
+ | `description` | string | Required: what the test should cover |
87
+ | `pageUrl` | string | Start page (default: `baseURL` / `webServer.url`) |
88
+ | `testDir`, `file` | string | Where to write; `file` must end in `.spec.*` or `.test.*` |
89
+ | `write` | boolean | Write to disk (default true) |
90
+ | `overwrite` | boolean | Replace a spec this tool generated earlier |
91
+ | `liveInspect` | boolean | Cross-check selectors on the live page |
92
+ | `config` | string | As above |
93
+
94
+ ## compare-visual-state
95
+
96
+ | Argument | Type | Notes |
97
+ | --- | --- | --- |
98
+ | `url` | string | Required |
99
+ | `name` | string | Baseline id, e.g. `checkout-page` |
100
+ | `action` | `compare` \| `baseline` | Default `compare`; `baseline` re-captures the reference |
101
+ | `selector` | string | Capture one element |
102
+ | `fullPage` | boolean | Full scrollable page |
103
+ | `tolerance` | number | Percent of pixels allowed to differ (default 0.1) |
104
+ | `pixelThreshold` | number | Per-pixel channel delta (default 60) |
105
+ | `waitUntil`, `waitFor`, `timeoutMs` | | As `inspect-page` |
106
+
107
+ Baselines live in `.pw-mcp/visual/`.
108
+
109
+ ## diagnose-flaky
110
+
111
+ | Argument | Type | Notes |
112
+ | --- | --- | --- |
113
+ | `testFiles` | string[] | Default: tests that failed in the last run |
114
+ | `runs` | number | 2 to 10 (default 3) |
115
+ | `isolate` | boolean | Repeat fully parallel (`workers` default 4), then repeat the failing tests with one worker (0.3.0+) |
116
+ | `separateProcesses` | boolean | One Playwright process per run instead of one `--repeat-each` process; slower (0.3.0+) |
117
+ | `browser`, `headed`, `workers`, `config` | | As `run-test` |
118
+ | `timeoutMs` | number | Per run (default 120000); the single `--repeat-each` process gets this × `runs` |
119
+
120
+ Runs with retries disabled and returns, per test, passes, failures, duration
121
+ spread, first error and `CONSISTENTLY FAILING`, `FLAKY` or `NOT REPRODUCING`,
122
+ plus the verdict block for the worst test. With `isolate`, a second table reads
123
+ each failing test as "fails only in parallel", "flaky even alone" or "fails
124
+ alone too". Versions before 0.3.0 return one run-level verdict and a per-run
125
+ table instead.
126
+
127
+ ## suggest-fix
128
+
129
+ | Argument | Type | Notes |
130
+ | --- | --- | --- |
131
+ | `index` | number | 1-based failure index from the last run (default 1) |
132
+ | `apply` | boolean | Write the fix (default false: diff only) |
133
+ | `verify` | boolean | After applying, re-run and revert if still failing (default true) |
134
+ | `allowExpectationUpdate` | boolean | Allow applying a changed expected text (default false) |
135
+ | `url`, `storageState`, `headers` | | Heal against a live page instead of the trace snapshot |
136
+ | `config`, `timeoutMs` | | As `run-test` |
137
+
138
+ Returns a unified diff: a locator fix rated `high` or `medium` confidence, or an
139
+ expectation update rated `low` that is applied only with
140
+ `allowExpectationUpdate: true`. Otherwise it refuses and says the element is most
141
+ likely missing.
142
+
143
+ ## get-run-status
144
+
145
+ | Argument | Type | Notes |
146
+ | --- | --- | --- |
147
+ | `runId` | string | From `run-test` with `background: true` (default: latest) |
148
+ | `waitSeconds` | number | Wait up to this long (max 55) |
149
+ | `cancel` | boolean | Stop the run |
150
+
151
+ ## analyze-history
152
+
153
+ | Argument | Type | Notes |
154
+ | --- | --- | --- |
155
+ | `view` | `flaky` \| `patterns` \| `test` | Default `flaky` |
156
+ | `test` | string | Substring of a test's file or title |
157
+ | `lastRuns` | number | Default 30 |
158
+ | `limit` | number | Default 15 |
159
+
160
+ Reads `.playwright-e2e-mcp/history.jsonl`, written by every run
161
+ (`PW_MCP_HISTORY=0` disables it).