playwright-e2e-mcp 0.4.2 → 0.5.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.
Files changed (50) hide show
  1. package/README.md +175 -33
  2. package/dist/http.d.ts +1 -1
  3. package/dist/http.js +1 -1
  4. package/dist/server.d.ts +2 -2
  5. package/dist/server.js +31 -4
  6. package/dist/server.js.map +1 -1
  7. package/dist/tools/analyze-history.d.ts +12 -1
  8. package/dist/tools/analyze-history.js +89 -5
  9. package/dist/tools/analyze-history.js.map +1 -1
  10. package/dist/tools/audit-accessibility.d.ts +85 -0
  11. package/dist/tools/audit-accessibility.js +4 -1
  12. package/dist/tools/audit-accessibility.js.map +1 -1
  13. package/dist/tools/audit-performance.d.ts +333 -0
  14. package/dist/tools/audit-performance.js +377 -0
  15. package/dist/tools/audit-performance.js.map +1 -0
  16. package/dist/tools/compare-visual-state.d.ts +84 -0
  17. package/dist/tools/generate-e2e-test.d.ts +90 -0
  18. package/dist/tools/generate-e2e-test.js +223 -34
  19. package/dist/tools/generate-e2e-test.js.map +1 -1
  20. package/dist/tools/get-failure.js +2 -1
  21. package/dist/tools/get-failure.js.map +1 -1
  22. package/dist/tools/inspect-page.d.ts +94 -0
  23. package/dist/tools/inspect-page.js +42 -5
  24. package/dist/tools/inspect-page.js.map +1 -1
  25. package/dist/tools/load-report.d.ts +48 -0
  26. package/dist/tools/load-report.js +167 -0
  27. package/dist/tools/load-report.js.map +1 -0
  28. package/dist/tools/probe-script.d.ts +7 -0
  29. package/dist/tools/probe-script.js +256 -7
  30. package/dist/tools/probe-script.js.map +1 -1
  31. package/dist/tools/shared.d.ts +137 -2
  32. package/dist/tools/shared.js +151 -7
  33. package/dist/tools/shared.js.map +1 -1
  34. package/dist/tools/suggest-fix.d.ts +35 -1
  35. package/dist/tools/suggest-fix.js +197 -17
  36. package/dist/tools/suggest-fix.js.map +1 -1
  37. package/dist/tools/validate-selector.d.ts +84 -0
  38. package/dist/tools/validate-selector.js +7 -1
  39. package/dist/tools/validate-selector.js.map +1 -1
  40. package/dist/types/index.d.ts +28 -0
  41. package/dist/utils/report-parser.d.ts +28 -3
  42. package/dist/utils/report-parser.js +77 -11
  43. package/dist/utils/report-parser.js.map +1 -1
  44. package/dist/utils/run-history.d.ts +66 -3
  45. package/dist/utils/run-history.js +149 -3
  46. package/dist/utils/run-history.js.map +1 -1
  47. package/package.json +2 -2
  48. package/skill/playwright-e2e-mcp/SKILL.md +71 -15
  49. package/skill/playwright-e2e-mcp/references/setup.md +1 -1
  50. package/skill/playwright-e2e-mcp/references/tools.md +67 -6
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Tool 13 — audit-performance: load a page in a real browser and return the
3
+ * lab Web Vitals (LCP, CLS, TBT, INP during `actions`, FCP, TTFB) rated
4
+ * against Google's thresholds or the caller's budgets, what each one is
5
+ * caused by (the LCP element and the elements that shifted, as verified
6
+ * Playwright locators; long tasks; render-blocking and heavy requests) and a
7
+ * budget check to paste into a spec.
8
+ *
9
+ * It takes the same page state as inspect-page (storageState, headers,
10
+ * actions, routes), so signed-in dashboards and later steps of a flow can be
11
+ * measured, and it can emulate a mid-range phone on a slow 4G network.
12
+ * Lab numbers vary between loads, so `runs` reports the median.
13
+ */
14
+ import { z } from 'zod';
15
+ import { PlaywrightMcpError } from '../types/index.js';
16
+ import { assertHttpUrl, bestLocator, describePageState, describeRouteHits, guard, loginHint, pageStateShape, resolvePageState, resolveProjectRoot, runBrowserScript, toolError, toolText, } from './shared.js';
17
+ import { assertUrlAllowed } from '../utils/url-policy.js';
18
+ /**
19
+ * Lighthouse's mobile preset: a mid-range phone (4x slower CPU) on slow 4G
20
+ * (150 ms RTT and 1.6 Mbps, with DevTools' packet-level adjustment).
21
+ */
22
+ export const MOBILE_PROFILE = {
23
+ cpuThrottle: 4,
24
+ network: { latencyMs: 562.5, downloadBps: Math.round((1_638.4 * 1024 * 0.9) / 8), uploadBps: Math.round((750 * 1024 * 0.9) / 8) },
25
+ viewport: { width: 412, height: 823 },
26
+ };
27
+ export const METRICS = [
28
+ { id: 'lcp', label: 'LCP · largest contentful paint', good: 2_500, poor: 4_000, unit: 'ms' },
29
+ { id: 'cls', label: 'CLS · cumulative layout shift', good: 0.1, poor: 0.25, unit: 'score' },
30
+ { id: 'inp', label: 'INP · slowest interaction (lab)', good: 200, poor: 500, unit: 'ms' },
31
+ { id: 'tbt', label: 'TBT · total blocking time', good: 200, poor: 600, unit: 'ms' },
32
+ { id: 'fcp', label: 'FCP · first contentful paint', good: 1_800, poor: 3_000, unit: 'ms' },
33
+ { id: 'ttfb', label: 'TTFB · time to first byte', good: 800, poor: 1_800, unit: 'ms' },
34
+ ];
35
+ const budgetsShape = z
36
+ .object({
37
+ lcpMs: z.number().min(0).optional(),
38
+ cls: z.number().min(0).optional(),
39
+ inpMs: z.number().min(0).optional(),
40
+ tbtMs: z.number().min(0).optional(),
41
+ fcpMs: z.number().min(0).optional(),
42
+ ttfbMs: z.number().min(0).optional(),
43
+ transferKb: z.number().min(0).optional().describe('Total bytes over the wire, in kB'),
44
+ requests: z.number().int().min(0).optional(),
45
+ })
46
+ .describe('Fail the audit when a metric exceeds its budget (default: rate against Google thresholds)');
47
+ const auditPerformanceInput = z.object({
48
+ url: z.string().describe('Full URL of the page to measure (http/https)'),
49
+ projectRoot: z.string().optional().describe('Project whose Playwright launches the browser (default: server root)'),
50
+ throttle: z
51
+ .enum(['none', 'mobile'])
52
+ .optional()
53
+ .describe("'mobile': phone viewport, 4x CPU slowdown and slow 4G like Lighthouse mobile; 'none' (default): desktop, unthrottled"),
54
+ cpuSlowdown: z.number().int().min(1).max(20).optional().describe('Override the CPU slowdown factor'),
55
+ runs: z.number().int().min(1).max(5).optional().describe('Load the page this many times and report the median (default 1)'),
56
+ budgets: budgetsShape.optional(),
57
+ waitFor: z.string().optional().describe('Wait for this selector first'),
58
+ ...pageStateShape,
59
+ waitUntil: z
60
+ .enum(['load', 'domcontentloaded', 'networkidle'])
61
+ .optional()
62
+ .describe('Navigation wait condition (default load)'),
63
+ settleMs: z.number().int().min(0).max(10_000).optional().describe('Keep observing after load for late paints and shifts (default 1500)'),
64
+ timeoutMs: z.number().int().min(5_000).max(300_000).optional().describe('Limit per run in ms (default 60000)'),
65
+ });
66
+ export const auditPerformanceSchema = auditPerformanceInput;
67
+ export function rate(id, value) {
68
+ const spec = METRICS.find((m) => m.id === id);
69
+ if (value <= spec.good)
70
+ return 'good';
71
+ if (value <= spec.poor)
72
+ return 'needs-improvement';
73
+ return 'poor';
74
+ }
75
+ export function metricValue(scan, id) {
76
+ switch (id) {
77
+ case 'lcp':
78
+ return scan.lcpMs;
79
+ case 'cls':
80
+ return scan.cls;
81
+ case 'inp':
82
+ return scan.inpMs;
83
+ case 'tbt':
84
+ return scan.tbtMs;
85
+ case 'fcp':
86
+ return scan.fcpMs;
87
+ case 'ttfb':
88
+ return scan.ttfbMs;
89
+ }
90
+ }
91
+ function budgetFor(budgets, id) {
92
+ if (!budgets)
93
+ return undefined;
94
+ return id === 'cls' ? budgets.cls : budgets[`${id}Ms`];
95
+ }
96
+ export function formatMs(ms) {
97
+ return ms >= 1_000 ? `${(ms / 1_000).toFixed(ms >= 10_000 ? 1 : 2)} s` : `${Math.round(ms)} ms`;
98
+ }
99
+ export function formatBytes(bytes) {
100
+ if (bytes >= 1_000_000)
101
+ return `${(bytes / 1_000_000).toFixed(1)} MB`;
102
+ if (bytes >= 1_000)
103
+ return `${Math.round(bytes / 1_000)} kB`;
104
+ return `${bytes} B`;
105
+ }
106
+ function formatMetric(spec, value) {
107
+ return spec.unit === 'score' ? value.toFixed(3) : formatMs(value);
108
+ }
109
+ function median(values) {
110
+ const sorted = [...values].sort((a, b) => a - b);
111
+ const mid = Math.floor(sorted.length / 2);
112
+ return sorted.length % 2 === 1 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
113
+ }
114
+ /**
115
+ * Combine several runs: every number is the median of the runs that
116
+ * measured it, and the details (LCP element, resources) come from the run
117
+ * whose LCP is closest to that median.
118
+ */
119
+ export function mergeRuns(runs) {
120
+ if (runs.length === 1)
121
+ return { data: runs[0] };
122
+ const scans = runs.map((run) => run.perf);
123
+ const pick = (get) => {
124
+ const values = scans.map(get).filter((v) => typeof v === 'number');
125
+ return values.length > 0 ? median(values) : undefined;
126
+ };
127
+ const lcp = pick((s) => s.lcpMs);
128
+ let representative = 0;
129
+ if (lcp !== undefined) {
130
+ let best = Infinity;
131
+ scans.forEach((scan, i) => {
132
+ const distance = Math.abs((scan.lcpMs ?? Infinity) - lcp);
133
+ if (distance < best) {
134
+ best = distance;
135
+ representative = i;
136
+ }
137
+ });
138
+ }
139
+ const base = runs[representative];
140
+ const perf = {
141
+ ...base.perf,
142
+ ttfbMs: pick((s) => s.ttfbMs),
143
+ fcpMs: pick((s) => s.fcpMs),
144
+ lcpMs: lcp,
145
+ cls: Math.round((pick((s) => s.cls) ?? 0) * 1_000) / 1_000,
146
+ tbtMs: Math.round(pick((s) => s.tbtMs) ?? 0),
147
+ inpMs: pick((s) => s.inpMs),
148
+ transferBytes: Math.round(pick((s) => s.transferBytes) ?? 0),
149
+ requests: Math.round(pick((s) => s.requests) ?? 0),
150
+ };
151
+ const lcps = scans.map((s) => s.lcpMs).filter((v) => typeof v === 'number');
152
+ return {
153
+ data: { ...base, perf },
154
+ spread: lcps.length > 1 ? { lcp: [Math.min(...lcps), Math.max(...lcps)] } : undefined,
155
+ };
156
+ }
157
+ export function metricRows(scan, budgets) {
158
+ return METRICS.map((spec) => {
159
+ const value = metricValue(scan, spec.id);
160
+ const budget = budgetFor(budgets, spec.id);
161
+ return {
162
+ spec,
163
+ value,
164
+ rating: value === undefined ? undefined : rate(spec.id, value),
165
+ budget,
166
+ overBudget: value !== undefined && budget !== undefined && value > budget,
167
+ };
168
+ });
169
+ }
170
+ function locatorOf(elements, index) {
171
+ const element = index >= 0 ? elements[index] : undefined;
172
+ if (!element)
173
+ return undefined;
174
+ return bestLocator(element) ?? element.selector;
175
+ }
176
+ /** Concrete causes and fixes for the metrics that are not good. */
177
+ export function perfFindings(data) {
178
+ const scan = data.perf;
179
+ const out = [];
180
+ const blocking = scan.renderBlocking;
181
+ if (scan.lcpMs !== undefined && rate('lcp', scan.lcpMs) !== 'good') {
182
+ const where = locatorOf(data.elements, scan.lcpElement);
183
+ const what = scan.lcpUrl ? `the ${scan.lcpTag ?? 'element'} loading \`${scan.lcpUrl}\`` : `a <${scan.lcpTag ?? '?'}> element`;
184
+ const tips = [];
185
+ if (scan.lcpUrl)
186
+ tips.push('preload it or set `fetchpriority="high"`, never `loading="lazy"` above the fold', 'serve it compressed (AVIF/WebP) at display size');
187
+ if (blocking.length > 0)
188
+ tips.push(`cut the ${blocking.length} render-blocking request(s) listed below`);
189
+ if (scan.ttfbMs !== undefined && rate('ttfb', scan.ttfbMs) !== 'good')
190
+ tips.push('the server answers slowly, so cache or stream the HTML');
191
+ if (tips.length === 0)
192
+ tips.push('render it from the HTML rather than after client-side JavaScript');
193
+ out.push(`**LCP ${formatMs(scan.lcpMs)}** is ${what}${where ? ` (\`${where}\`)` : ''}: ${tips.join('; ')}.`);
194
+ }
195
+ if (rate('cls', scan.cls) !== 'good') {
196
+ const moved = scan.shiftElements.map((i) => locatorOf(data.elements, i)).filter((l) => l !== undefined);
197
+ out.push(`**CLS ${scan.cls.toFixed(3)}**${moved.length ? `: these moved: ${moved.map((l) => `\`${l}\``).join(', ')}` : ''}. Reserve their space (width/height or aspect-ratio on media, min-height on late content, \`font-display: optional\` or size-adjusted fallbacks for web fonts).`);
198
+ }
199
+ if (rate('tbt', scan.tbtMs) !== 'good') {
200
+ out.push(`**TBT ${formatMs(scan.tbtMs)}** from ${scan.longTasks} long task(s), the longest ${formatMs(scan.longestTaskMs)}: split or defer JavaScript${scan.thirdPartyOrigins > 0 ? `, and load the ${scan.thirdPartyOrigins} third-party origin(s) after interaction` : ''}.`);
201
+ }
202
+ if (scan.inpMs !== undefined && rate('inp', scan.inpMs) !== 'good') {
203
+ out.push(`**INP ${formatMs(scan.inpMs)}**${scan.inpTarget ? ` on ${scan.inpTarget}` : ''}: the handler blocks the next paint; yield (\`await scheduler.yield()\`) or move work off the main thread.`);
204
+ }
205
+ if (scan.fcpMs !== undefined && rate('fcp', scan.fcpMs) !== 'good' && blocking.length > 0 && !out.some((l) => l.startsWith('**LCP'))) {
206
+ out.push(`**FCP ${formatMs(scan.fcpMs)}**: ${blocking.length} render-blocking request(s) delay the first paint; inline critical CSS and \`defer\` scripts.`);
207
+ }
208
+ return out;
209
+ }
210
+ export function budgetCheck(url, budgets) {
211
+ const lcp = budgets?.lcpMs ?? 2_500;
212
+ const cls = budgets?.cls ?? 0.1;
213
+ return [
214
+ '```ts',
215
+ "test('stays within the performance budget', async ({ page }) => {",
216
+ ` await page.goto(${JSON.stringify(url)});`,
217
+ ' const vitals = await page.evaluate(() => new Promise<{ lcp: number; cls: number }>((resolve) => {',
218
+ ' let lcp = 0;',
219
+ ' let cls = 0;',
220
+ " new PerformanceObserver((list) => { for (const e of list.getEntries()) lcp = e.startTime; }).observe({ type: 'largest-contentful-paint', buffered: true });",
221
+ " new PerformanceObserver((list) => { for (const e of list.getEntries() as any[]) if (!e.hadRecentInput) cls += e.value; }).observe({ type: 'layout-shift', buffered: true });",
222
+ ' setTimeout(() => resolve({ lcp, cls }), 1_500);',
223
+ ' }));',
224
+ ` expect(vitals.lcp).toBeLessThan(${lcp});`,
225
+ ` expect(vitals.cls).toBeLessThan(${cls});`,
226
+ '});',
227
+ '```',
228
+ ].join('\n');
229
+ }
230
+ const ICON = { good: '🟢 good', 'needs-improvement': '🟠 needs improvement', poor: '🔴 poor' };
231
+ export function renderPerformance(url, data, options) {
232
+ const scan = data.perf;
233
+ const rows = metricRows(scan, options.budgets);
234
+ const measured = rows.filter((r) => r.value !== undefined);
235
+ const budgets = options.budgets;
236
+ const overBudget = rows.filter((r) => r.overBudget).map((r) => r.spec.id.toUpperCase());
237
+ if (budgets?.transferKb !== undefined && scan.transferBytes / 1_000 > budgets.transferKb)
238
+ overBudget.push('transfer size');
239
+ if (budgets?.requests !== undefined && scan.requests > budgets.requests)
240
+ overBudget.push('request count');
241
+ const weak = measured.filter((r) => r.rating !== 'good');
242
+ const lines = [];
243
+ if (budgets) {
244
+ lines.push(overBudget.length > 0
245
+ ? `## ❌ ${overBudget.length} performance budget${overBudget.length === 1 ? '' : 's'} exceeded (${overBudget.join(', ')})`
246
+ : '## ✅ Within every performance budget');
247
+ }
248
+ else if (weak.length === 0) {
249
+ lines.push('## ✅ All measured Web Vitals are good');
250
+ }
251
+ else {
252
+ lines.push(`## ⚡ ${weak.length} of ${measured.length} metrics need work (${weak.map((r) => r.spec.id.toUpperCase()).join(', ')})`);
253
+ }
254
+ lines.push('');
255
+ lines.push(`**URL:** ${url}${data.finalUrl && data.finalUrl !== url ? ` → ${data.finalUrl}` : ''} | **Profile:** ${options.profile} | **Runs:** ${options.runs}${options.runs > 1 ? ' (median)' : ''}`);
256
+ if (options.stateLine)
257
+ lines.push(`**Page state:** ${options.stateLine}`);
258
+ if (data.actionsDone?.length)
259
+ lines.push(`**Steps run:** ${data.actionsDone.join('; ')}`);
260
+ lines.push('');
261
+ lines.push(`| Metric | Value | Rating |${budgets ? ' Budget |' : ''}`, `| --- | --- | --- |${budgets ? ' --- |' : ''}`);
262
+ for (const row of rows) {
263
+ if (row.value === undefined) {
264
+ if (row.spec.id === 'inp')
265
+ continue; // only measured when actions ran
266
+ lines.push(`| ${row.spec.label} | n/a | — |${budgets ? ' — |' : ''}`);
267
+ continue;
268
+ }
269
+ let value = formatMetric(row.spec, row.value);
270
+ if (row.spec.id === 'lcp' && options.spread)
271
+ value += ` (${formatMs(options.spread.lcp[0])}–${formatMs(options.spread.lcp[1])})`;
272
+ const budget = row.budget === undefined ? '—' : `${row.overBudget ? '❌' : '✅'} ≤ ${formatMetric(row.spec, row.budget)}`;
273
+ lines.push(`| ${row.spec.label} | ${value} | ${ICON[row.rating]} |${budgets ? ` ${budget} |` : ''}`);
274
+ }
275
+ lines.push('');
276
+ const findings = perfFindings(data);
277
+ if (findings.length > 0) {
278
+ lines.push('### What to fix', '');
279
+ for (const finding of findings)
280
+ lines.push(`- ${finding}`);
281
+ lines.push('');
282
+ }
283
+ lines.push('### Network', '');
284
+ const transferBudget = budgets?.transferKb !== undefined ? ` (budget ${budgets.transferKb} kB ${scan.transferBytes / 1_000 > budgets.transferKb ? '❌' : '✅'})` : '';
285
+ const requestBudget = budgets?.requests !== undefined ? ` (budget ${budgets.requests} ${scan.requests > budgets.requests ? '❌' : '✅'})` : '';
286
+ lines.push(`**Transfer:** ${formatBytes(scan.transferBytes)}${transferBudget} in ${scan.requests} requests${requestBudget}` +
287
+ (scan.thirdPartyOrigins > 0 ? ` · third-party: ${formatBytes(scan.thirdPartyBytes)} from ${scan.thirdPartyOrigins} origin(s)` : '') +
288
+ ` · DOM: ${scan.domNodes} nodes${scan.jsHeapBytes ? ` · JS heap: ${formatBytes(scan.jsHeapBytes)}` : ''}`);
289
+ if (scan.byType.length > 0) {
290
+ lines.push(`**By type:** ${scan.byType.slice(0, 6).map((t) => `${t.type} ${formatBytes(t.transferBytes)} (${t.requests})`).join(' · ')}`);
291
+ }
292
+ const largest = scan.largest.filter((r) => r.transferBytes > 0);
293
+ if (largest.length > 0) {
294
+ lines.push('', '**Heaviest requests:**');
295
+ for (const r of largest)
296
+ lines.push(`- ${formatBytes(r.transferBytes)} · ${r.type} · \`${r.url}\`${r.durationMs ? ` · ${formatMs(r.durationMs)}` : ''}`);
297
+ }
298
+ if (scan.renderBlocking.length > 0) {
299
+ lines.push('', '**Render-blocking:**');
300
+ for (const r of scan.renderBlocking)
301
+ lines.push(`- ${r.type} \`${r.url}\`${r.durationMs ? ` · ${formatMs(r.durationMs)}` : ''}`);
302
+ }
303
+ if (options.routeLines && options.routeLines.length > 0)
304
+ lines.push('', '**Network mocks:**', ...options.routeLines);
305
+ lines.push('');
306
+ lines.push('Lab numbers from one headless Chromium; field data (CrUX, RUM) can differ. INP is measured only when `actions` interact with the page.', '', '**Keep it fast:** add a budget check to the spec that reaches this page:', '', budgetCheck(data.finalUrl ?? url, budgets));
307
+ return lines.join('\n').trimEnd();
308
+ }
309
+ /* ------------------------------------------------------------------ */
310
+ /* Tool */
311
+ /* ------------------------------------------------------------------ */
312
+ export const auditPerformanceTool = {
313
+ name: 'audit-performance',
314
+ description: "Measure a page's lab Web Vitals (LCP, CLS, TBT, FCP, TTFB, and INP when actions interact) in headless Chromium, optionally as a throttled phone and as the median of several runs. Rates them against Google thresholds or your budgets, names the LCP element and shifting elements as verified locators, lists heavy and render-blocking requests, and returns a budget check for the spec. Accepts storageState/headers/actions/routes.",
315
+ inputSchema: auditPerformanceSchema,
316
+ handler: async (args, ctx) => guard('audit-performance', async () => {
317
+ const url = assertHttpUrl(args.url);
318
+ await assertUrlAllowed(url);
319
+ if (args.browser && args.browser !== 'chromium') {
320
+ throw new PlaywrightMcpError('audit-performance measures in Chromium only', 'INVALID_PATH', {
321
+ hint: 'Web Vitals, byte counts and throttling come from the Chrome DevTools Protocol. Leave browser unset.',
322
+ });
323
+ }
324
+ const root = await resolveProjectRoot(args.projectRoot, ctx);
325
+ const state = await resolvePageState(args, root, url, ctx);
326
+ const timeoutMs = args.timeoutMs ?? 60_000;
327
+ const mobile = args.throttle === 'mobile';
328
+ const cpuThrottle = args.cpuSlowdown ?? (mobile ? MOBILE_PROFILE.cpuThrottle : 1);
329
+ const runs = args.runs ?? 1;
330
+ const profile = [
331
+ mobile ? 'mobile, slow 4G' : 'desktop, unthrottled network',
332
+ cpuThrottle > 1 ? `${cpuThrottle}x CPU slowdown` : undefined,
333
+ ]
334
+ .filter(Boolean)
335
+ .join(', ');
336
+ const results = [];
337
+ for (let run = 1; run <= runs; run += 1) {
338
+ ctx.progress?.(run - 1, runs, `Loading ${url} (run ${run} of ${runs})`);
339
+ const outcome = await runBrowserScript({
340
+ ...state,
341
+ viewport: state.viewport ?? (mobile ? MOBILE_PROFILE.viewport : undefined),
342
+ mode: 'perf',
343
+ projectRoot: root,
344
+ url,
345
+ waitFor: args.waitFor,
346
+ waitUntil: args.waitUntil ?? 'load',
347
+ settleMs: args.settleMs ?? 1_500,
348
+ mobile,
349
+ cpuThrottle,
350
+ network: mobile ? MOBILE_PROFILE.network : undefined,
351
+ gotoTimeout: Math.max(5_000, timeoutMs - 10_000),
352
+ waitTimeout: Math.min(10_000, Math.max(3_000, timeoutMs - 10_000)),
353
+ startedAt: Date.now(),
354
+ }, { timeoutMs, signal: ctx.signal });
355
+ if (!outcome.ok || !outcome.data?.perf) {
356
+ const done = outcome.actionsDone?.length ? `\n\nSteps completed before the failure: ${outcome.actionsDone.join('; ')}` : '';
357
+ return toolError(outcome.kind ?? 'UNKNOWN', `Could not measure ${url}${runs > 1 ? ` (run ${run} of ${runs})` : ''}: ${outcome.error ?? 'no performance data'}${done}`, outcome.hint, outcome.stderrTail);
358
+ }
359
+ results.push(outcome.data);
360
+ }
361
+ ctx.progress?.(runs, runs, 'Done');
362
+ const { data, spread } = mergeRuns(results);
363
+ let text = renderPerformance(url, data, {
364
+ budgets: args.budgets,
365
+ profile,
366
+ runs,
367
+ spread,
368
+ stateLine: describePageState(state, root),
369
+ routeLines: describeRouteHits(state, data.routeHits),
370
+ });
371
+ const login = loginHint(data.finalUrl, state);
372
+ if (login)
373
+ text += `\n\n> 🔒 ${login}`;
374
+ return toolText(text);
375
+ }),
376
+ };
377
+ //# sourceMappingURL=audit-performance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-performance.js","sourceRoot":"","sources":["../../src/tools/audit-performance.ts"],"names":[],"mappings":"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"}
@@ -29,10 +29,38 @@ declare const compareInput: z.ZodObject<{
29
29
  url: z.ZodOptional<z.ZodString>;
30
30
  ms: z.ZodOptional<z.ZodNumber>;
31
31
  }, z.core.$strip>>>;
