playwright-e2e-mcp 0.6.1 → 0.8.0
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.
- package/README.md +150 -24
- package/dist/cli/ci.js +3 -0
- package/dist/cli/ci.js.map +1 -1
- package/dist/cli/doctor.d.ts +12 -1
- package/dist/cli/doctor.js +34 -4
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/guard.d.ts +11 -0
- package/dist/cli/guard.js +80 -0
- package/dist/cli/guard.js.map +1 -0
- package/dist/cli/upload.d.ts +14 -0
- package/dist/cli/upload.js +81 -0
- package/dist/cli/upload.js.map +1 -0
- package/dist/discovery.d.ts +61 -0
- package/dist/discovery.js +108 -0
- package/dist/discovery.js.map +1 -0
- package/dist/http.d.ts +10 -1
- package/dist/http.js +50 -4
- package/dist/http.js.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +2 -0
- package/dist/oauth.js +1 -1
- package/dist/oauth.js.map +1 -1
- package/dist/server.d.ts +24 -4
- package/dist/server.js +98 -15
- package/dist/server.js.map +1 -1
- package/dist/skills.d.ts +23 -0
- package/dist/skills.js +101 -0
- package/dist/skills.js.map +1 -0
- package/dist/tools/analyze-history.d.ts +15 -0
- package/dist/tools/analyze-history.js +44 -9
- package/dist/tools/analyze-history.js.map +1 -1
- package/dist/tools/audit-accessibility.d.ts +6 -0
- package/dist/tools/audit-performance.d.ts +6 -0
- package/dist/tools/check-test-change.d.ts +44 -0
- package/dist/tools/check-test-change.js +132 -0
- package/dist/tools/check-test-change.js.map +1 -0
- package/dist/tools/compare-visual-state.d.ts +6 -0
- package/dist/tools/diagnose-flaky.js +5 -1
- package/dist/tools/diagnose-flaky.js.map +1 -1
- package/dist/tools/generate-e2e-test.d.ts +3 -0
- package/dist/tools/generate-e2e-test.js +3 -0
- package/dist/tools/generate-e2e-test.js.map +1 -1
- package/dist/tools/get-failure.js +3 -1
- package/dist/tools/get-failure.js.map +1 -1
- package/dist/tools/get-run-status.js +8 -2
- package/dist/tools/get-run-status.js.map +1 -1
- package/dist/tools/inspect-page.d.ts +6 -0
- package/dist/tools/inspect-page.js +3 -1
- package/dist/tools/inspect-page.js.map +1 -1
- package/dist/tools/list-tests.js +16 -12
- package/dist/tools/list-tests.js.map +1 -1
- package/dist/tools/probe-script.js +181 -15
- package/dist/tools/probe-script.js.map +1 -1
- package/dist/tools/quarantine.d.ts +61 -0
- package/dist/tools/quarantine.js +133 -0
- package/dist/tools/quarantine.js.map +1 -0
- package/dist/tools/run-test.d.ts +10 -1
- package/dist/tools/run-test.js +38 -6
- package/dist/tools/run-test.js.map +1 -1
- package/dist/tools/save-login.d.ts +145 -0
- package/dist/tools/save-login.js +264 -0
- package/dist/tools/save-login.js.map +1 -0
- package/dist/tools/shared.d.ts +49 -2
- package/dist/tools/shared.js +57 -6
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/structured.d.ts +8 -1
- package/dist/tools/structured.js +8 -1
- package/dist/tools/structured.js.map +1 -1
- package/dist/tools/suggest-fix.js +4 -0
- package/dist/tools/suggest-fix.js.map +1 -1
- package/dist/tools/validate-selector.d.ts +6 -0
- package/dist/tools/validate-selector.js +10 -2
- package/dist/tools/validate-selector.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/live-reporter.d.ts +29 -0
- package/dist/utils/live-reporter.js +145 -0
- package/dist/utils/live-reporter.js.map +1 -0
- package/dist/utils/playwright-runner.js +36 -14
- package/dist/utils/playwright-runner.js.map +1 -1
- package/dist/utils/pro-client.d.ts +29 -0
- package/dist/utils/pro-client.js +114 -0
- package/dist/utils/pro-client.js.map +1 -0
- package/dist/utils/pytest-runner.d.ts +102 -0
- package/dist/utils/pytest-runner.js +715 -0
- package/dist/utils/pytest-runner.js.map +1 -0
- package/dist/utils/quarantine.d.ts +64 -0
- package/dist/utils/quarantine.js +106 -0
- package/dist/utils/quarantine.js.map +1 -0
- package/dist/utils/test-change-guard.d.ts +90 -0
- package/dist/utils/test-change-guard.js +516 -0
- package/dist/utils/test-change-guard.js.map +1 -0
- package/dist/utils/totp.d.ts +26 -0
- package/dist/utils/totp.js +84 -0
- package/dist/utils/totp.js.map +1 -0
- package/dist/utils/update-check.d.ts +50 -0
- package/dist/utils/update-check.js +75 -0
- package/dist/utils/update-check.js.map +1 -0
- package/examples/github-actions/playwright-e2e.yml +80 -0
- package/examples/gitlab-ci/playwright-e2e.yml +71 -0
- package/package.json +2 -2
- package/skill/playwright-e2e-mcp/SKILL.md +45 -7
- package/skill/playwright-e2e-mcp/references/setup.md +12 -1
- package/skill/playwright-e2e-mcp/references/tools.md +42 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp.js","sourceRoot":"","sources":["../../src/utils/totp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asks the npm registry for the latest published version of this package and
|
|
3
|
+
* compares it with the running one. Used by `doctor`, which a person runs on
|
|
4
|
+
* purpose; the MCP server itself never calls this.
|
|
5
|
+
*
|
|
6
|
+
* The request carries nothing but the package name (no project data, no
|
|
7
|
+
* identifiers). It is skipped when PW_MCP_NO_UPDATE_CHECK=1 or when called
|
|
8
|
+
* with `offline`, and any failure (no network, a proxy, a slow registry)
|
|
9
|
+
* resolves to `unknown` instead of throwing.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PACKAGE_NAME = "playwright-e2e-mcp";
|
|
12
|
+
export declare const REGISTRY_LATEST_URL = "https://registry.npmjs.org/playwright-e2e-mcp/latest";
|
|
13
|
+
export type UpdateStatus = {
|
|
14
|
+
state: 'current';
|
|
15
|
+
current: string;
|
|
16
|
+
latest: string;
|
|
17
|
+
} | {
|
|
18
|
+
state: 'outdated';
|
|
19
|
+
current: string;
|
|
20
|
+
latest: string;
|
|
21
|
+
} | {
|
|
22
|
+
state: 'ahead';
|
|
23
|
+
current: string;
|
|
24
|
+
latest: string;
|
|
25
|
+
} | {
|
|
26
|
+
state: 'unknown';
|
|
27
|
+
current: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
} | {
|
|
30
|
+
state: 'skipped';
|
|
31
|
+
current: string;
|
|
32
|
+
reason: string;
|
|
33
|
+
};
|
|
34
|
+
/** Compares two x.y.z versions (a pre-release sorts before its release). */
|
|
35
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
36
|
+
export interface UpdateCheckOptions {
|
|
37
|
+
offline?: boolean;
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
fetchImpl?: typeof fetch;
|
|
40
|
+
env?: NodeJS.ProcessEnv;
|
|
41
|
+
}
|
|
42
|
+
export declare function checkForUpdate(current: string, options?: UpdateCheckOptions): Promise<UpdateStatus>;
|
|
43
|
+
/**
|
|
44
|
+
* How to upgrade, by the way this copy was installed. `npx -y
|
|
45
|
+
* playwright-e2e-mcp` (npm 10, which ships with Node 22) checks the registry
|
|
46
|
+
* on every launch and picks up a new release by itself, so restarting the MCP
|
|
47
|
+
* client is enough there; a project or global install, a git clone or the
|
|
48
|
+
* Docker image stays on its version until updated.
|
|
49
|
+
*/
|
|
50
|
+
export declare const UPGRADE_HINT: string;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asks the npm registry for the latest published version of this package and
|
|
3
|
+
* compares it with the running one. Used by `doctor`, which a person runs on
|
|
4
|
+
* purpose; the MCP server itself never calls this.
|
|
5
|
+
*
|
|
6
|
+
* The request carries nothing but the package name (no project data, no
|
|
7
|
+
* identifiers). It is skipped when PW_MCP_NO_UPDATE_CHECK=1 or when called
|
|
8
|
+
* with `offline`, and any failure (no network, a proxy, a slow registry)
|
|
9
|
+
* resolves to `unknown` instead of throwing.
|
|
10
|
+
*/
|
|
11
|
+
export const PACKAGE_NAME = 'playwright-e2e-mcp';
|
|
12
|
+
export const REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
13
|
+
/** Compares two x.y.z versions (a pre-release sorts before its release). */
|
|
14
|
+
export function compareVersions(a, b) {
|
|
15
|
+
const parse = (v) => {
|
|
16
|
+
const [core = '', pre = ''] = v.trim().replace(/^v/, '').split('-', 2);
|
|
17
|
+
const nums = core.split('.').map((n) => Number.parseInt(n, 10) || 0);
|
|
18
|
+
while (nums.length < 3)
|
|
19
|
+
nums.push(0);
|
|
20
|
+
return { nums, pre };
|
|
21
|
+
};
|
|
22
|
+
const x = parse(a);
|
|
23
|
+
const y = parse(b);
|
|
24
|
+
for (let i = 0; i < 3; i++) {
|
|
25
|
+
if (x.nums[i] !== y.nums[i])
|
|
26
|
+
return x.nums[i] < y.nums[i] ? -1 : 1;
|
|
27
|
+
}
|
|
28
|
+
if (x.pre === y.pre)
|
|
29
|
+
return 0;
|
|
30
|
+
if (!x.pre)
|
|
31
|
+
return 1;
|
|
32
|
+
if (!y.pre)
|
|
33
|
+
return -1;
|
|
34
|
+
return x.pre < y.pre ? -1 : 1;
|
|
35
|
+
}
|
|
36
|
+
export async function checkForUpdate(current, options = {}) {
|
|
37
|
+
const env = options.env ?? process.env;
|
|
38
|
+
if (options.offline)
|
|
39
|
+
return { state: 'skipped', current, reason: '--offline' };
|
|
40
|
+
if (env.PW_MCP_NO_UPDATE_CHECK === '1' || env.PW_MCP_NO_UPDATE_CHECK === 'true') {
|
|
41
|
+
return { state: 'skipped', current, reason: 'PW_MCP_NO_UPDATE_CHECK is set' };
|
|
42
|
+
}
|
|
43
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
44
|
+
if (typeof fetchImpl !== 'function')
|
|
45
|
+
return { state: 'unknown', current, reason: 'fetch is not available' };
|
|
46
|
+
try {
|
|
47
|
+
const res = await fetchImpl(REGISTRY_LATEST_URL, {
|
|
48
|
+
headers: { accept: 'application/json' },
|
|
49
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 3000),
|
|
50
|
+
});
|
|
51
|
+
if (!res.ok)
|
|
52
|
+
return { state: 'unknown', current, reason: `npm registry answered ${res.status}` };
|
|
53
|
+
const body = (await res.json());
|
|
54
|
+
const latest = typeof body.version === 'string' ? body.version : '';
|
|
55
|
+
if (!/^\d+\.\d+\.\d+/.test(latest))
|
|
56
|
+
return { state: 'unknown', current, reason: 'npm registry gave no version' };
|
|
57
|
+
const cmp = compareVersions(current, latest);
|
|
58
|
+
return { state: cmp < 0 ? 'outdated' : cmp > 0 ? 'ahead' : 'current', current, latest };
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const message = err.name === 'TimeoutError' ? 'npm registry did not answer in time' : err.message.split('\n')[0];
|
|
62
|
+
return { state: 'unknown', current, reason: message };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* How to upgrade, by the way this copy was installed. `npx -y
|
|
67
|
+
* playwright-e2e-mcp` (npm 10, which ships with Node 22) checks the registry
|
|
68
|
+
* on every launch and picks up a new release by itself, so restarting the MCP
|
|
69
|
+
* client is enough there; a project or global install, a git clone or the
|
|
70
|
+
* Docker image stays on its version until updated.
|
|
71
|
+
*/
|
|
72
|
+
export const UPGRADE_HINT = 'restart your MCP client (npx -y playwright-e2e-mcp fetches the new version itself); ' +
|
|
73
|
+
'project install: npm install -D playwright-e2e-mcp@latest · global: npm install -g playwright-e2e-mcp@latest · ' +
|
|
74
|
+
'Docker: docker pull ghcr.io/xsignon-secure/playwright-e2e-mcp:latest · git clone: git pull && npm ci';
|
|
75
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Playwright E2E Diagnosis
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, master]
|
|
7
|
+
|
|
8
|
+
# Permissions required:
|
|
9
|
+
# - contents: read to check out the repository
|
|
10
|
+
# - pull-requests: write to post/update the PR comment report and suggested fixes
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
pull-requests: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
e2e:
|
|
17
|
+
name: Playwright E2E Tests
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 30
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout code
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
persist-credentials: false
|
|
26
|
+
|
|
27
|
+
- name: Set up Node.js
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: 22
|
|
31
|
+
cache: npm
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: npm ci
|
|
35
|
+
|
|
36
|
+
- name: Install Playwright browsers and OS dependencies
|
|
37
|
+
run: npx playwright install --with-deps chromium
|
|
38
|
+
|
|
39
|
+
- name: Run Playwright E2E diagnosis action
|
|
40
|
+
id: e2e
|
|
41
|
+
uses: xsignon-secure/E2E@v0.8.0
|
|
42
|
+
with:
|
|
43
|
+
# Directory containing playwright.config.* (default is workspace root)
|
|
44
|
+
project-root: .
|
|
45
|
+
|
|
46
|
+
# Extra arguments passed to playwright-e2e-mcp ci, e.g. "--browser chromium tests/checkout"
|
|
47
|
+
# args: --browser chromium tests/
|
|
48
|
+
|
|
49
|
+
# Repeat failing tests (2-10) to obtain an empirical flaky verdict; 0 skips
|
|
50
|
+
flaky-runs: 3
|
|
51
|
+
|
|
52
|
+
# Draft suggest-fix diffs for the first N failures (0-5)
|
|
53
|
+
suggest: 2
|
|
54
|
+
|
|
55
|
+
# Re-run each failing test with its fix applied and post only verified fixes
|
|
56
|
+
verify-fixes: true
|
|
57
|
+
|
|
58
|
+
# Post verified fixes directly as one-click GitHub suggested changes on the PR
|
|
59
|
+
review: true
|
|
60
|
+
|
|
61
|
+
# Post/edit a single diagnosis summary comment on the PR
|
|
62
|
+
comment: true
|
|
63
|
+
|
|
64
|
+
# Heal guard: block test changes that pass by checking less (deleted assertions, skipped tests, .only)
|
|
65
|
+
# guard: true
|
|
66
|
+
|
|
67
|
+
# Pro Cloud integration (optional, paid): upload run history to Pro Cloud
|
|
68
|
+
# pro-key: ${{ secrets.PW_MCP_PRO_KEY }}
|
|
69
|
+
# pro-url: https://pro.example.com
|
|
70
|
+
|
|
71
|
+
# Fail step when tests fail (default: true)
|
|
72
|
+
fail-on-failure: true
|
|
73
|
+
|
|
74
|
+
- name: Upload diagnosis report
|
|
75
|
+
if: always() && steps.e2e.outputs.report != ''
|
|
76
|
+
uses: actions/upload-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: playwright-e2e-diagnosis-report
|
|
79
|
+
path: ${{ steps.e2e.outputs.report }}
|
|
80
|
+
retention-days: 14
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# playwright-e2e-mcp on GitLab CI.
|
|
2
|
+
#
|
|
3
|
+
# Copy this into .gitlab-ci.yml (or `include:` it). It does what the GitHub
|
|
4
|
+
# Action does, with GitLab's own pieces:
|
|
5
|
+
# - on a merge request, the heal guard fails the job when a changed test
|
|
6
|
+
# now checks less (an assertion removed, a test skipped, `.only` added);
|
|
7
|
+
# - `ci` runs the suite (auto-retry once, so flaky tests are reported as
|
|
8
|
+
# flaky), repeats failures for a flaky verdict and drafts fixes;
|
|
9
|
+
# - the Markdown report is printed in the job log, kept as an artifact
|
|
10
|
+
# and, when E2E_REPORT_TOKEN is set, posted as a merge request comment.
|
|
11
|
+
#
|
|
12
|
+
# Exit codes of `ci`: 0 passed (flaky allowed), 1 tests failed, 2 the run
|
|
13
|
+
# itself failed (no Playwright, config error, timeout).
|
|
14
|
+
|
|
15
|
+
stages:
|
|
16
|
+
- test
|
|
17
|
+
|
|
18
|
+
playwright-e2e:
|
|
19
|
+
stage: test
|
|
20
|
+
# Microsoft's Playwright image ships Node and the browsers. Use the tag that
|
|
21
|
+
# matches the @playwright/test version in your package-lock.json (the
|
|
22
|
+
# browsers are tied to it), e.g. v1.64.1-noble for 1.64.1.
|
|
23
|
+
image: mcr.microsoft.com/playwright:v1.64.1-noble
|
|
24
|
+
variables:
|
|
25
|
+
# The guard compares with the target branch, so it needs real history.
|
|
26
|
+
GIT_DEPTH: "0"
|
|
27
|
+
npm_config_cache: "$CI_PROJECT_DIR/.npm"
|
|
28
|
+
cache:
|
|
29
|
+
key:
|
|
30
|
+
files:
|
|
31
|
+
- package-lock.json
|
|
32
|
+
paths:
|
|
33
|
+
- .npm/
|
|
34
|
+
rules:
|
|
35
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
36
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
37
|
+
before_script:
|
|
38
|
+
- npm ci --prefer-offline
|
|
39
|
+
script:
|
|
40
|
+
# 1. Heal guard, merge requests only. Add --strict to fail on warnings too.
|
|
41
|
+
- |
|
|
42
|
+
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
|
|
43
|
+
git fetch --quiet origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
|
|
44
|
+
npx -y playwright-e2e-mcp guard --base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
|
|
45
|
+
fi
|
|
46
|
+
# 2. Run and diagnose the suite. --verify-fixes re-runs each failing test
|
|
47
|
+
# with its drafted fix applied, then restores the file.
|
|
48
|
+
- npx -y playwright-e2e-mcp ci --flaky-runs 3 --suggest 2 --verify-fixes --output e2e-report.md
|
|
49
|
+
after_script:
|
|
50
|
+
# 3. Post the report on the merge request. E2E_REPORT_TOKEN is a project
|
|
51
|
+
# access token with the `api` scope, stored as a masked CI/CD variable.
|
|
52
|
+
# after_script runs even when the tests fail, so the report still lands.
|
|
53
|
+
- |
|
|
54
|
+
if [ -f e2e-report.md ] && [ -n "$CI_MERGE_REQUEST_IID" ] && [ -n "$E2E_REPORT_TOKEN" ]; then
|
|
55
|
+
node -e 'process.stdout.write(JSON.stringify({ body: require("fs").readFileSync("e2e-report.md", "utf8").slice(0, 900000) }))' > e2e-note.json
|
|
56
|
+
curl --silent --show-error --fail --request POST \
|
|
57
|
+
--header "PRIVATE-TOKEN: $E2E_REPORT_TOKEN" \
|
|
58
|
+
--header "Content-Type: application/json" \
|
|
59
|
+
--data @e2e-note.json \
|
|
60
|
+
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" > /dev/null \
|
|
61
|
+
|| echo "Could not post the report on the merge request"
|
|
62
|
+
fi
|
|
63
|
+
artifacts:
|
|
64
|
+
name: "playwright-e2e-$CI_COMMIT_REF_SLUG"
|
|
65
|
+
when: always
|
|
66
|
+
expose_as: "Playwright E2E report"
|
|
67
|
+
paths:
|
|
68
|
+
- e2e-report.md
|
|
69
|
+
- playwright-report/
|
|
70
|
+
- test-results/
|
|
71
|
+
expire_in: 14 days
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwright-e2e-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server and agent skill that run, diagnose and fix failing Playwright tests: CI report diagnosis, trace analysis, verified locator fixes, flaky verdicts, breaking commits,
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "MCP server and agent skill that run, diagnose and fix failing Playwright tests (TypeScript and pytest): CI report diagnosis, trace analysis, verified locator fixes, flaky verdicts, breaking commits, heal guard, accessibility and Web Vitals audits.",
|
|
5
5
|
"author": "xsignon-secure (https://github.com/xsignon-secure)",
|
|
6
6
|
"mcpName": "io.github.xsignon-secure/E2E",
|
|
7
7
|
"type": "module",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: playwright-e2e-mcp
|
|
3
|
-
description: Runs, debugs and fixes Playwright end-to-end tests through the playwright-e2e-mcp server
|
|
3
|
+
description: "Runs, debugs and fixes Playwright end-to-end tests through the playwright-e2e-mcp server: run results grouped by root cause, trace-based failure diagnostics, verified locators, self-healing fixes that re-run and revert if still red, a heal guard that blocks fixes which pass by checking less, per-test flaky verdicts (parallelism, test order, timing), an owned, expiring flaky-test quarantine, saved logins with 2FA codes, signed-in page inspection with network mocks, tests written by walking the flow, CI report diagnosis, accessibility and Web Vitals audits and run history with the commit that broke each test. Use when the user asks to run Playwright tests, fix a failing or broken e2e test, find out why CI failed, find flaky, unstable or slow tests, repair a selector, write or review a Playwright test, log in for tests, or check a page for accessibility, performance or visual regressions."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Playwright E2E with playwright-e2e-mcp
|
|
@@ -13,7 +13,7 @@ and concrete next steps. It can also propose and apply a verified fix for a brok
|
|
|
13
13
|
locator, inspect pages behind a login, run long suites in the background and keep
|
|
14
14
|
a local history of every run.
|
|
15
15
|
|
|
16
|
-
This skill is written for playwright-e2e-mcp 0.
|
|
16
|
+
This skill is written for playwright-e2e-mcp 0.8.0 and works with 0.2.0 or
|
|
17
17
|
newer. If `suggest-fix`, `get-run-status` or `analyze-history` is missing, the
|
|
18
18
|
server is older than 0.2.0: use the steps that do not need those tools and tell
|
|
19
19
|
the user to update it. `diagnose-flaky`'s per-test table and `isolate` option
|
|
@@ -21,7 +21,12 @@ arrived in 0.3.0; `audit-accessibility`, `diagnose-flaky`'s `order` option and
|
|
|
21
21
|
root-cause grouping in `run-test` arrived in 0.4.0; `audit-performance`,
|
|
22
22
|
`load-report`, network mocks (`routes`), `har`, `browser`, `inspect-page`'s
|
|
23
23
|
`view: "aria"`, `generate-e2e-test`'s `steps`, the `slow`, `trend` and `commits`
|
|
24
|
-
history views and strict-mode fixes in `suggest-fix` arrived in 0.5.0
|
|
24
|
+
history views and strict-mode fixes in `suggest-fix` arrived in 0.5.0;
|
|
25
|
+
`save-login`, `check-test-change` and `quarantine` arrived in 0.7.0; the
|
|
26
|
+
`switchTab` page step, `blockWrites`, recovery of crashed runs and
|
|
27
|
+
pytest-playwright projects (`run-test`, `get-failure`, `list-tests`) arrived in
|
|
28
|
+
0.8.0. If `doctor` says a newer version is out, pass its upgrade command on to
|
|
29
|
+
the user.
|
|
25
30
|
|
|
26
31
|
## Before you start
|
|
27
32
|
|
|
@@ -29,8 +34,8 @@ history views and strict-mode fixes in `suggest-fix` arrived in 0.5.0.
|
|
|
29
34
|
`get-run-status`, `get-failure`, `load-report`, `suggest-fix`, `inspect-page`,
|
|
30
35
|
`validate-selector`, `list-tests`, `generate-e2e-test`,
|
|
31
36
|
`compare-visual-state`, `audit-accessibility`, `audit-performance`,
|
|
32
|
-
`diagnose-flaky`
|
|
33
|
-
`
|
|
37
|
+
`diagnose-flaky`, `analyze-history`, `audit-tests`, `bisect-failure`,
|
|
38
|
+
`save-login`, `check-test-change` and `quarantine` (your client
|
|
34
39
|
may prefix them, e.g. `mcp__playwright-e2e__run-test`).
|
|
35
40
|
2. If they are all missing, stop and tell the user the MCP server is not
|
|
36
41
|
connected. Point them to `references/setup.md` for the one-line install for
|
|
@@ -39,7 +44,7 @@ history views and strict-mode fixes in `suggest-fix` arrived in 0.5.0.
|
|
|
39
44
|
`references/writing-tests.md`. Do not fall back to shelling out to `npx playwright test` unless
|
|
40
45
|
the user asks. If only some are missing, the server may run a smaller tool
|
|
41
46
|
profile (`--tools=core` exposes `run-test`, `get-run-status`, `get-failure`,
|
|
42
|
-
`suggest-fix`, `diagnose-flaky` and `list-tests`); work with what is there and
|
|
47
|
+
`suggest-fix`, `diagnose-flaky`, `check-test-change` and `list-tests`); work with what is there and
|
|
43
48
|
mention the profile when a task needs a page tool.
|
|
44
49
|
3. Every tool except `get-run-status` takes an optional `projectRoot`. Leave it
|
|
45
50
|
out unless the user works in a sub-project; the server defaults to `PW_MCP_PROJECT_ROOT` or its working
|
|
@@ -88,6 +93,10 @@ Follow these steps in order. Do not edit code before step 3.
|
|
|
88
93
|
- Failed network request (4xx/5xx/no response) right before the failure: the
|
|
89
94
|
backend is the likely cause; report it.
|
|
90
95
|
4. **Fix** the spec or the app code, the smallest change that addresses the cause.
|
|
96
|
+
Then call `check-test-change` (0.7.0+; no arguments checks the uncommitted
|
|
97
|
+
changes). If it says **BLOCK**, the fix made the test pass by checking less
|
|
98
|
+
(a deleted assertion, a skip, `.only`): undo that part and fix the cause. Treat
|
|
99
|
+
**WARN** findings as things to justify to the user, not to wave through.
|
|
91
100
|
5. **Re-run only what failed:** `run-test` with `{ "lastFailed": true }`. Repeat
|
|
92
101
|
from step 2 until green.
|
|
93
102
|
|
|
@@ -136,6 +145,26 @@ fresh browser, so a signed-in page shows the login screen unless you pass state:
|
|
|
136
145
|
(it must be installed; `audit-performance` stays Chromium-only).
|
|
137
146
|
- `viewport`: `{ "width": 390, "height": 844 }` for mobile layouts.
|
|
138
147
|
|
|
148
|
+
When there is no saved session yet, or it expired, call `save-login` (0.7.0+)
|
|
149
|
+
instead of typing credentials into `actions` every time:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{ "url": "http://localhost:3000/login",
|
|
153
|
+
"actions": [
|
|
154
|
+
{ "type": "fill", "locator": "getByLabel('Email')", "value": "qa@example.com" },
|
|
155
|
+
{ "type": "fill", "locator": "getByLabel('Password')", "value": "{{env:E2E_PASSWORD}}" },
|
|
156
|
+
{ "type": "fill", "locator": "getByLabel('Code')", "value": "{{totp}}" },
|
|
157
|
+
{ "type": "click", "locator": "getByRole('button', { name: 'Sign in' })" }],
|
|
158
|
+
"verify": { "url": "/account", "visible": "getByRole('button', { name: 'Sign out' })", "notUrl": "/login" },
|
|
159
|
+
"totpSecretEnv": "E2E_TOTP_SECRET" }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
It saves `playwright/.auth/user.json` and reuses it while `verify` passes. Never
|
|
163
|
+
put a password in a tool argument or in chat: ask the user to set it as an
|
|
164
|
+
environment variable for the server (`E2E_*`, `TEST_*`, `LOGIN_*`, or a name
|
|
165
|
+
listed in `PW_MCP_LOGIN_ENV`) and refer to it as `{{env:NAME}}`. `{{totp}}`
|
|
166
|
+
types the current authenticator code from the secret in `totpSecretEnv`.
|
|
167
|
+
|
|
139
168
|
When a response says the page landed on a login screen, retry with
|
|
140
169
|
`storageState`. `suggest-fix` takes `storageState` and `headers` too when you heal
|
|
141
170
|
against a live `url`.
|
|
@@ -183,6 +212,14 @@ one verdict **per test** (passes, failures, duration spread, first error):
|
|
|
183
212
|
tests that flaked; `fix: true` applies the mechanical rewrites and re-runs them.
|
|
184
213
|
- **NOT REPRODUCING**: passed every run. Report that the failure was one-off.
|
|
185
214
|
|
|
215
|
+
If a FLAKY test cannot be fixed right away and is blocking other work, offer
|
|
216
|
+
`quarantine` (0.7.0+) with `action: "add"`, the test (`index` of the last run's
|
|
217
|
+
failure, or `"file › title"`), an `owner` and a `reason` (an issue link is best).
|
|
218
|
+
It keeps running and being reported, but stops failing the run until the entry
|
|
219
|
+
expires (default 14 days). Ask the user before adding one; never quarantine a
|
|
220
|
+
CONSISTENTLY FAILING test, which is a real failure. `quarantine` with no
|
|
221
|
+
arguments lists the entries and the expired ones.
|
|
222
|
+
|
|
186
223
|
When a test is FLAKY and the suite runs in parallel, call `diagnose-flaky` again
|
|
187
224
|
with `isolate: true`. It repeats the tests fully parallel, then repeats the
|
|
188
225
|
failing ones with one worker, and reads each one:
|
|
@@ -244,7 +281,7 @@ with the commit it tested. `analyze-history` views:
|
|
|
244
281
|
`selector` for one region) returns the accessibility snapshot and a
|
|
245
282
|
`toMatchAriaSnapshot` assertion to paste into a spec.
|
|
246
283
|
- **Set up CI:** when the user wants the same diagnosis on every pull request,
|
|
247
|
-
point them to the GitHub Action (`uses: xsignon-secure/E2E@v0.
|
|
284
|
+
point them to the GitHub Action (`uses: xsignon-secure/E2E@v0.8.0`) or the
|
|
248
285
|
`npx -y playwright-e2e-mcp ci` command in `references/setup.md`. It writes the
|
|
249
286
|
run, flaky verdicts and fix diffs to the job summary and one PR comment.
|
|
250
287
|
- **Accessibility:** `audit-accessibility` with `url` runs axe-core against
|
|
@@ -284,6 +321,7 @@ When you finish, tell the user, in this order:
|
|
|
284
321
|
|
|
285
322
|
- Do not raise timeouts, add retries, add `waitForTimeout`, or delete or
|
|
286
323
|
`test.skip` a test to make a run green, unless the user explicitly asks.
|
|
324
|
+
`check-test-change` catches these; run it after every test edit.
|
|
287
325
|
- Do not accept a new visual baseline without the user's confirmation.
|
|
288
326
|
- Do not pass `allowExpectationUpdate: true` to `suggest-fix` unless the user
|
|
289
327
|
confirms the new text is intended; a changed expected value can be a real bug.
|
|
@@ -82,6 +82,13 @@ Set these in the server's `env` block. None of them are secrets except
|
|
|
82
82
|
| `PW_MCP_BLOCK_PRIVATE_URLS` | off for stdio | `1` makes the URL tools refuse loopback, private-network and cloud-metadata addresses |
|
|
83
83
|
| `PW_MCP_STORAGE_STATE` | none | Default Playwright storageState JSON (inside the project) for the page tools, so signed-in pages open logged in |
|
|
84
84
|
| `PW_MCP_SHUFFLE_SEEDS` | random | Seeds for `diagnose-flaky`'s `order` pass (comma separated), to replay reported orders |
|
|
85
|
+
| `PW_MCP_LOGIN_ENV` | — | Extra variables `save-login` may type through `{{env:NAME}}`, comma separated (default: only `E2E_*`, `TEST_*`, `PW_*`, `PLAYWRIGHT_*`, `LOGIN_*`) |
|
|
86
|
+
| `PW_MCP_PRO_KEY` / `PW_MCP_PRO_URL` | — | Optional paid Pro: CI runs uploaded with `upload` show up in `analyze-history` (`source: both`). Unset = no network calls |
|
|
87
|
+
| `PW_MCP_BLOCK_WRITES` | off | `1` makes the page tools abort POST, PUT, PATCH and DELETE requests that no mock or HAR answers (0.8.0+) |
|
|
88
|
+
| `PW_MCP_PYTHON` | project venv, then `python3` | The Python used for pytest-playwright projects (0.8.0+) |
|
|
89
|
+
| `PW_MCP_PROTOCOL` | both | `legacy` stops offering the 2026-07-28 MCP revision (0.8.0+) |
|
|
90
|
+
| `PW_MCP_SKILLS` | on | `0` stops serving this skill over the MCP Skills extension (0.8.0+) |
|
|
91
|
+
| `PW_MCP_NO_UPDATE_CHECK` | off | `1` stops `doctor` asking npm whether a newer version is out (0.8.0+) |
|
|
85
92
|
| `PW_MCP_HISTORY` | on | `0` stops recording runs to `<project>/.playwright-e2e-mcp/history.jsonl` (this turns off `analyze-history`) |
|
|
86
93
|
| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` or `silent` |
|
|
87
94
|
| `PW_MCP_HTTP_TOKEN` | none | HTTP bridge only: bearer token that unlocks all tools |
|
|
@@ -112,7 +119,7 @@ Exit code 0 means passed, 1 tests failed, 2 the run itself failed. On GitHub
|
|
|
112
119
|
Actions it also writes to the job summary. As an Action:
|
|
113
120
|
|
|
114
121
|
```yaml
|
|
115
|
-
- uses: xsignon-secure/E2E@v0.
|
|
122
|
+
- uses: xsignon-secure/E2E@v0.8.0
|
|
116
123
|
with:
|
|
117
124
|
flaky-runs: 3
|
|
118
125
|
suggest: 2
|
|
@@ -120,3 +127,7 @@ Actions it also writes to the job summary. As an Action:
|
|
|
120
127
|
|
|
121
128
|
It keeps one PR comment up to date when the run fails (needs
|
|
122
129
|
`pull-requests: write`).
|
|
130
|
+
|
|
131
|
+
From 0.7.0, `npx -y playwright-e2e-mcp guard --base origin/main` (or the
|
|
132
|
+
Action's `guard: true` input) fails the job when a changed test was made to
|
|
133
|
+
pass by checking less, and `ci` honours `playwright-quarantine.json`.
|
|
@@ -68,7 +68,7 @@ becomes the last run for `get-failure`, `suggest-fix` and `diagnose-flaky`.
|
|
|
68
68
|
| `view` | `elements` \| `locators` \| `aria` | `locators`: compact map of interactive elements with verified locators; `aria` (0.5.0+): accessibility snapshot of the page or of `selector`, with a `toMatchAriaSnapshot` assertion |
|
|
69
69
|
| `storageState` | string | Playwright storageState JSON inside the project (signed-in session); defaults to `PW_MCP_STORAGE_STATE` |
|
|
70
70
|
| `headers` | object | Extra HTTP headers |
|
|
71
|
-
| `actions` | array | Up to 20 steps after load: `{ type: click\|dblclick\|fill\|press\|check\|uncheck\|select\|hover\|wait\|goto, locator?, value?, url?, ms? }`. Locators may start with `frameLocator('#frame')` or use `.contentFrame()` for iframes (0.6.1+) |
|
|
71
|
+
| `actions` | array | Up to 20 steps after load: `{ type: click\|dblclick\|fill\|press\|check\|uncheck\|select\|hover\|wait\|goto, locator?, value?, url?, ms? }`. Locators may start with `frameLocator('#frame')` or use `.contentFrame()` for iframes (0.6.1+). `{ type: 'switchTab', value?: 'last'\|'first'\|'2'\|text in URL or title }` moves to a popup or new tab (0.8.0+) |
|
|
72
72
|
| `actionTimeoutMs` | number | How long each action waits for its element (0.6.1+, default 10000) |
|
|
73
73
|
| `routes` | array | Up to 20 network mocks before load, first match wins: `{ url (glob), method?, status?, json? \| body?, contentType?, headers?, abort?, delayMs? }` (0.5.0+). The result reports hits per mock |
|
|
74
74
|
| `har` | object | `{ path, mode?: replay\|record, url?, notFound?: abort\|fallback }` (0.5.0+): replay requests from a HAR inside the project, or record the traffic to one. `routes` still win |
|
|
@@ -278,3 +278,44 @@ mechanically. Files rank by findings weighted by their flaky rate in the history
|
|
|
278
278
|
Runs in a temporary git worktree with the current `node_modules` linked in;
|
|
279
279
|
untestable commits are skipped. `status` is `found`, `ambiguous`, `max-steps`,
|
|
280
280
|
`not-failing` (passes at bad) or `good-fails`.
|
|
281
|
+
|
|
282
|
+
## save-login (0.7.0+)
|
|
283
|
+
|
|
284
|
+
| Argument | Type | Notes |
|
|
285
|
+
| --- | --- | --- |
|
|
286
|
+
| `url` | string | Login page (required) |
|
|
287
|
+
| `actions` | array | Login steps as in `inspect-page`; fill values may use `{{env:NAME}}` and `{{totp}}` |
|
|
288
|
+
| `verify` | object | `url` (page to check, e.g. `/account`), `visible` (locator only a signed-in user sees), `notUrl` (bad if the URL contains it, e.g. `/login`) |
|
|
289
|
+
| `name` / `path` | string | Saved to `playwright/.auth/<name>.json` (default `user`) or `path` |
|
|
290
|
+
| `totpSecretEnv` | string | Variable holding the authenticator secret (base32 or `otpauth://`) |
|
|
291
|
+
| `reuse` | boolean | Keep a saved session that still passes `verify` (default true) |
|
|
292
|
+
|
|
293
|
+
`status` is `saved`, `valid` (reused, nothing typed) or `failed` (no file written).
|
|
294
|
+
Only `E2E_*`, `TEST_*`, `PW_*`, `PLAYWRIGHT_*`, `LOGIN_*` and names in
|
|
295
|
+
`PW_MCP_LOGIN_ENV` can be read through `{{env:…}}`.
|
|
296
|
+
|
|
297
|
+
## check-test-change (0.7.0+)
|
|
298
|
+
|
|
299
|
+
| Argument | Type | Notes |
|
|
300
|
+
| --- | --- | --- |
|
|
301
|
+
| `base` | string | Git ref (default `HEAD`: the uncommitted changes; `origin/main` for the branch) |
|
|
302
|
+
| `files` | string[] | Only these files |
|
|
303
|
+
| `file` + `after` | string | Check a proposed full file content before writing it |
|
|
304
|
+
|
|
305
|
+
`status` is `OK`, `WARN` or `BLOCK`; `ok` is false only on BLOCK. BLOCK: fewer
|
|
306
|
+
assertions in a test, a removed or skipped test, `.only`, a deleted spec. WARN:
|
|
307
|
+
`expect.soft`, a weaker matcher, `waitForTimeout`, `force: true`, a swallowed
|
|
308
|
+
error, a raised timeout, retries or screenshot tolerance.
|
|
309
|
+
|
|
310
|
+
## quarantine (0.7.0+)
|
|
311
|
+
|
|
312
|
+
| Argument | Type | Notes |
|
|
313
|
+
| --- | --- | --- |
|
|
314
|
+
| `action` | string | `list` (default), `add`, `remove` |
|
|
315
|
+
| `test` | string | `'file › title'`; or `file` + `title`; or `index` (last run's failure) |
|
|
316
|
+
| `owner` / `reason` | string | Required for `add` |
|
|
317
|
+
| `days` | number | 1–90, default 14 |
|
|
318
|
+
|
|
319
|
+
Stored in `playwright-quarantine.json` (commit it). A quarantined, unexpired
|
|
320
|
+
failure is listed under 🧊 and does not fail `run-test` or `ci`; `run.quarantined`
|
|
321
|
+
counts them. Expired entries block again.
|