executable-stories-react 0.7.0 → 0.9.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.
@@ -73,7 +73,7 @@ interface ReportCoverageSummary {
73
73
  functionsPct?: number;
74
74
  statementsPct?: number;
75
75
  }
76
- type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocCustom;
76
+ type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocState | ReportDocCustom;
77
77
  interface ReportDocNote {
78
78
  kind: "note";
79
79
  text: string;
@@ -159,6 +159,15 @@ interface ReportDocHtml {
159
159
  phase: DocPhase;
160
160
  children?: ReportDocEntry[];
161
161
  }
162
+ interface ReportDocState {
163
+ kind: "state";
164
+ /** Entity name ("Basket") — diff identity across steps. Unlabeled states share one lane. */
165
+ label?: string;
166
+ /** JSON-serializable snapshot of the state at this step. */
167
+ value: unknown;
168
+ phase: DocPhase;
169
+ children?: ReportDocEntry[];
170
+ }
162
171
  interface ReportDocCustom {
163
172
  kind: "custom";
164
173
  type: string;
@@ -363,12 +372,29 @@ interface ReportSearchProps {
363
372
  }
364
373
  declare const ReportSearch: react.ForwardRefExoticComponent<ReportSearchProps & react.RefAttributes<HTMLInputElement>>;
365
374
 
375
+ /**
376
+ * View state in the URL, so a filtered report survives a refresh and can be
377
+ * shared as a link.
378
+ *
379
+ * It lives in the HASH, not the query string, because the flagship surface is a
380
+ * single HTML file opened from disk. A `file://` document has an opaque origin,
381
+ * and Chrome refuses `history.pushState`/`replaceState` when the URL argument
382
+ * changes anything but the fragment there. The fragment is the one part every
383
+ * browser lets us rewrite in place.
384
+ *
385
+ * Format: `#<anchor>?<params>` — the anchor half stays exactly what it has
386
+ * always been, a scenario id deep link, so existing permalinks keep working and
387
+ * a link with no filters is unchanged.
388
+ */
389
+ type UrlStatusFilter = "all" | "passed" | "failed" | "skipped" | "pending";
390
+
366
391
  /**
367
392
  * Pure functions for filtering a StoryReport by a search query.
368
393
  * Used by <ReportInteractive>. Kept side-effect-free so it can be unit-tested.
369
394
  */
370
395
 
371
- type StatusFilter = "all" | "passed" | "failed" | "skipped" | "pending";
396
+ /** Defined with the URL codec that has to validate it, so the two can't drift. */
397
+ type StatusFilter = UrlStatusFilter;
372
398
  interface FilterCriteria {
373
399
  query?: string;
374
400
  status?: StatusFilter;
@@ -434,8 +460,13 @@ interface KeyboardShortcutHandlers {
434
460
  declare function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers): void;
435
461
 
436
462
  /**
437
- * Scrolls to a scenario by URL hash on mount and whenever the hash changes.
438
- * No-op in SSR (only runs in useEffect). Honours `prefers-reduced-motion`.
463
+ * Scrolls to a scenario by URL hash on mount and whenever the deep link
464
+ * changes. No-op in SSR (only runs in useEffect). Honours
465
+ * `prefers-reduced-motion`.
466
+ *
467
+ * The fragment also carries filter state (`#<anchor>?q=...`), so only the
468
+ * anchor half is read — and a hashchange that merely rewrote the filters must
469
+ * not yank the page back to the last anchor, hence the last-anchor guard.
439
470
  */
440
471
  declare function useDeepLinkScroll(): void;
441
472
 
@@ -73,7 +73,7 @@ interface ReportCoverageSummary {
73
73
  functionsPct?: number;
74
74
  statementsPct?: number;
75
75
  }
76
- type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocCustom;
76
+ type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocHtml | ReportDocState | ReportDocCustom;
77
77
  interface ReportDocNote {
78
78
  kind: "note";
79
79
  text: string;
@@ -159,6 +159,15 @@ interface ReportDocHtml {
159
159
  phase: DocPhase;
160
160
  children?: ReportDocEntry[];
161
161
  }
162
+ interface ReportDocState {
163
+ kind: "state";
164
+ /** Entity name ("Basket") — diff identity across steps. Unlabeled states share one lane. */
165
+ label?: string;
166
+ /** JSON-serializable snapshot of the state at this step. */
167
+ value: unknown;
168
+ phase: DocPhase;
169
+ children?: ReportDocEntry[];
170
+ }
162
171
  interface ReportDocCustom {
163
172
  kind: "custom";
164
173
  type: string;
@@ -363,12 +372,29 @@ interface ReportSearchProps {
363
372
  }
364
373
  declare const ReportSearch: react.ForwardRefExoticComponent<ReportSearchProps & react.RefAttributes<HTMLInputElement>>;
365
374
 
375
+ /**
376
+ * View state in the URL, so a filtered report survives a refresh and can be
377
+ * shared as a link.
378
+ *
379
+ * It lives in the HASH, not the query string, because the flagship surface is a
380
+ * single HTML file opened from disk. A `file://` document has an opaque origin,
381
+ * and Chrome refuses `history.pushState`/`replaceState` when the URL argument
382
+ * changes anything but the fragment there. The fragment is the one part every
383
+ * browser lets us rewrite in place.
384
+ *
385
+ * Format: `#<anchor>?<params>` — the anchor half stays exactly what it has
386
+ * always been, a scenario id deep link, so existing permalinks keep working and
387
+ * a link with no filters is unchanged.
388
+ */
389
+ type UrlStatusFilter = "all" | "passed" | "failed" | "skipped" | "pending";
390
+
366
391
  /**
367
392
  * Pure functions for filtering a StoryReport by a search query.
368
393
  * Used by <ReportInteractive>. Kept side-effect-free so it can be unit-tested.
369
394
  */
370
395
 
371
- type StatusFilter = "all" | "passed" | "failed" | "skipped" | "pending";
396
+ /** Defined with the URL codec that has to validate it, so the two can't drift. */
397
+ type StatusFilter = UrlStatusFilter;
372
398
  interface FilterCriteria {
373
399
  query?: string;
374
400
  status?: StatusFilter;
@@ -434,8 +460,13 @@ interface KeyboardShortcutHandlers {
434
460
  declare function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers): void;
435
461
 
436
462
  /**
437
- * Scrolls to a scenario by URL hash on mount and whenever the hash changes.
438
- * No-op in SSR (only runs in useEffect). Honours `prefers-reduced-motion`.
463
+ * Scrolls to a scenario by URL hash on mount and whenever the deep link
464
+ * changes. No-op in SSR (only runs in useEffect). Honours
465
+ * `prefers-reduced-motion`.
466
+ *
467
+ * The fragment also carries filter state (`#<anchor>?q=...`), so only the
468
+ * anchor half is read — and a hashchange that merely rewrote the filters must
469
+ * not yank the page back to the last anchor, hence the last-anchor guard.
439
470
  */
440
471
  declare function useDeepLinkScroll(): void;
441
472