32
+ routes: z.ZodOptional<z.ZodArray<z.ZodObject<{
33
+ url: z.ZodString;
34
+ method: z.ZodOptional<z.ZodString>;
35
+ status: z.ZodOptional<z.ZodNumber>;
36
+ json: z.ZodOptional<z.ZodUnknown>;
37
+ body: z.ZodOptional<z.ZodString>;
38
+ contentType: z.ZodOptional<z.ZodString>;
39
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
40
+ abort: z.ZodOptional<z.ZodBoolean>;
41
+ delayMs: z.ZodOptional<z.ZodNumber>;
42
+ }, z.core.$strip>>>;
32
43
  viewport: z.ZodOptional<z.ZodObject<{
33
44
  width: z.ZodNumber;
34
45
  height: z.ZodNumber;
35
46
  }, z.core.$strip>>;
47
+ har: z.ZodOptional<z.ZodObject<{
48
+ path: z.ZodString;
49
+ mode: z.ZodOptional<z.ZodEnum<{
50
+ record: "record";
51
+ replay: "replay";
52
+ }>>;
53
+ url: z.ZodOptional<z.ZodString>;
54
+ notFound: z.ZodOptional<z.ZodEnum<{
55
+ abort: "abort";
56
+ fallback: "fallback";
57
+ }>>;
58
+ }, z.core.$strip>>;
59
+ browser: z.ZodOptional<z.ZodEnum<{
60
+ chromium: "chromium";
61
+ firefox: "firefox";
62
+ webkit: "webkit";
63
+ }>>;
36
64
  url: z.ZodString;
