playwright-e2e-mcp 0.1.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/dist/http.d.ts +27 -0
  4. package/dist/http.js +156 -0
  5. package/dist/http.js.map +1 -0
  6. package/dist/index.d.ts +12 -0
  7. package/dist/index.js +56 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/server.d.ts +23 -0
  10. package/dist/server.js +225 -0
  11. package/dist/server.js.map +1 -0
  12. package/dist/tools/compare-visual-state.d.ts +77 -0
  13. package/dist/tools/compare-visual-state.js +223 -0
  14. package/dist/tools/compare-visual-state.js.map +1 -0
  15. package/dist/tools/diagnose-flaky.d.ts +87 -0
  16. package/dist/tools/diagnose-flaky.js +258 -0
  17. package/dist/tools/diagnose-flaky.js.map +1 -0
  18. package/dist/tools/generate-e2e-test.d.ts +51 -0
  19. package/dist/tools/generate-e2e-test.js +274 -0
  20. package/dist/tools/generate-e2e-test.js.map +1 -0
  21. package/dist/tools/get-failure.d.ts +26 -0
  22. package/dist/tools/get-failure.js +220 -0
  23. package/dist/tools/get-failure.js.map +1 -0
  24. package/dist/tools/inspect-page.d.ts +57 -0
  25. package/dist/tools/inspect-page.js +124 -0
  26. package/dist/tools/inspect-page.js.map +1 -0
  27. package/dist/tools/list-tests.d.ts +35 -0
  28. package/dist/tools/list-tests.js +88 -0
  29. package/dist/tools/list-tests.js.map +1 -0
  30. package/dist/tools/run-test.d.ts +70 -0
  31. package/dist/tools/run-test.js +169 -0
  32. package/dist/tools/run-test.js.map +1 -0
  33. package/dist/tools/shared.d.ts +86 -0
  34. package/dist/tools/shared.js +490 -0
  35. package/dist/tools/shared.js.map +1 -0
  36. package/dist/tools/validate-selector.d.ts +32 -0
  37. package/dist/tools/validate-selector.js +93 -0
  38. package/dist/tools/validate-selector.js.map +1 -0
  39. package/dist/types/index.d.ts +344 -0
  40. package/dist/types/index.js +51 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/dist/utils/change-analyzer.d.ts +46 -0
  43. package/dist/utils/change-analyzer.js +290 -0
  44. package/dist/utils/change-analyzer.js.map +1 -0
  45. package/dist/utils/image-diff.d.ts +61 -0
  46. package/dist/utils/image-diff.js +373 -0
  47. package/dist/utils/image-diff.js.map +1 -0
  48. package/dist/utils/logger.d.ts +21 -0
  49. package/dist/utils/logger.js +132 -0
  50. package/dist/utils/logger.js.map +1 -0
  51. package/dist/utils/path-utils.d.ts +55 -0
  52. package/dist/utils/path-utils.js +211 -0
  53. package/dist/utils/path-utils.js.map +1 -0
  54. package/dist/utils/playwright-runner.d.ts +63 -0
  55. package/dist/utils/playwright-runner.js +594 -0
  56. package/dist/utils/playwright-runner.js.map +1 -0
  57. package/dist/utils/project-detector.d.ts +43 -0
  58. package/dist/utils/project-detector.js +255 -0
  59. package/dist/utils/project-detector.js.map +1 -0
  60. package/dist/utils/report-parser.d.ts +60 -0
  61. package/dist/utils/report-parser.js +501 -0
  62. package/dist/utils/report-parser.js.map +1 -0
  63. package/dist/utils/trace-reader.d.ts +109 -0
  64. package/dist/utils/trace-reader.js +608 -0
  65. package/dist/utils/trace-reader.js.map +1 -0
  66. package/examples/sample-test.spec.ts +49 -0
  67. package/package.json +66 -0
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Project detection: locate playwright.config.*, verify Playwright is
3
+ * installed, identify the package manager, and discover test files.
4
+ *
5
+ * Supports monorepos by walking up to the filesystem root and picking
6
+ * the *nearest* directory containing a Playwright config. When several
7
+ * configs live side by side every candidate is returned so the caller
8
+ * can ask the user which one to use.
9
+ */
10
+ import { readdir, readFile, stat } from 'node:fs/promises';
11
+ import path from 'node:path';
12
+ import { isTestFile, normalizePath, resolvePath } from './path-utils.js';
13
+ const CONFIG_FILES = [
14
+ 'playwright.config.ts',
15
+ 'playwright.config.mts',
16
+ 'playwright.config.js',
17
+ 'playwright.config.mjs',
18
+ 'playwright.config.cjs',
19
+ ];
20
+ const IGNORED_DIRS = new Set([
21
+ 'node_modules',
22
+ 'dist',
23
+ 'build',
24
+ '.git',
25
+ '.hg',
26
+ '.svn',
27
+ 'test-results',
28
+ 'playwright-report',
29
+ 'blob-report',
30
+ 'coverage',
31
+ '.next',
32
+ '.cache',
33
+ '.turbo',
34
+ ]);
35
+ const LOCKFILES = [
36
+ { file: 'pnpm-lock.yaml', pm: 'pnpm' },
37
+ { file: 'yarn.lock', pm: 'yarn' },
38
+ { file: 'bun.lockb', pm: 'bun' },
39
+ { file: 'bun.lock', pm: 'bun' },
40
+ { file: 'package-lock.json', pm: 'npm' },
41
+ { file: 'npm-shrinkwrap.json', pm: 'npm' },
42
+ ];
43
+ async function isDirectory(p) {
44
+ try {
45
+ return (await stat(p)).isDirectory();
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ async function isFile(p) {
52
+ try {
53
+ return (await stat(p)).isFile();
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ async function readJson(p) {
60
+ try {
61
+ const text = await readFile(p, 'utf8');
62
+ const parsed = JSON.parse(text);
63
+ return parsed !== null && typeof parsed === 'object' ? parsed : null;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ /**
70
+ * Resolve the starting directory: accepts an existing dir, an existing
71
+ * file (uses its parent), a not-yet-existing path (nearest existing
72
+ * ancestor), and falls back to cwd.
73
+ */
74
+ export async function resolveStartDir(input) {
75
+ const candidate = normalizePath(input && input.trim() !== '' ? input : process.cwd());
76
+ if (await isDirectory(candidate))
77
+ return candidate;
78
+ if (await isFile(candidate))
79
+ return normalizePath(path.dirname(candidate));
80
+ let dir = candidate;
81
+ for (let i = 0; i < 64; i += 1) {
82
+ const parent = normalizePath(path.dirname(dir));
83
+ if (parent === dir)
84
+ break;
85
+ dir = parent;
86
+ if (await isDirectory(dir))
87
+ return dir;
88
+ }
89
+ return normalizePath(process.cwd());
90
+ }
91
+ async function findPlaywrightInstall(dir) {
92
+ for (const pkg of ['@playwright/test', 'playwright']) {
93
+ const manifest = path.join(dir, 'node_modules', ...pkg.split('/'), 'package.json');
94
+ if (await isFile(manifest)) {
95
+ const json = await readJson(manifest);
96
+ const version = typeof json?.version === 'string' ? json.version : null;
97
+ return { pkg, version };
98
+ }
99
+ }
100
+ return null;
101
+ }
102
+ async function detectPackageManager(root) {
103
+ for (const { file, pm } of LOCKFILES) {
104
+ if (await isFile(path.join(root, file)))
105
+ return pm;
106
+ }
107
+ return 'unknown';
108
+ }
109
+ /**
110
+ * Best-effort `testDir` extraction from the config file source.
111
+ * Handles `testDir: 'tests'` / `testDir: "e2e"` / `testDir: "./tests"`.
112
+ */
113
+ async function readTestDir(configPath, root) {
114
+ try {
115
+ const source = await readFile(configPath, 'utf8');
116
+ const match = /testDir\s*:\s*(['"])([^'"]+)\1/.exec(source);
117
+ if (!match)
118
+ return null;
119
+ const resolved = resolvePath(root, match[2]);
120
+ return resolved;
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ /**
127
+ * Detect the Playwright project around `startDir`.
128
+ *
129
+ * Walks upward looking for (in order of precedence) the nearest
130
+ * playwright.config.*, any package.json as a root fallback, and
131
+ * node_modules installs of @playwright/test or playwright.
132
+ */
133
+ export async function detectProject(startDir) {
134
+ const start = await resolveStartDir(startDir);
135
+ let packageRoot = null;
136
+ let playwright = null;
137
+ let configDir = null;
138
+ const configCandidates = [];
139
+ const visited = new Set();
140
+ let dir = start;
141
+ for (let depth = 0; depth < 64; depth += 1) {
142
+ if (visited.has(dir))
143
+ break;
144
+ visited.add(dir);
145
+ if (configDir === null) {
146
+ for (const name of CONFIG_FILES) {
147
+ const candidate = path.join(dir, name);
148
+ if (await isFile(candidate)) {
149
+ configDir = dir;
150
+ configCandidates.push(normalizePath(candidate));
151
+ }
152
+ }
153
+ }
154
+ if (packageRoot === null && (await isFile(path.join(dir, 'package.json')))) {
155
+ packageRoot = dir;
156
+ }
157
+ if (playwright === null) {
158
+ playwright = await findPlaywrightInstall(dir);
159
+ }
160
+ const parent = normalizePath(path.dirname(dir));
161
+ if (parent === dir)
162
+ break;
163
+ dir = parent;
164
+ }
165
+ const root = normalizePath(configDir ?? packageRoot ?? start);
166
+ const configPath = configCandidates[0] ?? null;
167
+ const testDir = configPath ? await readTestDir(configPath, root) : null;
168
+ const packageManager = await detectPackageManager(root);
169
+ return {
170
+ startDir: start,
171
+ root,
172
+ configPath,
173
+ configCandidates,
174
+ hasPlaywright: playwright !== null,
175
+ playwrightPackage: playwright?.pkg ?? null,
176
+ playwrightVersion: playwright?.version ?? null,
177
+ testDir,
178
+ packageManager,
179
+ };
180
+ }
181
+ /** Pick a config by 1-based index or exact path from the candidates list. */
182
+ export function selectConfig(candidates, selection) {
183
+ if (candidates.length === 0)
184
+ return null;
185
+ if (candidates.length === 1)
186
+ return candidates[0];
187
+ if (typeof selection === 'number') {
188
+ const index = selection - 1;
189
+ return index >= 0 && index < candidates.length ? candidates[index] : null;
190
+ }
191
+ if (typeof selection === 'string' && selection.trim() !== '') {
192
+ const wanted = normalizePath(selection).toLowerCase();
193
+ const hit = candidates.find((c) => c.toLowerCase() === wanted || normalizePath(c).endsWith(`/${wanted}`));
194
+ return hit ?? null;
195
+ }
196
+ return null;
197
+ }
198
+ /** Install instructions for a project where Playwright is missing. */
199
+ export function missingPlaywrightMessage(detection) {
200
+ const install = detection.packageManager === 'pnpm'
201
+ ? 'pnpm add -D @playwright/test'
202
+ : detection.packageManager === 'yarn'
203
+ ? 'yarn add -D @playwright/test'
204
+ : detection.packageManager === 'bun'
205
+ ? 'bun add -d @playwright/test'
206
+ : 'npm install -D @playwright/test';
207
+ const browsers = detection.packageManager === 'unknown'
208
+ ? 'npx playwright install'
209
+ : `${detection.packageManager === 'npm' ? 'npx' : detection.packageManager} playwright install`;
210
+ return {
211
+ message: 'Playwright is not installed in this project (no @playwright/test or playwright found in node_modules).',
212
+ hint: `Run:\n ${install}\n ${browsers}\nthen retry.`,
213
+ };
214
+ }
215
+ /**
216
+ * Recursively find Playwright spec files under `root`, skipping
217
+ * node_modules/build/report directories. Returns sorted, project-relative
218
+ * posix paths.
219
+ */
220
+ export async function findTestFiles(root, options = {}) {
221
+ const normalizedRoot = normalizePath(root);
222
+ const startDir = options.testDir ? normalizePath(options.testDir) : normalizedRoot;
223
+ const maxDepth = options.maxDepth ?? 8;
224
+ const limit = options.limit ?? 1000;
225
+ const results = [];
226
+ const walk = async (dir, depth) => {
227
+ if (depth > maxDepth || results.length >= limit)
228
+ return;
229
+ const entries = await readdir(dir, { withFileTypes: true, encoding: 'utf8' }).catch(() => null);
230
+ if (entries === null)
231
+ return;
232
+ const sorted = entries.sort((a, b) => a.name.localeCompare(b.name));
233
+ for (const entry of sorted) {
234
+ if (results.length >= limit)
235
+ return;
236
+ if (entry.name.startsWith('.') && entry.name !== '.')
237
+ continue;
238
+ const full = path.join(dir, entry.name);
239
+ if (entry.isDirectory()) {
240
+ if (IGNORED_DIRS.has(entry.name))
241
+ continue;
242
+ await walk(full, depth + 1);
243
+ }
244
+ else if (entry.isFile() && isTestFile(entry.name)) {
245
+ const relative = full.slice(normalizedRoot.endsWith('/') ? normalizedRoot.length : normalizedRoot.length + 1);
246
+ results.push(normalizePath(relative));
247
+ }
248
+ }
249
+ };
250
+ if (await isDirectory(startDir)) {
251
+ await walk(startDir, 0);
252
+ }
253
+ return results.sort((a, b) => a.localeCompare(b));
254
+ }
255
+ //# sourceMappingURL=project-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Parsing of Playwright's JSON reporter output plus text diagnostics.
3
+ *
4
+ * The JSON report is the source of truth for pass/fail stats and
5
+ * failures; when the run dies before a report exists (timeout, crash,
6
+ * syntax error, full disk…) `diagnoseOutput` turns raw stdout/stderr
7
+ * into an ErrorKind + actionable hint.
8
+ */
9
+ import type { DiscoveredTest, ErrorKind, FailureKind, ReportStats, TestFailure, TestStatus } from '../types/index.js';
10
+ export interface ParsedReport {
11
+ stats: ReportStats | null;
12
+ failures: TestFailure[];
13
+ failuresTruncated: boolean;
14
+ /** Every test case in the report (used by --list parsing). */
15
+ tests: DiscoveredTest[];
16
+ specCount: number;
17
+ projects: string[];
18
+ configPath: string | null;
19
+ parseError?: string;
20
+ }
21
+ export interface Diagnosis {
22
+ errorKind: ErrorKind;
23
+ errorMessage: string;
24
+ hint: string;
25
+ }
26
+ /** Remove ANSI color/control sequences from captured output. */
27
+ export declare function stripAnsi(text: string): string;
28
+ export declare function emptyStats(): ReportStats;
29
+ /** Classify a failure from its message/stack plus normalized status. */
30
+ export declare function classifyFailure(text: string, status: TestStatus): FailureKind;
31
+ /** Parse a JSON report from a raw string. Never throws. */
32
+ export declare function parseReportJson(raw: string, root?: string, maxFailures?: number): ParsedReport;
33
+ /**
34
+ * Parse an already-deserialized Playwright JSON report into normalized
35
+ * stats, failures, and a flat test listing.
36
+ */
37
+ export declare function parseReport(report: unknown, root?: string, maxFailures?: number): ParsedReport;
38
+ /**
39
+ * Best-effort extraction of a JSON object from mixed text (stdout that
40
+ * interleaves logs with the JSON reporter output).
41
+ */
42
+ export declare function extractJsonFromText(text: string): string | null;
43
+ /** First line that looks like an actual error, else first content line. */
44
+ export declare function firstMeaningfulLine(text: string): string | undefined;
45
+ /**
46
+ * Turn raw process output into an ErrorKind + hint when no structured
47
+ * report exists. Returns null when nothing recognizable was found.
48
+ */
49
+ export declare function diagnoseOutput(text: string): Diagnosis | null;
50
+ /** Extract `name: '…'` values from a playwright.config source. */
51
+ export declare function parseProjectNames(source: string): string[];
52
+ /**
53
+ * Regex-based extraction of `test(...)` / `test.describe(...)` titles
54
+ * from a spec file. Used only as a fallback when Playwright itself
55
+ * cannot list tests (not installed, config broken, syntax error).
56
+ */
57
+ export declare function extractTestTitles(source: string): Array<{
58
+ title: string;
59
+ line: number;
60
+ }>;