executable-stories-react 0.2.0 → 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.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) — the React
90
- * equivalent of the report's `.meta-info` block. Reads the top-level StoryReport
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
 
@@ -223,6 +444,14 @@ declare function MermaidDiagram({ entry, load }: {
223
444
  load?: MermaidLoader;
224
445
  }): react.JSX.Element;
225
446
 
447
+ /**
448
+ * A screenshot that's still an absolute local filesystem path by the time it
449
+ * reaches this component means the report's asset bundler couldn't find the
450
+ * file to inline/copy it (deleted, moved, or never captured — see
451
+ * inlineScreenshotIfPossible in executable-stories-playwright). `<img src>`
452
+ * would 404 against a path from the machine that generated the report, so
453
+ * show a placeholder instead of a broken image.
454
+ */
226
455
  declare function DocScreenshot({ entry }: {
227
456
  entry: ReportDocScreenshot;
228
457
  }): react.JSX.Element;
@@ -232,6 +461,10 @@ declare function DocScreenshot({ entry }: {
232
461
  * a URL or a path that resolves alongside the report. Both `path` and `poster`
233
462
  * are adapter-supplied, so they go through the same scheme allow-list as the
234
463
  * DocHtml iframe src (no `javascript:`/`data:` URLs reach the DOM).
464
+ *
465
+ * An absolute local filesystem path means the report's asset bundler
466
+ * couldn't find/copy the file — a `<video src>` pointed at a runner-local
467
+ * path would just fail to load, so show a placeholder instead.
235
468
  */
236
469
  declare function DocVideo({ entry }: {
237
470
  entry: ReportDocVideo;
@@ -281,6 +514,71 @@ declare function ScenarioExplorer({ scenarios, summary }: ScenarioExplorerProps)
281
514
  declare function useCustomRenderers(): CustomRenderers;
282
515
  declare function useBuiltinRenderers(): BuiltinRenderers;
283
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
+
284
582
  interface ReportEmptyProps {
285
583
  message?: string;
286
584
  }
@@ -291,7 +589,7 @@ interface ReportSchemaErrorProps {
291
589
  }
292
590
  declare function ReportSchemaError({ error }: ReportSchemaErrorProps): react.JSX.Element;
293
591
 
294
- declare function useReport(): executable_stories_core.StoryReport;
592
+ declare function useReport(): StoryReport;
295
593
 
296
594
  /**
297
595
  * parseStoryReport — boundary validator. Accepts unknown input (file contents,
@@ -321,4 +619,4 @@ declare const STORY_REPORT_SCHEMA_MAJOR: 1;
321
619
 
322
620
  declare const storyReportSchema: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
323
621
 
324
- 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 };