37
65
  name: z.ZodString;
38
66
  projectRoot: z.ZodOptional<z.ZodString>;
@@ -74,10 +102,38 @@ export declare const compareVisualStateSchema: z.ZodObject<{
74
102
  url: z.ZodOptional<z.ZodString>;
75
103
  ms: z.ZodOptional<z.ZodNumber>;
76
104
  }, z.core.$strip>>>;
105
+ routes: z.ZodOptional<z.ZodArray<z.ZodObject<{
106
+ url: z.ZodString;
107
+ method: z.ZodOptional<z.ZodString>;
108
+ status: z.ZodOptional<z.ZodNumber>;
109
+ json: z.ZodOptional<z.ZodUnknown>;
110
+ body: z.ZodOptional<z.ZodString>;
111
+ contentType: z.ZodOptional<z.ZodString>;
112
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
113
+ abort: z.ZodOptional<z.ZodBoolean>;
114
+ delayMs: z.ZodOptional<z.ZodNumber>;
115
+ }, z.core.$strip>>>;
77
116
  viewport: z.ZodOptional<z.ZodObject<{
78
117
  width: z.ZodNumber;
79
118
  height: z.ZodNumber;
80
119
  }, z.core.$strip>>;
120
+ har: z.ZodOptional<z.ZodObject<{
121
+ path: z.ZodString;
122
+ mode: z.ZodOptional<z.ZodEnum<{
123
+ record: "record";
124
+ replay: "replay";
125
+ }>>;
126
+ url: z.ZodOptional<z.ZodString>;
127
+ notFound: z.ZodOptional<z.ZodEnum<{
128
+ abort: "abort";
129
+ fallback: "fallback";
130
+ }>>;
131
+ }, z.core.$strip>>;
132
+ browser: z.ZodOptional<z.ZodEnum<{
133
+ chromium: "chromium";
134
+ firefox: "firefox";
135
+ webkit: "webkit";
136
+ }>>;
81
137
  url: z.ZodString;
