executable-stories-formatters 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/README.md +205 -0
- package/dist/adapters.cjs +324 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +1 -0
- package/dist/adapters.d.ts +1 -0
- package/dist/adapters.js +295 -0
- package/dist/adapters.js.map +1 -0
- package/dist/cli.js +5399 -0
- package/dist/cli.js.map +1 -0
- package/dist/index-DCJ0NvAp.d.cts +378 -0
- package/dist/index-DCJ0NvAp.d.ts +378 -0
- package/dist/index.cjs +5519 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1468 -0
- package/dist/index.d.ts +1468 -0
- package/dist/index.js +5448 -0
- package/dist/index.js.map +1 -0
- package/package.json +77 -0
- package/schemas/README.md +663 -0
- package/schemas/examples/dotnet.json +108 -0
- package/schemas/examples/full.json +254 -0
- package/schemas/examples/go.json +108 -0
- package/schemas/examples/junit5.json +108 -0
- package/schemas/examples/minimal.json +18 -0
- package/schemas/examples/pytest.json +108 -0
- package/schemas/examples/rust.json +108 -0
- package/schemas/raw-run.schema.json +437 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1468 @@
|
|
|
1
|
+
import { S as StoryMeta, a as StoryStep, D as DocEntry, R as RawStatus, b as RawAttachment, c as RawRun, d as RawCIInfo, e as adaptJestRun, f as adaptPlaywrightRun, g as adaptVitestRun } from './index-DCJ0NvAp.cjs';
|
|
2
|
+
export { h as DocPhase, J as JestAdapterOptions, i as JestAggregatedResult, j as JestFileResult, k as JestTestResult, P as PlaywrightAdapterOptions, l as PlaywrightAnnotation, m as PlaywrightAttachment, n as PlaywrightError, o as PlaywrightLocation, p as PlaywrightStatus, q as PlaywrightTestCase, r as PlaywrightTestResult, s as RawStepEvent, t as RawTestCase, u as STORY_META_KEY, v as StepKeyword, w as StepMode, x as StoryFileReport, V as VitestAdapterOptions, y as VitestSerializedError, z as VitestState, A as VitestTestCase, B as VitestTestModule, C as VitestTestResult } from './index-DCJ0NvAp.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Canonical types for Layer 2: Anti-Corruption Layer output.
|
|
6
|
+
*
|
|
7
|
+
* These types are strict and have all required fields populated.
|
|
8
|
+
* Formatters (Layer 3) accept only these canonical types.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Canonical test status (Cucumber-compatible) */
|
|
12
|
+
type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
13
|
+
/** Step result with status and timing */
|
|
14
|
+
interface StepResult {
|
|
15
|
+
/** Step index (0-based) */
|
|
16
|
+
index: number;
|
|
17
|
+
/** Step status */
|
|
18
|
+
status: TestStatus;
|
|
19
|
+
/** Duration in milliseconds (default 0) */
|
|
20
|
+
durationMs: number;
|
|
21
|
+
/** Error message if step failed */
|
|
22
|
+
errorMessage?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Resolved attachment (always has body) */
|
|
25
|
+
interface Attachment {
|
|
26
|
+
/** Attachment name */
|
|
27
|
+
name: string;
|
|
28
|
+
/** MIME type */
|
|
29
|
+
mediaType: string;
|
|
30
|
+
/** Content (base64-encoded or URL) */
|
|
31
|
+
body: string;
|
|
32
|
+
/** Content encoding */
|
|
33
|
+
contentEncoding: "BASE64" | "IDENTITY";
|
|
34
|
+
}
|
|
35
|
+
/** Single test attempt for retry tracking */
|
|
36
|
+
interface TestCaseAttempt {
|
|
37
|
+
/** Attempt number (0-based) */
|
|
38
|
+
attempt: number;
|
|
39
|
+
/** Status of this attempt */
|
|
40
|
+
status: TestStatus;
|
|
41
|
+
/** Duration of this attempt in milliseconds */
|
|
42
|
+
durationMs: number;
|
|
43
|
+
/** Error message if this attempt failed */
|
|
44
|
+
errorMessage?: string;
|
|
45
|
+
/** Error stack trace if this attempt failed */
|
|
46
|
+
errorStack?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Canonical test case result */
|
|
49
|
+
interface TestCaseResult {
|
|
50
|
+
/** Unique deterministic ID */
|
|
51
|
+
id: string;
|
|
52
|
+
/** Story metadata (required) */
|
|
53
|
+
story: StoryMeta;
|
|
54
|
+
/** Source file path (required) */
|
|
55
|
+
sourceFile: string;
|
|
56
|
+
/** Source line number (required, default 1) */
|
|
57
|
+
sourceLine: number;
|
|
58
|
+
/** Test status (required) */
|
|
59
|
+
status: TestStatus;
|
|
60
|
+
/** Duration in milliseconds (required, default 0) */
|
|
61
|
+
durationMs: number;
|
|
62
|
+
/** Error message if failed */
|
|
63
|
+
errorMessage?: string;
|
|
64
|
+
/** Error stack trace if failed */
|
|
65
|
+
errorStack?: string;
|
|
66
|
+
/** Attachments (required, empty array if none) */
|
|
67
|
+
attachments: Attachment[];
|
|
68
|
+
/** Step results (required, always populated via fallback rules) */
|
|
69
|
+
stepResults: StepResult[];
|
|
70
|
+
/** Full title path from suite/describe blocks (required, empty array if none) */
|
|
71
|
+
titlePath: string[];
|
|
72
|
+
/** Playwright project name (optional) */
|
|
73
|
+
projectName?: string;
|
|
74
|
+
/** Retry attempt number (required, default 0) */
|
|
75
|
+
retry: number;
|
|
76
|
+
/** Total retries configured (required, default 0) */
|
|
77
|
+
retries: number;
|
|
78
|
+
/** Normalized tags from story (required, empty array if none) */
|
|
79
|
+
tags: string[];
|
|
80
|
+
/** All retry attempts (optional, includes details per attempt) */
|
|
81
|
+
attempts?: TestCaseAttempt[];
|
|
82
|
+
}
|
|
83
|
+
/** CI environment info */
|
|
84
|
+
interface CIInfo {
|
|
85
|
+
name: string;
|
|
86
|
+
url?: string;
|
|
87
|
+
buildNumber?: string;
|
|
88
|
+
}
|
|
89
|
+
/** Coverage summary for the test run */
|
|
90
|
+
interface CoverageSummary {
|
|
91
|
+
/** Line coverage percentage (0-100) */
|
|
92
|
+
linesPct?: number;
|
|
93
|
+
/** Branch coverage percentage (0-100) */
|
|
94
|
+
branchesPct?: number;
|
|
95
|
+
/** Function coverage percentage (0-100) */
|
|
96
|
+
functionsPct?: number;
|
|
97
|
+
/** Statement coverage percentage (0-100) */
|
|
98
|
+
statementsPct?: number;
|
|
99
|
+
}
|
|
100
|
+
/** Canonical test run result */
|
|
101
|
+
interface TestRunResult {
|
|
102
|
+
/** All test case results */
|
|
103
|
+
testCases: TestCaseResult[];
|
|
104
|
+
/** Run start time (epoch ms, required) */
|
|
105
|
+
startedAtMs: number;
|
|
106
|
+
/** Run finish time (epoch ms, required) */
|
|
107
|
+
finishedAtMs: number;
|
|
108
|
+
/** Total duration in milliseconds (required) */
|
|
109
|
+
durationMs: number;
|
|
110
|
+
/** Project root directory (required) */
|
|
111
|
+
projectRoot: string;
|
|
112
|
+
/** Unique run ID (required, generated) */
|
|
113
|
+
runId: string;
|
|
114
|
+
/** Package version */
|
|
115
|
+
packageVersion?: string;
|
|
116
|
+
/** Git commit SHA */
|
|
117
|
+
gitSha?: string;
|
|
118
|
+
/** CI environment info */
|
|
119
|
+
ci?: CIInfo;
|
|
120
|
+
/** Coverage summary for the run */
|
|
121
|
+
coverage?: CoverageSummary;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Configuration options for ACL and formatters.
|
|
126
|
+
*/
|
|
127
|
+
/** Options for canonicalizing raw run data */
|
|
128
|
+
interface CanonicalizeOptions {
|
|
129
|
+
/** Attachment handling options */
|
|
130
|
+
attachments?: {
|
|
131
|
+
/** Max bytes before attachment becomes external link. Default: 512KB (524288) */
|
|
132
|
+
maxEmbedBytes?: number;
|
|
133
|
+
/** Directory for external attachments */
|
|
134
|
+
externalDir?: string;
|
|
135
|
+
};
|
|
136
|
+
/** Cucumber compatibility options */
|
|
137
|
+
cucumber?: {
|
|
138
|
+
/** Include trailing space in keywords (e.g., "Given "). Default: true */
|
|
139
|
+
keywordSpacing?: boolean;
|
|
140
|
+
/** Generate deterministic line numbers. Default: true */
|
|
141
|
+
deterministicLines?: boolean;
|
|
142
|
+
};
|
|
143
|
+
/** Default timestamps if not provided in raw data */
|
|
144
|
+
defaults?: {
|
|
145
|
+
/** Default start time (epoch ms). Default: Date.now() */
|
|
146
|
+
startedAtMs?: number;
|
|
147
|
+
/** Default finish time (epoch ms). Default: Date.now() */
|
|
148
|
+
finishedAtMs?: number;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/** Output format for report generation */
|
|
152
|
+
type OutputFormat = "cucumber-json" | "cucumber-messages" | "cucumber-html" | "html" | "junit" | "markdown";
|
|
153
|
+
/** Output mode for report routing */
|
|
154
|
+
type OutputMode = "aggregated" | "colocated";
|
|
155
|
+
/** Colocated output style */
|
|
156
|
+
type ColocatedStyle = "mirrored" | "adjacent";
|
|
157
|
+
/** Output rule for routing reports based on source file patterns */
|
|
158
|
+
interface OutputRule {
|
|
159
|
+
/** Glob pattern to match sourceFile (uses micromatch, forward slashes) */
|
|
160
|
+
match: string;
|
|
161
|
+
/** Output mode for matched files */
|
|
162
|
+
mode?: OutputMode;
|
|
163
|
+
/** Colocated style (only applicable when mode is "colocated") */
|
|
164
|
+
colocatedStyle?: ColocatedStyle;
|
|
165
|
+
/** Output directory override */
|
|
166
|
+
outputDir?: string;
|
|
167
|
+
/** Output filename override (without extension) */
|
|
168
|
+
outputName?: string;
|
|
169
|
+
/** Formats to generate for matched files */
|
|
170
|
+
formats?: OutputFormat[];
|
|
171
|
+
}
|
|
172
|
+
/** Output configuration for report routing */
|
|
173
|
+
interface OutputConfig {
|
|
174
|
+
/** Default output mode. Default: "aggregated" */
|
|
175
|
+
mode?: OutputMode;
|
|
176
|
+
/** Default colocated style. Default: "mirrored" */
|
|
177
|
+
colocatedStyle?: ColocatedStyle;
|
|
178
|
+
/** Rules for routing reports based on source file patterns */
|
|
179
|
+
rules?: OutputRule[];
|
|
180
|
+
/** Default output filename (without extension) */
|
|
181
|
+
outputName?: string;
|
|
182
|
+
}
|
|
183
|
+
/** Logger interface for dependency injection */
|
|
184
|
+
interface Logger {
|
|
185
|
+
warn(msg: string): void;
|
|
186
|
+
}
|
|
187
|
+
/** File writer function type for dependency injection */
|
|
188
|
+
type WriteFile = (path: string, contents: string) => Promise<void>;
|
|
189
|
+
/** Formatter options for report generation */
|
|
190
|
+
interface FormatterOptions {
|
|
191
|
+
/** Glob patterns to include test cases by sourceFile (forward slashes). If empty, all are considered. */
|
|
192
|
+
include?: string[];
|
|
193
|
+
/** Glob patterns to exclude test cases by sourceFile (forward slashes). Applied after include. */
|
|
194
|
+
exclude?: string[];
|
|
195
|
+
/** Output formats to generate. Default: ["cucumber-json"] */
|
|
196
|
+
formats?: OutputFormat[];
|
|
197
|
+
/** Output directory for generated reports. Default: "reports" */
|
|
198
|
+
outputDir?: string;
|
|
199
|
+
/** Base filename (without extension). Default: "test-results" */
|
|
200
|
+
outputName?: string;
|
|
201
|
+
/** Output routing configuration */
|
|
202
|
+
output?: OutputConfig;
|
|
203
|
+
/** Cucumber JSON specific options */
|
|
204
|
+
cucumberJson?: {
|
|
205
|
+
/** Pretty-print JSON output. Default: false */
|
|
206
|
+
pretty?: boolean;
|
|
207
|
+
};
|
|
208
|
+
/** HTML specific options */
|
|
209
|
+
html?: {
|
|
210
|
+
/** Report title. Default: "Test Results" */
|
|
211
|
+
title?: string;
|
|
212
|
+
/** Include dark mode toggle. Default: true */
|
|
213
|
+
darkMode?: boolean;
|
|
214
|
+
/** Include search/filter functionality. Default: true */
|
|
215
|
+
searchable?: boolean;
|
|
216
|
+
/** Start with scenarios collapsed. Default: false */
|
|
217
|
+
startCollapsed?: boolean;
|
|
218
|
+
/** Embed screenshots inline (base64). Default: true */
|
|
219
|
+
embedScreenshots?: boolean;
|
|
220
|
+
/** Enable syntax highlighting for code blocks (via highlight.js CDN). Default: true */
|
|
221
|
+
syntaxHighlighting?: boolean;
|
|
222
|
+
/** Enable live Mermaid diagram rendering (via Mermaid.js CDN). Default: true */
|
|
223
|
+
mermaidEnabled?: boolean;
|
|
224
|
+
/** Enable Markdown parsing for section doc entries (via marked.js CDN). Default: true */
|
|
225
|
+
markdownEnabled?: boolean;
|
|
226
|
+
};
|
|
227
|
+
/** JUnit XML specific options */
|
|
228
|
+
junit?: {
|
|
229
|
+
/** Test suite name. Default: "Test Suite" */
|
|
230
|
+
suiteName?: string;
|
|
231
|
+
/** Include system-out/system-err. Default: true */
|
|
232
|
+
includeOutput?: boolean;
|
|
233
|
+
};
|
|
234
|
+
/** Cucumber Messages (NDJSON) specific options */
|
|
235
|
+
cucumberMessages?: {
|
|
236
|
+
/** Strategy for deriving Source.uri. Default: "sourceFile" */
|
|
237
|
+
uriStrategy?: "sourceFile" | "virtual";
|
|
238
|
+
/** Whether to emit Source/GherkinDocument for synthesized features. Default: true */
|
|
239
|
+
includeSynthetics?: boolean;
|
|
240
|
+
/** Salt for deterministic IDs. Default: "" */
|
|
241
|
+
idSalt?: string;
|
|
242
|
+
/** Tool metadata for Meta envelope */
|
|
243
|
+
meta?: {
|
|
244
|
+
toolName?: string;
|
|
245
|
+
toolVersion?: string;
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
/** Markdown specific options */
|
|
249
|
+
markdown?: MarkdownFormatterOptions;
|
|
250
|
+
/** Logger for warnings and info. Default: console */
|
|
251
|
+
logger?: Logger;
|
|
252
|
+
/** File writer function. Default: fs.promises.writeFile */
|
|
253
|
+
writeFile?: WriteFile;
|
|
254
|
+
}
|
|
255
|
+
/** Markdown formatter options (extended for feature parity) */
|
|
256
|
+
interface MarkdownFormatterOptions {
|
|
257
|
+
/** Report title. Default: "User Stories" */
|
|
258
|
+
title?: string;
|
|
259
|
+
/** Include status icons. Default: true */
|
|
260
|
+
includeStatusIcons?: boolean;
|
|
261
|
+
/** Include metadata table. Default: true */
|
|
262
|
+
includeMetadata?: boolean;
|
|
263
|
+
/** Include error details. Default: true */
|
|
264
|
+
includeErrors?: boolean;
|
|
265
|
+
/** Scenario heading level. Default: 3 */
|
|
266
|
+
scenarioHeadingLevel?: 2 | 3 | 4;
|
|
267
|
+
/** Step style. Default: "bullets" */
|
|
268
|
+
stepStyle?: "bullets" | "gherkin";
|
|
269
|
+
/** Group scenarios by. Default: "file" */
|
|
270
|
+
groupBy?: "file" | "suite" | "none";
|
|
271
|
+
/** Sort scenarios. Default: "source" */
|
|
272
|
+
sortScenarios?: "alpha" | "source" | "none";
|
|
273
|
+
/** Suite path separator. Default: " - " */
|
|
274
|
+
suiteSeparator?: string;
|
|
275
|
+
/** Include YAML front-matter for machine parsing. Default: false */
|
|
276
|
+
includeFrontMatter?: boolean;
|
|
277
|
+
/** Include summary table (counts, duration). Default: false */
|
|
278
|
+
includeSummaryTable?: boolean;
|
|
279
|
+
/** Base URL for source permalinks. E.g., "https://github.com/user/repo/blob" */
|
|
280
|
+
permalinkBaseUrl?: string;
|
|
281
|
+
/** URL template for ticket links. Use {ticket} as placeholder. E.g., "https://jira.example.com/browse/{ticket}" */
|
|
282
|
+
ticketUrlTemplate?: string;
|
|
283
|
+
/** Include source links when permalinkBaseUrl is set. Default: true */
|
|
284
|
+
includeSourceLinks?: boolean;
|
|
285
|
+
/** Custom renderers for doc entries */
|
|
286
|
+
customRenderers?: MarkdownRenderers;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Custom renderers for markdown doc entries */
|
|
290
|
+
interface MarkdownRenderers {
|
|
291
|
+
/** Custom renderer for scenario header */
|
|
292
|
+
renderScenarioHeader?: (tc: TestCaseResult) => string | null;
|
|
293
|
+
/** Custom renderer for step */
|
|
294
|
+
renderStep?: (step: StoryStep) => string | null;
|
|
295
|
+
/** Custom renderer for doc entry */
|
|
296
|
+
renderDocEntry?: (entry: DocEntry) => string | null;
|
|
297
|
+
/** Custom renderer for footer */
|
|
298
|
+
renderFooter?: (run: TestRunResult) => string | null;
|
|
299
|
+
}
|
|
300
|
+
/** Resolved formatter options with all defaults applied */
|
|
301
|
+
interface ResolvedFormatterOptions {
|
|
302
|
+
include: string[];
|
|
303
|
+
exclude: string[];
|
|
304
|
+
formats: OutputFormat[];
|
|
305
|
+
outputDir: string;
|
|
306
|
+
outputName: string;
|
|
307
|
+
output: {
|
|
308
|
+
mode: OutputMode;
|
|
309
|
+
colocatedStyle: ColocatedStyle;
|
|
310
|
+
rules: OutputRule[];
|
|
311
|
+
outputName?: string;
|
|
312
|
+
};
|
|
313
|
+
cucumberJson: {
|
|
314
|
+
pretty: boolean;
|
|
315
|
+
};
|
|
316
|
+
cucumberMessages: {
|
|
317
|
+
uriStrategy: "sourceFile" | "virtual";
|
|
318
|
+
includeSynthetics: boolean;
|
|
319
|
+
idSalt: string;
|
|
320
|
+
meta?: {
|
|
321
|
+
toolName?: string;
|
|
322
|
+
toolVersion?: string;
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
html: {
|
|
326
|
+
title: string;
|
|
327
|
+
darkMode: boolean;
|
|
328
|
+
searchable: boolean;
|
|
329
|
+
startCollapsed: boolean;
|
|
330
|
+
embedScreenshots: boolean;
|
|
331
|
+
syntaxHighlighting: boolean;
|
|
332
|
+
mermaidEnabled: boolean;
|
|
333
|
+
markdownEnabled: boolean;
|
|
334
|
+
};
|
|
335
|
+
junit: {
|
|
336
|
+
suiteName: string;
|
|
337
|
+
includeOutput: boolean;
|
|
338
|
+
};
|
|
339
|
+
markdown: {
|
|
340
|
+
title: string;
|
|
341
|
+
includeStatusIcons: boolean;
|
|
342
|
+
includeMetadata: boolean;
|
|
343
|
+
includeErrors: boolean;
|
|
344
|
+
scenarioHeadingLevel: 2 | 3 | 4;
|
|
345
|
+
stepStyle: "bullets" | "gherkin";
|
|
346
|
+
groupBy: "file" | "suite" | "none";
|
|
347
|
+
sortScenarios: "alpha" | "source" | "none";
|
|
348
|
+
suiteSeparator: string;
|
|
349
|
+
includeFrontMatter: boolean;
|
|
350
|
+
includeSummaryTable: boolean;
|
|
351
|
+
permalinkBaseUrl?: string;
|
|
352
|
+
ticketUrlTemplate?: string;
|
|
353
|
+
includeSourceLinks: boolean;
|
|
354
|
+
customRenderers?: MarkdownRenderers;
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Cucumber JSON format types.
|
|
360
|
+
*
|
|
361
|
+
* Based on cucumber-js v11.x JSON formatter output.
|
|
362
|
+
* @see https://github.com/cucumber/cucumber-js/blob/main/src/formatter/json_formatter.ts
|
|
363
|
+
*/
|
|
364
|
+
/** Cucumber JSON tag */
|
|
365
|
+
interface IJsonTag {
|
|
366
|
+
name: string;
|
|
367
|
+
line?: number;
|
|
368
|
+
}
|
|
369
|
+
/** Cucumber JSON doc string (step argument) */
|
|
370
|
+
interface IJsonDocString {
|
|
371
|
+
content: string;
|
|
372
|
+
content_type?: string;
|
|
373
|
+
line: number;
|
|
374
|
+
}
|
|
375
|
+
/** Cucumber JSON data table row */
|
|
376
|
+
interface IJsonTableRow {
|
|
377
|
+
cells: string[];
|
|
378
|
+
}
|
|
379
|
+
/** Cucumber JSON data table (step argument) */
|
|
380
|
+
interface IJsonDataTable {
|
|
381
|
+
rows: IJsonTableRow[];
|
|
382
|
+
}
|
|
383
|
+
/** Cucumber JSON step argument */
|
|
384
|
+
interface IJsonStepArgument {
|
|
385
|
+
doc_string?: IJsonDocString;
|
|
386
|
+
rows?: IJsonTableRow[];
|
|
387
|
+
}
|
|
388
|
+
/** Cucumber JSON embedding (attachment) */
|
|
389
|
+
interface IJsonEmbedding {
|
|
390
|
+
data: string;
|
|
391
|
+
mime_type: string;
|
|
392
|
+
name?: string;
|
|
393
|
+
}
|
|
394
|
+
/** Cucumber JSON step result */
|
|
395
|
+
interface IJsonStepResult {
|
|
396
|
+
/** Duration in nanoseconds */
|
|
397
|
+
duration?: number;
|
|
398
|
+
/** Error message if failed */
|
|
399
|
+
error_message?: string;
|
|
400
|
+
/** Status string */
|
|
401
|
+
status: "passed" | "failed" | "skipped" | "pending" | "undefined" | "ambiguous";
|
|
402
|
+
}
|
|
403
|
+
/** Cucumber JSON step */
|
|
404
|
+
interface IJsonStep {
|
|
405
|
+
/** Step arguments (doc strings, data tables) */
|
|
406
|
+
arguments?: IJsonStepArgument[];
|
|
407
|
+
/** Embeddings (attachments) */
|
|
408
|
+
embeddings?: IJsonEmbedding[];
|
|
409
|
+
/** Step keyword with trailing space (e.g., "Given ") */
|
|
410
|
+
keyword: string;
|
|
411
|
+
/** Hidden step (background step, hook) */
|
|
412
|
+
hidden?: boolean;
|
|
413
|
+
/** Line number in feature file */
|
|
414
|
+
line: number;
|
|
415
|
+
/** Match info (step definition location) */
|
|
416
|
+
match?: {
|
|
417
|
+
location?: string;
|
|
418
|
+
};
|
|
419
|
+
/** Step name/text */
|
|
420
|
+
name: string;
|
|
421
|
+
/** Step result */
|
|
422
|
+
result: IJsonStepResult;
|
|
423
|
+
}
|
|
424
|
+
/** Cucumber JSON scenario (element) */
|
|
425
|
+
interface IJsonScenario {
|
|
426
|
+
/** Scenario description */
|
|
427
|
+
description: string;
|
|
428
|
+
/** Scenario ID (slugified) */
|
|
429
|
+
id: string;
|
|
430
|
+
/** Scenario keyword */
|
|
431
|
+
keyword: string;
|
|
432
|
+
/** Line number in feature file */
|
|
433
|
+
line: number;
|
|
434
|
+
/** Scenario name */
|
|
435
|
+
name: string;
|
|
436
|
+
/** Scenario steps */
|
|
437
|
+
steps: IJsonStep[];
|
|
438
|
+
/** Scenario tags */
|
|
439
|
+
tags: IJsonTag[];
|
|
440
|
+
/** Element type (always "scenario" for us) */
|
|
441
|
+
type: "scenario" | "background";
|
|
442
|
+
}
|
|
443
|
+
/** Cucumber JSON feature */
|
|
444
|
+
interface IJsonFeature {
|
|
445
|
+
/** Feature description */
|
|
446
|
+
description: string;
|
|
447
|
+
/** Feature elements (scenarios) */
|
|
448
|
+
elements: IJsonScenario[];
|
|
449
|
+
/** Feature ID (slugified) */
|
|
450
|
+
id: string;
|
|
451
|
+
/** Feature keyword */
|
|
452
|
+
keyword: string;
|
|
453
|
+
/** Line number (typically 1) */
|
|
454
|
+
line: number;
|
|
455
|
+
/** Feature name */
|
|
456
|
+
name: string;
|
|
457
|
+
/** Feature tags */
|
|
458
|
+
tags: IJsonTag[];
|
|
459
|
+
/** Feature file URI/path */
|
|
460
|
+
uri: string;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Status mapping from raw framework statuses to canonical TestStatus.
|
|
465
|
+
*/
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Convert a raw status to canonical TestStatus.
|
|
469
|
+
*
|
|
470
|
+
* @param raw - The raw status from a framework
|
|
471
|
+
* @returns The canonical TestStatus
|
|
472
|
+
*/
|
|
473
|
+
declare function normalizeStatus(raw: RawStatus): TestStatus;
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* ID generation and slug helpers for deterministic, Cucumber-compatible IDs.
|
|
477
|
+
*/
|
|
478
|
+
/**
|
|
479
|
+
* Generate a deterministic test case ID from source file and scenario name.
|
|
480
|
+
*
|
|
481
|
+
* @param sourceFile - The source file path
|
|
482
|
+
* @param scenario - The scenario name
|
|
483
|
+
* @returns A 12-character hex ID
|
|
484
|
+
*/
|
|
485
|
+
declare function generateTestCaseId(sourceFile: string, scenario: string): string;
|
|
486
|
+
/**
|
|
487
|
+
* Generate a deterministic run ID from timestamp and project root.
|
|
488
|
+
*
|
|
489
|
+
* @param startedAtMs - Run start timestamp
|
|
490
|
+
* @param projectRoot - Project root directory
|
|
491
|
+
* @returns A 16-character hex ID
|
|
492
|
+
*/
|
|
493
|
+
declare function generateRunId(startedAtMs: number, projectRoot: string): string;
|
|
494
|
+
/**
|
|
495
|
+
* Slugify a string for Cucumber JSON IDs.
|
|
496
|
+
*
|
|
497
|
+
* Converts to lowercase, replaces path separators/spaces with hyphens,
|
|
498
|
+
* removes other special chars, and trims leading/trailing hyphens.
|
|
499
|
+
*
|
|
500
|
+
* @param text - The text to slugify
|
|
501
|
+
* @returns A URL-safe slug
|
|
502
|
+
*/
|
|
503
|
+
declare function slugify(text: string): string;
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Step fallback rules for deriving step results from scenario status.
|
|
507
|
+
*
|
|
508
|
+
* When frameworks don't provide step-level results, we derive them
|
|
509
|
+
* from the overall scenario status using these rules.
|
|
510
|
+
*/
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Derive step results from story steps and scenario status.
|
|
514
|
+
*
|
|
515
|
+
* Rules:
|
|
516
|
+
* - Passed: All steps are passed
|
|
517
|
+
* - Skipped/Pending: All steps are skipped/pending
|
|
518
|
+
* - Failed: Steps up to failure are passed, failing step is failed, rest are skipped
|
|
519
|
+
* (Heuristic: last step is the failure, or use error info if available)
|
|
520
|
+
*
|
|
521
|
+
* @param steps - Story steps with keywords and text
|
|
522
|
+
* @param scenarioStatus - Overall scenario status
|
|
523
|
+
* @param error - Optional error information to help identify failing step
|
|
524
|
+
* @returns Array of step results
|
|
525
|
+
*/
|
|
526
|
+
declare function deriveStepResults(steps: StoryStep[], scenarioStatus: TestStatus, error?: {
|
|
527
|
+
message?: string;
|
|
528
|
+
stack?: string;
|
|
529
|
+
}): StepResult[];
|
|
530
|
+
/**
|
|
531
|
+
* Merge raw step events with derived step results.
|
|
532
|
+
*
|
|
533
|
+
* When we have partial step data from the framework, merge it with
|
|
534
|
+
* the derived results, preferring actual data over derived.
|
|
535
|
+
*
|
|
536
|
+
* @param derived - Derived step results from fallback rules
|
|
537
|
+
* @param events - Raw step events from framework (if any)
|
|
538
|
+
* @returns Merged step results
|
|
539
|
+
*/
|
|
540
|
+
declare function mergeStepResults(derived: StepResult[], events?: Array<{
|
|
541
|
+
index?: number;
|
|
542
|
+
status?: string;
|
|
543
|
+
durationMs?: number;
|
|
544
|
+
errorMessage?: string;
|
|
545
|
+
}>): StepResult[];
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Attachment resolution: embed vs link decision.
|
|
549
|
+
*
|
|
550
|
+
* Attachments can either be embedded inline (base64) or linked to
|
|
551
|
+
* external files based on size thresholds.
|
|
552
|
+
*/
|
|
553
|
+
|
|
554
|
+
/** Options for attachment resolution */
|
|
555
|
+
interface AttachmentOptions {
|
|
556
|
+
/** Max bytes before attachment becomes external link. Default: 512KB */
|
|
557
|
+
maxEmbedBytes?: number;
|
|
558
|
+
/** Directory for external attachments */
|
|
559
|
+
externalDir?: string;
|
|
560
|
+
/** Project root for relative paths */
|
|
561
|
+
projectRoot?: string;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Resolve a raw attachment to a canonical attachment.
|
|
565
|
+
*
|
|
566
|
+
* Decision logic:
|
|
567
|
+
* 1. If body is already provided, use it (check size for encoding decision)
|
|
568
|
+
* 2. If path is provided, read file and decide embed vs link
|
|
569
|
+
* 3. For large files, return a URL reference instead of embedding
|
|
570
|
+
*
|
|
571
|
+
* @param raw - Raw attachment from framework
|
|
572
|
+
* @param options - Resolution options
|
|
573
|
+
* @returns Resolved canonical attachment
|
|
574
|
+
*/
|
|
575
|
+
declare function resolveAttachment(raw: RawAttachment, options?: AttachmentOptions): Attachment;
|
|
576
|
+
/**
|
|
577
|
+
* Resolve multiple attachments.
|
|
578
|
+
*
|
|
579
|
+
* @param attachments - Raw attachments array
|
|
580
|
+
* @param options - Resolution options
|
|
581
|
+
* @returns Resolved canonical attachments
|
|
582
|
+
*/
|
|
583
|
+
declare function resolveAttachments(attachments: RawAttachment[] | undefined, options?: AttachmentOptions): Attachment[];
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Anti-Corruption Layer (ACL) - Layer 2.
|
|
587
|
+
*
|
|
588
|
+
* Transforms permissive RawRun data from framework adapters into
|
|
589
|
+
* strict canonical TestRunResult for formatters.
|
|
590
|
+
*/
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Canonicalize a raw run into a strict TestRunResult.
|
|
594
|
+
*
|
|
595
|
+
* This is the main entry point for the ACL. It:
|
|
596
|
+
* - Enforces required fields with defaults
|
|
597
|
+
* - Normalizes statuses to TestStatus enum
|
|
598
|
+
* - Applies step fallback rules
|
|
599
|
+
* - Resolves attachments (embed vs link)
|
|
600
|
+
* - Generates deterministic IDs
|
|
601
|
+
*
|
|
602
|
+
* @param raw - Raw run data from a framework adapter
|
|
603
|
+
* @param options - Canonicalization options
|
|
604
|
+
* @returns Strict canonical TestRunResult
|
|
605
|
+
*/
|
|
606
|
+
declare function canonicalizeRun(raw: RawRun, options?: CanonicalizeOptions): TestRunResult;
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Validation helpers for canonical TestRunResult.
|
|
610
|
+
*
|
|
611
|
+
* Used in tests to verify ACL output meets all invariants.
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
/** Validation result */
|
|
615
|
+
interface ValidationResult {
|
|
616
|
+
/** Whether the run is valid */
|
|
617
|
+
valid: boolean;
|
|
618
|
+
/** List of validation errors */
|
|
619
|
+
errors: string[];
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Validate a canonical TestRunResult.
|
|
623
|
+
*
|
|
624
|
+
* Checks:
|
|
625
|
+
* - All required fields are present
|
|
626
|
+
* - stepResults length matches story.steps length
|
|
627
|
+
* - stepResults indexes are valid and unique
|
|
628
|
+
* - Durations are non-negative
|
|
629
|
+
* - Timestamps are valid
|
|
630
|
+
*
|
|
631
|
+
* @param run - The TestRunResult to validate
|
|
632
|
+
* @returns Validation result with errors if any
|
|
633
|
+
*/
|
|
634
|
+
declare function validateCanonicalRun(run: TestRunResult): ValidationResult;
|
|
635
|
+
/**
|
|
636
|
+
* Assert that a run is valid, throwing if not.
|
|
637
|
+
*
|
|
638
|
+
* Useful in tests.
|
|
639
|
+
*
|
|
640
|
+
* @param run - The TestRunResult to validate
|
|
641
|
+
* @throws Error if validation fails
|
|
642
|
+
*/
|
|
643
|
+
declare function assertValidRun(run: TestRunResult): void;
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Cucumber JSON Formatter - Layer 3.
|
|
647
|
+
*
|
|
648
|
+
* Transforms canonical TestRunResult into Cucumber JSON format
|
|
649
|
+
* compatible with cucumber-js v11.x output.
|
|
650
|
+
*/
|
|
651
|
+
|
|
652
|
+
/** Options for Cucumber JSON formatting */
|
|
653
|
+
interface CucumberJsonOptions {
|
|
654
|
+
/** Pretty-print JSON output. Default: false */
|
|
655
|
+
pretty?: boolean;
|
|
656
|
+
/** Include trailing space in keywords. Default: true */
|
|
657
|
+
keywordSpacing?: boolean;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Cucumber JSON Formatter.
|
|
661
|
+
*
|
|
662
|
+
* Transforms TestRunResult into an array of IJsonFeature objects
|
|
663
|
+
* that match the Cucumber JSON format specification.
|
|
664
|
+
*/
|
|
665
|
+
declare class CucumberJsonFormatter {
|
|
666
|
+
private options;
|
|
667
|
+
constructor(options?: CucumberJsonOptions);
|
|
668
|
+
/**
|
|
669
|
+
* Format a test run into Cucumber JSON features.
|
|
670
|
+
*
|
|
671
|
+
* Groups test cases by source file (one feature per file).
|
|
672
|
+
*
|
|
673
|
+
* @param run - Canonical test run result
|
|
674
|
+
* @returns Array of Cucumber JSON features
|
|
675
|
+
*/
|
|
676
|
+
format(run: TestRunResult): IJsonFeature[];
|
|
677
|
+
/**
|
|
678
|
+
* Format and serialize to JSON string.
|
|
679
|
+
*
|
|
680
|
+
* @param run - Canonical test run result
|
|
681
|
+
* @returns JSON string
|
|
682
|
+
*/
|
|
683
|
+
formatToString(run: TestRunResult): string;
|
|
684
|
+
/**
|
|
685
|
+
* Build a single feature from test cases in the same file.
|
|
686
|
+
*/
|
|
687
|
+
private buildFeature;
|
|
688
|
+
/**
|
|
689
|
+
* Extract feature name from URI or test cases.
|
|
690
|
+
*
|
|
691
|
+
* Uses the top-level suite path if available, otherwise file name.
|
|
692
|
+
*/
|
|
693
|
+
private extractFeatureName;
|
|
694
|
+
/**
|
|
695
|
+
* Extract feature-level tags from all test cases.
|
|
696
|
+
*/
|
|
697
|
+
private extractFeatureTags;
|
|
698
|
+
/**
|
|
699
|
+
* Build a scenario from a test case.
|
|
700
|
+
*/
|
|
701
|
+
private buildScenario;
|
|
702
|
+
/**
|
|
703
|
+
* Build steps from story steps and step results.
|
|
704
|
+
*/
|
|
705
|
+
private buildSteps;
|
|
706
|
+
/**
|
|
707
|
+
* Build a single step.
|
|
708
|
+
*/
|
|
709
|
+
private buildStep;
|
|
710
|
+
/**
|
|
711
|
+
* Build embeddings from screenshot doc entries.
|
|
712
|
+
*/
|
|
713
|
+
private buildScreenshotEmbeddings;
|
|
714
|
+
/**
|
|
715
|
+
* Build step result.
|
|
716
|
+
*/
|
|
717
|
+
private buildStepResult;
|
|
718
|
+
/**
|
|
719
|
+
* Build embeddings (attachments) for a step.
|
|
720
|
+
*
|
|
721
|
+
* Cucumber convention: attach to the failing step, or last step if no failure.
|
|
722
|
+
*/
|
|
723
|
+
private buildEmbeddings;
|
|
724
|
+
/**
|
|
725
|
+
* Build step arguments from step docs.
|
|
726
|
+
*
|
|
727
|
+
* Converts doc entries to Cucumber step arguments (doc strings, data tables).
|
|
728
|
+
*/
|
|
729
|
+
private buildStepArguments;
|
|
730
|
+
/**
|
|
731
|
+
* Convert a doc entry to a Cucumber step argument.
|
|
732
|
+
*/
|
|
733
|
+
private docEntryToArgument;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* HTML Formatter - Layer 3.
|
|
738
|
+
*
|
|
739
|
+
* Transforms canonical TestRunResult into a standalone HTML report.
|
|
740
|
+
* Implemented via createHtmlFormatter (fn(args, deps) pattern).
|
|
741
|
+
*/
|
|
742
|
+
|
|
743
|
+
/** Options for HTML formatting */
|
|
744
|
+
interface HtmlOptions {
|
|
745
|
+
/** Report title. Default: "Test Results" */
|
|
746
|
+
title?: string;
|
|
747
|
+
/** Include dark mode toggle. Default: true */
|
|
748
|
+
darkMode?: boolean;
|
|
749
|
+
/** Include search/filter functionality. Default: true */
|
|
750
|
+
searchable?: boolean;
|
|
751
|
+
/** Start scenarios collapsed. Default: false */
|
|
752
|
+
startCollapsed?: boolean;
|
|
753
|
+
/** Embed screenshots inline (base64). Default: true */
|
|
754
|
+
embedScreenshots?: boolean;
|
|
755
|
+
/** Enable syntax highlighting for code blocks (via highlight.js CDN). Default: true */
|
|
756
|
+
syntaxHighlighting?: boolean;
|
|
757
|
+
/** Enable live Mermaid diagram rendering (via Mermaid.js CDN). Default: true */
|
|
758
|
+
mermaidEnabled?: boolean;
|
|
759
|
+
/** Enable Markdown parsing for section doc entries (via marked.js CDN). Default: true */
|
|
760
|
+
markdownEnabled?: boolean;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* HTML Formatter.
|
|
764
|
+
*
|
|
765
|
+
* Transforms TestRunResult into a standalone HTML report with:
|
|
766
|
+
* - Dark/light mode toggle
|
|
767
|
+
* - Search/filter functionality
|
|
768
|
+
* - Collapsible features and scenarios
|
|
769
|
+
* - Modern, accessible design
|
|
770
|
+
*
|
|
771
|
+
* Thin wrapper around createHtmlFormatter for backward compatibility.
|
|
772
|
+
*/
|
|
773
|
+
declare class HtmlFormatter {
|
|
774
|
+
private formatFn;
|
|
775
|
+
constructor(options?: HtmlOptions);
|
|
776
|
+
/**
|
|
777
|
+
* Format a test run into standalone HTML.
|
|
778
|
+
*
|
|
779
|
+
* @param run - Canonical test run result
|
|
780
|
+
* @returns HTML string
|
|
781
|
+
*/
|
|
782
|
+
format(run: TestRunResult): string;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* JUnit XML Formatter - Layer 3.
|
|
787
|
+
*
|
|
788
|
+
* Transforms canonical TestRunResult into JUnit XML format
|
|
789
|
+
* for CI system integration.
|
|
790
|
+
*/
|
|
791
|
+
|
|
792
|
+
/** Options for JUnit XML formatting */
|
|
793
|
+
interface JUnitOptions {
|
|
794
|
+
/** Test suite name. Default: "Test Suite" */
|
|
795
|
+
suiteName?: string;
|
|
796
|
+
/** Include system-out/system-err. Default: true */
|
|
797
|
+
includeOutput?: boolean;
|
|
798
|
+
/** Pretty-print XML output. Default: true */
|
|
799
|
+
pretty?: boolean;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* JUnit XML Formatter.
|
|
803
|
+
*
|
|
804
|
+
* Transforms TestRunResult into JUnit XML format for CI integrations.
|
|
805
|
+
* Compatible with Jenkins, GitHub Actions, and other CI systems.
|
|
806
|
+
*/
|
|
807
|
+
declare class JUnitFormatter {
|
|
808
|
+
private options;
|
|
809
|
+
constructor(options?: JUnitOptions);
|
|
810
|
+
/**
|
|
811
|
+
* Format a test run into JUnit XML.
|
|
812
|
+
*
|
|
813
|
+
* @param run - Canonical test run result
|
|
814
|
+
* @returns JUnit XML string
|
|
815
|
+
*/
|
|
816
|
+
format(run: TestRunResult): string;
|
|
817
|
+
/**
|
|
818
|
+
* Build a testsuite element for a file.
|
|
819
|
+
*/
|
|
820
|
+
private buildTestSuite;
|
|
821
|
+
/**
|
|
822
|
+
* Build a testcase element.
|
|
823
|
+
*/
|
|
824
|
+
private buildTestCase;
|
|
825
|
+
/**
|
|
826
|
+
* Build system-out content with steps and docs.
|
|
827
|
+
*/
|
|
828
|
+
private buildSystemOut;
|
|
829
|
+
/**
|
|
830
|
+
* Render a step with its docs.
|
|
831
|
+
*/
|
|
832
|
+
private renderStep;
|
|
833
|
+
/**
|
|
834
|
+
* Render a doc entry as plain text.
|
|
835
|
+
*/
|
|
836
|
+
private renderDocEntry;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Markdown Formatter - Layer 3.
|
|
841
|
+
*
|
|
842
|
+
* Transforms canonical TestRunResult into Markdown documentation.
|
|
843
|
+
* Compatible with existing markdown output from framework reporters.
|
|
844
|
+
*/
|
|
845
|
+
|
|
846
|
+
/** Options for Markdown formatting */
|
|
847
|
+
interface MarkdownOptions {
|
|
848
|
+
/** Report title. Default: "User Stories" */
|
|
849
|
+
title?: string;
|
|
850
|
+
/** Include status icons on scenarios. Default: true */
|
|
851
|
+
includeStatusIcons?: boolean;
|
|
852
|
+
/** Include metadata table (date, version). Default: true */
|
|
853
|
+
includeMetadata?: boolean;
|
|
854
|
+
/** Include error details for failed scenarios. Default: true */
|
|
855
|
+
includeErrors?: boolean;
|
|
856
|
+
/** Scenario heading level. Default: 3 */
|
|
857
|
+
scenarioHeadingLevel?: 2 | 3 | 4;
|
|
858
|
+
/** Step rendering style. Default: "bullets" */
|
|
859
|
+
stepStyle?: "bullets" | "gherkin";
|
|
860
|
+
/** Group scenarios by. Default: "file" */
|
|
861
|
+
groupBy?: "file" | "suite" | "none";
|
|
862
|
+
/** Sort scenarios. Default: "source" */
|
|
863
|
+
sortScenarios?: "alpha" | "source" | "none";
|
|
864
|
+
/** Suite path separator. Default: " - " */
|
|
865
|
+
suiteSeparator?: string;
|
|
866
|
+
/** Include YAML front-matter for machine parsing. Default: false */
|
|
867
|
+
includeFrontMatter?: boolean;
|
|
868
|
+
/** Include summary table (counts, duration). Default: false */
|
|
869
|
+
includeSummaryTable?: boolean;
|
|
870
|
+
/** Base URL for source permalinks. E.g., "https://github.com/user/repo/blob" */
|
|
871
|
+
permalinkBaseUrl?: string;
|
|
872
|
+
/** URL template for ticket links. Use {ticket} as placeholder */
|
|
873
|
+
ticketUrlTemplate?: string;
|
|
874
|
+
/** Include source links when permalinkBaseUrl is set. Default: true */
|
|
875
|
+
includeSourceLinks?: boolean;
|
|
876
|
+
/** Custom renderers for doc entries */
|
|
877
|
+
customRenderers?: MarkdownRenderers;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Markdown Formatter.
|
|
881
|
+
*
|
|
882
|
+
* Transforms TestRunResult into Markdown documentation that matches
|
|
883
|
+
* the output format of existing framework reporters.
|
|
884
|
+
*/
|
|
885
|
+
declare class MarkdownFormatter {
|
|
886
|
+
private options;
|
|
887
|
+
constructor(options?: MarkdownOptions);
|
|
888
|
+
/**
|
|
889
|
+
* Format a test run into Markdown.
|
|
890
|
+
*
|
|
891
|
+
* @param run - Canonical test run result
|
|
892
|
+
* @returns Markdown string
|
|
893
|
+
*/
|
|
894
|
+
format(run: TestRunResult): string;
|
|
895
|
+
/**
|
|
896
|
+
* Render YAML front-matter.
|
|
897
|
+
*/
|
|
898
|
+
private renderFrontMatter;
|
|
899
|
+
/**
|
|
900
|
+
* Render summary table.
|
|
901
|
+
*/
|
|
902
|
+
private renderSummaryTable;
|
|
903
|
+
/**
|
|
904
|
+
* Format duration in human-readable form.
|
|
905
|
+
*/
|
|
906
|
+
private formatDuration;
|
|
907
|
+
/**
|
|
908
|
+
* Render metadata table.
|
|
909
|
+
*/
|
|
910
|
+
private renderMetadata;
|
|
911
|
+
/**
|
|
912
|
+
* Render scenarios grouped by file.
|
|
913
|
+
*/
|
|
914
|
+
private renderByFile;
|
|
915
|
+
/**
|
|
916
|
+
* Render scenarios grouped by suite path.
|
|
917
|
+
*/
|
|
918
|
+
private renderBySuite;
|
|
919
|
+
/**
|
|
920
|
+
* Render suite groups.
|
|
921
|
+
*/
|
|
922
|
+
private renderSuiteGroups;
|
|
923
|
+
/**
|
|
924
|
+
* Render flat list of scenarios.
|
|
925
|
+
*/
|
|
926
|
+
private renderFlatList;
|
|
927
|
+
/**
|
|
928
|
+
* Render a single scenario.
|
|
929
|
+
*/
|
|
930
|
+
private renderScenario;
|
|
931
|
+
/**
|
|
932
|
+
* Render scenario body (docs, steps, errors).
|
|
933
|
+
*/
|
|
934
|
+
private renderScenarioBody;
|
|
935
|
+
/**
|
|
936
|
+
* Build permalink URL for a test case.
|
|
937
|
+
*/
|
|
938
|
+
private buildPermalink;
|
|
939
|
+
/**
|
|
940
|
+
* Render a step.
|
|
941
|
+
*/
|
|
942
|
+
private renderStep;
|
|
943
|
+
/**
|
|
944
|
+
* Render a documentation entry.
|
|
945
|
+
*/
|
|
946
|
+
private renderDocEntry;
|
|
947
|
+
/**
|
|
948
|
+
* Get status icon for a status.
|
|
949
|
+
*/
|
|
950
|
+
private getStatusIcon;
|
|
951
|
+
/**
|
|
952
|
+
* Sort scenarios based on options.
|
|
953
|
+
*/
|
|
954
|
+
private sortScenarios;
|
|
955
|
+
/**
|
|
956
|
+
* Sort suite groups.
|
|
957
|
+
*/
|
|
958
|
+
private sortSuiteGroups;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Cucumber Messages types for NDJSON output.
|
|
963
|
+
*
|
|
964
|
+
* Minimal own types (no @cucumber/messages dependency) — consistent with
|
|
965
|
+
* the project's zero-external-deps-at-runtime approach.
|
|
966
|
+
*
|
|
967
|
+
* Based on the Cucumber Messages protocol:
|
|
968
|
+
* https://github.com/cucumber/messages
|
|
969
|
+
*/
|
|
970
|
+
/** Protobuf-style timestamp { seconds, nanos } */
|
|
971
|
+
interface Timestamp {
|
|
972
|
+
seconds: number;
|
|
973
|
+
nanos: number;
|
|
974
|
+
}
|
|
975
|
+
/** Protobuf-style duration { seconds, nanos } */
|
|
976
|
+
interface Duration {
|
|
977
|
+
seconds: number;
|
|
978
|
+
nanos: number;
|
|
979
|
+
}
|
|
980
|
+
/** Location in a source file */
|
|
981
|
+
interface Location {
|
|
982
|
+
line: number;
|
|
983
|
+
column?: number;
|
|
984
|
+
}
|
|
985
|
+
interface Meta {
|
|
986
|
+
protocolVersion: string;
|
|
987
|
+
implementation: {
|
|
988
|
+
name: string;
|
|
989
|
+
version: string;
|
|
990
|
+
};
|
|
991
|
+
runtime: {
|
|
992
|
+
name: string;
|
|
993
|
+
version: string;
|
|
994
|
+
};
|
|
995
|
+
os: {
|
|
996
|
+
name: string;
|
|
997
|
+
};
|
|
998
|
+
cpu: {
|
|
999
|
+
name: string;
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
interface Source {
|
|
1003
|
+
uri: string;
|
|
1004
|
+
data: string;
|
|
1005
|
+
mediaType: "text/x.cucumber.gherkin+plain";
|
|
1006
|
+
}
|
|
1007
|
+
interface Tag {
|
|
1008
|
+
location: Location;
|
|
1009
|
+
name: string;
|
|
1010
|
+
id: string;
|
|
1011
|
+
}
|
|
1012
|
+
type KeywordType = "Unknown" | "Context" | "Action" | "Outcome" | "Conjunction";
|
|
1013
|
+
interface DocString {
|
|
1014
|
+
location: Location;
|
|
1015
|
+
mediaType?: string;
|
|
1016
|
+
content: string;
|
|
1017
|
+
delimiter: string;
|
|
1018
|
+
}
|
|
1019
|
+
interface TableCell {
|
|
1020
|
+
location: Location;
|
|
1021
|
+
value: string;
|
|
1022
|
+
}
|
|
1023
|
+
interface TableRow {
|
|
1024
|
+
location: Location;
|
|
1025
|
+
cells: TableCell[];
|
|
1026
|
+
id: string;
|
|
1027
|
+
}
|
|
1028
|
+
interface DataTable {
|
|
1029
|
+
location: Location;
|
|
1030
|
+
rows: TableRow[];
|
|
1031
|
+
}
|
|
1032
|
+
interface Step {
|
|
1033
|
+
location: Location;
|
|
1034
|
+
keyword: string;
|
|
1035
|
+
keywordType: KeywordType;
|
|
1036
|
+
text: string;
|
|
1037
|
+
id: string;
|
|
1038
|
+
docString?: DocString;
|
|
1039
|
+
dataTable?: DataTable;
|
|
1040
|
+
}
|
|
1041
|
+
interface Scenario {
|
|
1042
|
+
location: Location;
|
|
1043
|
+
tags: Tag[];
|
|
1044
|
+
keyword: string;
|
|
1045
|
+
name: string;
|
|
1046
|
+
description: string;
|
|
1047
|
+
steps: Step[];
|
|
1048
|
+
id: string;
|
|
1049
|
+
}
|
|
1050
|
+
interface Background {
|
|
1051
|
+
location: Location;
|
|
1052
|
+
keyword: string;
|
|
1053
|
+
name: string;
|
|
1054
|
+
description: string;
|
|
1055
|
+
steps: Step[];
|
|
1056
|
+
id: string;
|
|
1057
|
+
}
|
|
1058
|
+
type FeatureChild = {
|
|
1059
|
+
background: Background;
|
|
1060
|
+
scenario?: undefined;
|
|
1061
|
+
} | {
|
|
1062
|
+
scenario: Scenario;
|
|
1063
|
+
background?: undefined;
|
|
1064
|
+
};
|
|
1065
|
+
interface Feature {
|
|
1066
|
+
location: Location;
|
|
1067
|
+
tags: Tag[];
|
|
1068
|
+
language: string;
|
|
1069
|
+
keyword: string;
|
|
1070
|
+
name: string;
|
|
1071
|
+
description: string;
|
|
1072
|
+
children: FeatureChild[];
|
|
1073
|
+
}
|
|
1074
|
+
interface GherkinDocument {
|
|
1075
|
+
uri: string;
|
|
1076
|
+
feature: Feature;
|
|
1077
|
+
}
|
|
1078
|
+
type PickleStepType = "Unknown" | "Context" | "Action" | "Outcome";
|
|
1079
|
+
interface PickleDocString {
|
|
1080
|
+
mediaType?: string;
|
|
1081
|
+
content: string;
|
|
1082
|
+
}
|
|
1083
|
+
interface PickleTableCell {
|
|
1084
|
+
value: string;
|
|
1085
|
+
}
|
|
1086
|
+
interface PickleTableRow {
|
|
1087
|
+
cells: PickleTableCell[];
|
|
1088
|
+
}
|
|
1089
|
+
interface PickleTable {
|
|
1090
|
+
rows: PickleTableRow[];
|
|
1091
|
+
}
|
|
1092
|
+
interface PickleStepArgument {
|
|
1093
|
+
docString?: PickleDocString;
|
|
1094
|
+
dataTable?: PickleTable;
|
|
1095
|
+
}
|
|
1096
|
+
interface PickleStep {
|
|
1097
|
+
astNodeIds: string[];
|
|
1098
|
+
id: string;
|
|
1099
|
+
type: PickleStepType;
|
|
1100
|
+
text: string;
|
|
1101
|
+
argument?: PickleStepArgument;
|
|
1102
|
+
}
|
|
1103
|
+
interface PickleTag {
|
|
1104
|
+
name: string;
|
|
1105
|
+
astNodeId: string;
|
|
1106
|
+
}
|
|
1107
|
+
interface Pickle {
|
|
1108
|
+
id: string;
|
|
1109
|
+
uri: string;
|
|
1110
|
+
name: string;
|
|
1111
|
+
language: string;
|
|
1112
|
+
steps: PickleStep[];
|
|
1113
|
+
tags: PickleTag[];
|
|
1114
|
+
astNodeIds: string[];
|
|
1115
|
+
}
|
|
1116
|
+
type TestStepResultStatus = "UNKNOWN" | "PASSED" | "SKIPPED" | "PENDING" | "UNDEFINED" | "AMBIGUOUS" | "FAILED";
|
|
1117
|
+
interface TestStepResult {
|
|
1118
|
+
duration: Duration;
|
|
1119
|
+
status: TestStepResultStatus;
|
|
1120
|
+
message?: string;
|
|
1121
|
+
}
|
|
1122
|
+
interface TestStep {
|
|
1123
|
+
id: string;
|
|
1124
|
+
pickleStepId?: string;
|
|
1125
|
+
stepDefinitionIds?: string[];
|
|
1126
|
+
}
|
|
1127
|
+
interface TestCase {
|
|
1128
|
+
id: string;
|
|
1129
|
+
pickleId: string;
|
|
1130
|
+
testSteps: TestStep[];
|
|
1131
|
+
}
|
|
1132
|
+
interface TestRunStarted {
|
|
1133
|
+
timestamp: Timestamp;
|
|
1134
|
+
}
|
|
1135
|
+
interface TestCaseStarted {
|
|
1136
|
+
id: string;
|
|
1137
|
+
testCaseId: string;
|
|
1138
|
+
timestamp: Timestamp;
|
|
1139
|
+
attempt: number;
|
|
1140
|
+
}
|
|
1141
|
+
interface TestStepStarted {
|
|
1142
|
+
testCaseStartedId: string;
|
|
1143
|
+
testStepId: string;
|
|
1144
|
+
timestamp: Timestamp;
|
|
1145
|
+
}
|
|
1146
|
+
interface TestStepFinished {
|
|
1147
|
+
testCaseStartedId: string;
|
|
1148
|
+
testStepId: string;
|
|
1149
|
+
testStepResult: TestStepResult;
|
|
1150
|
+
timestamp: Timestamp;
|
|
1151
|
+
}
|
|
1152
|
+
interface TestCaseFinished {
|
|
1153
|
+
testCaseStartedId: string;
|
|
1154
|
+
timestamp: Timestamp;
|
|
1155
|
+
willBeRetried: boolean;
|
|
1156
|
+
}
|
|
1157
|
+
interface TestRunFinished {
|
|
1158
|
+
timestamp: Timestamp;
|
|
1159
|
+
success: boolean;
|
|
1160
|
+
}
|
|
1161
|
+
type AttachmentContentEncoding = "IDENTITY" | "BASE64";
|
|
1162
|
+
interface CucumberAttachment {
|
|
1163
|
+
testCaseStartedId: string;
|
|
1164
|
+
testStepId?: string;
|
|
1165
|
+
body: string;
|
|
1166
|
+
mediaType: string;
|
|
1167
|
+
contentEncoding: AttachmentContentEncoding;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Each NDJSON line is one Envelope with exactly one field set.
|
|
1171
|
+
*/
|
|
1172
|
+
type Envelope = {
|
|
1173
|
+
meta: Meta;
|
|
1174
|
+
} | {
|
|
1175
|
+
source: Source;
|
|
1176
|
+
} | {
|
|
1177
|
+
gherkinDocument: GherkinDocument;
|
|
1178
|
+
} | {
|
|
1179
|
+
pickle: Pickle;
|
|
1180
|
+
} | {
|
|
1181
|
+
testRunStarted: TestRunStarted;
|
|
1182
|
+
} | {
|
|
1183
|
+
testCase: TestCase;
|
|
1184
|
+
} | {
|
|
1185
|
+
testCaseStarted: TestCaseStarted;
|
|
1186
|
+
} | {
|
|
1187
|
+
testStepStarted: TestStepStarted;
|
|
1188
|
+
} | {
|
|
1189
|
+
testStepFinished: TestStepFinished;
|
|
1190
|
+
} | {
|
|
1191
|
+
testCaseFinished: TestCaseFinished;
|
|
1192
|
+
} | {
|
|
1193
|
+
testRunFinished: TestRunFinished;
|
|
1194
|
+
} | {
|
|
1195
|
+
attachment: CucumberAttachment;
|
|
1196
|
+
};
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* CucumberMessagesFormatter — produces NDJSON compatible with @cucumber/html-formatter.
|
|
1200
|
+
*
|
|
1201
|
+
* Message stream order:
|
|
1202
|
+
* Meta → Source* → GherkinDocument* → Pickle* → TestRunStarted →
|
|
1203
|
+
* [TestCase, TestCaseStarted, TestStep*, TestCaseFinished]* → TestRunFinished
|
|
1204
|
+
*/
|
|
1205
|
+
|
|
1206
|
+
interface CucumberMessagesOptions {
|
|
1207
|
+
/** Strategy for deriving Source.uri. Default: "sourceFile" */
|
|
1208
|
+
uriStrategy?: "sourceFile" | "virtual";
|
|
1209
|
+
/** Whether to emit Source/GherkinDocument for synthesized features. Default: true */
|
|
1210
|
+
includeSynthetics?: boolean;
|
|
1211
|
+
/** Salt for deterministic IDs. Default: "" */
|
|
1212
|
+
idSalt?: string;
|
|
1213
|
+
/** Tool metadata for Meta envelope */
|
|
1214
|
+
meta?: {
|
|
1215
|
+
toolName?: string;
|
|
1216
|
+
toolVersion?: string;
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
declare class CucumberMessagesFormatter {
|
|
1220
|
+
private options;
|
|
1221
|
+
constructor(options?: CucumberMessagesOptions);
|
|
1222
|
+
/**
|
|
1223
|
+
* Format a TestRunResult into an array of Envelope objects.
|
|
1224
|
+
*/
|
|
1225
|
+
format(run: TestRunResult): Envelope[];
|
|
1226
|
+
/**
|
|
1227
|
+
* Format as NDJSON string (one JSON line per envelope).
|
|
1228
|
+
*/
|
|
1229
|
+
formatToString(run: TestRunResult): string;
|
|
1230
|
+
/**
|
|
1231
|
+
* Build the Meta envelope.
|
|
1232
|
+
*/
|
|
1233
|
+
private buildMetaEnvelope;
|
|
1234
|
+
/**
|
|
1235
|
+
* Group test cases by source file, preserving order.
|
|
1236
|
+
*/
|
|
1237
|
+
private groupBySourceFile;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* CucumberHtmlFormatter — produces the official Cucumber HTML report.
|
|
1242
|
+
*
|
|
1243
|
+
* Thin wrapper: reuses CucumberMessagesFormatter to generate NDJSON envelopes,
|
|
1244
|
+
* then pipes them through @cucumber/html-formatter's CucumberHtmlStream.
|
|
1245
|
+
*/
|
|
1246
|
+
|
|
1247
|
+
interface CucumberHtmlOptions {
|
|
1248
|
+
/** Options forwarded to the underlying CucumberMessagesFormatter */
|
|
1249
|
+
messages?: CucumberMessagesOptions;
|
|
1250
|
+
}
|
|
1251
|
+
declare class CucumberHtmlFormatter {
|
|
1252
|
+
private messagesFormatter;
|
|
1253
|
+
constructor(options?: CucumberHtmlOptions);
|
|
1254
|
+
/**
|
|
1255
|
+
* Format a TestRunResult into official Cucumber HTML.
|
|
1256
|
+
*
|
|
1257
|
+
* Returns a Promise because CucumberHtmlStream is a Node.js Transform stream.
|
|
1258
|
+
*/
|
|
1259
|
+
format(run: TestRunResult): Promise<string>;
|
|
1260
|
+
/**
|
|
1261
|
+
* Format a TestRunResult into official Cucumber HTML string.
|
|
1262
|
+
*/
|
|
1263
|
+
formatToString(run: TestRunResult): Promise<string>;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* NDJSON-to-TestRunResult parser.
|
|
1268
|
+
*
|
|
1269
|
+
* Parses Cucumber Messages NDJSON (one JSON envelope per line) back into
|
|
1270
|
+
* a TestRunResult suitable for rendering by HtmlFormatter or other formatters.
|
|
1271
|
+
*
|
|
1272
|
+
* This is the NDJSON compat path: it produces a minimal but sufficient
|
|
1273
|
+
* TestRunResult. Fields not present in the NDJSON stream are given
|
|
1274
|
+
* sensible defaults.
|
|
1275
|
+
*/
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* Parse an NDJSON string into a TestRunResult.
|
|
1279
|
+
*
|
|
1280
|
+
* @param ndjson - NDJSON string (one JSON envelope per line)
|
|
1281
|
+
* @returns TestRunResult reconstructed from the envelopes
|
|
1282
|
+
*/
|
|
1283
|
+
declare function parseNdjson(ndjson: string): TestRunResult;
|
|
1284
|
+
/**
|
|
1285
|
+
* Parse an array of Envelope objects into a TestRunResult.
|
|
1286
|
+
*
|
|
1287
|
+
* @param envelopes - Array of Cucumber Messages envelopes
|
|
1288
|
+
* @returns TestRunResult reconstructed from the envelopes
|
|
1289
|
+
*/
|
|
1290
|
+
declare function parseEnvelopes(envelopes: Envelope[]): TestRunResult;
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* Git information utilities.
|
|
1294
|
+
*
|
|
1295
|
+
* Read git SHA and other info from the local repository.
|
|
1296
|
+
*/
|
|
1297
|
+
/**
|
|
1298
|
+
* Read the current git SHA.
|
|
1299
|
+
*
|
|
1300
|
+
* Checks environment variables first (for CI), then reads from .git directory.
|
|
1301
|
+
*
|
|
1302
|
+
* @param cwd - Working directory to start search from
|
|
1303
|
+
* @returns Git SHA or undefined if not in a git repo
|
|
1304
|
+
*/
|
|
1305
|
+
declare function readGitSha(cwd?: string): string | undefined;
|
|
1306
|
+
/**
|
|
1307
|
+
* Find the .git directory starting from a given directory.
|
|
1308
|
+
*
|
|
1309
|
+
* @param start - Directory to start search from
|
|
1310
|
+
* @returns Path to .git directory or undefined if not found
|
|
1311
|
+
*/
|
|
1312
|
+
declare function findGitDir(start: string): string | undefined;
|
|
1313
|
+
/**
|
|
1314
|
+
* Read the current branch name.
|
|
1315
|
+
*
|
|
1316
|
+
* @param cwd - Working directory
|
|
1317
|
+
* @returns Branch name or undefined
|
|
1318
|
+
*/
|
|
1319
|
+
declare function readBranchName(cwd?: string): string | undefined;
|
|
1320
|
+
|
|
1321
|
+
/**
|
|
1322
|
+
* Duration formatting utilities.
|
|
1323
|
+
*/
|
|
1324
|
+
/**
|
|
1325
|
+
* Format milliseconds as human-readable duration.
|
|
1326
|
+
*
|
|
1327
|
+
* @param ms - Duration in milliseconds
|
|
1328
|
+
* @returns Formatted string (e.g., "123 ms", "1.5 s", "2m 30s")
|
|
1329
|
+
*/
|
|
1330
|
+
declare function formatDuration(ms: number): string;
|
|
1331
|
+
/**
|
|
1332
|
+
* Convert milliseconds to nanoseconds.
|
|
1333
|
+
*
|
|
1334
|
+
* Used for Cucumber JSON format which expects nanoseconds.
|
|
1335
|
+
*
|
|
1336
|
+
* @param ms - Duration in milliseconds
|
|
1337
|
+
* @returns Duration in nanoseconds
|
|
1338
|
+
*/
|
|
1339
|
+
declare function msToNanoseconds(ms: number): number;
|
|
1340
|
+
/**
|
|
1341
|
+
* Convert nanoseconds to milliseconds.
|
|
1342
|
+
*
|
|
1343
|
+
* @param ns - Duration in nanoseconds
|
|
1344
|
+
* @returns Duration in milliseconds
|
|
1345
|
+
*/
|
|
1346
|
+
declare function nanosecondsToMs(ns: number): number;
|
|
1347
|
+
|
|
1348
|
+
/**
|
|
1349
|
+
* Metadata utilities for reading package information.
|
|
1350
|
+
*/
|
|
1351
|
+
/**
|
|
1352
|
+
* Read the package version from the closest package.json.
|
|
1353
|
+
*
|
|
1354
|
+
* Results are cached by root directory.
|
|
1355
|
+
*
|
|
1356
|
+
* @param root - Directory to start searching from
|
|
1357
|
+
* @returns Package version string or undefined if not found
|
|
1358
|
+
*/
|
|
1359
|
+
declare function readPackageVersion(root: string): string | undefined;
|
|
1360
|
+
/**
|
|
1361
|
+
* Clear the package version cache.
|
|
1362
|
+
* Useful for testing.
|
|
1363
|
+
*/
|
|
1364
|
+
declare function clearVersionCache(): void;
|
|
1365
|
+
|
|
1366
|
+
/**
|
|
1367
|
+
* CI environment auto-detection utility.
|
|
1368
|
+
*
|
|
1369
|
+
* Detects known CI providers from environment variables.
|
|
1370
|
+
* Precedence: GitHub Actions > CircleCI > Jenkins > Travis > GitLab CI > generic CI
|
|
1371
|
+
*/
|
|
1372
|
+
|
|
1373
|
+
/**
|
|
1374
|
+
* Detect CI environment from process.env.
|
|
1375
|
+
* Returns undefined when not running in CI.
|
|
1376
|
+
*/
|
|
1377
|
+
declare function detectCI(env?: Record<string, string | undefined>): RawCIInfo | undefined;
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* @executable-stories/formatters
|
|
1381
|
+
*
|
|
1382
|
+
* Cucumber-compatible report formats (JSON, HTML, JUnit, Markdown)
|
|
1383
|
+
* for Jest, Vitest, and Playwright test results.
|
|
1384
|
+
*
|
|
1385
|
+
* Architecture:
|
|
1386
|
+
* - Layer 1: Framework Adapters (adaptJestRun, adaptVitestRun, adaptPlaywrightRun)
|
|
1387
|
+
* - Layer 2: Anti-Corruption Layer (canonicalizeRun)
|
|
1388
|
+
* - Layer 3: Formatters (CucumberJsonFormatter, HtmlFormatter, JUnitFormatter, MarkdownFormatter)
|
|
1389
|
+
*/
|
|
1390
|
+
|
|
1391
|
+
/** Arguments for generate function */
|
|
1392
|
+
interface GenerateArgs {
|
|
1393
|
+
/** Canonical test run result */
|
|
1394
|
+
run: TestRunResult;
|
|
1395
|
+
/** Optional options override */
|
|
1396
|
+
options?: FormatterOptions;
|
|
1397
|
+
}
|
|
1398
|
+
/** Dependencies for generate function (injectable for testing) */
|
|
1399
|
+
interface GenerateDeps {
|
|
1400
|
+
/** Logger for warnings */
|
|
1401
|
+
logger: Logger;
|
|
1402
|
+
/** File writer function */
|
|
1403
|
+
writeFile: WriteFile;
|
|
1404
|
+
}
|
|
1405
|
+
/** Result of generate function: Map of format to array of file paths */
|
|
1406
|
+
type GenerateResult = Map<OutputFormat, string[]>;
|
|
1407
|
+
/**
|
|
1408
|
+
* High-level report generator that combines multiple formatters.
|
|
1409
|
+
*
|
|
1410
|
+
* Accepts ONLY canonical TestRunResult - use adapters + canonicalizeRun first.
|
|
1411
|
+
*
|
|
1412
|
+
* Supports output routing:
|
|
1413
|
+
* - Aggregated: All test cases in a single file
|
|
1414
|
+
* - Colocated mirrored: Files mirrored under outputDir preserving directory structure
|
|
1415
|
+
* - Colocated adjacent: Files written next to source files
|
|
1416
|
+
* - Rule-based: Different routing based on source file patterns
|
|
1417
|
+
*/
|
|
1418
|
+
declare class ReportGenerator {
|
|
1419
|
+
private options;
|
|
1420
|
+
private deps;
|
|
1421
|
+
constructor(options?: FormatterOptions, deps?: Partial<GenerateDeps>);
|
|
1422
|
+
/**
|
|
1423
|
+
* Resolve options with defaults.
|
|
1424
|
+
*/
|
|
1425
|
+
private resolveOptions;
|
|
1426
|
+
/**
|
|
1427
|
+
* Generate reports for a test run.
|
|
1428
|
+
*
|
|
1429
|
+
* @param run - Canonical TestRunResult (use canonicalizeRun to create from RawRun)
|
|
1430
|
+
* @returns Map of output format to generated file paths
|
|
1431
|
+
*/
|
|
1432
|
+
generate(run: TestRunResult): Promise<GenerateResult>;
|
|
1433
|
+
/**
|
|
1434
|
+
* Generate reports for a single format.
|
|
1435
|
+
*/
|
|
1436
|
+
private generateFormat;
|
|
1437
|
+
/**
|
|
1438
|
+
* Format content for a specific format.
|
|
1439
|
+
*/
|
|
1440
|
+
private formatContent;
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Factory function to create a ReportGenerator with dependency injection.
|
|
1444
|
+
*
|
|
1445
|
+
* Useful for testing and custom configurations.
|
|
1446
|
+
*/
|
|
1447
|
+
declare function createReportGenerator(options?: FormatterOptions, deps?: Partial<GenerateDeps>): ReportGenerator;
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* Normalize Jest results to canonical TestRunResult.
|
|
1451
|
+
*
|
|
1452
|
+
* Combines adaptJestRun + canonicalizeRun.
|
|
1453
|
+
*/
|
|
1454
|
+
declare function normalizeJestResults(jestResults: Parameters<typeof adaptJestRun>[0], storyReports: Parameters<typeof adaptJestRun>[1], adapterOptions?: Parameters<typeof adaptJestRun>[2], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
|
|
1455
|
+
/**
|
|
1456
|
+
* Normalize Vitest results to canonical TestRunResult.
|
|
1457
|
+
*
|
|
1458
|
+
* Combines adaptVitestRun + canonicalizeRun.
|
|
1459
|
+
*/
|
|
1460
|
+
declare function normalizeVitestResults(testModules: Parameters<typeof adaptVitestRun>[0], adapterOptions?: Parameters<typeof adaptVitestRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
|
|
1461
|
+
/**
|
|
1462
|
+
* Normalize Playwright results to canonical TestRunResult.
|
|
1463
|
+
*
|
|
1464
|
+
* Combines adaptPlaywrightRun + canonicalizeRun.
|
|
1465
|
+
*/
|
|
1466
|
+
declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
|
|
1467
|
+
|
|
1468
|
+
export { type Attachment, type CIInfo, type CanonicalizeOptions, type ColocatedStyle, type CoverageSummary, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DocEntry, type FormatterOptions, type GenerateArgs, type GenerateDeps, type GenerateResult, HtmlFormatter, type HtmlOptions, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type Logger, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, RawAttachment, RawCIInfo, RawRun, RawStatus, ReportGenerator, type ResolvedFormatterOptions, type StepResult, StoryMeta, StoryStep, type TestCaseAttempt, type TestCaseResult, type TestRunResult, type TestStatus, type ValidationResult, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assertValidRun, canonicalizeRun, clearVersionCache, createReportGenerator, deriveStepResults, detectCI, findGitDir, formatDuration, generateRunId, generateTestCaseId, mergeStepResults, msToNanoseconds, nanosecondsToMs, normalizeJestResults, normalizePlaywrightResults, normalizeStatus, normalizeVitestResults, parseEnvelopes, parseNdjson, readBranchName, readGitSha, readPackageVersion, resolveAttachment, resolveAttachments, slugify, validateCanonicalRun };
|