@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.
Files changed (140) hide show
  1. package/LICENSE +202 -0
  2. package/bin/gateforge-witness.js +40 -0
  3. package/dist/attestation/proxy.d.ts +40 -0
  4. package/dist/attestation/proxy.d.ts.map +1 -0
  5. package/dist/attestation/proxy.js +78 -0
  6. package/dist/attestation/proxy.js.map +1 -0
  7. package/dist/constants.d.ts +130 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +138 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/discovery/adapters.d.ts +167 -0
  12. package/dist/discovery/adapters.d.ts.map +1 -0
  13. package/dist/discovery/adapters.js +276 -0
  14. package/dist/discovery/adapters.js.map +1 -0
  15. package/dist/discovery/discover.d.ts +57 -0
  16. package/dist/discovery/discover.d.ts.map +1 -0
  17. package/dist/discovery/discover.js +544 -0
  18. package/dist/discovery/discover.js.map +1 -0
  19. package/dist/discovery/index.d.ts +15 -0
  20. package/dist/discovery/index.d.ts.map +1 -0
  21. package/dist/discovery/index.js +15 -0
  22. package/dist/discovery/index.js.map +1 -0
  23. package/dist/discovery/inference.d.ts +63 -0
  24. package/dist/discovery/inference.d.ts.map +1 -0
  25. package/dist/discovery/inference.js +173 -0
  26. package/dist/discovery/inference.js.map +1 -0
  27. package/dist/discovery/pytest-adapter.d.ts +205 -0
  28. package/dist/discovery/pytest-adapter.d.ts.map +1 -0
  29. package/dist/discovery/pytest-adapter.js +548 -0
  30. package/dist/discovery/pytest-adapter.js.map +1 -0
  31. package/dist/discovery/reconcile.d.ts +106 -0
  32. package/dist/discovery/reconcile.d.ts.map +1 -0
  33. package/dist/discovery/reconcile.js +268 -0
  34. package/dist/discovery/reconcile.js.map +1 -0
  35. package/dist/discovery/runner-env.d.ts +80 -0
  36. package/dist/discovery/runner-env.d.ts.map +1 -0
  37. package/dist/discovery/runner-env.js +139 -0
  38. package/dist/discovery/runner-env.js.map +1 -0
  39. package/dist/discovery/static-discovery.d.ts +121 -0
  40. package/dist/discovery/static-discovery.d.ts.map +1 -0
  41. package/dist/discovery/static-discovery.js +1028 -0
  42. package/dist/discovery/static-discovery.js.map +1 -0
  43. package/dist/discovery/supervised-run.d.ts +110 -0
  44. package/dist/discovery/supervised-run.d.ts.map +1 -0
  45. package/dist/discovery/supervised-run.js +328 -0
  46. package/dist/discovery/supervised-run.js.map +1 -0
  47. package/dist/discovery/trusted-config.d.ts +103 -0
  48. package/dist/discovery/trusted-config.d.ts.map +1 -0
  49. package/dist/discovery/trusted-config.js +117 -0
  50. package/dist/discovery/trusted-config.js.map +1 -0
  51. package/dist/fixture/evidence.d.ts +191 -0
  52. package/dist/fixture/evidence.d.ts.map +1 -0
  53. package/dist/fixture/evidence.js +366 -0
  54. package/dist/fixture/evidence.js.map +1 -0
  55. package/dist/fixture/fixture.d.ts +37 -0
  56. package/dist/fixture/fixture.d.ts.map +1 -0
  57. package/dist/fixture/fixture.js +38 -0
  58. package/dist/fixture/fixture.js.map +1 -0
  59. package/dist/fixture/witness-client.d.ts +164 -0
  60. package/dist/fixture/witness-client.d.ts.map +1 -0
  61. package/dist/fixture/witness-client.js +253 -0
  62. package/dist/fixture/witness-client.js.map +1 -0
  63. package/dist/index.d.ts +64 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +55 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/json.d.ts +16 -0
  68. package/dist/json.d.ts.map +1 -0
  69. package/dist/json.js +21 -0
  70. package/dist/json.js.map +1 -0
  71. package/dist/reporter/ledger.d.ts +105 -0
  72. package/dist/reporter/ledger.d.ts.map +1 -0
  73. package/dist/reporter/ledger.js +197 -0
  74. package/dist/reporter/ledger.js.map +1 -0
  75. package/dist/reporter/reporter.cjs +105 -0
  76. package/dist/reporter/reporter.cjs.map +1 -0
  77. package/dist/reporter/reporter.d.cts +35 -0
  78. package/dist/reporter/reporter.d.cts.map +1 -0
  79. package/dist/reporter/reporter.d.ts +167 -0
  80. package/dist/reporter/reporter.d.ts.map +1 -0
  81. package/dist/reporter/reporter.js +673 -0
  82. package/dist/reporter/reporter.js.map +1 -0
  83. package/dist/setup.d.ts +49 -0
  84. package/dist/setup.d.ts.map +1 -0
  85. package/dist/setup.js +167 -0
  86. package/dist/setup.js.map +1 -0
  87. package/dist/supervisor/client.d.ts +73 -0
  88. package/dist/supervisor/client.d.ts.map +1 -0
  89. package/dist/supervisor/client.js +164 -0
  90. package/dist/supervisor/client.js.map +1 -0
  91. package/dist/supervisor/drain.d.ts +45 -0
  92. package/dist/supervisor/drain.d.ts.map +1 -0
  93. package/dist/supervisor/drain.js +235 -0
  94. package/dist/supervisor/drain.js.map +1 -0
  95. package/dist/supervisor/index.d.ts +16 -0
  96. package/dist/supervisor/index.d.ts.map +1 -0
  97. package/dist/supervisor/index.js +13 -0
  98. package/dist/supervisor/index.js.map +1 -0
  99. package/dist/supervisor/spool.d.ts +137 -0
  100. package/dist/supervisor/spool.d.ts.map +1 -0
  101. package/dist/supervisor/spool.js +263 -0
  102. package/dist/supervisor/spool.js.map +1 -0
  103. package/dist/surface.d.ts +134 -0
  104. package/dist/surface.d.ts.map +1 -0
  105. package/dist/surface.js +139 -0
  106. package/dist/surface.js.map +1 -0
  107. package/dist/witness/adapter-registry.d.ts +38 -0
  108. package/dist/witness/adapter-registry.d.ts.map +1 -0
  109. package/dist/witness/adapter-registry.js +158 -0
  110. package/dist/witness/adapter-registry.js.map +1 -0
  111. package/dist/witness/bin.d.ts +21 -0
  112. package/dist/witness/bin.d.ts.map +1 -0
  113. package/dist/witness/bin.js +172 -0
  114. package/dist/witness/bin.js.map +1 -0
  115. package/dist/witness/browser.d.ts +173 -0
  116. package/dist/witness/browser.d.ts.map +1 -0
  117. package/dist/witness/browser.js +580 -0
  118. package/dist/witness/browser.js.map +1 -0
  119. package/dist/witness/classifications.d.ts +42 -0
  120. package/dist/witness/classifications.d.ts.map +1 -0
  121. package/dist/witness/classifications.js +87 -0
  122. package/dist/witness/classifications.js.map +1 -0
  123. package/dist/witness/env-attestation.d.ts +98 -0
  124. package/dist/witness/env-attestation.d.ts.map +1 -0
  125. package/dist/witness/env-attestation.js +202 -0
  126. package/dist/witness/env-attestation.js.map +1 -0
  127. package/dist/witness/loopback-pins.d.ts +79 -0
  128. package/dist/witness/loopback-pins.d.ts.map +1 -0
  129. package/dist/witness/loopback-pins.js +244 -0
  130. package/dist/witness/loopback-pins.js.map +1 -0
  131. package/dist/witness/server.d.ts +34 -0
  132. package/dist/witness/server.d.ts.map +1 -0
  133. package/dist/witness/server.js +2539 -0
  134. package/dist/witness/server.js.map +1 -0
  135. package/dist/witness/types.d.ts +643 -0
  136. package/dist/witness/types.d.ts.map +1 -0
  137. package/dist/witness/types.js +2 -0
  138. package/dist/witness/types.js.map +1 -0
  139. package/package.json +64 -0
  140. package/python/gateforge_persistence_intents.py +100 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Kind/category inference rules (plan 2026-09-13 phase 2 item 5): pure