82
138
  name: z.ZodString;
83
139
  projectRoot: z.ZodOptional<z.ZodString>;
@@ -121,10 +177,38 @@ export declare const compareVisualStateTool: {
121
177
  url: z.ZodOptional<z.ZodString>;
122
178
  ms: z.ZodOptional<z.ZodNumber>;
123
179
  }, z.core.$strip>>>;
180
+ routes: z.ZodOptional<z.ZodArray<z.ZodObject<{
181
+ url: z.ZodString;
182
+ method: z.ZodOptional<z.ZodString>;
183
+ status: z.ZodOptional<z.ZodNumber>;
184
+ json: z.ZodOptional<z.ZodUnknown>;
185
+ body: z.ZodOptional<z.ZodString>;
186
+ contentType: z.ZodOptional<z.ZodString>;
187
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
188
+ abort: z.ZodOptional<z.ZodBoolean>;
189
+ delayMs: z.ZodOptional<z.ZodNumber>;
190
+ }, z.core.$strip>>>;
124
191
  viewport: z.ZodOptional<z.ZodObject<{
125
192
  width: z.ZodNumber;
126
193
  height: z.ZodNumber;
127
194
  }, z.core.$strip>>;
195
+ har: z.ZodOptional<z.ZodObject<{
196
+ path: z.ZodString;
197
+ mode: z.ZodOptional<z.ZodEnum<{
198
+ record: "record";
199
+ replay: "replay";
200
+ }>>;
201
+ url: z.ZodOptional<z.ZodString>;
202
+ notFound: z.ZodOptional<z.ZodEnum<{
203
+ abort: "abort";
204
+ fallback: "fallback";
205
+ }>>;
206
+ }, z.core.$strip>>;
207
+ browser: z.ZodOptional<z.ZodEnum<{
208
+ chromium: "chromium";
209
+ firefox: "firefox";
210
+ webkit: "webkit";
211
+ }>>;
128
212
  url: z.ZodString;
