executable-stories-react 0.2.1 → 0.3.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/dist/index.cjs +344 -151
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +295 -9
- package/dist/index.d.ts +295 -9
- package/dist/index.js +328 -144
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +532 -238
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +269 -2
- package/dist/interactive.d.ts +269 -2
- package/dist/interactive.js +493 -200
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +4 -0
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +225 -3
- package/dist/parse.d.ts +225 -3
- package/dist/parse.js +4 -0
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +32 -32
- package/dist/ssr.cjs +274 -117
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.d.cts +250 -2
- package/dist/ssr.d.ts +250 -2
- package/dist/ssr.js +271 -114
- package/dist/ssr.js.map +1 -1
- package/dist/styles.css +26 -0
- package/dist/tailwind.css +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,12 +1,232 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, Ref } from 'react';
|
|
3
|
-
import * as executable_stories_core from 'executable-stories-core';
|
|
4
|
-
import { ReportDocMermaid, ReportDocCode, ReportDocSection, ReportDocCustom, StoryReport, ReportSummary as ReportSummary$1, ReportAttachment, ReportFeature as ReportFeature$1, ReportScenario as ReportScenario$1, ReportStep, ReportDocEntry, ReportDocNote, ReportDocTag, ReportDocKv, ReportDocTable, ReportDocLink, ReportDocScreenshot, ReportDocVideo, ReportDocHtml } from 'executable-stories-core';
|
|
5
|
-
export { StoryReport, ReportDocEntry as StoryReportDocEntry, ReportFeature as StoryReportFeature, ReportScenario as StoryReportScenario, ReportStep as StoryReportStep, ReportSummary as StoryReportSummary } from 'executable-stories-core';
|
|
6
|
-
import { OtelSpan } from 'executable-stories-core/types/otel';
|
|
7
3
|
import * as mermaid from 'mermaid';
|
|
8
4
|
import { z } from 'zod';
|
|
9
5
|
|
|
6
|
+
/**
|
|
7
|
+
* OTel span types for trace waterfall rendering.
|
|
8
|
+
*
|
|
9
|
+
* Structurally compatible with autotel's SerializedSpan
|
|
10
|
+
* and raw OTel nanosecond formats. No import dependency on autotel.
|
|
11
|
+
*/
|
|
12
|
+
type OtelAttributeValue = string | number | boolean | string[] | number[] | boolean[];
|
|
13
|
+
interface OtelSpan {
|
|
14
|
+
spanId: string;
|
|
15
|
+
parentSpanId?: string;
|
|
16
|
+
name: string;
|
|
17
|
+
/** Preferred: epoch-based milliseconds (from autotel's SerializedSpan) */
|
|
18
|
+
startTimeMs?: number;
|
|
19
|
+
durationMs?: number;
|
|
20
|
+
/** Compatibility: raw OTel nanosecond timestamps */
|
|
21
|
+
startTimeUnixNano?: number;
|
|
22
|
+
endTimeUnixNano?: number;
|
|
23
|
+
status: "ok" | "error" | "unset";
|
|
24
|
+
statusMessage?: string;
|
|
25
|
+
attributes?: Record<string, OtelAttributeValue>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Phase tracks when the doc entry was added */
|
|
29
|
+
type DocPhase = "static" | "runtime";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* StoryReport — public, frozen contract for UI renderers.
|
|
33
|
+
*
|
|
34
|
+
* Distinct from internal TestRunResult. Pre-grouped feature → scenario tree,
|
|
35
|
+
* with pre-computed summaries at every level. Adapter concerns (rawStatus,
|
|
36
|
+
* projectName, titlePath) are stripped at the toStoryReport boundary.
|
|
37
|
+
*
|
|
38
|
+
* Versioning: semver-style "<major>.<minor>". Additive-only within a major.
|
|
39
|
+
* Source of truth: schemas/story-report-v1.json. Types here must stay in sync.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
type StoryReportSchemaVersion = `1.${number}`;
|
|
43
|
+
type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
44
|
+
type StepKeyword = "Given" | "When" | "Then" | "And" | "But";
|
|
45
|
+
type StepMode = "normal" | "skip" | "only" | "todo" | "fails" | "concurrent";
|
|
46
|
+
interface ReportSummary$1 {
|
|
47
|
+
total: number;
|
|
48
|
+
passed: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
skipped: number;
|
|
51
|
+
pending: number;
|
|
52
|
+
durationMs: number;
|
|
53
|
+
}
|
|
54
|
+
interface ReportTicket {
|
|
55
|
+
id: string;
|
|
56
|
+
url?: string;
|
|
57
|
+
}
|
|
58
|
+
interface ReportAttachment {
|
|
59
|
+
name: string;
|
|
60
|
+
mediaType: string;
|
|
61
|
+
body: string;
|
|
62
|
+
contentEncoding: "BASE64" | "IDENTITY";
|
|
63
|
+
}
|
|
64
|
+
interface ReportCIInfo {
|
|
65
|
+
name: string;
|
|
66
|
+
url?: string;
|
|
67
|
+
buildNumber?: string;
|
|
68
|
+
branch?: string;
|
|
69
|
+
commitSha?: string;
|
|
70
|
+
prNumber?: string;
|
|
71
|
+
}
|
|
72
|
+
interface ReportCoverageSummary {
|
|
73
|
+
linesPct?: number;
|
|
74
|
+
branchesPct?: number;
|
|
75
|
+
functionsPct?: number;
|
|
76
|
+
statementsPct?: number;
|
|
77
|
+
}
|
|
78
|
+
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocCustom;
|
|
79
|
+
interface ReportDocNote {
|
|
80
|
+
kind: "note";
|
|
81
|
+
text: string;
|
|
82
|
+
phase: DocPhase;
|
|
83
|
+
children?: ReportDocEntry[];
|
|
84
|
+
}
|
|
85
|
+
interface ReportDocTag {
|
|
86
|
+
kind: "tag";
|
|
87
|
+
names: string[];
|
|
88
|
+
phase: DocPhase;
|
|
89
|
+
children?: ReportDocEntry[];
|
|
90
|
+
}
|
|
91
|
+
interface ReportDocKv {
|
|
92
|
+
kind: "kv";
|
|
93
|
+
label: string;
|
|
94
|
+
value: unknown;
|
|
95
|
+
phase: DocPhase;
|
|
96
|
+
children?: ReportDocEntry[];
|
|
97
|
+
}
|
|
98
|
+
interface ReportDocCode {
|
|
99
|
+
kind: "code";
|
|
100
|
+
label: string;
|
|
101
|
+
content: string;
|
|
102
|
+
lang?: string;
|
|
103
|
+
phase: DocPhase;
|
|
104
|
+
children?: ReportDocEntry[];
|
|
105
|
+
}
|
|
106
|
+
interface ReportDocTable {
|
|
107
|
+
kind: "table";
|
|
108
|
+
label: string;
|
|
109
|
+
columns: string[];
|
|
110
|
+
rows: string[][];
|
|
111
|
+
phase: DocPhase;
|
|
112
|
+
children?: ReportDocEntry[];
|
|
113
|
+
}
|
|
114
|
+
interface ReportDocLink {
|
|
115
|
+
kind: "link";
|
|
116
|
+
label: string;
|
|
117
|
+
url: string;
|
|
118
|
+
phase: DocPhase;
|
|
119
|
+
children?: ReportDocEntry[];
|
|
120
|
+
}
|
|
121
|
+
interface ReportDocSection {
|
|
122
|
+
kind: "section";
|
|
123
|
+
title: string;
|
|
124
|
+
markdown: string;
|
|
125
|
+
phase: DocPhase;
|
|
126
|
+
children?: ReportDocEntry[];
|
|
127
|
+
}
|
|
128
|
+
interface ReportDocMermaid {
|
|
129
|
+
kind: "mermaid";
|
|
130
|
+
code: string;
|
|
131
|
+
title?: string;
|
|
132
|
+
phase: DocPhase;
|
|
133
|
+
children?: ReportDocEntry[];
|
|
134
|
+
}
|
|
135
|
+
interface ReportDocScreenshot {
|
|
136
|
+
kind: "screenshot";
|
|
137
|
+
path: string;
|
|
138
|
+
alt?: string;
|
|
139
|
+
phase: DocPhase;
|
|
140
|
+
children?: ReportDocEntry[];
|
|
141
|
+
}
|
|
142
|
+
interface ReportDocVideo {
|
|
143
|
+
kind: "video";
|
|
144
|
+
path: string;
|
|
145
|
+
caption?: string;
|
|
146
|
+
poster?: string;
|
|
147
|
+
phase: DocPhase;
|
|
148
|
+
children?: ReportDocEntry[];
|
|
149
|
+
}
|
|
150
|
+
interface ReportDocHtml {
|
|
151
|
+
kind: "html";
|
|
152
|
+
/** Local HTML file path (exactly one of path/url/content) */
|
|
153
|
+
path?: string;
|
|
154
|
+
/** Remote URL rendered via iframe src (exactly one of path/url/content) */
|
|
155
|
+
url?: string;
|
|
156
|
+
/** Inline HTML content rendered via iframe srcdoc (exactly one of path/url/content) */
|
|
157
|
+
content?: string;
|
|
158
|
+
title?: string;
|
|
159
|
+
/** Iframe height: number → px, string passed through (e.g. "60vh"). Default 400px. */
|
|
160
|
+
height?: number | string;
|
|
161
|
+
phase: DocPhase;
|
|
162
|
+
children?: ReportDocEntry[];
|
|
163
|
+
}
|
|
164
|
+
interface ReportDocCustom {
|
|
165
|
+
kind: "custom";
|
|
166
|
+
type: string;
|
|
167
|
+
data: unknown;
|
|
168
|
+
phase: DocPhase;
|
|
169
|
+
children?: ReportDocEntry[];
|
|
170
|
+
}
|
|
171
|
+
interface ReportStep {
|
|
172
|
+
id: string;
|
|
173
|
+
index: number;
|
|
174
|
+
keyword: StepKeyword;
|
|
175
|
+
text: string;
|
|
176
|
+
status: TestStatus;
|
|
177
|
+
durationMs: number;
|
|
178
|
+
errorMessage?: string;
|
|
179
|
+
mode?: StepMode;
|
|
180
|
+
docEntries: ReportDocEntry[];
|
|
181
|
+
}
|
|
182
|
+
interface ReportScenario$1 {
|
|
183
|
+
id: string;
|
|
184
|
+
title: string;
|
|
185
|
+
status: TestStatus;
|
|
186
|
+
/**
|
|
187
|
+
* True for scenarios authored with the framework's todo modifier
|
|
188
|
+
* (e.g. `it.todo`): specified behavior with no implementation yet.
|
|
189
|
+
* Canonical status stays "pending"; this flags why.
|
|
190
|
+
*/
|
|
191
|
+
planned?: boolean;
|
|
192
|
+
durationMs: number;
|
|
193
|
+
tags: string[];
|
|
194
|
+
tickets?: ReportTicket[];
|
|
195
|
+
/** Product-code paths/globs this scenario exercises (project-root-relative). */
|
|
196
|
+
covers?: string[];
|
|
197
|
+
sourceLine?: number;
|
|
198
|
+
errorMessage?: string;
|
|
199
|
+
errorStack?: string;
|
|
200
|
+
retry: number;
|
|
201
|
+
retries: number;
|
|
202
|
+
docEntries: ReportDocEntry[];
|
|
203
|
+
steps: ReportStep[];
|
|
204
|
+
attachments: ReportAttachment[];
|
|
205
|
+
/** OTel spans for the trace waterfall (carried through from the run). */
|
|
206
|
+
otelSpans?: OtelSpan[];
|
|
207
|
+
}
|
|
208
|
+
interface ReportFeature$1 {
|
|
209
|
+
id: string;
|
|
210
|
+
title: string;
|
|
211
|
+
sourceFile: string;
|
|
212
|
+
summary: ReportSummary$1;
|
|
213
|
+
scenarios: ReportScenario$1[];
|
|
214
|
+
}
|
|
215
|
+
interface StoryReport {
|
|
216
|
+
schemaVersion: StoryReportSchemaVersion;
|
|
217
|
+
runId: string;
|
|
218
|
+
startedAtMs: number;
|
|
219
|
+
finishedAtMs: number;
|
|
220
|
+
durationMs: number;
|
|
221
|
+
projectRoot: string;
|
|
222
|
+
packageVersion?: string;
|
|
223
|
+
gitSha?: string;
|
|
224
|
+
ci?: ReportCIInfo;
|
|
225
|
+
coverage?: ReportCoverageSummary;
|
|
226
|
+
summary: ReportSummary$1;
|
|
227
|
+
features: ReportFeature$1[];
|
|
228
|
+
}
|
|
229
|
+
|
|
10
230
|
/**
|
|
11
231
|
* Result<T> — explicit success/error type matching the cookbook convention.
|
|
12
232
|
*
|
|
@@ -86,9 +306,10 @@ interface ReportSummaryViewProps {
|
|
|
86
306
|
declare function ReportSummaryView({ summary, className, ariaLabel }: ReportSummaryViewProps): react.JSX.Element;
|
|
87
307
|
|
|
88
308
|
/**
|
|
89
|
-
* Run metadata line (started, duration, version, git SHA, CI) —
|
|
90
|
-
* equivalent of the report's `.meta-info` block. Reads the top-level
|
|
91
|
-
* fields from context.
|
|
309
|
+
* Run metadata line (started, duration, version, branch, git SHA, CI, PR) —
|
|
310
|
+
* the React equivalent of the report's `.meta-info` block. Reads the top-level
|
|
311
|
+
* StoryReport fields from context. Commit and PR become links when the CI run
|
|
312
|
+
* URL lets us derive them safely (GitHub/GitLab shapes only).
|
|
92
313
|
*/
|
|
93
314
|
declare function ReportMeta(): react.JSX.Element | null;
|
|
94
315
|
|
|
@@ -293,6 +514,71 @@ declare function ScenarioExplorer({ scenarios, summary }: ScenarioExplorerProps)
|
|
|
293
514
|
declare function useCustomRenderers(): CustomRenderers;
|
|
294
515
|
declare function useBuiltinRenderers(): BuiltinRenderers;
|
|
295
516
|
|
|
517
|
+
type ReportCI = NonNullable<StoryReport["ci"]>;
|
|
518
|
+
/**
|
|
519
|
+
* Epoch ms of the run the report documents — the staleness reference.
|
|
520
|
+
* Prefers finishedAtMs; falls back to startedAtMs for reports from adapters
|
|
521
|
+
* that only stamp a start time.
|
|
522
|
+
*/
|
|
523
|
+
declare function reportLastRunMs(report: Pick<StoryReport, "startedAtMs" | "finishedAtMs">): number | undefined;
|
|
524
|
+
/**
|
|
525
|
+
* Human-readable age like "just now", "5 minutes ago", "3 hours ago",
|
|
526
|
+
* "12 days ago". Clock skew (thenMs in the future) reads as "just now".
|
|
527
|
+
*/
|
|
528
|
+
declare function formatRelativeAge(thenMs: number, nowMs: number): string;
|
|
529
|
+
/**
|
|
530
|
+
* A report is stale once its run is `staleAfterDays` or more days old.
|
|
531
|
+
* A threshold of 0 (or negative) disables staleness entirely.
|
|
532
|
+
*/
|
|
533
|
+
declare function isReportStale(lastRunMs: number | undefined, staleAfterDays: number, nowMs: number): boolean;
|
|
534
|
+
declare function ciDisplayName(name: string): string;
|
|
535
|
+
/**
|
|
536
|
+
* Derive a browsable commit URL from the CI run URL, for the providers whose
|
|
537
|
+
* URL structure makes that safe:
|
|
538
|
+
* GitHub Actions …/owner/repo/actions/runs/123 -> …/owner/repo/commit/<sha>
|
|
539
|
+
* GitLab CI …/group/project/-/pipelines/123 -> …/group/project/-/commit/<sha>
|
|
540
|
+
* Other providers return undefined (a wrong link is worse than none).
|
|
541
|
+
*/
|
|
542
|
+
declare function commitUrl(ci: ReportCI | undefined, sha: string | undefined): string | undefined;
|
|
543
|
+
/**
|
|
544
|
+
* Derive a pull-request URL for GitHub-shaped CI run URLs. GitLab and the
|
|
545
|
+
* rest return undefined for the same wrong-link-is-worse-than-none reason.
|
|
546
|
+
*/
|
|
547
|
+
declare function prUrl(ci: ReportCI | undefined): string | undefined;
|
|
548
|
+
|
|
549
|
+
type ScenarioRunStatus = "passed" | "failed" | "skipped" | "pending";
|
|
550
|
+
/** One historical run of a scenario, oldest → newest in a history array. */
|
|
551
|
+
interface ScenarioRunEvent {
|
|
552
|
+
/** Epoch ms the run started. */
|
|
553
|
+
timestamp: number;
|
|
554
|
+
status: ScenarioRunStatus;
|
|
555
|
+
runId?: string;
|
|
556
|
+
durationMs?: number;
|
|
557
|
+
commitSha?: string;
|
|
558
|
+
branch?: string;
|
|
559
|
+
}
|
|
560
|
+
/** Recent run events keyed by ReportScenario.id. */
|
|
561
|
+
type ScenarioHistoryMap = Record<string, ScenarioRunEvent[]>;
|
|
562
|
+
interface RunStreak {
|
|
563
|
+
status: ScenarioRunStatus;
|
|
564
|
+
/** How many consecutive trailing runs share that status (≥1). */
|
|
565
|
+
count: number;
|
|
566
|
+
}
|
|
567
|
+
/** The trailing same-status streak — "passing for 5 runs", "failing for 2". */
|
|
568
|
+
declare function currentStreak(entries: readonly ScenarioRunEvent[]): RunStreak | undefined;
|
|
569
|
+
/** Short human summary of a history window, used for the strip's tooltip. */
|
|
570
|
+
declare function describeRunHistory(entries: readonly ScenarioRunEvent[]): string;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Compact run-over-run timeline for one scenario: a dot per recent run,
|
|
574
|
+
* oldest → newest. Renders nothing outside <ReportInteractive> or when the
|
|
575
|
+
* report was generated without --history-file — history is presentation-layer
|
|
576
|
+
* data and never part of the StoryReport contract.
|
|
577
|
+
*/
|
|
578
|
+
declare function ScenarioRunHistory({ scenarioId }: {
|
|
579
|
+
scenarioId: string;
|
|
580
|
+
}): react.JSX.Element | null;
|
|
581
|
+
|
|
296
582
|
interface ReportEmptyProps {
|
|
297
583
|
message?: string;
|
|
298
584
|
}
|
|
@@ -303,7 +589,7 @@ interface ReportSchemaErrorProps {
|
|
|
303
589
|
}
|
|
304
590
|
declare function ReportSchemaError({ error }: ReportSchemaErrorProps): react.JSX.Element;
|
|
305
591
|
|
|
306
|
-
declare function useReport():
|
|
592
|
+
declare function useReport(): StoryReport;
|
|
307
593
|
|
|
308
594
|
/**
|
|
309
595
|
* parseStoryReport — boundary validator. Accepts unknown input (file contents,
|
|
@@ -333,4 +619,4 @@ declare const STORY_REPORT_SCHEMA_MAJOR: 1;
|
|
|
333
619
|
|
|
334
620
|
declare const storyReportSchema: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
335
621
|
|
|
336
|
-
export { type BuiltinRenderers, type CustomRenderer, type CustomRenderers, DocCode, DocCustom, DocEntry, DocHtml, DocKv, DocLink, DocMermaid, DocNote, DocScreenshot, DocSection, DocTable, DocTag, DocVideo, type ExplorerScenario, type ExplorerStatus, MermaidDiagram, MermaidSource, Report, ReportAttachments, ReportDocEntries, type ReportDocEntriesProps, ReportEmpty, type ReportEmptyProps, ReportFeature, ReportFeatureList, type ReportFeatureProps, ReportMeta, type ReportParseError, type ReportParseErrorCode, type ReportProps, ReportRoot, type ReportRootProps, ReportScenario, ReportScenarioList, type ReportScenarioListProps, type ReportScenarioProps, ReportSchemaError, type ReportSchemaErrorProps, ReportStepItem, ReportSteps, type ReportStepsProps, ReportSummary, type ReportSummaryProps, ReportSummaryView, type ReportSummaryViewProps, ReportTrace, type Result, STORY_REPORT_SCHEMA_MAJOR, ScenarioExplorer, type ScenarioExplorerProps, err, ok, parseStoryReport, storyReportSchema, useBuiltinRenderers, useCustomRenderers, useReport };
|
|
622
|
+
export { type BuiltinRenderers, type CustomRenderer, type CustomRenderers, DocCode, DocCustom, DocEntry, DocHtml, DocKv, DocLink, DocMermaid, DocNote, DocScreenshot, DocSection, DocTable, DocTag, DocVideo, type ExplorerScenario, type ExplorerStatus, MermaidDiagram, MermaidSource, Report, ReportAttachments, ReportDocEntries, type ReportDocEntriesProps, ReportEmpty, type ReportEmptyProps, ReportFeature, ReportFeatureList, type ReportFeatureProps, ReportMeta, type ReportParseError, type ReportParseErrorCode, type ReportProps, ReportRoot, type ReportRootProps, ReportScenario, ReportScenarioList, type ReportScenarioListProps, type ReportScenarioProps, ReportSchemaError, type ReportSchemaErrorProps, ReportStepItem, ReportSteps, type ReportStepsProps, ReportSummary, type ReportSummaryProps, ReportSummaryView, type ReportSummaryViewProps, ReportTrace, type Result, type RunStreak, STORY_REPORT_SCHEMA_MAJOR, ScenarioExplorer, type ScenarioExplorerProps, type ScenarioHistoryMap, type ScenarioRunEvent, ScenarioRunHistory, type ScenarioRunStatus, type StoryReport, type ReportDocEntry as StoryReportDocEntry, type ReportFeature$1 as StoryReportFeature, type ReportScenario$1 as StoryReportScenario, type ReportStep as StoryReportStep, type ReportSummary$1 as StoryReportSummary, ciDisplayName, commitUrl, currentStreak, describeRunHistory, err, formatRelativeAge, isReportStale, ok, parseStoryReport, prUrl, reportLastRunMs, storyReportSchema, useBuiltinRenderers, useCustomRenderers, useReport };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,232 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, Ref } from 'react';
|
|
3
|
-
import * as executable_stories_core from 'executable-stories-core';
|
|
4
|
-
import { ReportDocMermaid, ReportDocCode, ReportDocSection, ReportDocCustom, StoryReport, ReportSummary as ReportSummary$1, ReportAttachment, ReportFeature as ReportFeature$1, ReportScenario as ReportScenario$1, ReportStep, ReportDocEntry, ReportDocNote, ReportDocTag, ReportDocKv, ReportDocTable, ReportDocLink, ReportDocScreenshot, ReportDocVideo, ReportDocHtml } from 'executable-stories-core';
|
|
5
|
-
export { StoryReport, ReportDocEntry as StoryReportDocEntry, ReportFeature as StoryReportFeature, ReportScenario as StoryReportScenario, ReportStep as StoryReportStep, ReportSummary as StoryReportSummary } from 'executable-stories-core';
|
|
6
|
-
import { OtelSpan } from 'executable-stories-core/types/otel';
|
|
7
3
|
import * as mermaid from 'mermaid';
|
|
8
4
|
import { z } from 'zod';
|
|
9
5
|
|
|
6
|
+
/**
|
|
7
|
+
* OTel span types for trace waterfall rendering.
|
|
8
|
+
*
|
|
9
|
+
* Structurally compatible with autotel's SerializedSpan
|
|
10
|
+
* and raw OTel nanosecond formats. No import dependency on autotel.
|
|
11
|
+
*/
|
|
12
|
+
type OtelAttributeValue = string | number | boolean | string[] | number[] | boolean[];
|
|
13
|
+
interface OtelSpan {
|
|
14
|
+
spanId: string;
|
|
15
|
+
parentSpanId?: string;
|
|
16
|
+
name: string;
|
|
17
|
+
/** Preferred: epoch-based milliseconds (from autotel's SerializedSpan) */
|
|
18
|
+
startTimeMs?: number;
|
|
19
|
+
durationMs?: number;
|
|
20
|
+
/** Compatibility: raw OTel nanosecond timestamps */
|
|
21
|
+
startTimeUnixNano?: number;
|
|
22
|
+
endTimeUnixNano?: number;
|
|
23
|
+
status: "ok" | "error" | "unset";
|
|
24
|
+
statusMessage?: string;
|
|
25
|
+
attributes?: Record<string, OtelAttributeValue>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Phase tracks when the doc entry was added */
|
|
29
|
+
type DocPhase = "static" | "runtime";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* StoryReport — public, frozen contract for UI renderers.
|
|
33
|
+
*
|
|
34
|
+
* Distinct from internal TestRunResult. Pre-grouped feature → scenario tree,
|
|
35
|
+
* with pre-computed summaries at every level. Adapter concerns (rawStatus,
|
|
36
|
+
* projectName, titlePath) are stripped at the toStoryReport boundary.
|
|
37
|
+
*
|
|
38
|
+
* Versioning: semver-style "<major>.<minor>". Additive-only within a major.
|
|
39
|
+
* Source of truth: schemas/story-report-v1.json. Types here must stay in sync.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
type StoryReportSchemaVersion = `1.${number}`;
|
|
43
|
+
type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
44
|
+
type StepKeyword = "Given" | "When" | "Then" | "And" | "But";
|
|
45
|
+
type StepMode = "normal" | "skip" | "only" | "todo" | "fails" | "concurrent";
|
|
46
|
+
interface ReportSummary$1 {
|
|
47
|
+
total: number;
|
|
48
|
+
passed: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
skipped: number;
|
|
51
|
+
pending: number;
|
|
52
|
+
durationMs: number;
|
|
53
|
+
}
|
|
54
|
+
interface ReportTicket {
|
|
55
|
+
id: string;
|
|
56
|
+
url?: string;
|
|
57
|
+
}
|
|
58
|
+
interface ReportAttachment {
|
|
59
|
+
name: string;
|
|
60
|
+
mediaType: string;
|
|
61
|
+
body: string;
|
|
62
|
+
contentEncoding: "BASE64" | "IDENTITY";
|
|
63
|
+
}
|
|
64
|
+
interface ReportCIInfo {
|
|
65
|
+
name: string;
|
|
66
|
+
url?: string;
|
|
67
|
+
buildNumber?: string;
|
|
68
|
+
branch?: string;
|
|
69
|
+
commitSha?: string;
|
|
70
|
+
prNumber?: string;
|
|
71
|
+
}
|
|
72
|
+
interface ReportCoverageSummary {
|
|
73
|
+
linesPct?: number;
|
|
74
|
+
branchesPct?: number;
|
|
75
|
+
functionsPct?: number;
|
|
76
|
+
statementsPct?: number;
|
|
77
|
+
}
|
|
78
|
+
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocCustom;
|
|
79
|
+
interface ReportDocNote {
|
|
80
|
+
kind: "note";
|
|
81
|
+
text: string;
|
|
82
|
+
phase: DocPhase;
|
|
83
|
+
children?: ReportDocEntry[];
|
|
84
|
+
}
|
|
85
|
+
interface ReportDocTag {
|
|
86
|
+
kind: "tag";
|
|
87
|
+
names: string[];
|
|
88
|
+
phase: DocPhase;
|
|
89
|
+
children?: ReportDocEntry[];
|
|
90
|
+
}
|
|
91
|
+
interface ReportDocKv {
|
|
92
|
+
kind: "kv";
|
|
93
|
+
label: string;
|
|
94
|
+
value: unknown;
|
|
95
|
+
phase: DocPhase;
|
|
96
|
+
children?: ReportDocEntry[];
|
|
97
|
+
}
|
|
98
|
+
interface ReportDocCode {
|
|
99
|
+
kind: "code";
|
|
100
|
+
label: string;
|
|
101
|
+
content: string;
|
|
102
|
+
lang?: string;
|
|
103
|
+
phase: DocPhase;
|
|
104
|
+
children?: ReportDocEntry[];
|
|
105
|
+
}
|
|
106
|
+
interface ReportDocTable {
|
|
107
|
+
kind: "table";
|
|
108
|
+
label: string;
|
|
109
|
+
columns: string[];
|
|
110
|
+
rows: string[][];
|
|
111
|
+
phase: DocPhase;
|
|
112
|
+
children?: ReportDocEntry[];
|
|
113
|
+
}
|
|
114
|
+
interface ReportDocLink {
|
|
115
|
+
kind: "link";
|
|
116
|
+
label: string;
|
|
117
|
+
url: string;
|
|
118
|
+
phase: DocPhase;
|
|
119
|
+
children?: ReportDocEntry[];
|
|
120
|
+
}
|
|
121
|
+
interface ReportDocSection {
|
|
122
|
+
kind: "section";
|
|
123
|
+
title: string;
|
|
124
|
+
markdown: string;
|
|
125
|
+
phase: DocPhase;
|
|
126
|
+
children?: ReportDocEntry[];
|
|
127
|
+
}
|
|
128
|
+
interface ReportDocMermaid {
|
|
129
|
+
kind: "mermaid";
|
|
130
|
+
code: string;
|
|
131
|
+
title?: string;
|
|
132
|
+
phase: DocPhase;
|
|
133
|
+
children?: ReportDocEntry[];
|
|
134
|
+
}
|
|
135
|
+
interface ReportDocScreenshot {
|
|
136
|
+
kind: "screenshot";
|
|
137
|
+
path: string;
|
|
138
|
+
alt?: string;
|
|
139
|
+
phase: DocPhase;
|
|
140
|
+
children?: ReportDocEntry[];
|
|
141
|
+
}
|
|
142
|
+
interface ReportDocVideo {
|
|
143
|
+
kind: "video";
|
|
144
|
+
path: string;
|
|
145
|
+
caption?: string;
|
|
146
|
+
poster?: string;
|
|
147
|
+
phase: DocPhase;
|
|
148
|
+
children?: ReportDocEntry[];
|
|
149
|
+
}
|
|
150
|
+
interface ReportDocHtml {
|
|
151
|
+
kind: "html";
|
|
152
|
+
/** Local HTML file path (exactly one of path/url/content) */
|
|
153
|
+
path?: string;
|
|
154
|
+
/** Remote URL rendered via iframe src (exactly one of path/url/content) */
|
|
155
|
+
url?: string;
|
|
156
|
+
/** Inline HTML content rendered via iframe srcdoc (exactly one of path/url/content) */
|
|
157
|
+
content?: string;
|
|
158
|
+
title?: string;
|
|
159
|
+
/** Iframe height: number → px, string passed through (e.g. "60vh"). Default 400px. */
|
|
160
|
+
height?: number | string;
|
|
161
|
+
phase: DocPhase;
|
|
162
|
+
children?: ReportDocEntry[];
|
|
163
|
+
}
|
|
164
|
+
interface ReportDocCustom {
|
|
165
|
+
kind: "custom";
|
|
166
|
+
type: string;
|
|
167
|
+
data: unknown;
|
|
168
|
+
phase: DocPhase;
|
|
169
|
+
children?: ReportDocEntry[];
|
|
170
|
+
}
|
|
171
|
+
interface ReportStep {
|
|
172
|
+
id: string;
|
|
173
|
+
index: number;
|
|
174
|
+
keyword: StepKeyword;
|
|
175
|
+
text: string;
|
|
176
|
+
status: TestStatus;
|
|
177
|
+
durationMs: number;
|
|
178
|
+
errorMessage?: string;
|
|
179
|
+
mode?: StepMode;
|
|
180
|
+
docEntries: ReportDocEntry[];
|
|
181
|
+
}
|
|
182
|
+
interface ReportScenario$1 {
|
|
183
|
+
id: string;
|
|
184
|
+
title: string;
|
|
185
|
+
status: TestStatus;
|
|
186
|
+
/**
|
|
187
|
+
* True for scenarios authored with the framework's todo modifier
|
|
188
|
+
* (e.g. `it.todo`): specified behavior with no implementation yet.
|
|
189
|
+
* Canonical status stays "pending"; this flags why.
|
|
190
|
+
*/
|
|
191
|
+
planned?: boolean;
|
|
192
|
+
durationMs: number;
|
|
193
|
+
tags: string[];
|
|
194
|
+
tickets?: ReportTicket[];
|
|
195
|
+
/** Product-code paths/globs this scenario exercises (project-root-relative). */
|
|
196
|
+
covers?: string[];
|
|
197
|
+
sourceLine?: number;
|
|
198
|
+
errorMessage?: string;
|
|
199
|
+
errorStack?: string;
|
|
200
|
+
retry: number;
|
|
201
|
+
retries: number;
|
|
202
|
+
docEntries: ReportDocEntry[];
|
|
203
|
+
steps: ReportStep[];
|
|
204
|
+
attachments: ReportAttachment[];
|
|
205
|
+
/** OTel spans for the trace waterfall (carried through from the run). */
|
|
206
|
+
otelSpans?: OtelSpan[];
|
|
207
|
+
}
|
|
208
|
+
interface ReportFeature$1 {
|
|
209
|
+
id: string;
|
|
210
|
+
title: string;
|
|
211
|
+
sourceFile: string;
|
|
212
|
+
summary: ReportSummary$1;
|
|
213
|
+
scenarios: ReportScenario$1[];
|
|
214
|
+
}
|
|
215
|
+
interface StoryReport {
|
|
216
|
+
schemaVersion: StoryReportSchemaVersion;
|
|
217
|
+
runId: string;
|
|
218
|
+
startedAtMs: number;
|
|
219
|
+
finishedAtMs: number;
|
|
220
|
+
durationMs: number;
|
|
221
|
+
projectRoot: string;
|
|
222
|
+
packageVersion?: string;
|
|
223
|
+
gitSha?: string;
|
|
224
|
+
ci?: ReportCIInfo;
|
|
225
|
+
coverage?: ReportCoverageSummary;
|
|
226
|
+
summary: ReportSummary$1;
|
|
227
|
+
features: ReportFeature$1[];
|
|
228
|
+
}
|
|
229
|
+
|
|
10
230
|
/**
|
|
11
231
|
* Result<T> — explicit success/error type matching the cookbook convention.
|
|
12
232
|
*
|
|
@@ -86,9 +306,10 @@ interface ReportSummaryViewProps {
|
|
|
86
306
|
declare function ReportSummaryView({ summary, className, ariaLabel }: ReportSummaryViewProps): react.JSX.Element;
|
|
87
307
|
|
|
88
308
|
/**
|
|
89
|
-
* Run metadata line (started, duration, version, git SHA, CI) —
|
|
90
|
-
* equivalent of the report's `.meta-info` block. Reads the top-level
|
|
91
|
-
* fields from context.
|
|
309
|
+
* Run metadata line (started, duration, version, branch, git SHA, CI, PR) —
|
|
310
|
+
* the React equivalent of the report's `.meta-info` block. Reads the top-level
|
|
311
|
+
* StoryReport fields from context. Commit and PR become links when the CI run
|
|
312
|
+
* URL lets us derive them safely (GitHub/GitLab shapes only).
|
|
92
313
|
*/
|
|
93
314
|
declare function ReportMeta(): react.JSX.Element | null;
|
|
94
315
|
|
|
@@ -293,6 +514,71 @@ declare function ScenarioExplorer({ scenarios, summary }: ScenarioExplorerProps)
|
|
|
293
514
|
declare function useCustomRenderers(): CustomRenderers;
|
|
294
515
|
declare function useBuiltinRenderers(): BuiltinRenderers;
|
|
295
516
|
|
|
517
|
+
type ReportCI = NonNullable<StoryReport["ci"]>;
|
|
518
|
+
/**
|
|
519
|
+
* Epoch ms of the run the report documents — the staleness reference.
|
|
520
|
+
* Prefers finishedAtMs; falls back to startedAtMs for reports from adapters
|
|
521
|
+
* that only stamp a start time.
|
|
522
|
+
*/
|
|
523
|
+
declare function reportLastRunMs(report: Pick<StoryReport, "startedAtMs" | "finishedAtMs">): number | undefined;
|
|
524
|
+
/**
|
|
525
|
+
* Human-readable age like "just now", "5 minutes ago", "3 hours ago",
|
|
526
|
+
* "12 days ago". Clock skew (thenMs in the future) reads as "just now".
|
|
527
|
+
*/
|
|
528
|
+
declare function formatRelativeAge(thenMs: number, nowMs: number): string;
|
|
529
|
+
/**
|
|
530
|
+
* A report is stale once its run is `staleAfterDays` or more days old.
|
|
531
|
+
* A threshold of 0 (or negative) disables staleness entirely.
|
|
532
|
+
*/
|
|
533
|
+
declare function isReportStale(lastRunMs: number | undefined, staleAfterDays: number, nowMs: number): boolean;
|
|
534
|
+
declare function ciDisplayName(name: string): string;
|
|
535
|
+
/**
|
|
536
|
+
* Derive a browsable commit URL from the CI run URL, for the providers whose
|
|
537
|
+
* URL structure makes that safe:
|
|
538
|
+
* GitHub Actions …/owner/repo/actions/runs/123 -> …/owner/repo/commit/<sha>
|
|
539
|
+
* GitLab CI …/group/project/-/pipelines/123 -> …/group/project/-/commit/<sha>
|
|
540
|
+
* Other providers return undefined (a wrong link is worse than none).
|
|
541
|
+
*/
|
|
542
|
+
declare function commitUrl(ci: ReportCI | undefined, sha: string | undefined): string | undefined;
|
|
543
|
+
/**
|
|
544
|
+
* Derive a pull-request URL for GitHub-shaped CI run URLs. GitLab and the
|
|
545
|
+
* rest return undefined for the same wrong-link-is-worse-than-none reason.
|
|
546
|
+
*/
|
|
547
|
+
declare function prUrl(ci: ReportCI | undefined): string | undefined;
|
|
548
|
+
|
|
549
|
+
type ScenarioRunStatus = "passed" | "failed" | "skipped" | "pending";
|
|
550
|
+
/** One historical run of a scenario, oldest → newest in a history array. */
|
|
551
|
+
interface ScenarioRunEvent {
|
|
552
|
+
/** Epoch ms the run started. */
|
|
553
|
+
timestamp: number;
|
|
554
|
+
status: ScenarioRunStatus;
|
|
555
|
+
runId?: string;
|
|
556
|
+
durationMs?: number;
|
|
557
|
+
commitSha?: string;
|
|
558
|
+
branch?: string;
|
|
559
|
+
}
|
|
560
|
+
/** Recent run events keyed by ReportScenario.id. */
|
|
561
|
+
type ScenarioHistoryMap = Record<string, ScenarioRunEvent[]>;
|
|
562
|
+
interface RunStreak {
|
|
563
|
+
status: ScenarioRunStatus;
|
|
564
|
+
/** How many consecutive trailing runs share that status (≥1). */
|
|
565
|
+
count: number;
|
|
566
|
+
}
|
|
567
|
+
/** The trailing same-status streak — "passing for 5 runs", "failing for 2". */
|
|
568
|
+
declare function currentStreak(entries: readonly ScenarioRunEvent[]): RunStreak | undefined;
|
|
569
|
+
/** Short human summary of a history window, used for the strip's tooltip. */
|
|
570
|
+
declare function describeRunHistory(entries: readonly ScenarioRunEvent[]): string;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Compact run-over-run timeline for one scenario: a dot per recent run,
|
|
574
|
+
* oldest → newest. Renders nothing outside <ReportInteractive> or when the
|
|
575
|
+
* report was generated without --history-file — history is presentation-layer
|
|
576
|
+
* data and never part of the StoryReport contract.
|
|
577
|
+
*/
|
|
578
|
+
declare function ScenarioRunHistory({ scenarioId }: {
|
|
579
|
+
scenarioId: string;
|
|
580
|
+
}): react.JSX.Element | null;
|
|
581
|
+
|
|
296
582
|
interface ReportEmptyProps {
|
|
297
583
|
message?: string;
|
|
298
584
|
}
|
|
@@ -303,7 +589,7 @@ interface ReportSchemaErrorProps {
|
|
|
303
589
|
}
|
|
304
590
|
declare function ReportSchemaError({ error }: ReportSchemaErrorProps): react.JSX.Element;
|
|
305
591
|
|
|
306
|
-
declare function useReport():
|
|
592
|
+
declare function useReport(): StoryReport;
|
|
307
593
|
|
|
308
594
|
/**
|
|
309
595
|
* parseStoryReport — boundary validator. Accepts unknown input (file contents,
|
|
@@ -333,4 +619,4 @@ declare const STORY_REPORT_SCHEMA_MAJOR: 1;
|
|
|
333
619
|
|
|
334
620
|
declare const storyReportSchema: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
335
621
|
|
|
336
|
-
export { type BuiltinRenderers, type CustomRenderer, type CustomRenderers, DocCode, DocCustom, DocEntry, DocHtml, DocKv, DocLink, DocMermaid, DocNote, DocScreenshot, DocSection, DocTable, DocTag, DocVideo, type ExplorerScenario, type ExplorerStatus, MermaidDiagram, MermaidSource, Report, ReportAttachments, ReportDocEntries, type ReportDocEntriesProps, ReportEmpty, type ReportEmptyProps, ReportFeature, ReportFeatureList, type ReportFeatureProps, ReportMeta, type ReportParseError, type ReportParseErrorCode, type ReportProps, ReportRoot, type ReportRootProps, ReportScenario, ReportScenarioList, type ReportScenarioListProps, type ReportScenarioProps, ReportSchemaError, type ReportSchemaErrorProps, ReportStepItem, ReportSteps, type ReportStepsProps, ReportSummary, type ReportSummaryProps, ReportSummaryView, type ReportSummaryViewProps, ReportTrace, type Result, STORY_REPORT_SCHEMA_MAJOR, ScenarioExplorer, type ScenarioExplorerProps, err, ok, parseStoryReport, storyReportSchema, useBuiltinRenderers, useCustomRenderers, useReport };
|
|
622
|
+
export { type BuiltinRenderers, type CustomRenderer, type CustomRenderers, DocCode, DocCustom, DocEntry, DocHtml, DocKv, DocLink, DocMermaid, DocNote, DocScreenshot, DocSection, DocTable, DocTag, DocVideo, type ExplorerScenario, type ExplorerStatus, MermaidDiagram, MermaidSource, Report, ReportAttachments, ReportDocEntries, type ReportDocEntriesProps, ReportEmpty, type ReportEmptyProps, ReportFeature, ReportFeatureList, type ReportFeatureProps, ReportMeta, type ReportParseError, type ReportParseErrorCode, type ReportProps, ReportRoot, type ReportRootProps, ReportScenario, ReportScenarioList, type ReportScenarioListProps, type ReportScenarioProps, ReportSchemaError, type ReportSchemaErrorProps, ReportStepItem, ReportSteps, type ReportStepsProps, ReportSummary, type ReportSummaryProps, ReportSummaryView, type ReportSummaryViewProps, ReportTrace, type Result, type RunStreak, STORY_REPORT_SCHEMA_MAJOR, ScenarioExplorer, type ScenarioExplorerProps, type ScenarioHistoryMap, type ScenarioRunEvent, ScenarioRunHistory, type ScenarioRunStatus, type StoryReport, type ReportDocEntry as StoryReportDocEntry, type ReportFeature$1 as StoryReportFeature, type ReportScenario$1 as StoryReportScenario, type ReportStep as StoryReportStep, type ReportSummary$1 as StoryReportSummary, ciDisplayName, commitUrl, currentStreak, describeRunHistory, err, formatRelativeAge, isReportStale, ok, parseStoryReport, prUrl, reportLastRunMs, storyReportSchema, useBuiltinRenderers, useCustomRenderers, useReport };
|