playwright-e2e-mcp 0.5.0 → 0.6.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 +267 -1060
- package/dist/cli/ci.d.ts +5 -0
- package/dist/cli/ci.js +97 -5
- package/dist/cli/ci.js.map +1 -1
- package/dist/cli/doctor.d.ts +31 -0
- package/dist/cli/doctor.js +200 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.js +2 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/review.d.ts +50 -0
- package/dist/cli/review.js +148 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/http.d.ts +15 -1
- package/dist/http.js +44 -8
- package/dist/http.js.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +10 -0
- package/dist/oauth.js +29 -1
- package/dist/oauth.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +35 -3
- package/dist/server.js.map +1 -1
- package/dist/tools/audit-accessibility.d.ts +21 -0
- package/dist/tools/audit-accessibility.js +8 -1
- package/dist/tools/audit-accessibility.js.map +1 -1
- package/dist/tools/audit-performance.d.ts +21 -0
- package/dist/tools/audit-performance.js +13 -1
- package/dist/tools/audit-performance.js.map +1 -1
- package/dist/tools/audit-tests.d.ts +62 -0
- package/dist/tools/audit-tests.js +209 -0
- package/dist/tools/audit-tests.js.map +1 -0
- package/dist/tools/bisect-failure.d.ts +42 -0
- package/dist/tools/bisect-failure.js +291 -0
- package/dist/tools/bisect-failure.js.map +1 -0
- package/dist/tools/compare-visual-state.d.ts +21 -0
- package/dist/tools/diagnose-flaky.js +20 -3
- package/dist/tools/diagnose-flaky.js.map +1 -1
- package/dist/tools/get-failure.js +11 -2
- package/dist/tools/get-failure.js.map +1 -1
- package/dist/tools/get-run-status.js +4 -3
- package/dist/tools/get-run-status.js.map +1 -1
- package/dist/tools/inspect-page.d.ts +21 -0
- package/dist/tools/list-tests.js +5 -1
- package/dist/tools/list-tests.js.map +1 -1
- package/dist/tools/probe-script.js +33 -1
- package/dist/tools/probe-script.js.map +1 -1
- package/dist/tools/run-test.js +3 -2
- package/dist/tools/run-test.js.map +1 -1
- package/dist/tools/shared.d.ts +17 -1
- package/dist/tools/shared.js +69 -5
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/structured.d.ts +326 -0
- package/dist/tools/structured.js +170 -0
- package/dist/tools/structured.js.map +1 -0
- package/dist/tools/suggest-fix.js +14 -4
- package/dist/tools/suggest-fix.js.map +1 -1
- package/dist/tools/validate-selector.d.ts +21 -0
- package/dist/utils/attempt-limiter.d.ts +31 -0
- package/dist/utils/attempt-limiter.js +58 -0
- package/dist/utils/attempt-limiter.js.map +1 -0
- package/dist/utils/bisect.d.ts +31 -0
- package/dist/utils/bisect.js +47 -0
- package/dist/utils/bisect.js.map +1 -0
- package/dist/utils/flake-rules.d.ts +46 -0
- package/dist/utils/flake-rules.js +327 -0
- package/dist/utils/flake-rules.js.map +1 -0
- package/dist/utils/project-detector.js +2 -2
- package/dist/utils/project-detector.js.map +1 -1
- package/dist/utils/serverless-chromium.d.ts +32 -0
- package/dist/utils/serverless-chromium.js +64 -0
- package/dist/utils/serverless-chromium.js.map +1 -0
- package/package.json +7 -5
- package/skill/playwright-e2e-mcp/SKILL.md +14 -2
- package/skill/playwright-e2e-mcp/references/setup.md +2 -2
- package/skill/playwright-e2e-mcp/references/tools.md +32 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flake-risk rules for Playwright test code: patterns that make tests
|
|
3
|
+
* pass or fail by timing rather than by what the app does (hard waits,
|
|
4
|
+
* assertions that read once instead of retrying, promises nobody awaits,
|
|
5
|
+
* selectors tied to layout). Each finding says why it is risky, and the
|
|
6
|
+
* mechanical ones carry the replacement line.
|
|
7
|
+
*
|
|
8
|
+
* The scan is line based, not a TypeScript parse: it skips comments and
|
|
9
|
+
* aims for few false alarms over catching every case.
|
|
10
|
+
*/
|
|
11
|
+
export const SEVERITY_WEIGHT = { high: 5, medium: 2, low: 1 };
|
|
12
|
+
export const RULES = {
|
|
13
|
+
'hard-wait': {
|
|
14
|
+
severity: 'high',
|
|
15
|
+
message: 'Fixed wait: too short on a slow run, wasted time on a fast one. Wait for the state instead (a web-first assertion, waitForURL or waitForResponse).',
|
|
16
|
+
},
|
|
17
|
+
sleep: {
|
|
18
|
+
severity: 'high',
|
|
19
|
+
message: 'setTimeout sleep: the same problem as waitForTimeout, hidden from Playwright. Wait for the state instead.',
|
|
20
|
+
},
|
|
21
|
+
'non-retrying-assertion': {
|
|
22
|
+
severity: 'high',
|
|
23
|
+
message: 'Reads the page once and asserts on the value, so it fails if the page is a moment late. A web-first assertion retries until it holds.',
|
|
24
|
+
},
|
|
25
|
+
'missing-await': {
|
|
26
|
+
severity: 'high',
|
|
27
|
+
message: 'Not awaited: the test moves on (or ends) before this finishes, so a failure is lost or lands in another step.',
|
|
28
|
+
},
|
|
29
|
+
'focused-test': {
|
|
30
|
+
severity: 'high',
|
|
31
|
+
message: '.only left in: every other test in the run is skipped (and forbidOnly fails CI).',
|
|
32
|
+
},
|
|
33
|
+
'force-action': {
|
|
34
|
+
severity: 'medium',
|
|
35
|
+
message: 'force: true skips the actionability checks, so the action can hit a covered, moving or disabled element that a user could not.',
|
|
36
|
+
},
|
|
37
|
+
networkidle: {
|
|
38
|
+
severity: 'medium',
|
|
39
|
+
message: "networkidle waits for 500 ms without traffic, which polling, analytics or websockets can stop from ever happening. Playwright discourages it; wait for what the test needs.",
|
|
40
|
+
},
|
|
41
|
+
'element-handle': {
|
|
42
|
+
severity: 'medium',
|
|
43
|
+
message: 'ElementHandle API: the handle goes stale when the page re-renders. Locators re-resolve on every use.',
|
|
44
|
+
},
|
|
45
|
+
'fragile-selector': {
|
|
46
|
+
severity: 'medium',
|
|
47
|
+
message: 'Selector tied to layout or generated class names: it breaks when markup moves. Prefer getByRole, getByLabel, getByText or getByTestId.',
|
|
48
|
+
},
|
|
49
|
+
'no-timeout': {
|
|
50
|
+
severity: 'medium',
|
|
51
|
+
message: 'timeout: 0 means wait forever: a missed state hangs the run until the global timeout instead of failing at this step.',
|
|
52
|
+
},
|
|
53
|
+
'hardcoded-url': {
|
|
54
|
+
severity: 'low',
|
|
55
|
+
message: 'Hard-coded local URL: set baseURL in the config and goto a path, so the test runs against any environment.',
|
|
56
|
+
},
|
|
57
|
+
'serial-mode': {
|
|
58
|
+
severity: 'low',
|
|
59
|
+
message: 'Serial mode: tests depend on each other, so one failure skips the rest and retries re-run the whole group.',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
/* ------------------------------------------------------------------ */
|
|
63
|
+
/* Small parsing helpers */
|
|
64
|
+
/* ------------------------------------------------------------------ */
|
|
65
|
+
/** Index of the bracket closing the one at `open`, skipping quoted strings; -1 if unbalanced. */
|
|
66
|
+
export function matchBracket(text, open) {
|
|
67
|
+
const pairs = { '(': ')', '[': ']', '{': '}' };
|
|
68
|
+
const stack = [];
|
|
69
|
+
let quote = '';
|
|
70
|
+
for (let i = open; i < text.length; i += 1) {
|
|
71
|
+
const ch = text[i];
|
|
72
|
+
if (quote) {
|
|
73
|
+
if (ch === '\\')
|
|
74
|
+
i += 1;
|
|
75
|
+
else if (ch === quote)
|
|
76
|
+
quote = '';
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (ch === '"' || ch === "'" || ch === '`')
|
|
80
|
+
quote = ch;
|
|
81
|
+
else if (pairs[ch])
|
|
82
|
+
stack.push(pairs[ch]);
|
|
83
|
+
else if (ch === ')' || ch === ']' || ch === '}') {
|
|
84
|
+
if (stack.pop() !== ch)
|
|
85
|
+
return -1;
|
|
86
|
+
if (stack.length === 0)
|
|
87
|
+
return i;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return -1;
|
|
91
|
+
}
|
|
92
|
+
/** Splits `target.method(args)` into its parts when `expr` ends in a call. */
|
|
93
|
+
function trailingCall(expr) {
|
|
94
|
+
const trimmed = expr.trim();
|
|
95
|
+
if (!trimmed.endsWith(')'))
|
|
96
|
+
return undefined;
|
|
97
|
+
// Walk back to the call's opening parenthesis.
|
|
98
|
+
for (let open = trimmed.lastIndexOf('('); open >= 0; open = trimmed.lastIndexOf('(', open - 1)) {
|
|
99
|
+
if (matchBracket(trimmed, open) !== trimmed.length - 1)
|
|
100
|
+
continue;
|
|
101
|
+
const head = /\.(\w+)\s*$/.exec(trimmed.slice(0, open));
|
|
102
|
+
if (!head)
|
|
103
|
+
return undefined;
|
|
104
|
+
return { target: trimmed.slice(0, head.index), method: head[1], args: trimmed.slice(open + 1, -1).trim() };
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const STATE_MATCHERS = {
|
|
109
|
+
isVisible: 'toBeVisible',
|
|
110
|
+
isHidden: 'toBeHidden',
|
|
111
|
+
isEnabled: 'toBeEnabled',
|
|
112
|
+
isDisabled: 'toBeDisabled',
|
|
113
|
+
isChecked: 'toBeChecked',
|
|
114
|
+
isEditable: 'toBeEditable',
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* The web-first form of a one-shot assertion, e.g.
|
|
118
|
+
* `expect(await x.isVisible()).toBe(true)` → `await expect(x).toBeVisible()`.
|
|
119
|
+
* Returns the whole rewritten line, or undefined when the line is not one
|
|
120
|
+
* this knows how to rewrite.
|
|
121
|
+
*/
|
|
122
|
+
export function webFirstRewrite(line) {
|
|
123
|
+
const start = /\bexpect\(/.exec(line);
|
|
124
|
+
if (!start)
|
|
125
|
+
return undefined;
|
|
126
|
+
const open = start.index + 'expect'.length;
|
|
127
|
+
const close = matchBracket(line, open);
|
|
128
|
+
if (close < 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const inner = line.slice(open + 1, close).trim();
|
|
131
|
+
const after = line.slice(close + 1);
|
|
132
|
+
const assertion = /^\s*\.(not\.)?(toBe|toEqual|toStrictEqual|toBeTruthy|toBeFalsy|toContain)\(/.exec(after);
|
|
133
|
+
if (!assertion)
|
|
134
|
+
return undefined;
|
|
135
|
+
const argsOpen = assertion[0].length - 1;
|
|
136
|
+
const argsClose = matchBracket(after, argsOpen);
|
|
137
|
+
if (argsClose < 0)
|
|
138
|
+
return undefined;
|
|
139
|
+
const expected = after.slice(argsOpen + 1, argsClose).trim();
|
|
140
|
+
const tail = after.slice(argsClose + 1);
|
|
141
|
+
let negated = Boolean(assertion[1]);
|
|
142
|
+
const matcher = assertion[2];
|
|
143
|
+
const equality = matcher === 'toBe' || matcher === 'toEqual' || matcher === 'toStrictEqual';
|
|
144
|
+
let target;
|
|
145
|
+
let web;
|
|
146
|
+
let webArgs = '';
|
|
147
|
+
if (/^page\.url\(\)$/.test(inner)) {
|
|
148
|
+
if (!equality)
|
|
149
|
+
return undefined;
|
|
150
|
+
target = 'page';
|
|
151
|
+
web = 'toHaveURL';
|
|
152
|
+
webArgs = expected;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
if (!inner.startsWith('await '))
|
|
156
|
+
return undefined;
|
|
157
|
+
const call = trailingCall(inner.slice('await '.length));
|
|
158
|
+
if (!call || call.target.trim() === '')
|
|
159
|
+
return undefined;
|
|
160
|
+
target = call.target.trim();
|
|
161
|
+
if (STATE_MATCHERS[call.method] && call.args === '') {
|
|
162
|
+
if (matcher === 'toBeTruthy' || (equality && expected === 'true'))
|
|
163
|
+
web = STATE_MATCHERS[call.method];
|
|
164
|
+
else if (matcher === 'toBeFalsy' || (equality && expected === 'false')) {
|
|
165
|
+
web = STATE_MATCHERS[call.method];
|
|
166
|
+
negated = !negated;
|
|
167
|
+
}
|
|
168
|
+
else
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
else if ((call.method === 'textContent' || call.method === 'innerText') && call.args === '') {
|
|
172
|
+
if (equality)
|
|
173
|
+
web = 'toHaveText';
|
|
174
|
+
else if (matcher === 'toContain')
|
|
175
|
+
web = 'toContainText';
|
|
176
|
+
else
|
|
177
|
+
return undefined;
|
|
178
|
+
webArgs = expected;
|
|
179
|
+
}
|
|
180
|
+
else if (call.method === 'inputValue' && call.args === '' && equality) {
|
|
181
|
+
web = 'toHaveValue';
|
|
182
|
+
webArgs = expected;
|
|
183
|
+
}
|
|
184
|
+
else if (call.method === 'count' && call.args === '' && equality) {
|
|
185
|
+
web = 'toHaveCount';
|
|
186
|
+
webArgs = expected;
|
|
187
|
+
}
|
|
188
|
+
else if (call.method === 'getAttribute' && call.args !== '' && equality) {
|
|
189
|
+
web = 'toHaveAttribute';
|
|
190
|
+
webArgs = `${call.args}, ${expected}`;
|
|
191
|
+
}
|
|
192
|
+
else if (call.method === 'title' && call.args === '' && target === 'page' && equality) {
|
|
193
|
+
web = 'toHaveTitle';
|
|
194
|
+
webArgs = expected;
|
|
195
|
+
}
|
|
196
|
+
else
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const prefix = line.slice(0, start.index);
|
|
200
|
+
const awaited = /\bawait\s*$/.test(prefix) ? prefix : `${prefix}await `;
|
|
201
|
+
return `${awaited}expect(${target})${negated ? '.not' : ''}.${web}(${webArgs})${tail}`;
|
|
202
|
+
}
|
|
203
|
+
const ASYNC_MATCHERS = /\.(?:not\.)?(toBeVisible|toBeHidden|toBeEnabled|toBeDisabled|toBeChecked|toBeEditable|toBeFocused|toBeAttached|toBeInViewport|toBeEmpty|toHaveText|toContainText|toHaveValue|toHaveValues|toHaveCount|toHaveAttribute|toHaveClass|toContainClass|toHaveCSS|toHaveId|toHaveJSProperty|toHaveURL|toHaveTitle|toHaveScreenshot|toMatchAriaSnapshot|toHaveAccessibleName|toHaveAccessibleDescription|toHaveRole|toPass)\(/;
|
|
204
|
+
const PAGE_ACTIONS = /\.(goto|click|dblclick|fill|press|pressSequentially|type|check|uncheck|setChecked|selectOption|setInputFiles|hover|tap|focus|blur|clear|reload|goBack|goForward|waitForURL|waitForLoadState|dragTo|dragAndDrop|setViewportSize|screenshot)\(/;
|
|
205
|
+
const TEST_TITLE = /\btest(?:\.(?:only|fixme|skip|slow|fail))?\(\s*(['"`])((?:\\.|(?!\1).)+)\1/;
|
|
206
|
+
function selectorRisk(selector) {
|
|
207
|
+
const s = selector.trim();
|
|
208
|
+
if (/^(xpath=|\/\/|\(\/\/|\.\.\/)/.test(s))
|
|
209
|
+
return true;
|
|
210
|
+
if (/:nth-(child|of-type)\(/.test(s))
|
|
211
|
+
return true;
|
|
212
|
+
// Hashed class names from CSS-in-JS and CSS modules.
|
|
213
|
+
if (/\.(css|sc|jsx|emotion)-[a-z0-9]{5,}/i.test(s) || /\.[A-Za-z]+_[A-Za-z]+__[A-Za-z0-9]{5}/.test(s))
|
|
214
|
+
return true;
|
|
215
|
+
// A long chain of descendant or child steps.
|
|
216
|
+
const steps = s.replace(/\[[^\]]*\]|\([^)]*\)|"[^"]*"|'[^']*'/g, '').split(/\s*>\s*|\s+/).filter(Boolean);
|
|
217
|
+
return steps.length >= 4;
|
|
218
|
+
}
|
|
219
|
+
/** The statement starting at `index`: that line plus following lines until one ends it (at most six). */
|
|
220
|
+
function statementFrom(lines, index) {
|
|
221
|
+
const parts = [];
|
|
222
|
+
for (let i = index; i < lines.length && i < index + 6; i += 1) {
|
|
223
|
+
parts.push(lines[i].trim());
|
|
224
|
+
if (/[;{}]\s*$/.test(lines[i]) || (i > index && lines[i].trim() === ''))
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
return parts.join(' ');
|
|
228
|
+
}
|
|
229
|
+
/** Scan one spec file's source. `file` is only copied into the findings. */
|
|
230
|
+
export function scanFlakeRisks(file, source) {
|
|
231
|
+
const lines = source.split(/\r?\n/);
|
|
232
|
+
const findings = [];
|
|
233
|
+
let inBlockComment = false;
|
|
234
|
+
let currentTest;
|
|
235
|
+
const add = (index, rule, fix) => {
|
|
236
|
+
const lineText = lines[index];
|
|
237
|
+
findings.push({
|
|
238
|
+
file,
|
|
239
|
+
line: index + 1,
|
|
240
|
+
rule,
|
|
241
|
+
severity: RULES[rule].severity,
|
|
242
|
+
message: RULES[rule].message,
|
|
243
|
+
code: lineText.trim(),
|
|
244
|
+
...(fix !== undefined && fix !== lineText ? { fix } : {}),
|
|
245
|
+
...(currentTest ? { test: currentTest } : {}),
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
249
|
+
const raw = lines[i];
|
|
250
|
+
const trimmed = raw.trim();
|
|
251
|
+
if (inBlockComment) {
|
|
252
|
+
if (trimmed.includes('*/'))
|
|
253
|
+
inBlockComment = false;
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (trimmed.startsWith('/*')) {
|
|
257
|
+
if (!trimmed.includes('*/'))
|
|
258
|
+
inBlockComment = true;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (trimmed === '' || trimmed.startsWith('//') || trimmed.startsWith('*'))
|
|
262
|
+
continue;
|
|
263
|
+
// Drop a trailing line comment (not `://` inside a URL).
|
|
264
|
+
const code = raw.replace(/(^|[^:'"`])\/\/.*$/, '$1');
|
|
265
|
+
const title = TEST_TITLE.exec(code);
|
|
266
|
+
if (title && !/\btest\.(describe|step|use|beforeEach|afterEach|beforeAll|afterAll|extend)\b/.test(code))
|
|
267
|
+
currentTest = title[2];
|
|
268
|
+
if (/\.waitForTimeout\(/.test(code))
|
|
269
|
+
add(i, 'hard-wait');
|
|
270
|
+
if (/new Promise\(\s*\(?\s*\w*\s*\)?\s*=>\s*setTimeout\(/.test(code) || /\bsetTimeout\(\s*\w+\s*,\s*\d+\s*\)\s*\)/.test(code))
|
|
271
|
+
add(i, 'sleep');
|
|
272
|
+
if (/\bexpect\(\s*(await\s+[^;]*\.(isVisible|isHidden|isEnabled|isDisabled|isChecked|isEditable|textContent|innerText|inputValue|count|getAttribute)\(|page\.url\(\)\s*\)\s*\.(not\.)?(toBe|toEqual|toStrictEqual)\()/.test(code)) {
|
|
273
|
+
add(i, 'non-retrying-assertion', webFirstRewrite(raw));
|
|
274
|
+
}
|
|
275
|
+
else if (/^(expect(\.soft)?\(|expect\.poll\()/.test(trimmed)) {
|
|
276
|
+
const statement = statementFrom(lines, i);
|
|
277
|
+
if (trimmed.startsWith('expect.poll(') || ASYNC_MATCHERS.test(statement)) {
|
|
278
|
+
add(i, 'missing-await', raw.replace(/^(\s*)/, '$1await '));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (/^page\.\w/.test(trimmed)) {
|
|
282
|
+
const statement = statementFrom(lines, i);
|
|
283
|
+
if (PAGE_ACTIONS.test(statement) && !/,\s*$/.test(statement) && !/^page\.(on|once|off|route|unroute)\(/.test(trimmed)) {
|
|
284
|
+
add(i, 'missing-await', raw.replace(/^(\s*)/, '$1await '));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (/\b(test|describe)(\.describe)?\.only\(/.test(code))
|
|
288
|
+
add(i, 'focused-test', raw.replace(/\.only\(/, '('));
|
|
289
|
+
if (/\bforce\s*:\s*true\b/.test(code))
|
|
290
|
+
add(i, 'force-action');
|
|
291
|
+
if (/['"`]networkidle['"`]/.test(code))
|
|
292
|
+
add(i, 'networkidle');
|
|
293
|
+
if (/\bpage\.(\$|\$\$|\$eval|\$\$eval)\(|\.waitForSelector\(|\.elementHandles?\(/.test(code))
|
|
294
|
+
add(i, 'element-handle');
|
|
295
|
+
for (const m of code.matchAll(/(?:\.locator|\.\$\$?|waitForSelector)\(\s*(['"`])((?:\\.|(?!\1).)+)\1/g)) {
|
|
296
|
+
if (selectorRisk(m[2])) {
|
|
297
|
+
add(i, 'fragile-selector');
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (/\btimeout\s*:\s*0\b/.test(code) || /setTimeout\(\s*0\s*\)|setDefaultTimeout\(\s*0\s*\)/.test(code))
|
|
302
|
+
add(i, 'no-timeout');
|
|
303
|
+
if (/\.goto\(\s*['"`]https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)[:/'"`]/.test(code))
|
|
304
|
+
add(i, 'hardcoded-url');
|
|
305
|
+
if (/mode\s*:\s*['"`]serial['"`]/.test(code))
|
|
306
|
+
add(i, 'serial-mode');
|
|
307
|
+
}
|
|
308
|
+
return findings;
|
|
309
|
+
}
|
|
310
|
+
/** Apply every finding's fix to the source, line by line. Findings must belong to this source. */
|
|
311
|
+
export function applyFlakeFixes(source, findings) {
|
|
312
|
+
const eol = source.includes('\r\n') ? '\r\n' : '\n';
|
|
313
|
+
const lines = source.split(/\r?\n/);
|
|
314
|
+
const applied = [];
|
|
315
|
+
const done = new Set();
|
|
316
|
+
for (const finding of findings) {
|
|
317
|
+
if (finding.fix === undefined || done.has(finding.line))
|
|
318
|
+
continue;
|
|
319
|
+
if (lines[finding.line - 1]?.trim() !== finding.code)
|
|
320
|
+
continue;
|
|
321
|
+
lines[finding.line - 1] = finding.fix;
|
|
322
|
+
done.add(finding.line);
|
|
323
|
+
applied.push(finding);
|
|
324
|
+
}
|
|
325
|
+
return { source: lines.join(eol), applied };
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=flake-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flake-rules.js","sourceRoot":"","sources":["../../src/utils/flake-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -202,8 +202,8 @@ export function isHostedDeployment() {
|
|
|
202
202
|
}
|
|
203
203
|
/** What to tell a caller of the hosted bridge that asked for a browser or a test run. */
|
|
204
204
|
export const HOSTED_NO_BROWSER = {
|
|
205
|
-
message: 'The hosted endpoint has no
|
|
206
|
-
hint: '
|
|
205
|
+
message: 'The hosted endpoint has no copy of your project, so it cannot run your tests.',
|
|
206
|
+
hint: 'Here the page tools (inspect-page, validate-selector, audit-accessibility, audit-performance) work on public URLs. To run and fix your own tests, run the server next to your project: `npx -y playwright-e2e-mcp init` in the project folder, then restart your AI app.',
|
|
207
207
|
};
|
|
208
208
|
export function missingPlaywrightMessage(detection) {
|
|
209
209
|
const install = detection.packageManager === 'pnpm'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serverless Chromium for the hosted bridge. A Vercel function has no
|
|
3
|
+
* Playwright browser download, so the page tools launch the Chromium build
|
|
4
|
+
* from `@sparticuz/chromium` (a dev dependency, bundled into the function by
|
|
5
|
+
* vercel.json) with the project's Playwright driving it.
|
|
6
|
+
*
|
|
7
|
+
* On by default on Vercel; PW_MCP_SERVERLESS_CHROMIUM=1 turns it on
|
|
8
|
+
* elsewhere (Linux x64 only, Node 22+) and `0` turns it off.
|
|
9
|
+
*/
|
|
10
|
+
export interface ServerlessChromium {
|
|
11
|
+
executablePath: string;
|
|
12
|
+
args: string[];
|
|
13
|
+
/** Library and font paths the binary needs, for the probe child's env. */
|
|
14
|
+
env: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
interface ChromiumModule {
|
|
17
|
+
executablePath(): Promise<string>;
|
|
18
|
+
args: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Hand over the imported module. The Vercel entry point imports it
|
|
22
|
+
* statically so the function bundler traces it and its dependencies.
|
|
23
|
+
*/
|
|
24
|
+
export declare function provideServerlessChromium(chromium: ChromiumModule): void;
|
|
25
|
+
export declare function serverlessChromiumEnabled(): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The extracted binary and its launch flags, or null when serverless
|
|
28
|
+
* Chromium is off or not installed. Extraction to the temp dir happens
|
|
29
|
+
* once per warm instance.
|
|
30
|
+
*/
|
|
31
|
+
export declare function serverlessChromium(): Promise<ServerlessChromium | null>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serverless Chromium for the hosted bridge. A Vercel function has no
|
|
3
|
+
* Playwright browser download, so the page tools launch the Chromium build
|
|
4
|
+
* from `@sparticuz/chromium` (a dev dependency, bundled into the function by
|
|
5
|
+
* vercel.json) with the project's Playwright driving it.
|
|
6
|
+
*
|
|
7
|
+
* On by default on Vercel; PW_MCP_SERVERLESS_CHROMIUM=1 turns it on
|
|
8
|
+
* elsewhere (Linux x64 only, Node 22+) and `0` turns it off.
|
|
9
|
+
*/
|
|
10
|
+
import { isHostedDeployment } from './project-detector.js';
|
|
11
|
+
const MODULE = '@sparticuz/chromium';
|
|
12
|
+
let provided;
|
|
13
|
+
let loading;
|
|
14
|
+
/**
|
|
15
|
+
* Hand over the imported module. The Vercel entry point imports it
|
|
16
|
+
* statically so the function bundler traces it and its dependencies.
|
|
17
|
+
*/
|
|
18
|
+
export function provideServerlessChromium(chromium) {
|
|
19
|
+
provided = chromium;
|
|
20
|
+
}
|
|
21
|
+
export function serverlessChromiumEnabled() {
|
|
22
|
+
const flag = process.env.PW_MCP_SERVERLESS_CHROMIUM;
|
|
23
|
+
if (flag === '0')
|
|
24
|
+
return false;
|
|
25
|
+
return flag === '1' || isHostedDeployment();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The extracted binary and its launch flags, or null when serverless
|
|
29
|
+
* Chromium is off or not installed. Extraction to the temp dir happens
|
|
30
|
+
* once per warm instance.
|
|
31
|
+
*/
|
|
32
|
+
export function serverlessChromium() {
|
|
33
|
+
if (!serverlessChromiumEnabled())
|
|
34
|
+
return Promise.resolve(null);
|
|
35
|
+
loading ??= load().catch((err) => {
|
|
36
|
+
loading = undefined;
|
|
37
|
+
throw err;
|
|
38
|
+
});
|
|
39
|
+
return loading;
|
|
40
|
+
}
|
|
41
|
+
async function load() {
|
|
42
|
+
let chromium = provided;
|
|
43
|
+
if (!chromium) {
|
|
44
|
+
try {
|
|
45
|
+
// A variable specifier keeps tsc from resolving an optional module.
|
|
46
|
+
const name = MODULE;
|
|
47
|
+
chromium = (await import(name)).default;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const executablePath = await chromium.executablePath();
|
|
54
|
+
// Importing the module sets these on process.env for Amazon Linux;
|
|
55
|
+
// the probe child gets a scrubbed env on the bridge, so pass them on.
|
|
56
|
+
const env = {};
|
|
57
|
+
for (const key of ['LD_LIBRARY_PATH', 'FONTCONFIG_PATH']) {
|
|
58
|
+
const value = process.env[key];
|
|
59
|
+
if (value)
|
|
60
|
+
env[key] = value;
|
|
61
|
+
}
|
|
62
|
+
return { executablePath, args: chromium.args, env };
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=serverless-chromium.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverless-chromium.js","sourceRoot":"","sources":["../../src/utils/serverless-chromium.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAS3D,MAAM,MAAM,GAAG,qBAAqB,CAAC;AAOrC,IAAI,QAAoC,CAAC;AACzC,IAAI,OAAuD,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAwB;IAChE,QAAQ,GAAG,QAAQ,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACpD,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,IAAI,KAAK,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC,yBAAyB,EAAE;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACxC,OAAO,GAAG,SAAS,CAAC;QACpB,MAAM,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC;YACH,oEAAoE;YACpE,MAAM,IAAI,GAAG,MAAM,CAAC;YACpB,QAAQ,GAAI,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAiC,CAAC,OAAO,CAAC;QAC3E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;IACvD,mEAAmE;IACnE,sEAAsE;IACtE,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AACtD,CAAC"}
|
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
|
|
3
|
+
"version": "0.6.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, tests written by walking the flow, 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",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"prepare": "npm run build",
|
|
61
61
|
"watch": "tsc -p tsconfig.json --watch",
|
|
62
62
|
"test": "npm run build && node test/run-tests.mjs",
|
|
63
|
+
"coverage": "npm run build && node test/run-tests.mjs --coverage",
|
|
63
64
|
"e2e": "npm run build && node e2e/run.mjs",
|
|
64
65
|
"mcpb": "npm run build && node scripts/build-mcpb.mjs",
|
|
65
66
|
"mcpb:smoke": "npm run mcpb && node scripts/mcpb-launch-sim.mjs && node scripts/mcpb-client-check.mjs",
|
|
@@ -73,17 +74,18 @@
|
|
|
73
74
|
"prepublishOnly": "npm test"
|
|
74
75
|
},
|
|
75
76
|
"engines": {
|
|
76
|
-
"node": ">=
|
|
77
|
+
"node": ">=22"
|
|
77
78
|
},
|
|
78
79
|
"dependencies": {
|
|
79
|
-
"@modelcontextprotocol/server": "^2.
|
|
80
|
+
"@modelcontextprotocol/server": "^2.4.0",
|
|
80
81
|
"axe-core": "^4.14.0",
|
|
81
82
|
"zod": "^4.2.0"
|
|
82
83
|
},
|
|
83
84
|
"devDependencies": {
|
|
84
85
|
"@anthropic-ai/mcpb": "^2.1.2",
|
|
85
|
-
"@modelcontextprotocol/client": "^2.
|
|
86
|
+
"@modelcontextprotocol/client": "^2.4.0",
|
|
86
87
|
"@playwright/test": "1.64.1",
|
|
88
|
+
"@sparticuz/chromium": "153.0.0",
|
|
87
89
|
"@types/node": "^26.6.5",
|
|
88
90
|
"typescript": "^7.0.2"
|
|
89
91
|
},
|
|
@@ -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.6.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
|
|
@@ -148,6 +148,16 @@ re-runs the fix locally. If it says traces were not found, pass `traceDirs` with
|
|
|
148
148
|
the folder where `test-results` was unpacked. The run is added to the history
|
|
149
149
|
with its commit.
|
|
150
150
|
|
|
151
|
+
## A test that used to pass
|
|
152
|
+
|
|
153
|
+
When a test fails at HEAD but passed at some earlier commit, call
|
|
154
|
+
`bisect-failure` (0.6.0+) `{ "test": "tests/cart.spec.ts", "grep": "adds an item" }`.
|
|
155
|
+
It runs the test across git history in a temporary worktree (the checkout is not
|
|
156
|
+
touched) and names the first bad commit with its diff summary. Pass `good` (a
|
|
157
|
+
tag or `HEAD~30`) when the run history has no passing run of it; pass `repeat: 3`
|
|
158
|
+
when the failure is intermittent. Read that commit's change before editing the
|
|
159
|
+
test: the fix usually belongs in the app.
|
|
160
|
+
|
|
151
161
|
## Flaky or intermittent failures
|
|
152
162
|
|
|
153
163
|
Start with `analyze-history` (default view `flaky`) to see which tests flip
|
|
@@ -164,6 +174,8 @@ one verdict **per test** (passes, failures, duration spread, first error):
|
|
|
164
174
|
missing awaits, assertions without auto-waiting, shared state between tests and
|
|
165
175
|
fixed `waitForTimeout` sleeps. Never "fix" flakiness by only adding retries or
|
|
166
176
|
sleeps.
|
|
177
|
+
`audit-tests` (0.6.0+) finds these in the test code and names the ones in
|
|
178
|
+
tests that flaked; `fix: true` applies the mechanical rewrites and re-runs them.
|
|
167
179
|
- **NOT REPRODUCING**: passed every run. Report that the failure was one-off.
|
|
168
180
|
|
|
169
181
|
When a test is FLAKY and the suite runs in parallel, call `diagnose-flaky` again
|
|
@@ -227,7 +239,7 @@ with the commit it tested. `analyze-history` views:
|
|
|
227
239
|
`selector` for one region) returns the accessibility snapshot and a
|
|
228
240
|
`toMatchAriaSnapshot` assertion to paste into a spec.
|
|
229
241
|
- **Set up CI:** when the user wants the same diagnosis on every pull request,
|
|
230
|
-
point them to the GitHub Action (`uses: xsignon-secure/E2E@v0.
|
|
242
|
+
point them to the GitHub Action (`uses: xsignon-secure/E2E@v0.6.0`) or the
|
|
231
243
|
`npx -y playwright-e2e-mcp ci` command in `references/setup.md`. It writes the
|
|
232
244
|
run, flaky verdicts and fix diffs to the job summary and one PR comment.
|
|
233
245
|
- **Accessibility:** `audit-accessibility` with `url` runs axe-core against
|
|
@@ -12,7 +12,7 @@ This skill only gives the agent instructions. The tools come from the
|
|
|
12
12
|
(needs Playwright 1.64+) and root-cause grouping in 0.4.0. Check with
|
|
13
13
|
`npx -y playwright-e2e-mcp --version`.
|
|
14
14
|
|
|
15
|
-
- Node.js
|
|
15
|
+
- Node.js 22 or newer.
|
|
16
16
|
- A project with `@playwright/test` installed and a browser available:
|
|
17
17
|
`npx playwright install chromium`.
|
|
18
18
|
|
|
@@ -112,7 +112,7 @@ Exit code 0 means passed, 1 tests failed, 2 the run itself failed. On GitHub
|
|
|
112
112
|
Actions it also writes to the job summary. As an Action:
|
|
113
113
|
|
|
114
114
|
```yaml
|
|
115
|
-
- uses: xsignon-secure/E2E@v0.
|
|
115
|
+
- uses: xsignon-secure/E2E@v0.6.0
|
|
116
116
|
with:
|
|
117
117
|
flaky-runs: 3
|
|
118
118
|
suggest: 2
|
|
@@ -245,3 +245,35 @@ Reads `.playwright-e2e-mcp/history.jsonl`, written by every run
|
|
|
245
245
|
passing runs and flags ones that got slower; `trend` shows failed and flaky
|
|
246
246
|
executions per day; `commits` names, per failing or flaky test, the first bad
|
|
247
247
|
commit after its last passing streak and the last good one.
|
|
248
|
+
|
|
249
|
+
## audit-tests (0.6.0+)
|
|
250
|
+
|
|
251
|
+
| Argument | Type | Notes |
|
|
252
|
+
| --- | --- | --- |
|
|
253
|
+
| `testDir` / `filter` | string | Narrow the files |
|
|
254
|
+
| `minSeverity` | `low` \| `medium` \| `high` | Default `low` |
|
|
255
|
+
| `historyRuns` | number | Default 50 |
|
|
256
|
+
| `limit` | number | Findings listed, default 50 |
|
|
257
|
+
| `fix` | boolean | Rewrite mechanical findings, re-run touched files, revert on failure |
|
|
258
|
+
| `verify` | boolean | Default true |
|
|
259
|
+
|
|
260
|
+
Rules: `hard-wait`, `sleep`, `non-retrying-assertion`, `missing-await`,
|
|
261
|
+
`focused-test` (high); `force-action`, `networkidle`, `element-handle`,
|
|
262
|
+
`fragile-selector`, `no-timeout` (medium); `hardcoded-url`, `serial-mode` (low).
|
|
263
|
+
Only `non-retrying-assertion`, `missing-await` and `focused-test` are fixed
|
|
264
|
+
mechanically. Files rank by findings weighted by their flaky rate in the history.
|
|
265
|
+
|
|
266
|
+
## bisect-failure (0.6.0+)
|
|
267
|
+
|
|
268
|
+
| Argument | Type | Notes |
|
|
269
|
+
| --- | --- | --- |
|
|
270
|
+
| `test` | string | Spec file (required) |
|
|
271
|
+
| `grep` | string | Test title; better than `:line` across commits |
|
|
272
|
+
| `good` / `bad` | string | Commits or refs; `good` defaults to the newest passing commit in the history, `bad` to HEAD |
|
|
273
|
+
| `repeat` | number | Runs per commit (1–10) for intermittent failures |
|
|
274
|
+
| `maxSteps` | number | Default 12 |
|
|
275
|
+
| `stepTimeoutMs` | number | Default 180000 |
|
|
276
|
+
|
|
277
|
+
Runs in a temporary git worktree with the current `node_modules` linked in;
|
|
278
|
+
untestable commits are skipped. `status` is `found`, `ambiguous`, `max-steps`,
|
|
279
|
+
`not-failing` (passes at bad) or `good-fails`.
|