129
213
  name: z.ZodString;
130
214
  projectRoot: z.ZodOptional<z.ZodString>;
@@ -10,6 +10,7 @@
10
10
  import { z } from 'zod';
11
11
  import type { ToolContext, ToolResponse } from '../types/index.js';
12
12
  import type { ElementInfo } from '../types/index.js';
13
+ import type { ResolvedPageState } from './shared.js';
13
14
  declare const generateInput: z.ZodObject<{
14
15
  description: z.ZodString;
15
16
  pageUrl: z.ZodOptional<z.ZodString>;
@@ -20,6 +21,29 @@ declare const generateInput: z.ZodObject<{
20
21
  write: z.ZodOptional<z.ZodBoolean>;
21
22
  overwrite: z.ZodOptional<z.ZodBoolean>;
22
23
  liveInspect: z.ZodOptional<z.ZodBoolean>;
24
+ steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
25
+ type: z.ZodEnum<{
26
+ check: "check";
27
+ click: "click";
28
+ dblclick: "dblclick";
29
+ fill: "fill";
30
+ goto: "goto";
31
+ hover: "hover";
32
+ press: "press";
33
+ select: "select";
34
+ uncheck: "uncheck";
35
+ wait: "wait";
36
+ }>;
37
+ locator: z.ZodOptional<z.ZodString>;
38
+ value: z.ZodOptional<z.ZodString>;
39
+ url: z.ZodOptional<z.ZodString>;
40
+ ms: z.ZodOptional<z.ZodNumber>;
41
+ }, z.core.$strip>>>;
42
+ storageState: z.ZodOptional<z.ZodString>;
43
+ assertScope: z.ZodOptional<z.ZodString>;
44
+ verify: z.ZodOptional<z.ZodBoolean>;
45
+ project: z.ZodOptional<z.ZodString>;
46
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
23
47
  }, z.core.$strip>;
