@gate-forge/pack-playwright 0.7.1 → 0.8.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 +100 -3
- 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 +9 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +9 -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 +80 -11
- package/dist/discovery/reconcile.d.ts.map +1 -1
- package/dist/discovery/reconcile.js +395 -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/static-discovery.d.ts +38 -3
- package/dist/discovery/static-discovery.d.ts.map +1 -1
- package/dist/discovery/static-discovery.js +454 -15
- 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 +92 -0
- package/dist/reporter/project-graph-reporter.d.ts.map +1 -0
- package/dist/reporter/project-graph-reporter.js +92 -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 +8 -2
- package/python/__pycache__/gateforge_persistence_intents.cpython-312.pyc +0 -0
- package/python/__pycache__/gateforge_persistence_intents.cpython-314.pyc +0 -0
- package/python/gateforge_pytest_plugin.py +462 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pytest runner adapter behind the runner-neutral `RunnerAdapter`
|
|
3
|
+
* contract (plan 2026-09-25 phase 3).
|
|
4
|
+
*
|
|
5
|
+
* pytest is promoted from a diagnostics runner (§3.5) to a
|
|
6
|
+
* witness-producing runner with the SAME evidence rules as Playwright:
|
|
7
|
+
* - enumerate: the CONFIGURED §3.5 argv runs `--collect-only -q`
|
|
8
|
+
* (`collectPytestSuite`) — the expected set is fixed BEFORE the run;
|
|
9
|
+
* - tag: the pack's pytest plugin (`python/gateforge_pytest_plugin.py`)
|
|
10
|
+
* resolves the supervisor-issued session for the running test and
|
|
11
|
+
* routes its `httpx` client through the per-test session proxy origin
|
|
12
|
+
* (the `session-proxy` channel, exactly like the Playwright fixture);
|
|
13
|
+
* - execute: the configured argv plus a junit-XML report into the
|
|
14
|
+
* EXCLUDED run-state dir; the plugin is loaded through PYTHONPATH and
|
|
15
|
+
* stays inert without supervised wiring;
|
|
16
|
+
* - parse: strict junit parsing (`parseJunitXml`, fail closed) mapped
|
|
17
|
+
* onto the supervision envelope.
|
|
18
|
+
*
|
|
19
|
+
* Identity: a junit row joins an enumerated test on (file, title path)
|
|
20
|
+
* — the `file` attribute pytest's `junit_family=xunit1` emits. A row
|
|
21
|
+
* without it is NEVER attributed to a test (the same fail-closed rule
|
|
22
|
+
* the Playwright path applies to traffic that bypassed every session
|
|
23
|
+
* channel), and a report whose rows cannot be attributed never grades
|
|
24
|
+
* complete. Runner-assisted retries surface as duplicated rows for one
|
|
25
|
+
* identity and are reported as `retriesDetected` (required retries are
|
|
26
|
+
* zero).
|
|
27
|
+
*/
|
|
28
|
+
import { spawn } from 'node:child_process';
|
|
29
|
+
import { readFileSync } from 'node:fs';
|
|
30
|
+
import { join } from 'node:path';
|
|
31
|
+
import { fileURLToPath } from 'node:url';
|
|
32
|
+
import { loadConfig } from '@gate-forge/core';
|
|
33
|
+
import { ENV_APP_BASE_URL, ENV_RUN_ID, ENV_RUN_TOKEN, ENV_STATE_DIR, ENV_WITNESS_URL } from '@gate-forge/witness/constants';
|
|
34
|
+
import { parseJunitXml, } from './pytest-adapter.js';
|
|
35
|
+
import { collectPytestSuite } from './pytest-adapter.js';
|
|
36
|
+
import { buildWitnessedPytestSessionEnv } from './runner-env.js';
|
|
37
|
+
/** Per-test session variables a runner adapter publishes to the test. */
|
|
38
|
+
export const PYTEST_ENV_SESSION_ID = 'GATEFORGE_SESSION_ID';
|
|
39
|
+
export const PYTEST_ENV_SESSION_TOKEN = 'GATEFORGE_SESSION_TOKEN';
|
|
40
|
+
export const PYTEST_ENV_SESSION_PROXY_URL = 'GATEFORGE_SESSION_PROXY_URL';
|
|
41
|
+
/** The variables that carry ONE test's identity to its traffic. */
|
|
42
|
+
export const PYTEST_IDENTITY_ENV = [
|
|
43
|
+
PYTEST_ENV_SESSION_ID,
|
|
44
|
+
PYTEST_ENV_SESSION_TOKEN,
|
|
45
|
+
PYTEST_ENV_SESSION_PROXY_URL,
|
|
46
|
+
];
|
|
47
|
+
/** The runner-side plugin module name (`-p gateforge_pytest_plugin`). */
|
|
48
|
+
export const PYTEST_PLUGIN_MODULE = 'gateforge_pytest_plugin';
|
|
49
|
+
/** Directory the pack ships the pytest plugin in (added to PYTHONPATH). */
|
|
50
|
+
export function pytestPluginDir() {
|
|
51
|
+
return fileURLToPath(new URL('../../python', import.meta.url));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The pytest runner adapter.
|
|
55
|
+
*
|
|
56
|
+
* Every invocation composes ONLY the configured argv plus collection /
|
|
57
|
+
* report flags (the §3.5 discipline): no directory guessing, no
|
|
58
|
+
* commands the config did not name.
|
|
59
|
+
*/
|
|
60
|
+
export class PytestRunnerAdapter {
|
|
61
|
+
options;
|
|
62
|
+
runner = 'pytest';
|
|
63
|
+
capabilities = {
|
|
64
|
+
inventory: 'available',
|
|
65
|
+
resolveInstances: 'available',
|
|
66
|
+
execute: 'available',
|
|
67
|
+
};
|
|
68
|
+
constructor(options = {}) {
|
|
69
|
+
this.options = options;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Job 1: the expected set, fixed BEFORE the run (configured-argv
|
|
73
|
+
* collection, node ids preserved).
|
|
74
|
+
*
|
|
75
|
+
* Args:
|
|
76
|
+
* cwd: absolute repo root the `.gateforge.yml` suite config lives under.
|
|
77
|
+
*
|
|
78
|
+
* Returns:
|
|
79
|
+
* Promise<RunnerEnumeration>: the enumerated tests, or an
|
|
80
|
+
* `unavailable` verdict with a single cause. A repo with no pytest
|
|
81
|
+
* suite configured, a collection error, and a zero-test collection
|
|
82
|
+
* are all `unavailable` — nothing executed proves nothing.
|
|
83
|
+
*/
|
|
84
|
+
async enumerate(cwd) {
|
|
85
|
+
let suites;
|
|
86
|
+
try {
|
|
87
|
+
suites = this.suitesOf(cwd);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
status: 'unavailable',
|
|
92
|
+
detail: `pytest enumeration could not load the gateforge config: ${describeError(error)}`,
|
|
93
|
+
tests: [],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (suites.length === 0) {
|
|
97
|
+
return {
|
|
98
|
+
status: 'unavailable',
|
|
99
|
+
detail: `pytest enumeration found no configured pytest diagnostic suite in ${cwd} ` +
|
|
100
|
+
'(register one under diagnostics.suites with runner: pytest)',
|
|
101
|
+
tests: [],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const tests = [];
|
|
105
|
+
for (const suite of suites) {
|
|
106
|
+
const collection = await collectPytestSuite(suite, cwd);
|
|
107
|
+
if (collection.status !== 'discovered') {
|
|
108
|
+
return {
|
|
109
|
+
status: 'unavailable',
|
|
110
|
+
detail: `pytest enumeration failed: ${collection.detail}`,
|
|
111
|
+
tests: [],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
for (const collected of collection.cases) {
|
|
115
|
+
tests.push(collectedIdentityOf(collected));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const unique = [...new Map(tests.map((test) => [test.logicalKey, test])).values()].sort(byLogicalKey);
|
|
119
|
+
if (unique.length === 0) {
|
|
120
|
+
return {
|
|
121
|
+
status: 'unavailable',
|
|
122
|
+
detail: `pytest enumeration collected no tests under ${cwd} — a zero-test run never proves coverage`,
|
|
123
|
+
tests: [],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { status: 'discovered', detail: `enumerated ${String(unique.length)} pytest test(s) via configured argv`, tests: unique };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Job 2: the per-test tag. The plugin resolves the supervisor-issued
|
|
130
|
+
* session for the running test and routes its httpx client through
|
|
131
|
+
* that session's proxy origin, so every exchange is attributed to
|
|
132
|
+
* THAT session.
|
|
133
|
+
*
|
|
134
|
+
* Args:
|
|
135
|
+
* session: the test being tagged.
|
|
136
|
+
* context: run-scoped, non-secret witness wiring.
|
|
137
|
+
*
|
|
138
|
+
* Returns:
|
|
139
|
+
* RunnerChildEnv: the run identity plus the session-scoped tag.
|
|
140
|
+
*/
|
|
141
|
+
childEnv(_session, context) {
|
|
142
|
+
return {
|
|
143
|
+
vars: {
|
|
144
|
+
[ENV_WITNESS_URL]: context.witnessUrl,
|
|
145
|
+
[ENV_RUN_TOKEN]: context.runToken,
|
|
146
|
+
[ENV_APP_BASE_URL]: context.appBaseUrl,
|
|
147
|
+
[ENV_STATE_DIR]: '<run-state dir>',
|
|
148
|
+
[ENV_RUN_ID]: '<run id>',
|
|
149
|
+
[PYTEST_ENV_SESSION_ID]: context.sessionId,
|
|
150
|
+
[PYTEST_ENV_SESSION_TOKEN]: context.sessionToken,
|
|
151
|
+
[PYTEST_ENV_SESSION_PROXY_URL]: context.sessionProxyUrl,
|
|
152
|
+
},
|
|
153
|
+
tagChannel: 'session-proxy',
|
|
154
|
+
identityVars: PYTEST_IDENTITY_ENV,
|
|
155
|
+
mechanism: 'gateforge pytest plugin resolves the supervisor session for the running test and routes its ' +
|
|
156
|
+
'httpx client through the per-test session proxy origin',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Job 3: runs the SELECTED pytest tests under a junit-XML report with
|
|
161
|
+
* the pack plugin loaded (per-test sessions + proxied httpx). The
|
|
162
|
+
* child environment is the witnessed-session allowlist: the run
|
|
163
|
+
* identity the plugin needs to address the lifecycle spool plus the
|
|
164
|
+
* non-secret run wiring — never the verifier key, never any other
|
|
165
|
+
* parent-side name.
|
|
166
|
+
*
|
|
167
|
+
* Args:
|
|
168
|
+
* request: the exact selection, run identity, and wall-clock bound.
|
|
169
|
+
*
|
|
170
|
+
* Returns:
|
|
171
|
+
* Promise<RunnerExecutionEnvelope>: the structured outcome envelope
|
|
172
|
+
* (a runner exit code alone is never a gate result).
|
|
173
|
+
*/
|
|
174
|
+
async execute(request) {
|
|
175
|
+
let suites;
|
|
176
|
+
try {
|
|
177
|
+
suites = this.suitesOf(request.cwd);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return envelopeIncomplete(null, `pytest execution could not load the gateforge config: ${describeError(error)}`);
|
|
181
|
+
}
|
|
182
|
+
const suite = suites[0];
|
|
183
|
+
if (suite === undefined) {
|
|
184
|
+
return envelopeIncomplete(null, 'pytest execution found no configured pytest diagnostic suite to run');
|
|
185
|
+
}
|
|
186
|
+
const nodeIds = [];
|
|
187
|
+
for (const logicalKey of request.logicalKeys) {
|
|
188
|
+
const nodeId = logicalKeyToNodeId(logicalKey);
|
|
189
|
+
if (nodeId === null) {
|
|
190
|
+
return envelopeIncomplete(null, `pytest execution cannot run '${logicalKey}': not a <file>#<title path> identity this adapter enumerated`);
|
|
191
|
+
}
|
|
192
|
+
nodeIds.push(nodeId);
|
|
193
|
+
}
|
|
194
|
+
const reportPath = join(request.stateDir, 'pytest', `${request.runId}`, 'report.xml');
|
|
195
|
+
const pluginDir = pytestPluginDir();
|
|
196
|
+
const argv = [
|
|
197
|
+
...suite.argv,
|
|
198
|
+
'-o',
|
|
199
|
+
'junit_family=xunit1',
|
|
200
|
+
`--junitxml=${reportPath}`,
|
|
201
|
+
'-p',
|
|
202
|
+
PYTEST_PLUGIN_MODULE,
|
|
203
|
+
...nodeIds,
|
|
204
|
+
];
|
|
205
|
+
const child = spawn(argv[0] ?? '', argv.slice(1), {
|
|
206
|
+
cwd: join(request.cwd, suite.cwd),
|
|
207
|
+
env: buildWitnessedPytestSessionEnv({
|
|
208
|
+
[ENV_WITNESS_URL]: this.options.witness?.url ?? process.env[ENV_WITNESS_URL] ?? '',
|
|
209
|
+
[ENV_RUN_TOKEN]: this.options.witness?.token ?? process.env[ENV_RUN_TOKEN] ?? '',
|
|
210
|
+
[ENV_STATE_DIR]: request.stateDir,
|
|
211
|
+
[ENV_RUN_ID]: request.runId,
|
|
212
|
+
[ENV_APP_BASE_URL]: this.options.appBaseUrl ?? process.env[ENV_APP_BASE_URL] ?? '',
|
|
213
|
+
// The candidate workspace must stay byte-identical across the
|
|
214
|
+
// run: CPython would otherwise write `__pycache__/*.pyc` beside
|
|
215
|
+
// the collected suite AFTER the authority froze the candidate
|
|
216
|
+
// tree, and the fail-closed drift gate then refuses the whole
|
|
217
|
+
// run. Collection and the diagnostic executor already carry
|
|
218
|
+
// this; the supervised session child must too.
|
|
219
|
+
PYTHONDONTWRITEBYTECODE: '1',
|
|
220
|
+
}, process.env, pluginDir),
|
|
221
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
222
|
+
});
|
|
223
|
+
const outcome = await new Promise((settle) => {
|
|
224
|
+
let timedOut = false;
|
|
225
|
+
const timer = setTimeout(() => {
|
|
226
|
+
timedOut = true;
|
|
227
|
+
child.kill('SIGKILL');
|
|
228
|
+
}, request.timeoutMs);
|
|
229
|
+
child.stderr?.resume();
|
|
230
|
+
child.once('error', (error) => {
|
|
231
|
+
clearTimeout(timer);
|
|
232
|
+
settle({ code: null, timedOut: false, error });
|
|
233
|
+
});
|
|
234
|
+
child.once('exit', (code) => {
|
|
235
|
+
clearTimeout(timer);
|
|
236
|
+
settle({ code, timedOut, error: null });
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
if (outcome.error !== null) {
|
|
240
|
+
return envelopeIncomplete(null, `pytest execution could not start (${argv[0] ?? ''}): ${outcome.error.message}`);
|
|
241
|
+
}
|
|
242
|
+
if (outcome.timedOut) {
|
|
243
|
+
return envelopeIncomplete(null, `pytest execution exceeded its ${String(request.timeoutMs)}ms bound and was killed — an incomplete run never grades complete`);
|
|
244
|
+
}
|
|
245
|
+
let report = '';
|
|
246
|
+
try {
|
|
247
|
+
report = readFileSync(reportPath, 'utf8');
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
report = '';
|
|
251
|
+
}
|
|
252
|
+
const envelope = this.parseResults({ processExit: outcome.code, report });
|
|
253
|
+
if (!envelope.complete && report === '') {
|
|
254
|
+
return {
|
|
255
|
+
...envelope,
|
|
256
|
+
incompleteDetail: `pytest produced no junit report at ${reportPath} (exit ${String(outcome.code)}) — fail closed`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return envelope;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Job 4: strict junit parsing mapped onto the supervision envelope.
|
|
263
|
+
*
|
|
264
|
+
* Args:
|
|
265
|
+
* raw: the junit-XML document text plus the runner exit status.
|
|
266
|
+
*
|
|
267
|
+
* Returns:
|
|
268
|
+
* RunnerExecutionEnvelope: reporter INPUT, never a verdict. An
|
|
269
|
+
* unreadable report, a zero-test run, a collection error, a run of
|
|
270
|
+
* only skipped cases, and a report whose rows carry no attributable
|
|
271
|
+
* pytest identity are all `complete: false`.
|
|
272
|
+
*/
|
|
273
|
+
parseResults(raw) {
|
|
274
|
+
if (raw.report.trim() === '') {
|
|
275
|
+
return envelopeIncomplete(raw.processExit, 'no junit report — a missing report never proves anything');
|
|
276
|
+
}
|
|
277
|
+
let document;
|
|
278
|
+
try {
|
|
279
|
+
document = parseJunitXml(raw.report);
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
return envelopeIncomplete(raw.processExit, `unparsable junit report — fail closed: ${describeError(error)}`);
|
|
283
|
+
}
|
|
284
|
+
const rows = [];
|
|
285
|
+
for (const testCase of document.cases) {
|
|
286
|
+
const identity = junitIdentityOf(testCase);
|
|
287
|
+
if (identity !== null) {
|
|
288
|
+
rows.push({
|
|
289
|
+
identity: identity.logicalKey,
|
|
290
|
+
case: testCase,
|
|
291
|
+
frameworkId: `${identity.file}::${identity.titlePath.join('::')}`,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (document.cases.length > 0 && rows.length === 0) {
|
|
296
|
+
return envelopeIncomplete(raw.processExit, `junit report carries ${String(document.cases.length)} row(s) with no attributable pytest ` +
|
|
297
|
+
'file identity — an unidentified row is never attributed to a test');
|
|
298
|
+
}
|
|
299
|
+
const collectionError = document.cases.some((testCase) => testCase.name === 'pytest_collection');
|
|
300
|
+
if (collectionError) {
|
|
301
|
+
return envelopeIncomplete(raw.processExit, 'junit report carries a pytest collection error — the expected set never ran');
|
|
302
|
+
}
|
|
303
|
+
if (document.tests === 0) {
|
|
304
|
+
return envelopeIncomplete(raw.processExit, 'junit report covers zero tests — a zero-test run is incomplete');
|
|
305
|
+
}
|
|
306
|
+
if (document.cases.length > 0 && document.cases.every((testCase) => testCase.outcome === 'skipped')) {
|
|
307
|
+
return envelopeIncomplete(raw.processExit, 'junit report ran only skipped/expected-failure cases — nothing executed');
|
|
308
|
+
}
|
|
309
|
+
const attemptsByIdentity = new Map();
|
|
310
|
+
for (const row of rows)
|
|
311
|
+
attemptsByIdentity.set(row.identity, (attemptsByIdentity.get(row.identity) ?? 0) + 1);
|
|
312
|
+
const retriesDetected = rows.some((row) => (attemptsByIdentity.get(row.identity) ?? 0) > 1);
|
|
313
|
+
const seen = new Set();
|
|
314
|
+
const outcomes = [];
|
|
315
|
+
for (const row of rows) {
|
|
316
|
+
if (seen.has(row.identity))
|
|
317
|
+
continue;
|
|
318
|
+
seen.add(row.identity);
|
|
319
|
+
const attempt = attemptsByIdentity.get(row.identity) ?? 1;
|
|
320
|
+
const status = row.case.outcome === 'passed'
|
|
321
|
+
? 'passed'
|
|
322
|
+
: row.case.outcome === 'skipped'
|
|
323
|
+
? 'skipped'
|
|
324
|
+
: 'failed';
|
|
325
|
+
outcomes.push({
|
|
326
|
+
logicalKey: row.identity,
|
|
327
|
+
project: null,
|
|
328
|
+
frameworkId: row.frameworkId,
|
|
329
|
+
status,
|
|
330
|
+
attempt,
|
|
331
|
+
expectedFailure: row.case.skipType === 'pytest.xfail' || row.case.skipType === 'xfail',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
const exitDetail = exitIncompleteDetail(raw.processExit);
|
|
335
|
+
if (exitDetail !== null)
|
|
336
|
+
return { ...envelopeIncomplete(raw.processExit, exitDetail), outcomes };
|
|
337
|
+
// The junit body IS the runner's own fixture/teardown outcome: an
|
|
338
|
+
// `<error>` row means a setup or teardown failure, which grades
|
|
339
|
+
// 'failed'; a clean parsed body grades 'passed'. A missing or
|
|
340
|
+
// unparsable report never got here (fail closed above as 'unknown').
|
|
341
|
+
const fixtureOutcome = document.cases.some((testCase) => testCase.outcome === 'error')
|
|
342
|
+
? 'failed'
|
|
343
|
+
: 'passed';
|
|
344
|
+
return {
|
|
345
|
+
processExit: raw.processExit,
|
|
346
|
+
complete: true,
|
|
347
|
+
outcomes,
|
|
348
|
+
fixtureOutcome,
|
|
349
|
+
...(retriesDetected
|
|
350
|
+
? {
|
|
351
|
+
retriesDetected: true,
|
|
352
|
+
retriesDetail: 'junit report carries duplicated rows for at least one test identity — a runner-assisted retry executed',
|
|
353
|
+
}
|
|
354
|
+
: {}),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* The runner's native parsed report (diagnostics surfaces).
|
|
359
|
+
*
|
|
360
|
+
* Args:
|
|
361
|
+
* raw: the junit-XML document text plus the runner exit status.
|
|
362
|
+
*
|
|
363
|
+
* Returns:
|
|
364
|
+
* JunitDocument | null: the parsed document, or null when the
|
|
365
|
+
* report is absent or unparsable (never a guess).
|
|
366
|
+
*/
|
|
367
|
+
parseReport(raw) {
|
|
368
|
+
if (raw.report.trim() === '')
|
|
369
|
+
return null;
|
|
370
|
+
try {
|
|
371
|
+
return parseJunitXml(raw.report);
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/** The configured pytest suites (option override, else the config). */
|
|
378
|
+
suitesOf(cwd) {
|
|
379
|
+
if (this.options.suite !== undefined)
|
|
380
|
+
return [this.options.suite];
|
|
381
|
+
const config = this.options.config ?? loadConfig(`${cwd}/.gateforge.yml`);
|
|
382
|
+
return (config.diagnostics?.suites ?? []).filter((suite) => suite.runner === 'pytest');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/** One enumerated test's identity from its collected node id. */
|
|
386
|
+
function collectedIdentityOf(collected) {
|
|
387
|
+
const logicalKey = `${collected.file}#${collected.titlePath.join('>')}`;
|
|
388
|
+
return {
|
|
389
|
+
logicalKey,
|
|
390
|
+
project: null,
|
|
391
|
+
file: collected.file,
|
|
392
|
+
titlePath: collected.titlePath,
|
|
393
|
+
blockingAnnotations: [],
|
|
394
|
+
// The plugin spools `item.nodeid` — registration must name the same id.
|
|
395
|
+
frameworkId: collected.nodeId,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* The (file, title path) identity of one junit row, or null when the
|
|
400
|
+
* row cannot be attributed: the pytest `file` attribute must be present
|
|
401
|
+
* and the dotted classname must start with the file's module path.
|
|
402
|
+
*/
|
|
403
|
+
function junitIdentityOf(testCase) {
|
|
404
|
+
if (testCase.file === undefined || testCase.file === '')
|
|
405
|
+
return null;
|
|
406
|
+
const file = testCase.file.split('\\').join('/');
|
|
407
|
+
const module = file.replace(/\.[^.]+$/, '').split('/').join('.');
|
|
408
|
+
const segments = testCase.classname.split('.').filter((segment) => segment !== '');
|
|
409
|
+
if (module !== '' && segments.slice(0, module.split('.').length).join('.') !== module)
|
|
410
|
+
return null;
|
|
411
|
+
const classPath = module === '' ? segments : segments.slice(module.split('.').length);
|
|
412
|
+
const titlePath = [...classPath, testCase.name];
|
|
413
|
+
return { logicalKey: `${file}#${titlePath.join('>')}`, file, titlePath };
|
|
414
|
+
}
|
|
415
|
+
/** The pytest node id of a `<file>#<title path>` identity, or null. */
|
|
416
|
+
function logicalKeyToNodeId(logicalKey) {
|
|
417
|
+
const hash = logicalKey.indexOf('#');
|
|
418
|
+
if (hash <= 0)
|
|
419
|
+
return null;
|
|
420
|
+
const file = logicalKey.slice(0, hash);
|
|
421
|
+
const titlePath = logicalKey.slice(hash + 1);
|
|
422
|
+
if (file === '' || titlePath === '' || titlePath.includes('#'))
|
|
423
|
+
return null;
|
|
424
|
+
return `${file}::${titlePath.split('>').join('::')}`;
|
|
425
|
+
}
|
|
426
|
+
/** Single-cause incomplete envelope (no outcomes are ever invented). */
|
|
427
|
+
function envelopeIncomplete(processExit, detail) {
|
|
428
|
+
return {
|
|
429
|
+
processExit,
|
|
430
|
+
complete: false,
|
|
431
|
+
incompleteDetail: detail,
|
|
432
|
+
outcomes: [],
|
|
433
|
+
fixtureOutcome: 'unknown',
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
/** Exit-status honesty: pytest's own exit codes, fail closed. */
|
|
437
|
+
function exitIncompleteDetail(exit) {
|
|
438
|
+
if (exit === null)
|
|
439
|
+
return 'pytest ended without an exit status — incomplete';
|
|
440
|
+
if (exit === 5)
|
|
441
|
+
return 'pytest collected no tests (exit 5) — a zero-test run is incomplete';
|
|
442
|
+
if (exit >= 2)
|
|
443
|
+
return `pytest ended with status ${String(exit)} (interrupted/internal/usage error) — incomplete`;
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
/** Logical-key sort (stable enumeration order). */
|
|
447
|
+
function byLogicalKey(a, b) {
|
|
448
|
+
return a.logicalKey < b.logicalKey ? -1 : a.logicalKey > b.logicalKey ? 1 : 0;
|
|
449
|
+
}
|
|
450
|
+
/** Single-line message of an unknown thrown value. */
|
|
451
|
+
function describeError(error) {
|
|
452
|
+
return error instanceof Error ? error.message : String(error);
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=pytest-runner-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pytest-runner-adapter.js","sourceRoot":"","sources":["../../src/discovery/pytest-runner-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AAgBpE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC5H,OAAO,EACL,aAAa,GAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAA4B,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAEjE,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAClE,MAAM,CAAC,MAAM,4BAA4B,GAAG,6BAA6B,CAAC;AAE1E,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,qBAAqB;IACrB,wBAAwB;IACxB,4BAA4B;CAC7B,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE9D,2EAA2E;AAC3E,MAAM,UAAU,eAAe;IAC7B,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACjE,CAAC;AAsBD;;;;;;GAMG;AACH,MAAM,OAAO,mBAAmB;IASD;IARpB,MAAM,GAAG,QAAQ,CAAC;IAElB,YAAY,GAAG;QACtB,SAAS,EAAE,WAAW;QACtB,gBAAgB,EAAE,WAAW;QAC7B,OAAO,EAAE,WAAW;KACZ,CAAC;IAEX,YAA6B,UAAsC,EAAE;QAAxC,YAAO,GAAP,OAAO,CAAiC;IAAG,CAAC;IAEzE;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,IAAI,MAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,MAAM,EAAE,2DAA2D,aAAa,CAAC,KAAK,CAAC,EAAE;gBACzF,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,MAAM,EACJ,qEAAqE,GAAG,GAAG;oBAC3E,6DAA6D;gBAC/D,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAyB,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACxD,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACvC,OAAO;oBACL,MAAM,EAAE,aAAa;oBACrB,MAAM,EAAE,8BAA8B,UAAU,CAAC,MAAM,EAAE;oBACzD,KAAK,EAAE,EAAE;iBACV,CAAC;YACJ,CAAC;YACD,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtG,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,MAAM,EAAE,+CAA+C,GAAG,0CAA0C;gBACpG,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,qCAAqC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACnI,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,QAA0B,EAAE,OAA8B;QACjE,OAAO;YACL,IAAI,EAAE;gBACJ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,UAAU;gBACrC,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,QAAQ;gBACjC,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,UAAU;gBACtC,CAAC,aAAa,CAAC,EAAE,iBAAiB;gBAClC,CAAC,UAAU,CAAC,EAAE,UAAU;gBACxB,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC,SAAS;gBAC1C,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC,YAAY;gBAChD,CAAC,4BAA4B,CAAC,EAAE,OAAO,CAAC,eAAe;aACxD;YACD,UAAU,EAAE,eAAe;YAC3B,YAAY,EAAE,mBAAmB;YACjC,SAAS,EACP,8FAA8F;gBAC9F,wDAAwD;SAC3D,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,OAAO,CAAC,OAA6B;QACzC,IAAI,MAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,kBAAkB,CAAC,IAAI,EAAE,yDAAyD,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,kBAAkB,CAAC,IAAI,EAAE,qEAAqE,CAAC,CAAC;QACzG,CAAC;QACD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,kBAAkB,CACvB,IAAI,EACJ,gCAAgC,UAAU,+DAA+D,CAC1G,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG;YACX,GAAG,KAAK,CAAC,IAAI;YACb,IAAI;YACJ,qBAAqB;YACrB,cAAc,UAAU,EAAE;YAC1B,IAAI;YACJ,oBAAoB;YACpB,GAAG,OAAO;SACX,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YAChD,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC;YACjC,GAAG,EAAE,8BAA8B,CACjC;gBACE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE;gBAClF,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE;gBAChF,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,QAAQ;gBACjC,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK;gBAC3B,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE;gBAClF,8DAA8D;gBAC9D,gEAAgE;gBAChE,8DAA8D;gBAC9D,8DAA8D;gBAC9D,4DAA4D;gBAC5D,+CAA+C;gBAC/C,uBAAuB,EAAE,GAAG;aAC7B,EACD,OAAO,CAAC,GAAG,EACX,SAAS,CACV;YACD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAkE,CAAC,MAAM,EAAE,EAAE;YAC5G,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACtB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC5B,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,kBAAkB,CAAC,IAAI,EAAE,qCAAqC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,kBAAkB,CACvB,IAAI,EACJ,iCAAiC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,mEAAmE,CAC9H,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YACxC,OAAO;gBACL,GAAG,QAAQ;gBACX,gBAAgB,EAAE,sCAAsC,UAAU,UAAU,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB;aAClH,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,GAAqB;QAChC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7B,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,0DAA0D,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,QAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,0CAA0C,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/G,CAAC;QACD,MAAM,IAAI,GAA0E,EAAE,CAAC;QACvF,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC;oBACR,QAAQ,EAAE,QAAQ,CAAC,UAAU;oBAC7B,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,GAAG,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAClE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,kBAAkB,CACvB,GAAG,CAAC,WAAW,EACf,wBAAwB,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,sCAAsC;gBACzF,mEAAmE,CACtE,CAAC;QACJ,CAAC;QACD,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;QACjG,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,6EAA6E,CAAC,CAAC;QAC5H,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,gEAAgE,CAAC,CAAC;QAC/G,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;YACpG,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,yEAAyE,CAAC,CAAC;QACxH,CAAC;QACD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,IAAI;YAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9G,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACrC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvB,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,MAAM,GACV,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ;gBAC3B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS;oBAC9B,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,QAAQ,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC;gBACZ,UAAU,EAAE,GAAG,CAAC,QAAQ;gBACxB,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,MAAM;gBACN,OAAO;gBACP,eAAe,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO;aACvF,CAAC,CAAC;QACL,CAAC;QACD,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzD,IAAI,UAAU,KAAK,IAAI;YAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;QACjG,kEAAkE;QAClE,gEAAgE;QAChE,8DAA8D;QAC9D,qEAAqE;QACrE,MAAM,cAAc,GAAwB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,OAAO,CAAC;YACzG,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,QAAQ,CAAC;QACb,OAAO;YACL,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,IAAI;YACd,QAAQ;YACR,cAAc;YACd,GAAG,CAAC,eAAe;gBACjB,CAAC,CAAC;oBACE,eAAe,EAAE,IAAI;oBACrB,aAAa,EACX,wGAAwG;iBAC3G;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW,CAAC,GAAqB;QAC/B,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,uEAAuE;IAC/D,QAAQ,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC,GAAG,GAAG,iBAAiB,CAAC,CAAC;QAC1E,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IACzF,CAAC;CACF;AAED,iEAAiE;AACjE,SAAS,mBAAmB,CAAC,SAA8B;IACzD,MAAM,UAAU,GAAG,GAAG,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxE,OAAO;QACL,UAAU;QACV,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,mBAAmB,EAAE,EAAE;QACvB,wEAAwE;QACxE,WAAW,EAAE,SAAS,CAAC,MAAM;KAC9B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,QAAuB;IAC9C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;IACnF,IAAI,MAAM,KAAK,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACnG,MAAM,SAAS,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACtF,MAAM,SAAS,GAAG,CAAC,GAAG,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC3E,CAAC;AAED,uEAAuE;AACvE,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,EAAE,IAAI,SAAS,KAAK,EAAE,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,GAAG,IAAI,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,wEAAwE;AACxE,SAAS,kBAAkB,CAAC,WAA0B,EAAE,MAAc;IACpE,OAAO;QACL,WAAW;QACX,QAAQ,EAAE,KAAK;QACf,gBAAgB,EAAE,MAAM;QACxB,QAAQ,EAAE,EAAE;QACZ,cAAc,EAAE,SAAkB;KACnC,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,SAAS,oBAAoB,CAAC,IAAmB;IAC/C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,kDAAkD,CAAC;IAC7E,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,oEAAoE,CAAC;IAC5F,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,4BAA4B,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC;IACjH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mDAAmD;AACnD,SAAS,YAAY,CAAC,CAAqB,EAAE,CAAqB;IAChE,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,sDAAsD;AACtD,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -37,9 +37,35 @@ export interface NativeListResult {
|
|
|
37
37
|
instances: NativeInstance[];
|
|
38
38
|
/** Reporter errors from the JSON document (data, not a throw). */
|
|
39
39
|
errors: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Project name → the names it depends on, as the RUNNER resolved them
|
|
42
|
+
* (see {@link projectGraphReporterEntry}). Absent when the enumeration
|
|
43
|
+
* could not read the graph — never guessed, and never a partial graph
|
|
44
|
+
* treated as a complete one.
|
|
45
|
+
*/
|
|
46
|
+
projectDependencies?: Record<string, string[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Project name → the `use.storageState` STRING the runner resolved for
|
|
49
|
+
* it (the standard auth pattern's declared state file). Absent when no
|
|
50
|
+
* project declares one, and absent together with
|
|
51
|
+
* {@link projectDependencies} whenever the graph itself was unreadable.
|
|
52
|
+
*/
|
|
53
|
+
projectStorageStates?: Record<string, string>;
|
|
40
54
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the engine-owned project-graph reporter entry.
|
|
57
|
+
*
|
|
58
|
+
* Absolute and pack-relative for the same reason the trusted reporter
|
|
59
|
+
* entry is: the enumeration child must load an ENGINE file by absolute
|
|
60
|
+
* path, never a candidate-relative one. Resolution works from both the
|
|
61
|
+
* `src/` and `dist/` layouts.
|
|
62
|
+
*
|
|
63
|
+
* @param fromModule: module URL to resolve the pack from (default: this file).
|
|
64
|
+
*
|
|
65
|
+
* @returns
|
|
66
|
+
* string: absolute `<pack>/dist/reporter/project-graph-reporter.js`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function projectGraphReporterEntry(fromModule?: string): string;
|
|
43
69
|
/**
|
|
44
70
|
* Strips every `GATEFORGE_*` variable from the environment for UNTRUSTED
|
|
45
71
|
* child runs, then adds only a caller-owned temporary state directory.
|
|
@@ -55,18 +81,44 @@ export declare function localPlaywrightCliCandidates(cwd: string): string[];
|
|
|
55
81
|
*/
|
|
56
82
|
export declare function untrustedEnv(env: NodeJS.ProcessEnv, discoveryStateDir?: string): NodeJS.ProcessEnv;
|
|
57
83
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
84
|
+
* Enumerates EVERY playwright config the search space contains, in the
|
|
85
|
+
* order the choice is made: repo-root configs first (in
|
|
86
|
+
* {@link PLAYWRIGHT_CONFIG_NAMES} order), then ONE directory level
|
|
87
|
+
* deep (immediate subdirectories, dependency/build/VCS/runner
|
|
88
|
+
* directories pruned, alphabetically).
|
|
89
|
+
*
|
|
90
|
+
* Enumeration runs exactly one config, so a repo with several configs
|
|
91
|
+
* is inventoried as a subset. Listing them all is what lets that
|
|
92
|
+
* narrowing be reported instead of silent — see
|
|
93
|
+
* {@link findPlaywrightConfig}.
|
|
94
|
+
*
|
|
95
|
+
* Args:
|
|
96
|
+
* cwd: absolute repo root.
|
|
97
|
+
*
|
|
98
|
+
* Returns:
|
|
99
|
+
* string[]: repo-relative posix config paths, in choice order.
|
|
100
|
+
*/
|
|
101
|
+
export declare function findPlaywrightConfigs(cwd: string): string[];
|
|
102
|
+
/**
|
|
103
|
+
* Finds the ONE consumer playwright config enumeration runs: at the
|
|
104
|
+
* repo root first, then — only when no root-level config exists — ONE
|
|
105
|
+
* directory level deep (see {@link findPlaywrightConfigs}). Returns
|
|
106
|
+
* the repo-relative posix path (`'playwright.config.ts'`, or
|
|
107
|
+
* `'e2e/playwright.config.ts'` for a subdirectory project), or null
|
|
108
|
+
* when none exists.
|
|
64
109
|
*
|
|
65
110
|
* Root-level configs always win: an existing root project must keep its
|
|
66
111
|
* exact historical invocation. The nested search only extends discovery
|
|
67
112
|
* to the self-contained subdirectory layout (the config's OWN directory
|
|
68
113
|
* pins its playwright install — see {@link playwrightCliPath}).
|
|
69
114
|
*
|
|
115
|
+
* The choice is never silent: when more than one config exists,
|
|
116
|
+
* {@link listNativePlaywrightTests} names every discovered config, the
|
|
117
|
+
* one used and why, and the ones NOT inventoried. There is deliberately
|
|
118
|
+
* no configuration key for the choice: any such key would change WHICH
|
|
119
|
+
* consumer code runs, not just what is reported, and it would have to
|
|
120
|
+
* be plumbed through the discovery callers' option sets.
|
|
121
|
+
*
|
|
70
122
|
* Args:
|
|
71
123
|
* cwd: absolute repo root.
|
|
72
124
|
*
|
|
@@ -89,8 +141,8 @@ export declare function findPlaywrightConfig(cwd: string): string | null;
|
|
|
89
141
|
* invocation (repo-root cwd, auto-discovered config, no `--config`).
|
|
90
142
|
*
|
|
91
143
|
* Args:
|
|
92
|
-
* options: `cwd` (absolute repo root)
|
|
93
|
-
*
|
|
144
|
+
* options: `cwd` (absolute repo root), optional `timeoutMs`, and
|
|
145
|
+
* optional allowlisted wired-runner variables for registration comparison.
|
|
94
146
|
*
|
|
95
147
|
* Returns:
|
|
96
148
|
* Promise<NativeListResult>: enumerated instances, reporter errors,
|
|
@@ -98,12 +150,29 @@ export declare function findPlaywrightConfig(cwd: string): string | null;
|
|
|
98
150
|
*
|
|
99
151
|
* Throws:
|
|
100
152
|
* TestDiscoveryError: when the child cannot spawn, exceeds the
|
|
101
|
-
* timeout, or
|
|
153
|
+
* timeout, or produced no readable reporter JSON (the report is read
|
|
154
|
+
* from the reporter's own output file, never from stdout).
|
|
102
155
|
*/
|
|
103
156
|
export declare function listNativePlaywrightTests(options: {
|
|
104
157
|
cwd: string;
|
|
105
158
|
timeoutMs?: number;
|
|
159
|
+
wiredEnv?: Readonly<Record<string, string>>;
|
|
106
160
|
}): Promise<NativeListResult>;
|
|
161
|
+
/**
|
|
162
|
+
* Finds registration instances present in only one environment's native
|
|
163
|
+
* Playwright listing, treating project and duplicate instances as identity.
|
|
164
|
+
*
|
|
165
|
+
* Args:
|
|
166
|
+
* scrubbed: native instances enumerated without run wiring.
|
|
167
|
+
* wired: native instances enumerated with the runner's safe run variables.
|
|
168
|
+
*
|
|
169
|
+
* Returns:
|
|
170
|
+
* An object containing project-qualified instances unique to each listing.
|
|
171
|
+
*/
|
|
172
|
+
export declare function diffNativePlaywrightTests(scrubbed: readonly NativeInstance[], wired: readonly NativeInstance[]): {
|
|
173
|
+
scrubbedOnly: NativeInstance[];
|
|
174
|
+
wiredOnly: NativeInstance[];
|
|
175
|
+
};
|
|
107
176
|
/** Matching key for reconciliation: file + full title path (no project). */
|
|
108
177
|
export declare function reconciliationKey(file: string, titlePath: readonly string[]): string;
|
|
109
178
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/discovery/reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/discovery/reconcile.ts"],"names":[],"mappings":"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"}
|