@gate-forge/pack-playwright 0.7.1 → 0.9.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 +31 -0
- package/dist/constants.d.ts +13 -140
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +13 -148
- package/dist/constants.js.map +1 -1
- package/dist/cypress/plugin.d.ts +53 -0
- package/dist/cypress/plugin.d.ts.map +1 -0
- package/dist/cypress/plugin.js +369 -0
- package/dist/cypress/plugin.js.map +1 -0
- package/dist/cypress/spec-scan.d.ts +39 -0
- package/dist/cypress/spec-scan.d.ts.map +1 -0
- package/dist/cypress/spec-scan.js +301 -0
- package/dist/cypress/spec-scan.js.map +1 -0
- package/dist/diagnosis.d.ts +39 -0
- package/dist/diagnosis.d.ts.map +1 -0
- package/dist/diagnosis.js +63 -0
- package/dist/diagnosis.js.map +1 -0
- package/dist/discovery/adapter-projection.d.ts +13 -0
- package/dist/discovery/adapter-projection.d.ts.map +1 -0
- package/dist/discovery/adapter-projection.js +84 -0
- package/dist/discovery/adapter-projection.js.map +1 -0
- package/dist/discovery/config-locations.d.ts +5 -0
- package/dist/discovery/config-locations.d.ts.map +1 -0
- package/dist/discovery/config-locations.js +19 -0
- package/dist/discovery/config-locations.js.map +1 -0
- package/dist/discovery/cypress-runner-adapter.d.ts +112 -0
- package/dist/discovery/cypress-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/cypress-runner-adapter.js +501 -0
- package/dist/discovery/cypress-runner-adapter.js.map +1 -0
- package/dist/discovery/discover.d.ts +53 -1
- package/dist/discovery/discover.d.ts.map +1 -1
- package/dist/discovery/discover.js +290 -30
- package/dist/discovery/discover.js.map +1 -1
- package/dist/discovery/git-ignore.d.ts +13 -0
- package/dist/discovery/git-ignore.d.ts.map +1 -0
- package/dist/discovery/git-ignore.js +62 -0
- package/dist/discovery/git-ignore.js.map +1 -0
- package/dist/discovery/index.d.ts +10 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +10 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/playwright-runner-adapter.d.ts +108 -0
- package/dist/discovery/playwright-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/playwright-runner-adapter.js +185 -0
- package/dist/discovery/playwright-runner-adapter.js.map +1 -0
- package/dist/discovery/prepare-barrier.d.ts +522 -0
- package/dist/discovery/prepare-barrier.d.ts.map +1 -0
- package/dist/discovery/prepare-barrier.js +739 -0
- package/dist/discovery/prepare-barrier.js.map +1 -0
- package/dist/discovery/pytest-adapter.d.ts.map +1 -1
- package/dist/discovery/pytest-adapter.js +6 -2
- package/dist/discovery/pytest-adapter.js.map +1 -1
- package/dist/discovery/pytest-runner-adapter.d.ts +124 -0
- package/dist/discovery/pytest-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/pytest-runner-adapter.js +454 -0
- package/dist/discovery/pytest-runner-adapter.js.map +1 -0
- package/dist/discovery/reconcile.d.ts +89 -11
- package/dist/discovery/reconcile.d.ts.map +1 -1
- package/dist/discovery/reconcile.js +440 -78
- package/dist/discovery/reconcile.js.map +1 -1
- package/dist/discovery/runner-env.d.ts +88 -2
- package/dist/discovery/runner-env.d.ts.map +1 -1
- package/dist/discovery/runner-env.js +142 -4
- package/dist/discovery/runner-env.js.map +1 -1
- package/dist/discovery/runner-file-scope.d.ts +114 -0
- package/dist/discovery/runner-file-scope.d.ts.map +1 -0
- package/dist/discovery/runner-file-scope.js +638 -0
- package/dist/discovery/runner-file-scope.js.map +1 -0
- package/dist/discovery/static-discovery.d.ts +49 -3
- package/dist/discovery/static-discovery.d.ts.map +1 -1
- package/dist/discovery/static-discovery.js +477 -18
- package/dist/discovery/static-discovery.js.map +1 -1
- package/dist/discovery/supervised-run.d.ts +199 -10
- package/dist/discovery/supervised-run.d.ts.map +1 -1
- package/dist/discovery/supervised-run.js +350 -39
- package/dist/discovery/supervised-run.js.map +1 -1
- package/dist/discovery/trusted-config.d.ts +180 -6
- package/dist/discovery/trusted-config.d.ts.map +1 -1
- package/dist/discovery/trusted-config.js +279 -10
- package/dist/discovery/trusted-config.js.map +1 -1
- package/dist/discovery/vitest-runner-adapter.d.ts +172 -0
- package/dist/discovery/vitest-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/vitest-runner-adapter.js +607 -0
- package/dist/discovery/vitest-runner-adapter.js.map +1 -0
- package/dist/fixture/consumer-runner.d.ts +4 -0
- package/dist/fixture/consumer-runner.d.ts.map +1 -0
- package/dist/fixture/consumer-runner.js +38 -0
- package/dist/fixture/consumer-runner.js.map +1 -0
- package/dist/fixture/evidence.d.ts +27 -0
- package/dist/fixture/evidence.d.ts.map +1 -1
- package/dist/fixture/evidence.js +12 -0
- package/dist/fixture/evidence.js.map +1 -1
- package/dist/fixture/fixture.d.ts +2 -1
- package/dist/fixture/fixture.d.ts.map +1 -1
- package/dist/fixture/fixture.js +1 -17
- package/dist/fixture/fixture.js.map +1 -1
- package/dist/fixture/witness-client.d.ts +6 -174
- package/dist/fixture/witness-client.d.ts.map +1 -1
- package/dist/fixture/witness-client.js +6 -267
- package/dist/fixture/witness-client.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +6 -12
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +6 -17
- package/dist/json.js.map +1 -1
- package/dist/reporter/project-graph-reporter.d.ts +121 -0
- package/dist/reporter/project-graph-reporter.d.ts.map +1 -0
- package/dist/reporter/project-graph-reporter.js +132 -0
- package/dist/reporter/project-graph-reporter.js.map +1 -0
- package/dist/reporter/reporter.cjs.map +1 -1
- package/dist/reporter/reporter.d.ts +93 -4
- package/dist/reporter/reporter.d.ts.map +1 -1
- package/dist/reporter/reporter.js +174 -18
- package/dist/reporter/reporter.js.map +1 -1
- package/dist/runner-claims.d.ts +13 -0
- package/dist/runner-claims.d.ts.map +1 -0
- package/dist/runner-claims.js +46 -0
- package/dist/runner-claims.js.map +1 -0
- package/dist/runner-resolution.d.ts +3 -0
- package/dist/runner-resolution.d.ts.map +1 -0
- package/dist/runner-resolution.js +14 -0
- package/dist/runner-resolution.js.map +1 -0
- package/dist/supervisor/client.d.ts +23 -1
- package/dist/supervisor/client.d.ts.map +1 -1
- package/dist/supervisor/client.js +49 -0
- package/dist/supervisor/client.js.map +1 -1
- package/dist/supervisor/drain.d.ts +65 -0
- package/dist/supervisor/drain.d.ts.map +1 -1
- package/dist/supervisor/drain.js +353 -9
- package/dist/supervisor/drain.js.map +1 -1
- package/dist/supervisor/index.d.ts +7 -3
- package/dist/supervisor/index.d.ts.map +1 -1
- package/dist/supervisor/index.js +7 -3
- package/dist/supervisor/index.js.map +1 -1
- package/dist/supervisor/spool.d.ts +65 -2
- package/dist/supervisor/spool.d.ts.map +1 -1
- package/dist/supervisor/spool.js +47 -0
- package/dist/supervisor/spool.js.map +1 -1
- package/dist/surface.d.ts +6 -207
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +6 -264
- package/dist/surface.js.map +1 -1
- package/dist/vitest/index.d.ts +23 -0
- package/dist/vitest/index.d.ts.map +1 -0
- package/dist/vitest/index.js +356 -0
- package/dist/vitest/index.js.map +1 -0
- package/dist/vitest/reporter.d.ts +83 -0
- package/dist/vitest/reporter.d.ts.map +1 -0
- package/dist/vitest/reporter.js +211 -0
- package/dist/vitest/reporter.js.map +1 -0
- package/dist/vitest/worker-slot.d.ts +36 -0
- package/dist/vitest/worker-slot.d.ts.map +1 -0
- package/dist/vitest/worker-slot.js +51 -0
- package/dist/vitest/worker-slot.js.map +1 -0
- package/dist/witness/adapter-registry.d.ts +6 -50
- package/dist/witness/adapter-registry.d.ts.map +1 -1
- package/dist/witness/adapter-registry.js +6 -257
- package/dist/witness/adapter-registry.js.map +1 -1
- package/dist/witness/behavior-request.d.ts +6 -76
- package/dist/witness/behavior-request.d.ts.map +1 -1
- package/dist/witness/behavior-request.js +6 -273
- package/dist/witness/behavior-request.js.map +1 -1
- package/dist/witness/behavior.d.ts +6 -48
- package/dist/witness/behavior.d.ts.map +1 -1
- package/dist/witness/behavior.js +6 -114
- package/dist/witness/behavior.js.map +1 -1
- package/dist/witness/bin.d.ts +6 -17
- package/dist/witness/bin.d.ts.map +1 -1
- package/dist/witness/bin.js +6 -168
- package/dist/witness/bin.js.map +1 -1
- package/dist/witness/browser.d.ts +14 -206
- package/dist/witness/browser.d.ts.map +1 -1
- package/dist/witness/browser.js +15 -654
- package/dist/witness/browser.js.map +1 -1
- package/dist/witness/classifications.d.ts +6 -38
- package/dist/witness/classifications.d.ts.map +1 -1
- package/dist/witness/classifications.js +6 -83
- package/dist/witness/classifications.js.map +1 -1
- package/dist/witness/env-attestation.d.ts +6 -94
- package/dist/witness/env-attestation.d.ts.map +1 -1
- package/dist/witness/env-attestation.js +6 -198
- package/dist/witness/env-attestation.js.map +1 -1
- package/dist/witness/fixture-provider.d.ts +6 -82
- package/dist/witness/fixture-provider.d.ts.map +1 -1
- package/dist/witness/fixture-provider.js +6 -105
- package/dist/witness/fixture-provider.js.map +1 -1
- package/dist/witness/loopback-pins.d.ts +6 -75
- package/dist/witness/loopback-pins.d.ts.map +1 -1
- package/dist/witness/loopback-pins.js +6 -240
- package/dist/witness/loopback-pins.js.map +1 -1
- package/dist/witness/server.d.ts +8 -26
- package/dist/witness/server.d.ts.map +1 -1
- package/dist/witness/server.js +24 -3761
- package/dist/witness/server.js.map +1 -1
- package/dist/witness/types.d.ts +6 -882
- package/dist/witness/types.d.ts.map +1 -1
- package/dist/witness/types.js +9 -1
- package/dist/witness/types.js.map +1 -1
- package/examples/overlay-proof.spec.js +75 -0
- package/package.json +12 -3
- package/python/gateforge_pytest_plugin.py +462 -0
- package/python/__pycache__/gateforge_persistence_intents.cpython-314.pyc +0 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static enumeration of a Cypress project's specs (plan 2026-09-25
|
|
3
|
+
* phase 2, job 1).
|
|
4
|
+
*
|
|
5
|
+
* Cypress has no `--list-tests` mode: the only runner-native way to
|
|
6
|
+
* learn the test set is to RUN the suite, which would execute the very
|
|
7
|
+
* tests whose set must be fixed BEFORE the run. So the expected set is
|
|
8
|
+
* read from the spec sources instead, and it is read FAIL CLOSED: a
|
|
9
|
+
* spec whose suite or test titles are not static string literals cannot
|
|
10
|
+
* be enumerated honestly, and the enumeration reports `unavailable`
|
|
11
|
+
* rather than a partial guess — supervision then blocks the run, never
|
|
12
|
+
* a green run against a half-known expected set.
|
|
13
|
+
*
|
|
14
|
+
* Scope: the spec files Cypress itself collects by default under a
|
|
15
|
+
* `cypress/` tree — `*.cy.{js,jsx,ts,tsx}` and `*.spec.{js,jsx,ts,tsx}`
|
|
16
|
+
* (support files and `node_modules` are never specs).
|
|
17
|
+
*/
|
|
18
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
19
|
+
import { join, relative } from 'node:path';
|
|
20
|
+
/** Spec file extensions Cypress collects by default. */
|
|
21
|
+
const SPEC_EXTENSIONS = [
|
|
22
|
+
'.cy.js',
|
|
23
|
+
'.cy.jsx',
|
|
24
|
+
'.cy.ts',
|
|
25
|
+
'.cy.tsx',
|
|
26
|
+
'.spec.js',
|
|
27
|
+
'.spec.jsx',
|
|
28
|
+
'.spec.ts',
|
|
29
|
+
'.spec.tsx',
|
|
30
|
+
];
|
|
31
|
+
/** Directory names never walked while collecting specs. */
|
|
32
|
+
const SKIPPED_DIRECTORIES = [
|
|
33
|
+
'node_modules',
|
|
34
|
+
'support',
|
|
35
|
+
'downloads',
|
|
36
|
+
'screenshots',
|
|
37
|
+
'videos',
|
|
38
|
+
];
|
|
39
|
+
/** The opening token of a suite declaration (`describe`/`context`). */
|
|
40
|
+
const SUITE_TOKENS = [
|
|
41
|
+
'describe.only',
|
|
42
|
+
'describe.skip',
|
|
43
|
+
'context.only',
|
|
44
|
+
'context.skip',
|
|
45
|
+
'describe',
|
|
46
|
+
'context',
|
|
47
|
+
];
|
|
48
|
+
/** A suite opening token (any `describe`/`context` modifier). */
|
|
49
|
+
const SUITE_TOKEN = /^(?:describe|context)(?:\.(?:only|skip))?$/;
|
|
50
|
+
/** A test opening token (`it`/`test`, any modifier). */
|
|
51
|
+
const TEST_TOKEN = /^(?:it|test)(?:\.(?:only|skip))?$/;
|
|
52
|
+
/** Why one spec could not be enumerated statically. */
|
|
53
|
+
class UnscannableSpec extends Error {
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Collects the spec files of a project (repo-relative posix paths,
|
|
57
|
+
* sorted). Only the default `cypress/` spec tree is walked.
|
|
58
|
+
*
|
|
59
|
+
* Args:
|
|
60
|
+
* root: absolute project root.
|
|
61
|
+
*
|
|
62
|
+
* Returns:
|
|
63
|
+
* string[]: the spec files, sorted; [] when the project has none.
|
|
64
|
+
*/
|
|
65
|
+
export function cypressSpecFiles(root) {
|
|
66
|
+
const found = [];
|
|
67
|
+
const walk = (directory) => {
|
|
68
|
+
let entries;
|
|
69
|
+
try {
|
|
70
|
+
entries = readdirSync(directory, { withFileTypes: true });
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
if (entry.isDirectory()) {
|
|
77
|
+
if (!SKIPPED_DIRECTORIES.includes(entry.name))
|
|
78
|
+
walk(join(directory, entry.name));
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (SPEC_EXTENSIONS.some((extension) => entry.name.endsWith(extension))) {
|
|
82
|
+
found.push(relative(root, join(directory, entry.name)).split('\\').join('/'));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
walk(join(root, 'cypress'));
|
|
87
|
+
return found.sort();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Statically enumerates every test a project's specs declare.
|
|
91
|
+
*
|
|
92
|
+
* Args:
|
|
93
|
+
* root: absolute project root.
|
|
94
|
+
*
|
|
95
|
+
* Returns:
|
|
96
|
+
* SpecScanResult: the declared tests, or `unavailable` with a single
|
|
97
|
+
* cause when a spec uses a non-literal title or declares no test
|
|
98
|
+
* (never a partial set, never a faked empty success).
|
|
99
|
+
*/
|
|
100
|
+
export function scanCypressSpecs(root) {
|
|
101
|
+
const files = cypressSpecFiles(root);
|
|
102
|
+
if (files.length === 0) {
|
|
103
|
+
return {
|
|
104
|
+
status: 'unavailable',
|
|
105
|
+
detail: `no Cypress spec file under ${join(root, 'cypress')} — a zero-test project never proves coverage`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const tests = [];
|
|
109
|
+
for (const file of files) {
|
|
110
|
+
let source;
|
|
111
|
+
try {
|
|
112
|
+
source = readFileSync(join(root, file), 'utf8');
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
return { status: 'unavailable', detail: `cannot read Cypress spec '${file}': ${error.message}` };
|
|
116
|
+
}
|
|
117
|
+
let declarations;
|
|
118
|
+
try {
|
|
119
|
+
declarations = declarationsOf(source);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const reason = error instanceof UnscannableSpec ? error.message : error.message;
|
|
123
|
+
return {
|
|
124
|
+
status: 'unavailable',
|
|
125
|
+
detail: `Cypress spec '${file}' cannot be enumerated statically (${reason}) — ` +
|
|
126
|
+
'the expected set is never guessed',
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
tests.push(...resolveTitlePaths(declarations).map((resolved) => ({ file, titlePath: resolved })));
|
|
130
|
+
}
|
|
131
|
+
if (tests.length === 0) {
|
|
132
|
+
return {
|
|
133
|
+
status: 'unavailable',
|
|
134
|
+
detail: `the ${String(files.length)} Cypress spec file(s) under ${root} declare no test`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return { status: 'scanned', tests };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Scans one spec source into its suite/test declarations.
|
|
141
|
+
*
|
|
142
|
+
* Args:
|
|
143
|
+
* source: the spec file text.
|
|
144
|
+
*
|
|
145
|
+
* Returns:
|
|
146
|
+
* Declaration[]: declarations in source order.
|
|
147
|
+
*
|
|
148
|
+
* Throws:
|
|
149
|
+
* UnscannableSpec: when a declaration's title is not a static string
|
|
150
|
+
* literal (the expected set would be a guess).
|
|
151
|
+
*/
|
|
152
|
+
function declarationsOf(source) {
|
|
153
|
+
const declarations = [];
|
|
154
|
+
let index = 0;
|
|
155
|
+
let depth = 0;
|
|
156
|
+
while (index < source.length) {
|
|
157
|
+
const character = source[index];
|
|
158
|
+
if (character === '/' && (source[index + 1] === '/' || source[index + 1] === '*')) {
|
|
159
|
+
index = skipComment(source, index);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (character === '"' || character === "'" || character === '`') {
|
|
163
|
+
index = skipStringLiteral(source, index, character);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (character === '{') {
|
|
167
|
+
depth += 1;
|
|
168
|
+
index += 1;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (character === '}') {
|
|
172
|
+
depth -= 1;
|
|
173
|
+
index += 1;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const declaration = declarationAt(source, index, depth);
|
|
177
|
+
if (declaration !== null) {
|
|
178
|
+
declarations.push(declaration.declaration);
|
|
179
|
+
index = declaration.next;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
index += 1;
|
|
183
|
+
}
|
|
184
|
+
return declarations;
|
|
185
|
+
}
|
|
186
|
+
/** The index just past the line or block comment starting at `start`. */
|
|
187
|
+
function skipComment(source, start) {
|
|
188
|
+
if (source[start + 1] === '/') {
|
|
189
|
+
const end = source.indexOf('\n', start);
|
|
190
|
+
return end === -1 ? source.length : end;
|
|
191
|
+
}
|
|
192
|
+
const end = source.indexOf('*/', start + 2);
|
|
193
|
+
return end === -1 ? source.length : end + 2;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Skips one string literal (quotes and escapes), returning the index
|
|
197
|
+
* just past its end.
|
|
198
|
+
*/
|
|
199
|
+
function skipStringLiteral(source, start, quote) {
|
|
200
|
+
let index = start + 1;
|
|
201
|
+
while (index < source.length) {
|
|
202
|
+
const character = source[index];
|
|
203
|
+
if (character === '\\') {
|
|
204
|
+
index += 2;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (character === quote)
|
|
208
|
+
return index + 1;
|
|
209
|
+
index += 1;
|
|
210
|
+
}
|
|
211
|
+
return source.length;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Matches a suite/test declaration whose identifier starts at `index`.
|
|
215
|
+
*
|
|
216
|
+
* Args:
|
|
217
|
+
* source: the spec file text.
|
|
218
|
+
* index: the candidate identifier start.
|
|
219
|
+
* depth: the brace depth in effect at `index`.
|
|
220
|
+
*
|
|
221
|
+
* Returns:
|
|
222
|
+
* { declaration: Declaration; next: number } | null: the parsed
|
|
223
|
+
* declaration and the index just past its argument list; null when
|
|
224
|
+
* the position starts no declaration.
|
|
225
|
+
*
|
|
226
|
+
* Throws:
|
|
227
|
+
* UnscannableSpec: when the declaration's title is not a literal.
|
|
228
|
+
*/
|
|
229
|
+
function declarationAt(source, index, depth) {
|
|
230
|
+
if (index > 0 && /[\w$.]/.test(source[index - 1]))
|
|
231
|
+
return null;
|
|
232
|
+
const window = source.slice(index, index + 40);
|
|
233
|
+
const suite = SUITE_TOKENS.find((token) => window.startsWith(token) && !/[\w$]/.test(window[token.length] ?? ''));
|
|
234
|
+
const test = /^(?:it|test)(?:\.(?:only|skip))?(?![A-Za-z0-9_$])/.exec(window);
|
|
235
|
+
const token = suite ?? test?.[0];
|
|
236
|
+
if (token === undefined)
|
|
237
|
+
return null;
|
|
238
|
+
const open = source.indexOf('(', index + token.length);
|
|
239
|
+
if (open === -1)
|
|
240
|
+
throw new UnscannableSpec(`'${token}' has no argument list`);
|
|
241
|
+
// Resume right after the TITLE literal, not after the whole argument
|
|
242
|
+
// list: a suite's body holds the declarations nested inside it, and
|
|
243
|
+
// brace-depth scoping resolves them.
|
|
244
|
+
const { title, end } = readLiteralTitle(source, open + 1, token);
|
|
245
|
+
return {
|
|
246
|
+
declaration: { kind: TEST_TOKEN.test(token) ? 'test' : 'suite', title, depth },
|
|
247
|
+
next: end,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Reads a declaration's static title literal.
|
|
252
|
+
*
|
|
253
|
+
* Args:
|
|
254
|
+
* source: the spec file text.
|
|
255
|
+
* start: the index just after the opening parenthesis.
|
|
256
|
+
* token: the declaration token (named in the failure message).
|
|
257
|
+
*
|
|
258
|
+
* Returns:
|
|
259
|
+
* { title: string; end: number }: the literal title and the index just
|
|
260
|
+
* past its closing quote.
|
|
261
|
+
*
|
|
262
|
+
* Throws:
|
|
263
|
+
* UnscannableSpec: when the first argument is not a string literal.
|
|
264
|
+
*/
|
|
265
|
+
function readLiteralTitle(source, start, token) {
|
|
266
|
+
let index = start;
|
|
267
|
+
while (index < source.length && /\s/.test(source[index]))
|
|
268
|
+
index += 1;
|
|
269
|
+
const quote = source[index];
|
|
270
|
+
if (quote !== '"' && quote !== "'" && quote !== '`') {
|
|
271
|
+
throw new UnscannableSpec(`'${token}' has a non-literal title`);
|
|
272
|
+
}
|
|
273
|
+
const end = skipStringLiteral(source, index, quote);
|
|
274
|
+
return { title: source.slice(index + 1, end - 1), end };
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Resolves the full title path of every test declaration: a suite
|
|
278
|
+
* scopes the declarations nested inside its own brace depth.
|
|
279
|
+
*
|
|
280
|
+
* Args:
|
|
281
|
+
* declarations: the declarations in source order, with brace depths.
|
|
282
|
+
*
|
|
283
|
+
* Returns:
|
|
284
|
+
* string[][]: one suite chain + leaf title per test declaration.
|
|
285
|
+
*/
|
|
286
|
+
function resolveTitlePaths(declarations) {
|
|
287
|
+
const resolved = [];
|
|
288
|
+
const open = [];
|
|
289
|
+
for (const declaration of declarations) {
|
|
290
|
+
while (open.length > 0 && open[open.length - 1].depth >= declaration.depth) {
|
|
291
|
+
open.pop();
|
|
292
|
+
}
|
|
293
|
+
if (declaration.kind === 'suite') {
|
|
294
|
+
open.push({ title: declaration.title, depth: declaration.depth });
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
resolved.push([...open.map((suite) => suite.title), declaration.title]);
|
|
298
|
+
}
|
|
299
|
+
return resolved;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=spec-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-scan.js","sourceRoot":"","sources":["../../src/cypress/spec-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** The structural shape every runner's serialized error reduces to. */
|
|
2
|
+
export interface SerializedFailure {
|
|
3
|
+
/** The runner's own error message. */
|
|
4
|
+
message?: string;
|
|
5
|
+
/** The runner's own serialized stack, when it exposes one. */
|
|
6
|
+
stack?: string;
|
|
7
|
+
}
|
|
8
|
+
/** The diagnosis one failed test contributes to its `testEnd` event. */
|
|
9
|
+
export interface FailureDiagnosis {
|
|
10
|
+
/** The runner's first error message. */
|
|
11
|
+
errorMessage: string;
|
|
12
|
+
/** Up to five repo-relative `file:line` frames, in runner order. */
|
|
13
|
+
stackFrames: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The `file:line` frames of a serialized stack, repo-relative, first
|
|
17
|
+
* five. Anything that is not a source frame (a message line, a runtime
|
|
18
|
+
* banner, a frame outside the tested tree) is dropped — a diagnosis
|
|
19
|
+
* points a human at a line of the repository, nothing else.
|
|
20
|
+
*
|
|
21
|
+
* Args:
|
|
22
|
+
* stack: the runner's serialized stack text.
|
|
23
|
+
*
|
|
24
|
+
* Returns:
|
|
25
|
+
* string[]: deduplicated `file:line` frames in the order reported.
|
|
26
|
+
*/
|
|
27
|
+
export declare function stackFramesOf(stack: string): string[];
|
|
28
|
+
/**
|
|
29
|
+
* The diagnosis of one failed test, or null when the runner reported
|
|
30
|
+
* nothing usable (a passing test, or a runner that exposes no error).
|
|
31
|
+
*
|
|
32
|
+
* Args:
|
|
33
|
+
* errors: the runner's serialized errors for the test, in its order.
|
|
34
|
+
*
|
|
35
|
+
* Returns:
|
|
36
|
+
* FailureDiagnosis | null: the first error's message and short stack.
|
|
37
|
+
*/
|
|
38
|
+
export declare function failureDiagnosisOf(errors: readonly SerializedFailure[] | undefined): FailureDiagnosis | null;
|
|
39
|
+
//# sourceMappingURL=diagnosis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnosis.d.ts","sourceRoot":"","sources":["../src/diagnosis.ts"],"names":[],"mappings":"AAcA,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAWrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,GAC/C,gBAAgB,GAAG,IAAI,CAOzB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ADDITIVE failure diagnosis a runner adapter may attach to its
|
|
3
|
+
* `testEnd` spool event, for the CI progress stream and the
|
|
4
|
+
* Gateforge-owned failures artifact.
|
|
5
|
+
*
|
|
6
|
+
* This is the one place runner output is ever consulted, and it is
|
|
7
|
+
* consulted structurally, never as text: a failing test's first error
|
|
8
|
+
* message and up to five `file:line` frames. The runner's raw log is
|
|
9
|
+
* never copied, filtered, or tailed — a filter over secret text is not
|
|
10
|
+
* secret-free, and the trusted CLI screens the message against the
|
|
11
|
+
* credential shapes before it reaches a console or an artifact.
|
|
12
|
+
*/
|
|
13
|
+
import { relative, sep } from 'node:path';
|
|
14
|
+
/** The most stack frames a diagnosis keeps. */
|
|
15
|
+
const MAX_FRAMES = 5;
|
|
16
|
+
/**
|
|
17
|
+
* The `file:line` frames of a serialized stack, repo-relative, first
|
|
18
|
+
* five. Anything that is not a source frame (a message line, a runtime
|
|
19
|
+
* banner, a frame outside the tested tree) is dropped — a diagnosis
|
|
20
|
+
* points a human at a line of the repository, nothing else.
|
|
21
|
+
*
|
|
22
|
+
* Args:
|
|
23
|
+
* stack: the runner's serialized stack text.
|
|
24
|
+
*
|
|
25
|
+
* Returns:
|
|
26
|
+
* string[]: deduplicated `file:line` frames in the order reported.
|
|
27
|
+
*/
|
|
28
|
+
export function stackFramesOf(stack) {
|
|
29
|
+
const frames = [];
|
|
30
|
+
for (const line of stack.split('\n')) {
|
|
31
|
+
const match = /(?:at\s+.*\()?(\S+):(\d+)(?::\d+)?\)?\s*$/.exec(line.trim());
|
|
32
|
+
if (match === null)
|
|
33
|
+
continue;
|
|
34
|
+
const file = relative(process.cwd(), match[1] ?? '').split(sep).join('/');
|
|
35
|
+
if (file.length === 0 || file.startsWith('..'))
|
|
36
|
+
continue;
|
|
37
|
+
frames.push(`${file}:${match[2] ?? '0'}`);
|
|
38
|
+
if (frames.length === MAX_FRAMES)
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
return frames;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The diagnosis of one failed test, or null when the runner reported
|
|
45
|
+
* nothing usable (a passing test, or a runner that exposes no error).
|
|
46
|
+
*
|
|
47
|
+
* Args:
|
|
48
|
+
* errors: the runner's serialized errors for the test, in its order.
|
|
49
|
+
*
|
|
50
|
+
* Returns:
|
|
51
|
+
* FailureDiagnosis | null: the first error's message and short stack.
|
|
52
|
+
*/
|
|
53
|
+
export function failureDiagnosisOf(errors) {
|
|
54
|
+
const first = errors?.[0];
|
|
55
|
+
if (first === undefined)
|
|
56
|
+
return null;
|
|
57
|
+
const message = typeof first.message === 'string' ? first.message : '';
|
|
58
|
+
const frames = typeof first.stack === 'string' ? [...new Set(stackFramesOf(first.stack))] : [];
|
|
59
|
+
if (message.length === 0 && frames.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
return { errorMessage: message, stackFrames: frames };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=diagnosis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnosis.js","sourceRoot":"","sources":["../src/diagnosis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAkB1C,+CAA+C;AAC/C,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QACzD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;YAAE,MAAM;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAgD;IAEhD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a literal `fields` array from an adapter's default export without
|
|
3
|
+
* evaluating the adapter module.
|
|
4
|
+
*
|
|
5
|
+
* Args:
|
|
6
|
+
* sourceText: JavaScript or TypeScript module source.
|
|
7
|
+
*
|
|
8
|
+
* Returns:
|
|
9
|
+
* string[] | null: the declared literal field projection, or null when absent
|
|
10
|
+
* or when the module uses a dynamic/unrecognized declaration.
|
|
11
|
+
*/
|
|
12
|
+
export declare function staticAdapterFieldsFromSource(sourceText: string): string[] | null;
|
|
13
|
+
//# sourceMappingURL=adapter-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-projection.d.ts","sourceRoot":"","sources":["../../src/discovery/adapter-projection.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAyCjF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe static extraction of adapter field projections. Adapter modules
|
|
3
|
+
* are never executed to answer repository policy questions.
|
|
4
|
+
*/
|
|
5
|
+
import ts from 'typescript';
|
|
6
|
+
/**
|
|
7
|
+
* Removes syntax-only wrappers from a statically inspectable expression.
|
|
8
|
+
*
|
|
9
|
+
* Args:
|
|
10
|
+
* expression: parsed TypeScript expression.
|
|
11
|
+
*
|
|
12
|
+
* Returns:
|
|
13
|
+
* ts.Expression: the wrapped expression without parentheses or type syntax.
|
|
14
|
+
*/
|
|
15
|
+
function unwrapStaticExpression(expression) {
|
|
16
|
+
let current = expression;
|
|
17
|
+
while (ts.isParenthesizedExpression(current) ||
|
|
18
|
+
ts.isAsExpression(current) ||
|
|
19
|
+
ts.isTypeAssertionExpression(current) ||
|
|
20
|
+
ts.isNonNullExpression(current) ||
|
|
21
|
+
ts.isSatisfiesExpression(current)) {
|
|
22
|
+
current = current.expression;
|
|
23
|
+
}
|
|
24
|
+
return current;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Reads a literal `fields` array from an adapter's default export without
|
|
28
|
+
* evaluating the adapter module.
|
|
29
|
+
*
|
|
30
|
+
* Args:
|
|
31
|
+
* sourceText: JavaScript or TypeScript module source.
|
|
32
|
+
*
|
|
33
|
+
* Returns:
|
|
34
|
+
* string[] | null: the declared literal field projection, or null when absent
|
|
35
|
+
* or when the module uses a dynamic/unrecognized declaration.
|
|
36
|
+
*/
|
|
37
|
+
export function staticAdapterFieldsFromSource(sourceText) {
|
|
38
|
+
const source = ts.createSourceFile('adapter.mjs', sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
39
|
+
const parseDiagnostics = source.parseDiagnostics ?? [];
|
|
40
|
+
if (parseDiagnostics.length > 0)
|
|
41
|
+
return null;
|
|
42
|
+
const exportAssignment = source.statements.find((statement) => ts.isExportAssignment(statement) && !statement.isExportEquals);
|
|
43
|
+
if (exportAssignment === undefined)
|
|
44
|
+
return null;
|
|
45
|
+
let exported = unwrapStaticExpression(exportAssignment.expression);
|
|
46
|
+
if (ts.isIdentifier(exported)) {
|
|
47
|
+
const exportName = exported.text;
|
|
48
|
+
const declaration = source.statements
|
|
49
|
+
.filter(ts.isVariableStatement)
|
|
50
|
+
.flatMap((statement) => statement.declarationList.declarations)
|
|
51
|
+
.find((candidate) => ts.isIdentifier(candidate.name) && candidate.name.text === exportName);
|
|
52
|
+
if (declaration?.initializer === undefined)
|
|
53
|
+
return null;
|
|
54
|
+
exported = unwrapStaticExpression(declaration.initializer);
|
|
55
|
+
}
|
|
56
|
+
if (!ts.isObjectLiteralExpression(exported))
|
|
57
|
+
return null;
|
|
58
|
+
const fieldProperties = exported.properties.filter((member) => {
|
|
59
|
+
if (!ts.isPropertyAssignment(member))
|
|
60
|
+
return false;
|
|
61
|
+
const name = member.name;
|
|
62
|
+
return ((ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNoSubstitutionTemplateLiteral(name)) &&
|
|
63
|
+
name.text === 'fields');
|
|
64
|
+
});
|
|
65
|
+
if (fieldProperties.length !== 1)
|
|
66
|
+
return null;
|
|
67
|
+
const property = fieldProperties[0];
|
|
68
|
+
if (property === undefined || !ts.isPropertyAssignment(property))
|
|
69
|
+
return null;
|
|
70
|
+
const initializer = unwrapStaticExpression(property.initializer);
|
|
71
|
+
if (!ts.isArrayLiteralExpression(initializer))
|
|
72
|
+
return null;
|
|
73
|
+
const fields = [];
|
|
74
|
+
for (const element of initializer.elements) {
|
|
75
|
+
const value = unwrapStaticExpression(element);
|
|
76
|
+
if (!ts.isStringLiteral(value) && !ts.isNoSubstitutionTemplateLiteral(value))
|
|
77
|
+
return null;
|
|
78
|
+
if (value.text.length === 0)
|
|
79
|
+
return null;
|
|
80
|
+
fields.push(value.text);
|
|
81
|
+
}
|
|
82
|
+
return fields;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=adapter-projection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-projection.js","sourceRoot":"","sources":["../../src/discovery/adapter-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Configuration search convention shared by enumeration and sealed-tree re-sealing. */
|
|
2
|
+
export declare const PLAYWRIGHT_CONFIG_NAMES: readonly ["playwright.config.ts", "playwright.config.mts", "playwright.config.cts", "playwright.config.js", "playwright.config.mjs", "playwright.config.cjs"];
|
|
3
|
+
/** Dependency trees, build output, VCS state, and runner artifacts are not projects. */
|
|
4
|
+
export declare const CONFIG_SEARCH_PRUNED_DIRS: Readonly<Record<string, true>>;
|
|
5
|
+
//# sourceMappingURL=config-locations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-locations.d.ts","sourceRoot":"","sources":["../../src/discovery/config-locations.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,eAAO,MAAM,uBAAuB,+JAO1B,CAAC;AAEX,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAOpE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Configuration search convention shared by enumeration and sealed-tree re-sealing. */
|
|
2
|
+
export const PLAYWRIGHT_CONFIG_NAMES = [
|
|
3
|
+
'playwright.config.ts',
|
|
4
|
+
'playwright.config.mts',
|
|
5
|
+
'playwright.config.cts',
|
|
6
|
+
'playwright.config.js',
|
|
7
|
+
'playwright.config.mjs',
|
|
8
|
+
'playwright.config.cjs',
|
|
9
|
+
];
|
|
10
|
+
/** Dependency trees, build output, VCS state, and runner artifacts are not projects. */
|
|
11
|
+
export const CONFIG_SEARCH_PRUNED_DIRS = {
|
|
12
|
+
node_modules: true,
|
|
13
|
+
dist: true,
|
|
14
|
+
'.git': true,
|
|
15
|
+
'test-results': true,
|
|
16
|
+
coverage: true,
|
|
17
|
+
build: true,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=config-locations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-locations.js","sourceRoot":"","sources":["../../src/discovery/config-locations.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,sBAAsB;IACtB,uBAAuB;IACvB,uBAAuB;IACvB,sBAAsB;IACtB,uBAAuB;IACvB,uBAAuB;CACf,CAAC;AAEX,wFAAwF;AACxF,MAAM,CAAC,MAAM,yBAAyB,GAAmC;IACvE,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,cAAc,EAAE,IAAI;IACpB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;CACZ,CAAC"}
|