24
48
  export type GenerateE2ETestInput = z.infer<typeof generateInput>;
25
49
  export declare const generateE2ETestSchema: z.ZodObject<{
@@ -32,6 +56,29 @@ export declare const generateE2ETestSchema: z.ZodObject<{
32
56
  write: z.ZodOptional<z.ZodBoolean>;
33
57
  overwrite: z.ZodOptional<z.ZodBoolean>;
34
58
  liveInspect: z.ZodOptional<z.ZodBoolean>;
59
+ steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
60
+ type: z.ZodEnum<{
61
+ check: "check";
62
+ click: "click";
63
+ dblclick: "dblclick";
64
+ fill: "fill";
65
+ goto: "goto";
66
+ hover: "hover";
67
+ press: "press";
68
+ select: "select";
69
+ uncheck: "uncheck";
70
+ wait: "wait";
71
+ }>;
72
+ locator: z.ZodOptional<z.ZodString>;
73
+ value: z.ZodOptional<z.ZodString>;
74
+ url: z.ZodOptional<z.ZodString>;
75
+ ms: z.ZodOptional<z.ZodNumber>;
76
+ }, z.core.$strip>>>;
77
+ storageState: z.ZodOptional<z.ZodString>;
78
+ assertScope: z.ZodOptional<z.ZodString>;
79
+ verify: z.ZodOptional<z.ZodBoolean>;
80
+ project: z.ZodOptional<z.ZodString>;
81
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
35
82
  }, z.core.$strip>;
