@gate-forge/pack-playwright 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.
- package/LICENSE +202 -0
- package/bin/gateforge-witness.js +40 -0
- package/dist/attestation/proxy.d.ts +40 -0
- package/dist/attestation/proxy.d.ts.map +1 -0
- package/dist/attestation/proxy.js +78 -0
- package/dist/attestation/proxy.js.map +1 -0
- package/dist/constants.d.ts +130 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +138 -0
- package/dist/constants.js.map +1 -0
- package/dist/discovery/adapters.d.ts +167 -0
- package/dist/discovery/adapters.d.ts.map +1 -0
- package/dist/discovery/adapters.js +276 -0
- package/dist/discovery/adapters.js.map +1 -0
- package/dist/discovery/discover.d.ts +57 -0
- package/dist/discovery/discover.d.ts.map +1 -0
- package/dist/discovery/discover.js +544 -0
- package/dist/discovery/discover.js.map +1 -0
- package/dist/discovery/index.d.ts +15 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +15 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/inference.d.ts +63 -0
- package/dist/discovery/inference.d.ts.map +1 -0
- package/dist/discovery/inference.js +173 -0
- package/dist/discovery/inference.js.map +1 -0
- package/dist/discovery/pytest-adapter.d.ts +205 -0
- package/dist/discovery/pytest-adapter.d.ts.map +1 -0
- package/dist/discovery/pytest-adapter.js +548 -0
- package/dist/discovery/pytest-adapter.js.map +1 -0
- package/dist/discovery/reconcile.d.ts +106 -0
- package/dist/discovery/reconcile.d.ts.map +1 -0
- package/dist/discovery/reconcile.js +268 -0
- package/dist/discovery/reconcile.js.map +1 -0
- package/dist/discovery/runner-env.d.ts +80 -0
- package/dist/discovery/runner-env.d.ts.map +1 -0
- package/dist/discovery/runner-env.js +139 -0
- package/dist/discovery/runner-env.js.map +1 -0
- package/dist/discovery/static-discovery.d.ts +121 -0
- package/dist/discovery/static-discovery.d.ts.map +1 -0
- package/dist/discovery/static-discovery.js +1028 -0
- package/dist/discovery/static-discovery.js.map +1 -0
- package/dist/discovery/supervised-run.d.ts +110 -0
- package/dist/discovery/supervised-run.d.ts.map +1 -0
- package/dist/discovery/supervised-run.js +328 -0
- package/dist/discovery/supervised-run.js.map +1 -0
- package/dist/discovery/trusted-config.d.ts +103 -0
- package/dist/discovery/trusted-config.d.ts.map +1 -0
- package/dist/discovery/trusted-config.js +117 -0
- package/dist/discovery/trusted-config.js.map +1 -0
- package/dist/fixture/evidence.d.ts +191 -0
- package/dist/fixture/evidence.d.ts.map +1 -0
- package/dist/fixture/evidence.js +366 -0
- package/dist/fixture/evidence.js.map +1 -0
- package/dist/fixture/fixture.d.ts +37 -0
- package/dist/fixture/fixture.d.ts.map +1 -0
- package/dist/fixture/fixture.js +38 -0
- package/dist/fixture/fixture.js.map +1 -0
- package/dist/fixture/witness-client.d.ts +164 -0
- package/dist/fixture/witness-client.d.ts.map +1 -0
- package/dist/fixture/witness-client.js +253 -0
- package/dist/fixture/witness-client.js.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +16 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +21 -0
- package/dist/json.js.map +1 -0
- package/dist/reporter/ledger.d.ts +105 -0
- package/dist/reporter/ledger.d.ts.map +1 -0
- package/dist/reporter/ledger.js +197 -0
- package/dist/reporter/ledger.js.map +1 -0
- package/dist/reporter/reporter.cjs +105 -0
- package/dist/reporter/reporter.cjs.map +1 -0
- package/dist/reporter/reporter.d.cts +35 -0
- package/dist/reporter/reporter.d.cts.map +1 -0
- package/dist/reporter/reporter.d.ts +167 -0
- package/dist/reporter/reporter.d.ts.map +1 -0
- package/dist/reporter/reporter.js +673 -0
- package/dist/reporter/reporter.js.map +1 -0
- package/dist/setup.d.ts +49 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +167 -0
- package/dist/setup.js.map +1 -0
- package/dist/supervisor/client.d.ts +73 -0
- package/dist/supervisor/client.d.ts.map +1 -0
- package/dist/supervisor/client.js +164 -0
- package/dist/supervisor/client.js.map +1 -0
- package/dist/supervisor/drain.d.ts +45 -0
- package/dist/supervisor/drain.d.ts.map +1 -0
- package/dist/supervisor/drain.js +235 -0
- package/dist/supervisor/drain.js.map +1 -0
- package/dist/supervisor/index.d.ts +16 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +13 -0
- package/dist/supervisor/index.js.map +1 -0
- package/dist/supervisor/spool.d.ts +137 -0
- package/dist/supervisor/spool.d.ts.map +1 -0
- package/dist/supervisor/spool.js +263 -0
- package/dist/supervisor/spool.js.map +1 -0
- package/dist/surface.d.ts +134 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +139 -0
- package/dist/surface.js.map +1 -0
- package/dist/witness/adapter-registry.d.ts +38 -0
- package/dist/witness/adapter-registry.d.ts.map +1 -0
- package/dist/witness/adapter-registry.js +158 -0
- package/dist/witness/adapter-registry.js.map +1 -0
- package/dist/witness/bin.d.ts +21 -0
- package/dist/witness/bin.d.ts.map +1 -0
- package/dist/witness/bin.js +172 -0
- package/dist/witness/bin.js.map +1 -0
- package/dist/witness/browser.d.ts +173 -0
- package/dist/witness/browser.d.ts.map +1 -0
- package/dist/witness/browser.js +580 -0
- package/dist/witness/browser.js.map +1 -0
- package/dist/witness/classifications.d.ts +42 -0
- package/dist/witness/classifications.d.ts.map +1 -0
- package/dist/witness/classifications.js +87 -0
- package/dist/witness/classifications.js.map +1 -0
- package/dist/witness/env-attestation.d.ts +98 -0
- package/dist/witness/env-attestation.d.ts.map +1 -0
- package/dist/witness/env-attestation.js +202 -0
- package/dist/witness/env-attestation.js.map +1 -0
- package/dist/witness/loopback-pins.d.ts +79 -0
- package/dist/witness/loopback-pins.d.ts.map +1 -0
- package/dist/witness/loopback-pins.js +244 -0
- package/dist/witness/loopback-pins.js.map +1 -0
- package/dist/witness/server.d.ts +34 -0
- package/dist/witness/server.d.ts.map +1 -0
- package/dist/witness/server.js +2539 -0
- package/dist/witness/server.js.map +1 -0
- package/dist/witness/types.d.ts +643 -0
- package/dist/witness/types.d.ts.map +1 -0
- package/dist/witness/types.js +2 -0
- package/dist/witness/types.js.map +1 -0
- package/package.json +64 -0
- package/python/gateforge_persistence_intents.py +100 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog orchestration (plan 2026-09-13 phase 2 item 1): builds the
|
|
3
|
+
* validated {@link TestCatalog} from the static scan, the native
|
|
4
|
+
* playwright reconciliation, kind/category inference, and the configured
|
|
5
|
+
* pytest diagnostic suites.
|
|
6
|
+
*
|
|
7
|
+
* Invariants enforced here (fail closed as DATA, never silence):
|
|
8
|
+
* - every statically detected call, unresolved gap, and parse error is a
|
|
9
|
+
* catalog row — a failed scan never reads as "no tests";
|
|
10
|
+
* - reconciliation is STATIC-FIRST with a native fallback: a case the
|
|
11
|
+
* static scan derived (and the native list confirmed) is `matched`
|
|
12
|
+
* with origin `'static'`; a case ONLY the native runner enumerated is
|
|
13
|
+
* still a DISCOVERED row (origin `'native-list'`, reconciliation
|
|
14
|
+
* `list-only`) — the runner proved it exists and will execute it —
|
|
15
|
+
* while a case ONLY the static scan found stays `static-only` and
|
|
16
|
+
* unresolved (the runner cannot execute what it never enumerated);
|
|
17
|
+
* - `inventoryComplete` is true only when every enabled enumeration
|
|
18
|
+
* step ran clean (parse errors, budget cuts, unresolved static-only
|
|
19
|
+
* rows, native reporter errors, and failed pytest collection all make
|
|
20
|
+
* it false);
|
|
21
|
+
* - the final document passes the strict core schema (duplicate logical
|
|
22
|
+
* keys are typed errors listing both sources).
|
|
23
|
+
*
|
|
24
|
+
* Output ordering is deterministic: entries sort by (file, titlePath,
|
|
25
|
+
* project); unresolved/parse errors sort by location.
|
|
26
|
+
*/
|
|
27
|
+
import { join } from 'node:path';
|
|
28
|
+
import { canonicalJson, deriveLogicalKey, TestCatalogSchema, } from '@gate-forge/core';
|
|
29
|
+
import { inferTestKind } from './inference.js';
|
|
30
|
+
import { collectPytestSuite, repoRelative, } from './pytest-adapter.js';
|
|
31
|
+
import { fileDigest, listNativePlaywrightTests, reconciliationKey, } from './reconcile.js';
|
|
32
|
+
import { scanTestFiles, UNRESOLVED_TITLE_PLACEHOLDER, } from './static-discovery.js';
|
|
33
|
+
/**
|
|
34
|
+
* Runs discovery + reconciliation and returns the validated catalog.
|
|
35
|
+
*
|
|
36
|
+
* Pytest suites (plan §3.5) are registered-but-diagnostic-only by
|
|
37
|
+
* default: they appear in `runnerSummaries` with status `registered`
|
|
38
|
+
* (their configured identities, no execution, no collection). With
|
|
39
|
+
* `collectPytest: true` (CLI `--pytest`), the adapter runs the
|
|
40
|
+
* configured argv with `--collect-only -q` and adds one entry per
|
|
41
|
+
* collected node id; diagnostic EXECUTION remains Phase 4 work.
|
|
42
|
+
*
|
|
43
|
+
* Args:
|
|
44
|
+
* options: cwd, config, optional pytest collection + timeouts.
|
|
45
|
+
*
|
|
46
|
+
* Returns:
|
|
47
|
+
* Promise<DiscoverResult>: validated catalog + canonical JSON.
|
|
48
|
+
*
|
|
49
|
+
* Throws:
|
|
50
|
+
* TestDiscoveryError: when an enabled native enumeration could not
|
|
51
|
+
* run at all (spawn failure, timeout, unparseable output) — the CLI
|
|
52
|
+
* maps this to exit 2. Scanner-detectable problems are rows, not
|
|
53
|
+
* throws.
|
|
54
|
+
*/
|
|
55
|
+
export async function discoverTestCatalog(options) {
|
|
56
|
+
const { cwd, config } = options;
|
|
57
|
+
const scan = scanTestFiles({
|
|
58
|
+
cwd,
|
|
59
|
+
include: config.project.paths.include,
|
|
60
|
+
exclude: config.project.paths.exclude,
|
|
61
|
+
});
|
|
62
|
+
const native = await listNativePlaywrightTests({
|
|
63
|
+
cwd,
|
|
64
|
+
timeoutMs: options.playwrightTimeoutMs,
|
|
65
|
+
});
|
|
66
|
+
const builder = new CatalogBuilder(cwd, scan, native);
|
|
67
|
+
const runnerSummaries = [builder.playwrightSummary()];
|
|
68
|
+
const entries = builder.buildEntries();
|
|
69
|
+
// Registered pytest suites: diagnostic-only identities (§3.5).
|
|
70
|
+
const suites = config.diagnostics?.suites ?? [];
|
|
71
|
+
for (const suite of suites) {
|
|
72
|
+
if (options.collectPytest === true) {
|
|
73
|
+
const collection = await collectPytestSuite(suite, join(cwd, suite.cwd));
|
|
74
|
+
runnerSummaries.push({
|
|
75
|
+
runner: 'pytest',
|
|
76
|
+
name: suite.name,
|
|
77
|
+
status: collection.status === 'discovered' ? 'discovered' : 'unavailable',
|
|
78
|
+
detail: collection.detail,
|
|
79
|
+
});
|
|
80
|
+
if (collection.status !== 'discovered')
|
|
81
|
+
continue;
|
|
82
|
+
for (const testCase of collection.cases) {
|
|
83
|
+
// Collected files are suite-cwd-relative; the catalog rows and
|
|
84
|
+
// digests use repo-relative posix paths.
|
|
85
|
+
const repoFile = repoRelative(cwd, join(cwd, suite.cwd, testCase.file));
|
|
86
|
+
const row = builder.pytestEntry(suite.name, testCase.nodeId, repoFile, testCase.titlePath);
|
|
87
|
+
if (row !== null)
|
|
88
|
+
entries.push(row);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
runnerSummaries.push({
|
|
93
|
+
runner: 'pytest',
|
|
94
|
+
name: suite.name,
|
|
95
|
+
status: 'registered',
|
|
96
|
+
detail: 'registered for diagnostics; collection not requested (run tests discover --pytest); execution is Phase 4',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const catalog = builder.finalize(entries, runnerSummaries);
|
|
101
|
+
return { catalog, json: canonicalJson(catalog) };
|
|
102
|
+
}
|
|
103
|
+
/** Assembles catalog rows from the scan + native enumeration. */
|
|
104
|
+
class CatalogBuilder {
|
|
105
|
+
cwd;
|
|
106
|
+
scan;
|
|
107
|
+
native;
|
|
108
|
+
/** Static entries keyed by file#titlePath for matching. */
|
|
109
|
+
staticByKey = new Map();
|
|
110
|
+
constructor(cwd, scan, native) {
|
|
111
|
+
this.cwd = cwd;
|
|
112
|
+
this.scan = scan;
|
|
113
|
+
this.native = native;
|
|
114
|
+
for (const entry of scan.entries) {
|
|
115
|
+
this.staticByKey.set(reconciliationKey(entry.file, entry.titlePath), entry);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** The playwright runner summary line for this run. */
|
|
119
|
+
playwrightSummary() {
|
|
120
|
+
if (this.native.status === 'unavailable') {
|
|
121
|
+
return { runner: 'playwright', name: 'playwright', status: 'unavailable', detail: this.native.detail };
|
|
122
|
+
}
|
|
123
|
+
// Native reporter errors (e.g. a spec that fails to load) are DATA:
|
|
124
|
+
// surfaced on the summary and reflected in inventoryComplete.
|
|
125
|
+
const errors = this.native.errors.length > 0 ? `; native errors: ${this.native.errors.join(' | ').slice(0, 500)}` : '';
|
|
126
|
+
return { runner: 'playwright', name: 'playwright', status: 'discovered', detail: `${this.native.detail}${errors}` };
|
|
127
|
+
}
|
|
128
|
+
/** Builds every playwright row: matched, list-only, static-only, gaps. */
|
|
129
|
+
buildEntries() {
|
|
130
|
+
const rows = [];
|
|
131
|
+
const matchedStaticKeys = new Set();
|
|
132
|
+
// Parameterized static templates (`for (const x of ITEMS)
|
|
133
|
+
// test(\`...${x}...\`)`): the template title is not itself runnable —
|
|
134
|
+
// its concrete instances are. A template whose enumerated instances
|
|
135
|
+
// all share its file + describe ancestry merges its static facts
|
|
136
|
+
// into each instance row (origin 'static' + a template-expansion
|
|
137
|
+
// weak signal) instead of leaving a blocking static-only gap beside
|
|
138
|
+
// fact-less list-only rows (consumer migration, E22). Templates with
|
|
139
|
+
// ZERO enumerated instances stay static-only and blocking (a
|
|
140
|
+
// parameterized case no configuration executes — the owner wires it
|
|
141
|
+
// into a project or removes it). An instance matching two templates,
|
|
142
|
+
// or exactly matching a static entry, merges into no template
|
|
143
|
+
// (ambiguity and exact identity win). Only the LAST titlePath segment
|
|
144
|
+
// may carry `${}` slots; a template slot in a describe segment stays
|
|
145
|
+
// static-only (documented limit).
|
|
146
|
+
const templateConsumed = new Set();
|
|
147
|
+
const instanceTemplate = new Map();
|
|
148
|
+
if (this.native.status === 'discovered') {
|
|
149
|
+
const enumeratedKeys = new Set(this.native.instances.map((instance) => reconciliationKey(instance.file, instance.titlePath)));
|
|
150
|
+
const templates = [...this.staticByKey.values()].filter((entry) => !enumeratedKeys.has(reconciliationKey(entry.file, entry.titlePath)) &&
|
|
151
|
+
templateTitlePattern(entry.title) !== null);
|
|
152
|
+
const claimsByInstance = new Map();
|
|
153
|
+
for (const template of templates) {
|
|
154
|
+
const pattern = templateTitlePattern(template.title);
|
|
155
|
+
if (pattern === null)
|
|
156
|
+
continue;
|
|
157
|
+
const templateKey = reconciliationKey(template.file, template.titlePath);
|
|
158
|
+
const describes = template.titlePath.slice(0, -1);
|
|
159
|
+
for (const instance of this.native.instances) {
|
|
160
|
+
const instanceKey = reconciliationKey(instance.file, instance.titlePath);
|
|
161
|
+
// Exact static identity wins over template expansion.
|
|
162
|
+
if (this.staticByKey.has(instanceKey))
|
|
163
|
+
continue;
|
|
164
|
+
if (instance.file !== template.file)
|
|
165
|
+
continue;
|
|
166
|
+
if (instance.titlePath.length !== template.titlePath.length)
|
|
167
|
+
continue;
|
|
168
|
+
if (!describes.every((segment, index) => segment === instance.titlePath[index]))
|
|
169
|
+
continue;
|
|
170
|
+
if (!pattern.test(instance.titlePath[instance.titlePath.length - 1] ?? ''))
|
|
171
|
+
continue;
|
|
172
|
+
const claims = claimsByInstance.get(instanceKey) ?? [];
|
|
173
|
+
claims.push(templateKey);
|
|
174
|
+
claimsByInstance.set(instanceKey, claims);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// An instance claimed by two templates merges into neither.
|
|
178
|
+
for (const [instanceKey, templateKeys] of claimsByInstance) {
|
|
179
|
+
if (templateKeys.length !== 1 || templateKeys[0] === undefined)
|
|
180
|
+
continue;
|
|
181
|
+
const template = this.staticByKey.get(templateKeys[0]);
|
|
182
|
+
if (template === undefined)
|
|
183
|
+
continue;
|
|
184
|
+
templateConsumed.add(templateKeys[0]);
|
|
185
|
+
instanceTemplate.set(instanceKey, template);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Static unresolved gaps, keyed by reconciliation identity, with
|
|
189
|
+
// duplicates merged (§5.2: line numbers are never identity — two
|
|
190
|
+
// unprovable calls sharing a title path collapse into one gap).
|
|
191
|
+
const gapsByKey = new Map();
|
|
192
|
+
const gapExtras = new Map();
|
|
193
|
+
for (const gap of this.scan.unresolved) {
|
|
194
|
+
const key = reconciliationKey(gap.file, gap.titlePath);
|
|
195
|
+
const existing = gapsByKey.get(key);
|
|
196
|
+
if (existing === undefined) {
|
|
197
|
+
gapsByKey.set(key, gap);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const extras = gapExtras.get(key) ?? [];
|
|
201
|
+
extras.push(`${gap.location.file}:${String(gap.location.line)}`);
|
|
202
|
+
gapExtras.set(key, extras);
|
|
203
|
+
}
|
|
204
|
+
// A gap the native runner ALSO enumerated is RESOLVED BY THE RUNNER:
|
|
205
|
+
// the --list run loaded the file and will execute that exact case, so
|
|
206
|
+
// the discovered row stands and the gap merges into it as a weak
|
|
207
|
+
// signal — a second row over the same identity would duplicate the
|
|
208
|
+
// logical key (the strict schema correctly rejects that).
|
|
209
|
+
const enumeratedKeys = new Set();
|
|
210
|
+
if (this.native.status === 'discovered') {
|
|
211
|
+
for (const instance of this.native.instances) {
|
|
212
|
+
const key = reconciliationKey(instance.file, instance.titlePath);
|
|
213
|
+
enumeratedKeys.add(key);
|
|
214
|
+
const template = instanceTemplate.get(key);
|
|
215
|
+
const staticEntry = this.staticByKey.get(key) ?? template;
|
|
216
|
+
if (staticEntry !== undefined)
|
|
217
|
+
matchedStaticKeys.add(key);
|
|
218
|
+
const gap = gapsByKey.get(key);
|
|
219
|
+
rows.push(this.playwrightRow(instance, staticEntry, gap, template));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
for (const [key, staticEntry] of this.staticByKey) {
|
|
223
|
+
if (matchedStaticKeys.has(key) || templateConsumed.has(key))
|
|
224
|
+
continue;
|
|
225
|
+
rows.push(this.staticOnlyRow(staticEntry));
|
|
226
|
+
}
|
|
227
|
+
// Remaining unresolved static gaps become visible rows (never
|
|
228
|
+
// omitted): unprovable shapes the runner did NOT enumerate (they
|
|
229
|
+
// cannot execute) stay typed unresolved entries and block the
|
|
230
|
+
// inventory honestly.
|
|
231
|
+
for (const [key, gap] of [...gapsByKey.entries()].sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))) {
|
|
232
|
+
if (enumeratedKeys.has(key))
|
|
233
|
+
continue;
|
|
234
|
+
const row = this.unresolvedRow(gap);
|
|
235
|
+
const extras = gapExtras.get(key);
|
|
236
|
+
if (extras !== undefined && row.unresolvedReason !== undefined) {
|
|
237
|
+
row.unresolvedReason = {
|
|
238
|
+
...row.unresolvedReason,
|
|
239
|
+
detail: `${row.unresolvedReason.detail} (further call sites: ${extras.join(', ')})`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
rows.push(row);
|
|
243
|
+
}
|
|
244
|
+
return rows;
|
|
245
|
+
}
|
|
246
|
+
/** One matched/native-list playwright instance row. */
|
|
247
|
+
playwrightRow(instance, staticEntry, staticGap, template) {
|
|
248
|
+
const digest = fileDigest(this.cwd, instance.file);
|
|
249
|
+
// The native list reports '' when the run has no projects; the
|
|
250
|
+
// catalog identity uses null for that (same as static-only rows) —
|
|
251
|
+
// an empty-string project is a schema violation, never an identity.
|
|
252
|
+
const project = instance.project === '' ? null : instance.project;
|
|
253
|
+
const matched = staticEntry !== undefined;
|
|
254
|
+
// Static-first: when the static scan derived the case, its facts feed
|
|
255
|
+
// kind inference. When it could not (or the file is outside the
|
|
256
|
+
// configured globs), the native runner's OWN enumeration is the
|
|
257
|
+
// identity source (resolution origin 'native-list'): the row is
|
|
258
|
+
// DISCOVERED — the runner proved the case exists and will execute it
|
|
259
|
+
// in the supervised run — but honestly weaker-classified: no static
|
|
260
|
+
// call-site facts were read, so no strong kind rule may fire.
|
|
261
|
+
const inference = staticEntry === undefined
|
|
262
|
+
? nativeOnlyInference(instance)
|
|
263
|
+
: inferTestKind({ file: staticEntry.file, title: staticEntry.title, titlePath: staticEntry.titlePath, facts: staticEntry.facts });
|
|
264
|
+
const suppression = matched
|
|
265
|
+
? suppressionOf(staticEntry, instance.annotations, instance.location)
|
|
266
|
+
: { mocks: nativeSuppression(instance.annotations, instance.location), flags: [] };
|
|
267
|
+
const weakSignals = [...inference.weakSignals];
|
|
268
|
+
if (template !== undefined) {
|
|
269
|
+
// The identity is a concrete enumerated instance; the static facts
|
|
270
|
+
// came from its parameterized template (same loop body, same
|
|
271
|
+
// fixtures — sound per-instance). Recorded, never silent.
|
|
272
|
+
weakSignals.push({
|
|
273
|
+
ruleId: 'template-expansion',
|
|
274
|
+
evidence: `static parameterized title '${template.title}' expanded over the enumerated instance (same file, same describe ancestry)`,
|
|
275
|
+
location: template.location,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (staticGap !== undefined) {
|
|
279
|
+
// The static scan could not PROVE this call a test (wrapper/
|
|
280
|
+
// dynamic title), yet the runner enumerated it: the runner wins
|
|
281
|
+
// for identity, and the unprovability stays visible as a weak
|
|
282
|
+
// signal (never silently dropped, never blocking twice).
|
|
283
|
+
weakSignals.push({
|
|
284
|
+
ruleId: staticGap.code,
|
|
285
|
+
evidence: `${staticGap.detail} (resolved by native enumeration)`,
|
|
286
|
+
location: staticGap.location,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
logicalKey: deriveLogicalKey({ runner: 'playwright', project, file: instance.file, titlePath: instance.titlePath }),
|
|
291
|
+
runner: 'playwright',
|
|
292
|
+
project,
|
|
293
|
+
file: instance.file,
|
|
294
|
+
titlePath: [...instance.titlePath],
|
|
295
|
+
title: instance.title,
|
|
296
|
+
sourceLocation: instance.location,
|
|
297
|
+
parameterIdentity: instance.frameworkId,
|
|
298
|
+
sourceDigest: digest ?? EMPTY_SHA256,
|
|
299
|
+
discoveryStatus: 'discovered',
|
|
300
|
+
reconciliation: matched ? 'matched' : 'list-only',
|
|
301
|
+
resolutionOrigin: matched ? 'static' : 'native-list',
|
|
302
|
+
inferredKind: inference.inferredKind,
|
|
303
|
+
kindSignals: inference.kindSignals,
|
|
304
|
+
weakSignals,
|
|
305
|
+
rulesFired: inference.rulesFired,
|
|
306
|
+
categorySignals: inference.categorySignals,
|
|
307
|
+
suppressionSignals: suppression.mocks,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/** One static-only row: static scan found it, native list did not. */
|
|
311
|
+
staticOnlyRow(staticEntry) {
|
|
312
|
+
const inference = inferTestKind({
|
|
313
|
+
file: staticEntry.file,
|
|
314
|
+
title: staticEntry.title,
|
|
315
|
+
titlePath: staticEntry.titlePath,
|
|
316
|
+
facts: staticEntry.facts,
|
|
317
|
+
});
|
|
318
|
+
const digest = fileDigest(this.cwd, staticEntry.file);
|
|
319
|
+
const suppression = suppressionOf(staticEntry, [], staticEntry.location);
|
|
320
|
+
return {
|
|
321
|
+
logicalKey: deriveLogicalKey({ runner: 'playwright', project: null, file: staticEntry.file, titlePath: staticEntry.titlePath }),
|
|
322
|
+
runner: 'playwright',
|
|
323
|
+
project: null,
|
|
324
|
+
file: staticEntry.file,
|
|
325
|
+
titlePath: [...staticEntry.titlePath],
|
|
326
|
+
title: staticEntry.title,
|
|
327
|
+
sourceLocation: staticEntry.location,
|
|
328
|
+
parameterIdentity: staticEntry.parameterIdentity,
|
|
329
|
+
sourceDigest: digest ?? EMPTY_SHA256,
|
|
330
|
+
discoveryStatus: 'unresolved',
|
|
331
|
+
reconciliation: this.native.status === 'unavailable' ? 'unavailable' : 'static-only',
|
|
332
|
+
resolutionOrigin: 'static',
|
|
333
|
+
inferredKind: inference.inferredKind,
|
|
334
|
+
kindSignals: inference.kindSignals,
|
|
335
|
+
weakSignals: inference.weakSignals,
|
|
336
|
+
rulesFired: inference.rulesFired,
|
|
337
|
+
categorySignals: inference.categorySignals,
|
|
338
|
+
suppressionSignals: [...suppression.mocks, ...suppression.flags],
|
|
339
|
+
unresolvedReason: {
|
|
340
|
+
code: this.native.status === 'unavailable'
|
|
341
|
+
? 'reconciliation-unavailable'
|
|
342
|
+
: 'reconciliation-static-only',
|
|
343
|
+
detail: this.native.status === 'unavailable'
|
|
344
|
+
? 'no native playwright enumeration ran (no playwright config) — the case is statically visible only'
|
|
345
|
+
: 'the static scan found this case but the runner did not enumerate it (check configured globs, dynamic titles, or filters)',
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
/** One unresolved-gap row (unresolvable wrapper, budget, dynamic title). */
|
|
350
|
+
unresolvedRow(gap) {
|
|
351
|
+
return {
|
|
352
|
+
logicalKey: deriveLogicalKey({
|
|
353
|
+
runner: 'playwright',
|
|
354
|
+
project: null,
|
|
355
|
+
file: gap.file,
|
|
356
|
+
titlePath: gap.titlePath.length > 0 ? gap.titlePath : [UNRESOLVED_TITLE_PLACEHOLDER],
|
|
357
|
+
}),
|
|
358
|
+
runner: 'playwright',
|
|
359
|
+
project: null,
|
|
360
|
+
file: gap.file,
|
|
361
|
+
titlePath: gap.titlePath.length > 0 ? gap.titlePath : [UNRESOLVED_TITLE_PLACEHOLDER],
|
|
362
|
+
title: gap.titlePath[gap.titlePath.length - 1] ?? UNRESOLVED_TITLE_PLACEHOLDER,
|
|
363
|
+
sourceLocation: gap.location,
|
|
364
|
+
parameterIdentity: null,
|
|
365
|
+
sourceDigest: fileDigest(this.cwd, gap.file) ?? EMPTY_SHA256,
|
|
366
|
+
discoveryStatus: 'unresolved',
|
|
367
|
+
reconciliation: this.native.status === 'unavailable' ? 'unavailable' : 'static-only',
|
|
368
|
+
resolutionOrigin: 'static',
|
|
369
|
+
inferredKind: 'unknown',
|
|
370
|
+
kindSignals: [],
|
|
371
|
+
weakSignals: [],
|
|
372
|
+
rulesFired: [],
|
|
373
|
+
categorySignals: [],
|
|
374
|
+
suppressionSignals: [],
|
|
375
|
+
unresolvedReason: { code: gap.code, detail: gap.detail },
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/** One pytest collected-case row (diagnostic identity only, §3.5). */
|
|
379
|
+
pytestEntry(suiteName, nodeId, file, titlePath) {
|
|
380
|
+
// Suite-cwd-relative file → repo-relative for the digest lookup.
|
|
381
|
+
const repoFile = file;
|
|
382
|
+
const digest = fileDigest(this.cwd, repoFile);
|
|
383
|
+
if (digest === null)
|
|
384
|
+
return null; // unreadable file: no fabricated row
|
|
385
|
+
return {
|
|
386
|
+
logicalKey: deriveLogicalKey({ runner: 'pytest', project: suiteName, file: repoFile, titlePath }),
|
|
387
|
+
runner: 'pytest',
|
|
388
|
+
project: suiteName,
|
|
389
|
+
file: repoFile,
|
|
390
|
+
titlePath,
|
|
391
|
+
title: titlePath[titlePath.length - 1] ?? nodeId,
|
|
392
|
+
sourceLocation: { file: repoFile, line: 1, col: 0 },
|
|
393
|
+
parameterIdentity: nodeId,
|
|
394
|
+
sourceDigest: digest,
|
|
395
|
+
discoveryStatus: 'discovered',
|
|
396
|
+
reconciliation: 'unavailable',
|
|
397
|
+
inferredKind: 'unknown',
|
|
398
|
+
kindSignals: [],
|
|
399
|
+
weakSignals: [],
|
|
400
|
+
rulesFired: [],
|
|
401
|
+
categorySignals: [],
|
|
402
|
+
suppressionSignals: nodeId.includes('[xfail]') || nodeId.includes('[xpass]') ? [{ kind: 'fixme', detail: 'pytest xfail/xpass parameter', location: { file: repoFile, line: 1, col: 0 } }] : [],
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/** Validates + orders everything into the final catalog. */
|
|
406
|
+
finalize(entries, runnerSummaries) {
|
|
407
|
+
const sorted = [...entries].sort((a, b) => compareRows(a, b));
|
|
408
|
+
const unresolved = sorted
|
|
409
|
+
.filter((row) => row.discoveryStatus === 'unresolved' && row.unresolvedReason !== undefined)
|
|
410
|
+
.map((row) => ({
|
|
411
|
+
logicalKey: row.logicalKey,
|
|
412
|
+
code: row.unresolvedReason?.code ?? 'unknown',
|
|
413
|
+
detail: row.unresolvedReason?.detail ?? '',
|
|
414
|
+
location: row.sourceLocation,
|
|
415
|
+
}))
|
|
416
|
+
.sort((a, b) => compareLocations(a.location, b.location) || (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));
|
|
417
|
+
const parseErrors = this.scan.parseErrors
|
|
418
|
+
.map((error) => ({ file: error.file, message: error.message, location: error.location }))
|
|
419
|
+
.sort((a, b) => compareLocations(a.location, b.location));
|
|
420
|
+
// Completeness is about ENUMERATION, never classification
|
|
421
|
+
// uncertainty (plan phase 2 item 7): unknown KINDS stay complete;
|
|
422
|
+
// failed parses, budget cuts, native reporter errors, unresolved
|
|
423
|
+
// static-only rows (cases the runner never enumerated — they cannot
|
|
424
|
+
// execute), and failed configured diagnostic suites do not. Rows
|
|
425
|
+
// discovered only through the native list (origin 'native-list')
|
|
426
|
+
// ARE complete enumeration: the runner itself proved the case.
|
|
427
|
+
// A repo with no playwright rows at all is vacuously complete even
|
|
428
|
+
// when native reconciliation reported unavailable (non-playwright
|
|
429
|
+
// repos).
|
|
430
|
+
const diagnosticUnavailable = runnerSummaries.some((summary) => summary.runner !== 'playwright' && summary.status === 'unavailable');
|
|
431
|
+
const complete = parseErrors.length === 0 &&
|
|
432
|
+
!this.scan.budgetExceeded &&
|
|
433
|
+
this.native.errors.length === 0 &&
|
|
434
|
+
!sorted.some((row) => row.runner === 'playwright' && row.discoveryStatus === 'unresolved') &&
|
|
435
|
+
!diagnosticUnavailable;
|
|
436
|
+
// Validate through the strict schema: duplicate logical keys and
|
|
437
|
+
// inconsistent roll-ups fail closed here, at construction time.
|
|
438
|
+
return TestCatalogSchema.parse({
|
|
439
|
+
schemaVersion: 1,
|
|
440
|
+
entries: sorted,
|
|
441
|
+
unresolved,
|
|
442
|
+
parseErrors,
|
|
443
|
+
inventoryComplete: complete,
|
|
444
|
+
runnerSummaries: [...runnerSummaries].sort((a, b) => (a.runner < b.runner ? -1 : a.runner > b.runner ? 1 : 0) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)),
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/** sha256 of empty bytes — placeholder ONLY when a digest is unreadable. */
|
|
449
|
+
const EMPTY_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
|
|
450
|
+
/**
|
|
451
|
+
* Builds the instance-title matcher for a parameterized static title, or
|
|
452
|
+
* null when the title carries no `${}` template slots. Literal parts
|
|
453
|
+
* match exactly (regex-escaped); each slot matches any (possibly empty)
|
|
454
|
+
* text — the same expansion the runner performs over the loop values.
|
|
455
|
+
*
|
|
456
|
+
* Args:
|
|
457
|
+
* title: the static title (may contain `${}` slots).
|
|
458
|
+
*
|
|
459
|
+
* Returns:
|
|
460
|
+
* Anchored RegExp, or null for non-parameterized titles.
|
|
461
|
+
*/
|
|
462
|
+
export function templateTitlePattern(title) {
|
|
463
|
+
if (!title.includes('${}'))
|
|
464
|
+
return null;
|
|
465
|
+
const escaped = title.split('${}').map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
466
|
+
return new RegExp(`^${escaped.join('.*')}$`);
|
|
467
|
+
}
|
|
468
|
+
/** Stable key for location dedupe. */
|
|
469
|
+
function locationKey(location) {
|
|
470
|
+
return `${location.file}:${String(location.line)}:${String(location.col)}`;
|
|
471
|
+
}
|
|
472
|
+
/** Row order: file, then titlePath, then project (deterministic). */
|
|
473
|
+
function compareRows(a, b) {
|
|
474
|
+
const projectA = a.project ?? '';
|
|
475
|
+
const projectB = b.project ?? '';
|
|
476
|
+
return ((a.file < b.file ? -1 : a.file > b.file ? 1 : 0) ||
|
|
477
|
+
(a.titlePath.join('>') < b.titlePath.join('>') ? -1 : a.titlePath.join('>') > b.titlePath.join('>') ? 1 : 0) ||
|
|
478
|
+
(projectA < projectB ? -1 : projectA > projectB ? 1 : 0));
|
|
479
|
+
}
|
|
480
|
+
/** Location order: file, line, col. */
|
|
481
|
+
function compareLocations(a, b) {
|
|
482
|
+
return ((a.file < b.file ? -1 : a.file > b.file ? 1 : 0) ||
|
|
483
|
+
a.line - b.line ||
|
|
484
|
+
a.col - b.col);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Inference for rows whose ONLY enumeration source is the native runner
|
|
488
|
+
* list (resolution origin `'native-list'`): no static facts were read,
|
|
489
|
+
* so NO strong kind rule may fire (running the rules over empty facts
|
|
490
|
+
* would fabricate a `unit` proposal from absence). The kind stays
|
|
491
|
+
* `unknown` and the native-only identity is recorded as a weak signal.
|
|
492
|
+
*/
|
|
493
|
+
function nativeOnlyInference(instance) {
|
|
494
|
+
const weak = {
|
|
495
|
+
ruleId: 'native-list-only',
|
|
496
|
+
evidence: 'identity resolved by the native runner enumeration alone; the static scan did not derive this case ' +
|
|
497
|
+
'(outside configured globs or not statically followable) — no call-site facts were read',
|
|
498
|
+
location: instance.location,
|
|
499
|
+
};
|
|
500
|
+
return { inferredKind: 'unknown', kindSignals: [], weakSignals: [weak], rulesFired: [], categorySignals: [], mockSignals: [] };
|
|
501
|
+
}
|
|
502
|
+
/** Splits static signals into mock vs skip/only/fixme rows. */
|
|
503
|
+
function suppressionOf(staticEntry, annotations, annotationLocation) {
|
|
504
|
+
const mocks = mockSignalsOf(staticEntry);
|
|
505
|
+
const flags = staticEntry.signals.map((signal) => ({
|
|
506
|
+
kind: signal.kind,
|
|
507
|
+
detail: signal.detail,
|
|
508
|
+
location: signal.location,
|
|
509
|
+
}));
|
|
510
|
+
for (const annotation of annotations) {
|
|
511
|
+
if (annotation === 'skip' || annotation === 'fixme') {
|
|
512
|
+
flags.push({
|
|
513
|
+
kind: annotation,
|
|
514
|
+
detail: `native ${annotation} annotation`,
|
|
515
|
+
location: annotationLocation,
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return { mocks, flags };
|
|
520
|
+
}
|
|
521
|
+
/** Suppression rows derived from native annotations alone. */
|
|
522
|
+
function nativeSuppression(annotations, location) {
|
|
523
|
+
return annotations
|
|
524
|
+
.filter((annotation) => annotation === 'skip' || annotation === 'fixme')
|
|
525
|
+
.map((annotation) => ({
|
|
526
|
+
kind: annotation,
|
|
527
|
+
detail: `native ${annotation} annotation`,
|
|
528
|
+
location,
|
|
529
|
+
}));
|
|
530
|
+
}
|
|
531
|
+
/** Mock suppression signals from a static entry's facts. */
|
|
532
|
+
function mockSignalsOf(staticEntry) {
|
|
533
|
+
const signals = [];
|
|
534
|
+
if (staticEntry.facts.pageRoute !== null) {
|
|
535
|
+
signals.push({ kind: 'mock', detail: 'page.route interception inside the test body', location: staticEntry.facts.pageRoute });
|
|
536
|
+
}
|
|
537
|
+
if (staticEntry.facts.fileMockImport !== null) {
|
|
538
|
+
signals.push({ kind: 'mock', detail: 'vi.mock/jest.mock module mock in the test file', location: staticEntry.facts.fileMockImport });
|
|
539
|
+
}
|
|
540
|
+
return signals;
|
|
541
|
+
}
|
|
542
|
+
// Re-exports kept minimal: the CLI needs repoRelative nowhere else today.
|
|
543
|
+
export { repoRelative };
|
|
544
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/discovery/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test discovery surface of the Playwright pack (plan 2026-09-13
|
|
3
|
+
* phase 2): bounded static scanning, native reconciliation, kind
|
|
4
|
+
* inference, the runner adapters, and the pytest diagnostic adapter.
|
|
5
|
+
*/
|
|
6
|
+
export * from './static-discovery.js';
|
|
7
|
+
export * from './inference.js';
|
|
8
|
+
export * from './reconcile.js';
|
|
9
|
+
export * from './pytest-adapter.js';
|
|
10
|
+
export * from './discover.js';
|
|
11
|
+
export * from './adapters.js';
|
|
12
|
+
export * from './supervised-run.js';
|
|
13
|
+
export * from './trusted-config.js';
|
|
14
|
+
export * from './runner-env.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test discovery surface of the Playwright pack (plan 2026-09-13
|
|
3
|
+
* phase 2): bounded static scanning, native reconciliation, kind
|
|
4
|
+
* inference, the runner adapters, and the pytest diagnostic adapter.
|
|
5
|
+
*/
|
|
6
|
+
export * from './static-discovery.js';
|
|
7
|
+
export * from './inference.js';
|
|
8
|
+
export * from './reconcile.js';
|
|
9
|
+
export * from './pytest-adapter.js';
|
|
10
|
+
export * from './discover.js';
|
|
11
|
+
export * from './adapters.js';
|
|
12
|
+
export * from './supervised-run.js';
|
|
13
|
+
export * from './trusted-config.js';
|
|
14
|
+
export * from './runner-env.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}
|