3
+ * functions over the facts a static scan collected. Every rule returns
4
+ * its id plus the source location that fired it — no opaque confidence
5
+ * scores, and no rule is allowed to silently become proof:
6
+ *
7
+ * - Strong kind rules (fixtures, request contexts, HTTP-client calls,
8
+ * network-less bodies) propose a {@link TestKind}.
9
+ * - Agreeing proposals decide the kind; conflicting or absent proposals
10
+ * resolve to `unknown` (visible, never promoted).
11
+ * - Title/folder keyword matches are WEAK signals only — recorded, but
12
+ * never kind-deciding (§3.2: "a unit test named 'creates account' is
13
+ * still a unit test").
14
+ * - Known mock patterns (`page.route`, `vi.mock`/`jest.mock`) become
15
+ * suppression signals; they can disqualify later proof but do not
16
+ * classify the test by themselves.
17
+ */
18
+ import type { CategorySignal, KindSignal, RuleEvidence, SuppressionSignal, TestKind, WeakSignal } from '@gate-forge/core';
19
+ import type { StaticTestFacts } from './static-discovery.js';
20
+ /** Signature parameter names that prove a real API context is in play. */
21
+ export declare const API_FIXTURE_PARAMS: readonly string[];
22
+ /** The facts inference consumes (file-level facts shared by the scan). */
23
+ export interface InferenceFacts {
24
+ /** Repo-relative file (weak path hints). */
25
+ file: string;
26
+ /** Test title (weak title hints, category keywords). */
27
+ title: string;
28
+ /** Full title path (weak title hints). */
29
+ titlePath: readonly string[];
30
+ /** The static facts of the call: fixtures + body/file patterns. */
31
+ facts: StaticTestFacts;
32
+ }
33
+ /** What inference concluded for one test. */
34
+ export interface InferenceResult {
35
+ /** The concluded kind (`unknown` when nothing or a conflict). */
36
+ inferredKind: TestKind;
37
+ /** Strong kind rules that fired (kind + code evidence). */
38
+ kindSignals: KindSignal[];
39
+ /** Weak title/folder hints (never kind-deciding). */
40
+ weakSignals: WeakSignal[];
41
+ /** EVERY rule that fired, in stable rule-id order. */
42
+ rulesFired: RuleEvidence[];
43
+ /** Behavior-category hints (labels only). */
44
+ categorySignals: CategorySignal[];
45
+ /** Mock-pattern suppression signals observed for this test. */
46
+ mockSignals: SuppressionSignal[];
47
+ }
48
+ /**
49
+ * Runs every rule over one test's facts and resolves the kind.
50
+ *
51
+ * Combination rule: distinct PROPOSED kinds are computed first — exactly
52
+ * one distinct kind decides; zero or more-than-one resolve to
53
+ * `unknown` (recorded, visible, never silently promoted).
54
+ *
55
+ * Args:
56
+ * input: the test's file/title/facts bundle.
57
+ *
58
+ * Returns:
59
+ * InferenceResult: kind, all fired rules with evidence locations,
60
+ * weak signals, category hints, and mock signals.
61
+ */
62
+ export declare function inferTestKind(input: InferenceFacts): InferenceResult;
63
+ //# sourceMappingURL=inference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference.d.ts","sourceRoot":"","sources":["../../src/discovery/inference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EAEV,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAAgB,CAAC;AAEjE,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,mEAAmE;IACnE,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,YAAY,EAAE,QAAQ,CAAC;IACvB,2DAA2D;IAC3D,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,qDAAqD;IACrD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,6CAA6C;IAC7C,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,+DAA+D;IAC/D,WAAW,EAAE,iBAAiB,EAAE,CAAC;CAClC;AA+ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAqEpE"}
@@ -0,0 +1,173 @@
1
+ import { BROWSER_FIXTURE_PARAMS } from './static-discovery.js';
2
+ /** Signature parameter names that prove a real API context is in play. */
3
+ export const API_FIXTURE_PARAMS = ['request'];
4
+ /** Rules that propose a kind, strongest-first, with their evidence. */
5
+ const KIND_RULES = [
6
+ {
7
+ ruleId: 'browser-fixture',
8
+ kind: 'browser-e2e',
9
+ applies: (input) => {
10
+ const browserParams = input.facts.signatureParams.filter((name) => BROWSER_FIXTURE_PARAMS.has(name));
11
+ if (browserParams.length === 0)
12
+ return null;
13
+ return {
14
+ evidence: `test signature declares browser fixture(s): ${browserParams.join(', ')}`,
15
+ };
16
+ },
17
+ },
18
+ {
19
+ ruleId: 'api-request-fixture',
20
+ kind: 'api-e2e',
21
+ applies: (input) => {
22
+ const apiParams = input.facts.signatureParams.filter((name) => API_FIXTURE_PARAMS.includes(name));
23
+ if (apiParams.length === 0)
24
+ return null;
25
+ return { evidence: `test signature declares API fixture(s): ${apiParams.join(', ')}` };
26
+ },
27
+ },
28
+ {
29
+ ruleId: 'http-client-call',
30
+ kind: 'api-e2e',
31
+ applies: (input) => {
32
+ const where = input.facts.httpClientCall ?? input.facts.fileHttpClientCall;
33
+ if (where === null)
34
+ return null;
35
+ return {
36
+ evidence: `HTTP client call at ${where.file}:${String(where.line)} reaches the application boundary`,
37
+ };
38
+ },
39
+ },
40
+ {
41
+ // Network-less pure-function probe: no fixtures at all and no
42
+ // app-boundary (HTTP) call anywhere in the file → unit hint.
43
+ ruleId: 'networkless-unit',
44
+ kind: 'unit',
45
+ applies: (input) => {
46
+ if (input.facts.signatureParams.length > 0)
47
+ return null;
48
+ if (input.facts.pageRoute !== null)
49
+ return null;
50
+ if (input.facts.httpClientCall !== null || input.facts.fileHttpClientCall !== null)
51
+ return null;
52
+ return { evidence: 'no fixtures and no application-boundary call: a network-less function probe' };
53
+ },
54
+ },
55
+ ];
56
+ /** Weak keyword hints per title/path token. Never kind-deciding. */
57
+ const TITLE_KEYWORD_RULES = [
58
+ { token: 'e2e', hint: 'title mentions e2e (weak)' },
59
+ { token: 'integration', hint: 'title mentions integration (weak)' },
60
+ { token: 'unit', hint: 'title mentions unit (weak)' },
61
+ ];
62
+ /** Path segments treated as weak hints. */
63
+ const PATH_KEYWORD_RULES = [
64
+ { token: 'e2e', hint: 'path segment mentions e2e (weak)' },
65
+ { token: 'integration', hint: 'path segment mentions integration (weak)' },
66
+ { token: 'unit', hint: 'path segment mentions unit (weak)' },
67
+ ];
68
+ /** Category keyword → dotted label (hints only, never proof). */
69
+ const CATEGORY_KEYWORDS = [
70
+ { pattern: /\bcreat|\badd/i, label: 'persistence.create' },
71
+ { pattern: /\bupdate|\bedit/i, label: 'persistence.update' },
72
+ { pattern: /\bdelet|\bremov|\bdestroy/i, label: 'persistence.delete' },
73
+ { pattern: /\bread|\bshow|\bview|\blist|\bdisplay/i, label: 'persistence.read' },
74
+ { pattern: /\blogin|\blogout|\bauth|\bsign[ -]?(in|up)/i, label: 'authentication' },
75
+ { pattern: /\bvalid|\binvalid/i, label: 'validation' },
76
+ { pattern: /\bnavigat|\bredirect/i, label: 'navigation' },
77
+ { pattern: /\bworkflow|\bjourney/i, label: 'workflow' },
78
+ ];
79
+ /**
80
+ * Runs every rule over one test's facts and resolves the kind.
81
+ *
82
+ * Combination rule: distinct PROPOSED kinds are computed first — exactly
83
+ * one distinct kind decides; zero or more-than-one resolve to
84
+ * `unknown` (recorded, visible, never silently promoted).
85
+ *
86
+ * Args:
87
+ * input: the test's file/title/facts bundle.
88
+ *
89
+ * Returns:
90
+ * InferenceResult: kind, all fired rules with evidence locations,
91
+ * weak signals, category hints, and mock signals.
92
+ */
93
+ export function inferTestKind(input) {
94
+ const kindSignals = [];
95
+ const rulesFired = [];
96
+ const weakSignals = [];
97
+ const categorySignals = [];
98
+ const mockSignals = [];
99
+ for (const rule of KIND_RULES) {
100
+ const outcome = rule.applies(input);
101
+ if (outcome === null)
102
+ continue;
103
+ // The evidence location: prefer the exact body location when the
104
+ // rule observed one, else the first fixture param is located at the
105
+ // call (unknown here) — inference callers pass call-level facts, so
106
+ // the evidence points at what the rule saw.
107
+ rulesFired.push({ ruleId: rule.ruleId, evidence: outcome.evidence, location: evidenceLocation(rule.ruleId, input) });
108
+ kindSignals.push({ ruleId: rule.ruleId, kind: rule.kind, evidence: outcome.evidence, location: evidenceLocation(rule.ruleId, input) });
109
+ }
110
+ for (const rule of TITLE_KEYWORD_RULES) {
111
+ const haystack = [...input.titlePath, input.title].join(' ').toLowerCase();
112
+ if (haystack.includes(rule.token)) {
113
+ weakSignals.push({ ruleId: 'title-keywords', evidence: rule.hint, location: weakLocation(input) });
114
+ rulesFired.push({ ruleId: 'title-keywords', evidence: rule.hint, location: weakLocation(input) });
115
+ break; // one title hint is enough; keep the trace small
116
+ }
117
+ }
118
+ for (const rule of PATH_KEYWORD_RULES) {
119
+ const segments = input.file.toLowerCase().split('/');
120
+ if (segments.includes(rule.token)) {
121
+ weakSignals.push({ ruleId: 'path-keywords', evidence: rule.hint, location: weakLocation(input) });
122
+ rulesFired.push({ ruleId: 'path-keywords', evidence: rule.hint, location: weakLocation(input) });
123
+ break;
124
+ }
125
+ }
126
+ if (input.facts.pageRoute !== null) {
127
+ mockSignals.push({
128
+ kind: 'mock',
129
+ detail: 'page.route interception inside the test body',
130
+ location: input.facts.pageRoute,
131
+ });
132
+ rulesFired.push({ ruleId: 'mock-page-route', evidence: 'page.route call intercepts network', location: input.facts.pageRoute });
133
+ }
134
+ if (input.facts.fileMockImport !== null) {
135
+ mockSignals.push({
136
+ kind: 'mock',
137
+ detail: 'vi.mock/jest.mock module mock in the test file',
138
+ location: input.facts.fileMockImport,
139
+ });
140
+ rulesFired.push({ ruleId: 'mock-module-import', evidence: 'module-level mock call', location: input.facts.fileMockImport });
141
+ }
142
+ for (const rule of CATEGORY_KEYWORDS) {
143
+ if (rule.pattern.test(input.title)) {
144
+ categorySignals.push({ label: rule.label, ruleId: 'category-keywords', location: weakLocation(input) });
145
+ }
146
+ }
147
+ const distinct = [...new Set(kindSignals.map((signal) => signal.kind))];
148
+ const inferredKind = distinct.length === 1 ? distinct[0] : 'unknown';
149
+ if (distinct.length > 1) {
150
+ rulesFired.push({
151
+ ruleId: 'kind-conflict',
152
+ evidence: `rules propose conflicting kinds (${distinct.sort().join(', ')}): resolved to unknown`,
153
+ location: weakLocation(input),
154
+ });
155
+ }
156
+ return { inferredKind, kindSignals, weakSignals, rulesFired, categorySignals, mockSignals };
157
+ }
158
+ /** The location a strong rule's evidence points at. */
159
+ function evidenceLocation(ruleId, input) {
160
+ if (ruleId === 'http-client-call') {
161
+ return input.facts.httpClientCall ?? input.facts.fileHttpClientCall ?? { file: input.file, line: 1, col: 0 };
162
+ }
163
+ if (ruleId === 'mock-page-route')
164
+ return input.facts.pageRoute ?? { file: input.file, line: 1, col: 0 };
165
+ // Fixture/unit rules have no sharper location than the file itself at
166
+ // line 1 — the catalog row carries the exact call location separately.
167
+ return { file: input.file, line: 1, col: 0 };
168
+ }
169
+ /** Stable placeholder location for file-level weak signals. */
170
+ function weakLocation(input) {
171
+ return { file: input.file, line: 1, col: 0 };
172
+ }
173
+ //# sourceMappingURL=inference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference.js","sourceRoot":"","sources":["../../src/discovery/inference.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ import type { DiagnosticSuite } from '@gate-forge/core';
2
+ import { TestDiscoveryError } from './reconcile.js';
3
+ /** One collected pytest case, identity preserved (§3.5). */
4
+ export interface PytestCollectedCase {
5
+ /** The exact pytest node id, parameters included. */
6
+ nodeId: string;
7
+ /** File part of the node id (posix, suite-cwd-relative). */
8
+ file: string;
9
+ /** Class/test segments after the file part. */
10
+ titlePath: string[];
11
+ }
12
+ /** Outcome of one collection run. */
13
+ export interface PytestCollectionResult {
14
+ status: 'discovered' | 'unavailable';
15
+ /** Single-cause detail (errors verbatim, bounded). */
16
+ detail: string;
17
+ cases: PytestCollectedCase[];
18
+ /** Node ids pytest reported as collection errors, if any. */
19
+ collectionErrors: string[];
20
+ exitCode: number | null;
21
+ }
22
+ /**
23
+ * Composes the collection argv for a configured suite: the configured
24
+ * interpreter/args verbatim, then `--collect-only -q`, then the
25
+ * configured testPaths. Nothing else — no directory guessing, no extra
26
+ * commands beyond the configured argv + collection flags.
27
+ *
28
+ * Args:
29
+ * suite: the configured diagnostic suite.
30
+ *
31
+ * Returns:
32
+ * string[]: argv to spawn with cwd = repo root (the adapter passes the
33
+ * suite's own testPaths, which are repo-root-relative and resolved by
34
+ * the caller's cwd choice).
35
+ */
36
+ export declare function pytestCollectArgv(suite: DiagnosticSuite): string[];
37
+ /**
38
+ * Composes the Phase 4 diagnostic EXECUTION argv (junit XML into the
39
+ * EXCLUDED run-state dir). Exported now so the composition is tested;
40
+ * invoking it is Phase 4 work.
41
+ *
42
+ * Args:
43
+ * suite: the configured diagnostic suite.
44
+ * stateDir: absolute run-state directory (excluded from inputs).
45
+ *
46
+ * Returns:
47
+ * string[]: argv running the suite with a junitxml report at
48
+ * `<stateDir>/diagnostics/<suite.name>.xml`.
49
+ */
50
+ export declare function pytestExecutionArgv(suite: DiagnosticSuite, stateDir: string): string[];
51
+ /**
52
+ * Runs one bounded collection for a configured suite. The child runs as
53
+ * UNTRUSTED consumer code (all `GATEFORGE_*` env stripped — same trust
54
+ * boundary as playwright enumeration) with the suite's finite timeout.
55
+ *
56
+ * Args:
57
+ * suite: the configured suite (argv, testPaths, timeoutMs).
58
+ * cwd: absolute repo root the repo-relative testPaths resolve against.
59
+ *
60
+ * Returns:
61
+ * Promise<PytestCollectionResult>: collected node ids or an
62
+ * unavailable verdict — collection failure is data (§3.5: show
63
+ * incomplete status), never a fabricated empty success.
64
+ */
65
+ export declare function collectPytestSuite(suite: DiagnosticSuite, cwd: string): Promise<PytestCollectionResult>;
66
+ /** One parsed junit-XML testcase (pytest diagnostics surface). */
67
+ export interface JunitTestCase {
68
+ /** Classname (module path as pytest emitted it). */
69
+ classname: string;
70
+ /** Test name incl. parameters, e.g. `test_x[param-2]`. */
71
+ name: string;
72
+ /** passed | failed | error | skipped. */
73
+ outcome: 'passed' | 'failed' | 'error' | 'skipped';
74
+ /** The skip/xfail type attribute when skipped, e.g. `pytest.xfail`. */
75
+ skipType?: string;
76
+ /** First line of failure/error/skip message, when present. */
77
+ message?: string;
78
+ /** The file attribute pytest emits when present (node-id reconstruction). */
79
+ file?: string;
80
+ }
81
+ /** Parsed junit-XML document (one testsuite). */
82
+ export interface JunitDocument {
83
+ suiteName: string;
84
+ tests: number;
85
+ failures: number;
86
+ errors: number;
87
+ skipped: number;
88
+ cases: JunitTestCase[];
89
+ }
90
+ /** Typed parser failure for malformed junit XML (fail closed). */
91
+ export declare class JunitParseError extends Error {
92
+ constructor(message: string);
93
+ }
94
+ /**
95
+ * Parses a pytest junit-XML document into structured outcomes (plan
96
+ * phase 2 item 8: prefer structured results over parsing terminal
97
+ * colors). Bounded and strict: the parser understands the exact subset
98
+ * pytest emits (`<testsuite>` with `<testcase>` children carrying
99
+ * `<failure>`, `<error>`, or `<skipped type="...">` children) and THROWS
100
+ * (`JunitParseError`) on anything else — a malformed report is never
101
+ * silently read as a green run. xfail appears as `skipped` with
102
+ * `type="pytest.xfail"`; collection errors appear as testcases named
103
+ * `pytest_collection` with an `<error>` child.
104
+ *
105
+ * Args:
106
+ * xml: the junit-XML document text.
107
+ *
108
+ * Returns:
109
+ * JunitDocument: suite counters + one row per testcase.
110
+ *
111
+ * Throws:
112
+ * JunitParseError: on missing/malformed structure (fail closed).
113
+ */
114
+ export declare function parseJunitXml(xml: string): JunitDocument;
115
+ /**
116
+ * Repo-relative form of `path` against `cwd` (absolute inputs only by
117
+ * contract; relative pass through normalized).
118
+ */
119
+ export declare function repoRelative(cwd: string, path: string): string;
120
+ /** Honest status of one diagnostic suite run (§3.5 — never E2E proof). */
121
+ export type DiagnosticRunStatus =
122
+ /** Completed run, ≥1 passing test, no unexpected failures. */
123
+ 'completed'
124
+ /** Completed run with ≥1 test failure. */
125
+ | 'failures'
126
+ /** Unavailable/incomplete: collection error, timeout, missing
127
+ * interpreter, interruption, zero tests, or only skipped/xfail. */
128
+ | 'incomplete';
129
+ /** Advisory diagnostic cause codes (plan §5.4 — report-only, never verdicts). */
130
+ export type DiagnosticCause = 'DIAGNOSTIC_TEST_FAILURE' | 'DIAGNOSTIC_RUN_INCOMPLETE';
131
+ /** One structured per-suite diagnostic result (plan §5.1 "Diagnostic result"). */
132
+ export interface DiagnosticRunResult {
133
+ /** The configured suite name. */
134
+ suite: string;
135
+ /** Honest status: completed | failures | incomplete. */
136
+ status: DiagnosticRunStatus;
137
+ /** Suite process exit code (pytest exit codes, null on spawn failure). */
138
+ exitCode: number | null;
139
+ /** True when the finite timeout expired and the child was killed. */
140
+ timedOut: boolean;
141
+ /** Spawn failure detail (e.g. missing interpreter), or null. */
142
+ spawnError: string | null;
143
+ /** Collection/setup errors observed (from stderr scan + junit). */
144
+ collectionErrors: string[];
145
+ /** The selected scope (the configured testPaths, verbatim). */
146
+ selectedScope: string[];
147
+ /** Node ids the report covered (file::name, parameters included). */
148
+ nodeIds: string[];
149
+ /** Per-case outcomes from the junit report. */
150
+ cases: Array<{
151
+ nodeId: string;
152
+ outcome: 'passed' | 'failed' | 'error' | 'skipped';
153
+ skipType?: string;
154
+ message?: string;
155
+ /** Failure phase: collection/setup surface as 'error', others 'call'. */
156
+ phase: 'collection' | 'setup' | 'call' | 'teardown' | 'unknown';
157
+ }>;
158
+ /** Explicit counters — skips/xfail never become passes or proof. */
159
+ counts: {
160
+ passed: number;
161
+ failed: number;
162
+ errors: number;
163
+ skipped: number;
164
+ xfailed: number;
165
+ };
166
+ /** True only when the run was bounded and its report parsed. */
167
+ complete: boolean;
168
+ /** Single-cause detail when incomplete. */
169
+ incompleteDetail: string | null;
170
+ /** Advisory causes for this suite (report-only). */
171
+ causes: DiagnosticCause[];
172
+ /** Absolute junit-XML report path (inside the excluded run-state dir). */
173
+ reportPath: string;
174
+ /** Whether the report file exists on disk. */
175
+ reportExists: boolean;
176
+ /** True when the junit report existed but could not be parsed (fail closed). */
177
+ reportUnparsable: boolean;
178
+ }
179
+ /**
180
+ * Executes one configured diagnostic suite ONCE (plan Phase 4 item 9, §3.5):
181
+ * an isolated process (every `GATEFORGE_*` variable stripped), the
182
+ * configured argv + a junit-XML report into the EXCLUDED run-state dir,
183
+ * and a finite timeout. The result is advisory diagnostic data — it is
184
+ * never witness evidence and never satisfies an E2E obligation.
185
+ *
186
+ * Exit semantics (plan §3.5 / pytest exit codes):
187
+ * - `completed`: run finished, ≥1 passed, no unexpected failures;
188
+ * - `failures`: the run finished with test failures;
189
+ * - `incomplete`: collection/setup error, timeout, missing interpreter,
190
+ * interruption, zero tests, or a run of ONLY skipped/xfail cases —
191
+ * never displayed as a passing diagnostic run.
192
+ *
193
+ * Args:
194
+ * suite: the configured suite (argv, testPaths, timeoutMs).
195
+ * repoRoot: absolute repo root (suite.cwd resolves against it).
196
+ * stateDir: absolute run-state directory (excluded from inputs); the
197
+ * junit report lands at `<stateDir>/diagnostics/<suite.name>.xml`.
198
+ *
199
+ * Returns:
200
+ * Promise<DiagnosticRunResult>: the structured diagnostic result.
201
+ */
202
+ export declare function executePytestSuite(suite: DiagnosticSuite, repoRoot: string, stateDir: string): Promise<DiagnosticRunResult>;
203
+ /** Re-export so the adapter module is the single pytest surface. */
204
+ export { TestDiscoveryError };
205
+ //# sourceMappingURL=pytest-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pytest-adapter.d.ts","sourceRoot":"","sources":["../../src/discovery/pytest-adapter.ts"],"names":[],"mappings":"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"}