36
83
  /**
37
84
  * Live elements worth a step: those whose accessible name or test id shares
@@ -43,6 +90,26 @@ export declare function pickLiveLocators(description: string, elements: ElementI
43
90
  role?: string;
44
91
  name?: string;
45
92
  }>;
93
+ /** One walked step as Playwright code. */
94
+ export declare function stepCode(action: NonNullable<ResolvedPageState['actions']>[number]): string;
95
+ /**
96
+ * End-state assertions: the URL the flow lands on (path only, so query
97
+ * ids do not pin it) and the accessibility snapshot of the scope, or its
98
+ * headings when the snapshot is too long to be a useful assertion.
99
+ */
100
+ export declare function endStateAssertions(options: {
101
+ entryUrl: string;
102
+ finalUrl?: string;
103
+ snapshot?: string;
104
+ scope?: string;
105
+ }): string[];
106
+ export declare function buildWalkSpec(options: {
107
+ description: string;
108
+ entryUrl: string;
109
+ steps: NonNullable<ResolvedPageState['actions']>;
110
+ storageState?: string;
111
+ assertions: string[];
112
+ }): string;
46
113
  export declare const generateE2ETestTool: {
47
114
  name: string;
48
115
  description: string;
@@ -56,6 +123,29 @@ export declare const generateE2ETestTool: {
56
123
  write: z.ZodOptional<z.ZodBoolean>;
57
124
  overwrite: z.ZodOptional<z.ZodBoolean>;
58
125
  liveInspect: z.ZodOptional<z.ZodBoolean>;
126
+ steps: z.ZodOptional<z.ZodArray<z.ZodObject<{
127
+ type: z.ZodEnum<{
128
+ check: "check";
129
+ click: "click";
130
+ dblclick: "dblclick";
131
+ fill: "fill";
132
+ goto: "goto";
133
+ hover: "hover";
134
+ press: "press";
135
+ select: "select";
136
+ uncheck: "uncheck";
137
+ wait: "wait";
138
+ }>;
139
+ locator: z.ZodOptional<z.ZodString>;
140
+ value: z.ZodOptional<z.ZodString>;
141
+ url: z.ZodOptional<z.ZodString>;
142
+ ms: z.ZodOptional<z.ZodNumber>;
143
+ }, z.core.$strip>>>;
144
+ storageState: z.ZodOptional<z.ZodString>;
145
+ assertScope: z.ZodOptional<z.ZodString>;
146
+ verify: z.ZodOptional<z.ZodBoolean>;
147
+ project: z.ZodOptional<z.ZodString>;
148
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
59
149
  }, z.core.$strip>;
60
150
  handler: (args: GenerateE2ETestInput, ctx: ToolContext) => Promise<ToolResponse>;
61
151
  };