executable-stories-react 0.10.0 → 0.11.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 +216 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -235
- package/dist/index.d.ts +6 -235
- package/dist/index.js +208 -262
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +266 -476
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +1 -233
- package/dist/interactive.d.ts +1 -233
- package/dist/interactive.js +258 -468
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +40 -1
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +3 -234
- package/dist/parse.d.ts +3 -234
- package/dist/parse.js +40 -1
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +23 -21
- package/dist/ssr.cjs +143 -236
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.d.cts +1 -232
- package/dist/ssr.d.ts +1 -232
- package/dist/ssr.js +135 -228
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +4 -4
package/dist/ssr.cjs
CHANGED
|
@@ -311,23 +311,11 @@ function useReport() {
|
|
|
311
311
|
return ctx.report;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (ms < 6e4) {
|
|
320
|
-
return `${(ms / 1e3).toFixed(2)} s`;
|
|
321
|
-
}
|
|
322
|
-
const minutes = Math.floor(ms / 6e4);
|
|
323
|
-
const seconds = Math.floor(ms % 6e4 / 1e3);
|
|
324
|
-
if (minutes < 60) {
|
|
325
|
-
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
326
|
-
}
|
|
327
|
-
const hours = Math.floor(minutes / 60);
|
|
328
|
-
const remainingMinutes = minutes % 60;
|
|
329
|
-
return `${hours}h ${remainingMinutes}m`;
|
|
330
|
-
}
|
|
314
|
+
// src/components/ReportScenario.tsx
|
|
315
|
+
var import_duration3 = require("executable-stories-core/utils/duration");
|
|
316
|
+
|
|
317
|
+
// src/components/ReportSteps.tsx
|
|
318
|
+
var import_duration = require("executable-stories-core/utils/duration");
|
|
331
319
|
|
|
332
320
|
// src/components/doc/DocNote.tsx
|
|
333
321
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -416,36 +404,29 @@ function DocLink({ entry }) {
|
|
|
416
404
|
);
|
|
417
405
|
}
|
|
418
406
|
|
|
419
|
-
// src/
|
|
407
|
+
// src/lib/markdown.ts
|
|
420
408
|
var import_marked = require("marked");
|
|
421
409
|
|
|
422
|
-
//
|
|
423
|
-
|
|
424
|
-
if (!value) return void 0;
|
|
425
|
-
const trimmed = value.trim();
|
|
426
|
-
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(trimmed);
|
|
427
|
-
if (scheme && !/^https?$/i.test(scheme[1] ?? "")) return void 0;
|
|
428
|
-
return trimmed;
|
|
429
|
-
}
|
|
430
|
-
function safeImageUrl(value) {
|
|
431
|
-
if (!value) return void 0;
|
|
432
|
-
const trimmed = value.trim();
|
|
433
|
-
if (/^data:image\//i.test(trimmed)) return trimmed;
|
|
434
|
-
return safeUrl(trimmed);
|
|
435
|
-
}
|
|
436
|
-
function isLocalFsPath(value) {
|
|
437
|
-
return /^(?:[/\\]|[A-Za-z]:[/\\])/.test(value);
|
|
438
|
-
}
|
|
410
|
+
// src/lib/url.ts
|
|
411
|
+
var import_url = require("executable-stories-core/utils/url");
|
|
439
412
|
|
|
440
|
-
// src/
|
|
441
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
442
|
-
function neutralizeUrl(value) {
|
|
443
|
-
return safeUrl(value) ?? "#";
|
|
444
|
-
}
|
|
413
|
+
// src/lib/markdown.ts
|
|
445
414
|
function safeMarkdownHtml(markdown) {
|
|
446
415
|
const raw = import_marked.marked.parse(markdown, { async: false });
|
|
447
416
|
return raw.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<\/?(?:iframe|object|embed|form|base)\b[^>]*>/gi, "").replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, "").replace(/\son[a-z]+\s*=\s*'[^']*'/gi, "").replace(/\son[a-z]+\s*=\s*[^\s>]+/gi, "").replace(/(href|src)\s*=\s*"([^"]*)"/gi, (_m, attr, val) => `${attr}="${neutralizeUrl(val)}"`).replace(/(href|src)\s*=\s*'([^']*)'/gi, (_m, attr, val) => `${attr}='${neutralizeUrl(val)}'`);
|
|
448
417
|
}
|
|
418
|
+
function dedent(text) {
|
|
419
|
+
const lines = text.replace(/\t/g, " ").split("\n");
|
|
420
|
+
const indents = lines.filter((line) => line.trim().length > 0).map((line) => line.length - line.trimStart().length);
|
|
421
|
+
const shortest = indents.length > 0 ? Math.min(...indents) : 0;
|
|
422
|
+
return lines.map((line) => line.slice(shortest)).join("\n").trim();
|
|
423
|
+
}
|
|
424
|
+
function neutralizeUrl(value) {
|
|
425
|
+
return (0, import_url.safeUrl)(value) ?? "#";
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/components/doc/DocSection.tsx
|
|
429
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
449
430
|
function DocSection({ entry }) {
|
|
450
431
|
const renderers = useBuiltinRenderers();
|
|
451
432
|
if (renderers.section) {
|
|
@@ -491,7 +472,7 @@ function DocMermaid({ entry }) {
|
|
|
491
472
|
// src/components/doc/DocScreenshot.tsx
|
|
492
473
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
493
474
|
function DocScreenshot({ entry }) {
|
|
494
|
-
const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
|
|
475
|
+
const src = (0, import_url.isLocalFsPath)(entry.path) ? void 0 : (0, import_url.safeImageUrl)(entry.path);
|
|
495
476
|
if (!src) {
|
|
496
477
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
497
478
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-medium", children: "Screenshot unavailable" }),
|
|
@@ -516,15 +497,15 @@ function DocScreenshot({ entry }) {
|
|
|
516
497
|
// src/components/doc/DocVideo.tsx
|
|
517
498
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
518
499
|
function DocVideo({ entry }) {
|
|
519
|
-
if (isLocalFsPath(entry.path)) {
|
|
500
|
+
if ((0, import_url.isLocalFsPath)(entry.path)) {
|
|
520
501
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
521
502
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "font-medium", children: "Video unavailable" }),
|
|
522
503
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
523
504
|
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
|
|
524
505
|
] });
|
|
525
506
|
}
|
|
526
|
-
const src = safeUrl(entry.path);
|
|
527
|
-
const poster = safeUrl(entry.poster);
|
|
507
|
+
const src = (0, import_url.safeUrl)(entry.path);
|
|
508
|
+
const poster = (0, import_url.safeUrl)(entry.poster);
|
|
528
509
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3", children: [
|
|
529
510
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
530
511
|
"video",
|
|
@@ -545,7 +526,7 @@ var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
|
545
526
|
function DocHtml({ entry }) {
|
|
546
527
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
547
528
|
const title = entry.title ?? "Embedded HTML";
|
|
548
|
-
const safeHref = safeUrl(entry.url ?? entry.path);
|
|
529
|
+
const safeHref = (0, import_url.safeUrl)(entry.url ?? entry.path);
|
|
549
530
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
550
531
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
551
532
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figcaption", { className: "flex items-center justify-between border-b border-border bg-muted/40 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
@@ -712,7 +693,7 @@ function ReportStepItem({ step }) {
|
|
|
712
693
|
}
|
|
713
694
|
),
|
|
714
695
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
715
|
-
step.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
|
|
696
|
+
step.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: (0, import_duration.formatDuration)(step.durationMs) }) : null
|
|
716
697
|
] }),
|
|
717
698
|
step.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
718
699
|
"pre",
|
|
@@ -728,125 +709,10 @@ function ReportStepItem({ step }) {
|
|
|
728
709
|
);
|
|
729
710
|
}
|
|
730
711
|
|
|
731
|
-
// ../executable-stories-core/dist/state-diff.js
|
|
732
|
-
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
733
|
-
function deepEqual(a, b) {
|
|
734
|
-
if (Object.is(a, b)) return true;
|
|
735
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
736
|
-
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
737
|
-
}
|
|
738
|
-
if (isPlainObject(a) && isPlainObject(b)) {
|
|
739
|
-
const ak = Object.keys(a);
|
|
740
|
-
const bk = Object.keys(b);
|
|
741
|
-
return ak.length === bk.length && ak.every((k) => k in b && deepEqual(a[k], b[k]));
|
|
742
|
-
}
|
|
743
|
-
return false;
|
|
744
|
-
}
|
|
745
|
-
var joinKey = (path, key) => path === "" ? key : `${path}.${key}`;
|
|
746
|
-
function walk(path, before, after, out) {
|
|
747
|
-
if (Object.is(before, after)) return;
|
|
748
|
-
if (Array.isArray(before) && Array.isArray(after)) {
|
|
749
|
-
const shared = Math.min(before.length, after.length);
|
|
750
|
-
for (let i = 0; i < shared; i++) walk(`${path}[${i}]`, before[i], after[i], out);
|
|
751
|
-
for (let i = shared; i < after.length; i++) out.push({ path: `${path}[${i}]`, kind: "added", after: after[i] });
|
|
752
|
-
for (let i = shared; i < before.length; i++) out.push({ path: `${path}[${i}]`, kind: "removed", before: before[i] });
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
|
-
if (isPlainObject(before) && isPlainObject(after)) {
|
|
756
|
-
for (const key of Object.keys(after)) {
|
|
757
|
-
const p = joinKey(path, key);
|
|
758
|
-
if (key in before) walk(p, before[key], after[key], out);
|
|
759
|
-
else out.push({ path: p, kind: "added", after: after[key] });
|
|
760
|
-
}
|
|
761
|
-
for (const key of Object.keys(before)) {
|
|
762
|
-
if (!(key in after)) out.push({ path: joinKey(path, key), kind: "removed", before: before[key] });
|
|
763
|
-
}
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
if (!deepEqual(before, after)) out.push({ path, kind: "changed", before, after });
|
|
767
|
-
}
|
|
768
|
-
function diffStateValues(before, after) {
|
|
769
|
-
const out = [];
|
|
770
|
-
walk("", before, after, out);
|
|
771
|
-
return out;
|
|
772
|
-
}
|
|
773
|
-
function formatStateValue(value, maxLen = 60) {
|
|
774
|
-
const s = value === void 0 ? "undefined" : JSON.stringify(value);
|
|
775
|
-
return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
|
|
776
|
-
}
|
|
777
|
-
function summarizeStateChanges(changes) {
|
|
778
|
-
return changes.map((c) => {
|
|
779
|
-
const at = c.path === "" ? "(root)" : c.path;
|
|
780
|
-
switch (c.kind) {
|
|
781
|
-
case "added":
|
|
782
|
-
return `+ ${at}: ${formatStateValue(c.after)}`;
|
|
783
|
-
case "removed":
|
|
784
|
-
return `\u2212 ${at}`;
|
|
785
|
-
case "changed":
|
|
786
|
-
return `${at}: ${formatStateValue(c.before)} \u2192 ${formatStateValue(c.after)}`;
|
|
787
|
-
}
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
// ../executable-stories-core/dist/storyboard.js
|
|
792
|
-
function findScreenshot(entries) {
|
|
793
|
-
for (const entry of entries) {
|
|
794
|
-
if (entry.kind === "screenshot") return entry;
|
|
795
|
-
if (entry.children) {
|
|
796
|
-
const nested = findScreenshot(entry.children);
|
|
797
|
-
if (nested) return nested;
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
return void 0;
|
|
801
|
-
}
|
|
802
|
-
function findStates(entries, out = []) {
|
|
803
|
-
for (const entry of entries) {
|
|
804
|
-
if (entry.kind === "state") out.push(entry);
|
|
805
|
-
if (entry.children) findStates(entry.children, out);
|
|
806
|
-
}
|
|
807
|
-
return out;
|
|
808
|
-
}
|
|
809
|
-
var laneOf = (label) => label ?? "";
|
|
810
|
-
function extractStoryboardFrames(scenario) {
|
|
811
|
-
const frames = [];
|
|
812
|
-
const laneOrder = [];
|
|
813
|
-
const previous = /* @__PURE__ */ new Map();
|
|
814
|
-
for (const step of scenario.steps) {
|
|
815
|
-
const shot = findScreenshot(step.docEntries);
|
|
816
|
-
const stateDocs = findStates(step.docEntries);
|
|
817
|
-
if (!shot && stateDocs.length === 0) continue;
|
|
818
|
-
const byLane = /* @__PURE__ */ new Map();
|
|
819
|
-
for (const doc of stateDocs) {
|
|
820
|
-
const lane = laneOf(doc.label);
|
|
821
|
-
if (!byLane.has(lane) && !laneOrder.includes(lane)) laneOrder.push(lane);
|
|
822
|
-
byLane.set(lane, doc);
|
|
823
|
-
}
|
|
824
|
-
const states = [];
|
|
825
|
-
for (const lane of laneOrder) {
|
|
826
|
-
const doc = byLane.get(lane);
|
|
827
|
-
if (!doc) continue;
|
|
828
|
-
const card = {
|
|
829
|
-
...doc.label !== void 0 && { label: doc.label },
|
|
830
|
-
value: doc.value
|
|
831
|
-
};
|
|
832
|
-
if (previous.has(lane)) card.changes = diffStateValues(previous.get(lane), doc.value);
|
|
833
|
-
previous.set(lane, doc.value);
|
|
834
|
-
states.push(card);
|
|
835
|
-
}
|
|
836
|
-
frames.push({
|
|
837
|
-
stepId: step.id,
|
|
838
|
-
stepIndex: step.index,
|
|
839
|
-
keyword: step.keyword,
|
|
840
|
-
text: step.text,
|
|
841
|
-
status: step.status,
|
|
842
|
-
...shot && { screenshot: { path: shot.path, ...shot.alt !== void 0 && { alt: shot.alt } } },
|
|
843
|
-
states
|
|
844
|
-
});
|
|
845
|
-
}
|
|
846
|
-
return frames;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
712
|
// src/components/ReportStoryboard.tsx
|
|
713
|
+
var import_storyboard = require("executable-stories-core/storyboard");
|
|
714
|
+
var import_state_diff = require("executable-stories-core/state-diff");
|
|
715
|
+
var import_url6 = require("executable-stories-core/utils/url");
|
|
850
716
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
851
717
|
var FRAME_GLYPH = {
|
|
852
718
|
passed: "\u2713",
|
|
@@ -861,7 +727,7 @@ var FRAME_GLYPH_COLOR = {
|
|
|
861
727
|
pending: "text-pend"
|
|
862
728
|
};
|
|
863
729
|
function ReportStoryboard({ scenario }) {
|
|
864
|
-
const frames = extractStoryboardFrames(scenario);
|
|
730
|
+
const frames = (0, import_storyboard.extractStoryboardFrames)(scenario);
|
|
865
731
|
if (frames.length < 2) return null;
|
|
866
732
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
867
733
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
@@ -895,7 +761,7 @@ function StoryboardFrameItem({ frame }) {
|
|
|
895
761
|
}
|
|
896
762
|
function FrameScreenshot({ frame, label }) {
|
|
897
763
|
const path = frame.screenshot?.path ?? "";
|
|
898
|
-
const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
|
|
764
|
+
const src = (0, import_url6.isLocalFsPath)(path) ? void 0 : (0, import_url6.safeImageUrl)(path);
|
|
899
765
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
900
766
|
"a",
|
|
901
767
|
{
|
|
@@ -941,7 +807,7 @@ function StateCardView({ card }) {
|
|
|
941
807
|
"rounded-sm px-1.5 py-0.5 font-mono text-[0.625rem] leading-snug break-all",
|
|
942
808
|
CHANGE_TONE[change.kind]
|
|
943
809
|
),
|
|
944
|
-
children: summarizeStateChanges([change])[0]
|
|
810
|
+
children: (0, import_state_diff.summarizeStateChanges)([change])[0]
|
|
945
811
|
},
|
|
946
812
|
i
|
|
947
813
|
)) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
|
|
@@ -1001,6 +867,9 @@ function ReportAttachments({ attachments }) {
|
|
|
1001
867
|
);
|
|
1002
868
|
}
|
|
1003
869
|
|
|
870
|
+
// src/components/ReportTrace.tsx
|
|
871
|
+
var import_duration2 = require("executable-stories-core/utils/duration");
|
|
872
|
+
|
|
1004
873
|
// src/lib/trace.ts
|
|
1005
874
|
var VALID = /* @__PURE__ */ new Set(["ok", "error", "unset"]);
|
|
1006
875
|
var safeStatus = (s) => VALID.has(s) ? s : "unset";
|
|
@@ -1053,15 +922,15 @@ function toTraceRows(spans) {
|
|
|
1053
922
|
roots.sort((a, b) => a.span.startTimeMs - b.span.startTimeMs);
|
|
1054
923
|
const rows = [];
|
|
1055
924
|
const seen = /* @__PURE__ */ new Set();
|
|
1056
|
-
const
|
|
925
|
+
const walk = (node, depth) => {
|
|
1057
926
|
if (seen.has(node.span.spanId)) return;
|
|
1058
927
|
seen.add(node.span.spanId);
|
|
1059
928
|
rows.push({ ...node.span, depth });
|
|
1060
|
-
for (const child of node.children)
|
|
929
|
+
for (const child of node.children) walk(child, depth + 1);
|
|
1061
930
|
};
|
|
1062
|
-
for (const root of roots)
|
|
931
|
+
for (const root of roots) walk(root, 0);
|
|
1063
932
|
for (const node of byId.values()) {
|
|
1064
|
-
if (!seen.has(node.span.spanId))
|
|
933
|
+
if (!seen.has(node.span.spanId)) walk(node, 0);
|
|
1065
934
|
}
|
|
1066
935
|
return rows;
|
|
1067
936
|
}
|
|
@@ -1095,7 +964,7 @@ function ReportTrace({ spans }) {
|
|
|
1095
964
|
" span",
|
|
1096
965
|
rows.length === 1 ? "" : "s",
|
|
1097
966
|
", ",
|
|
1098
|
-
formatDuration(totalMs),
|
|
967
|
+
(0, import_duration2.formatDuration)(totalMs),
|
|
1099
968
|
")"
|
|
1100
969
|
] }),
|
|
1101
970
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
@@ -1118,7 +987,7 @@ function ReportTrace({ spans }) {
|
|
|
1118
987
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
1119
988
|
}
|
|
1120
989
|
) }),
|
|
1121
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: (0, import_duration2.formatDuration)(row.durationMs) })
|
|
1122
991
|
] }, `${row.spanId}-${i}`);
|
|
1123
992
|
}) })
|
|
1124
993
|
] });
|
|
@@ -1229,6 +1098,7 @@ function useCollapse() {
|
|
|
1229
1098
|
|
|
1230
1099
|
// src/interactive/scenario-actions.tsx
|
|
1231
1100
|
var import_react7 = require("react");
|
|
1101
|
+
var import_scenario_markdown = require("executable-stories-core/utils/scenario-markdown");
|
|
1232
1102
|
var ScenarioActionsContext = (0, import_react7.createContext)(null);
|
|
1233
1103
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1234
1104
|
function useScenarioActions() {
|
|
@@ -1374,7 +1244,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1374
1244
|
] }),
|
|
1375
1245
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1376
1246
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1377
|
-
scenario.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1247
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: (0, import_duration3.formatDuration)(scenario.durationMs) }) : null,
|
|
1378
1248
|
meta.showPill ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1379
1249
|
actions ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenu, { children: [
|
|
1380
1250
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
@@ -1433,8 +1303,35 @@ function ReportScenarioList({ feature }) {
|
|
|
1433
1303
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_jsx_runtime27.Fragment, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportScenario, { scenario }, scenario.id)) });
|
|
1434
1304
|
}
|
|
1435
1305
|
|
|
1436
|
-
// src/components/
|
|
1306
|
+
// src/components/ReportFeatureIntro.tsx
|
|
1437
1307
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1308
|
+
function ReportFeatureIntro({ feature }) {
|
|
1309
|
+
const hasNarrative = Boolean(feature.narrative?.trim());
|
|
1310
|
+
const hasGlossary = Boolean(feature.glossary?.length);
|
|
1311
|
+
if (!hasNarrative && !hasGlossary) return null;
|
|
1312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
|
|
1313
|
+
hasNarrative ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1314
|
+
"div",
|
|
1315
|
+
{
|
|
1316
|
+
className: "es-doc-prose prose prose-sm max-w-none text-muted-foreground",
|
|
1317
|
+
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1318
|
+
}
|
|
1319
|
+
) : null,
|
|
1320
|
+
hasGlossary ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
|
|
1321
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1322
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
|
|
1323
|
+
] }, entry.term)) }) : null
|
|
1324
|
+
] });
|
|
1325
|
+
}
|
|
1326
|
+
function featureKindLabel(kind) {
|
|
1327
|
+
if (kind === "ability") return "Ability";
|
|
1328
|
+
if (kind === "business-need") return "Business need";
|
|
1329
|
+
if (kind === "feature") return "Feature";
|
|
1330
|
+
return null;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
// src/components/ReportFeature.tsx
|
|
1334
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1438
1335
|
function ReportFeature({ feature }) {
|
|
1439
1336
|
const titleId = `${feature.id}-title`;
|
|
1440
1337
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1442,10 +1339,11 @@ function ReportFeature({ feature }) {
|
|
|
1442
1339
|
const skipped = s.skipped + s.pending;
|
|
1443
1340
|
const collapse = useCollapse();
|
|
1444
1341
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1342
|
+
const kindLabel = featureKindLabel(feature.kind);
|
|
1445
1343
|
return (
|
|
1446
1344
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1447
1345
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1448
|
-
/* @__PURE__ */ (0,
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1449
1347
|
"section",
|
|
1450
1348
|
{
|
|
1451
1349
|
id: feature.id,
|
|
@@ -1453,9 +1351,9 @@ function ReportFeature({ feature }) {
|
|
|
1453
1351
|
"aria-labelledby": titleId,
|
|
1454
1352
|
className: "flex flex-col gap-3",
|
|
1455
1353
|
children: [
|
|
1456
|
-
/* @__PURE__ */ (0,
|
|
1457
|
-
/* @__PURE__ */ (0,
|
|
1458
|
-
/* @__PURE__ */ (0,
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1355
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0", children: [
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1459
1357
|
"button",
|
|
1460
1358
|
{
|
|
1461
1359
|
type: "button",
|
|
@@ -1464,31 +1362,34 @@ function ReportFeature({ feature }) {
|
|
|
1464
1362
|
"aria-controls": bodyId,
|
|
1465
1363
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1466
1364
|
children: [
|
|
1467
|
-
/* @__PURE__ */ (0,
|
|
1468
|
-
/* @__PURE__ */ (0,
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate", children: feature.title })
|
|
1469
1367
|
]
|
|
1470
1368
|
}
|
|
1471
1369
|
) : feature.title }),
|
|
1472
|
-
/* @__PURE__ */ (0,
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { className: cn("mt-0.5 flex items-center gap-2 text-xs text-muted-foreground", collapse && "pl-5"), children: [
|
|
1371
|
+
kindLabel ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "shrink-0 rounded-sm bg-muted px-1.5 py-0.5 font-medium text-foreground", children: kindLabel }) : null,
|
|
1372
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate font-mono", children: feature.sourceFile })
|
|
1373
|
+
] })
|
|
1473
1374
|
] }),
|
|
1474
|
-
/* @__PURE__ */ (0,
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1475
1376
|
"p",
|
|
1476
1377
|
{
|
|
1477
1378
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1478
1379
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1479
1380
|
children: [
|
|
1480
|
-
/* @__PURE__ */ (0,
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
|
|
1481
1382
|
s.passed,
|
|
1482
1383
|
" passed"
|
|
1483
1384
|
] }),
|
|
1484
|
-
/* @__PURE__ */ (0,
|
|
1485
|
-
/* @__PURE__ */ (0,
|
|
1385
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1486
1387
|
s.failed,
|
|
1487
1388
|
" failed"
|
|
1488
1389
|
] }),
|
|
1489
|
-
skipped > 0 ? /* @__PURE__ */ (0,
|
|
1490
|
-
/* @__PURE__ */ (0,
|
|
1491
|
-
/* @__PURE__ */ (0,
|
|
1390
|
+
skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
1391
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1392
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
|
|
1492
1393
|
skipped,
|
|
1493
1394
|
" skipped"
|
|
1494
1395
|
] })
|
|
@@ -1497,7 +1398,10 @@ function ReportFeature({ feature }) {
|
|
|
1497
1398
|
}
|
|
1498
1399
|
)
|
|
1499
1400
|
] }),
|
|
1500
|
-
/* @__PURE__ */ (0,
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
|
|
1402
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportFeatureIntro, { feature }),
|
|
1403
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportScenarioList, { feature })
|
|
1404
|
+
] })
|
|
1501
1405
|
]
|
|
1502
1406
|
}
|
|
1503
1407
|
)
|
|
@@ -1505,17 +1409,17 @@ function ReportFeature({ feature }) {
|
|
|
1505
1409
|
}
|
|
1506
1410
|
|
|
1507
1411
|
// src/components/ReportFeatureList.tsx
|
|
1508
|
-
var
|
|
1412
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1509
1413
|
function ReportFeatureList() {
|
|
1510
1414
|
const report = useReport();
|
|
1511
|
-
return /* @__PURE__ */ (0,
|
|
1415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReportFeature, { feature }, feature.id)) });
|
|
1512
1416
|
}
|
|
1513
1417
|
|
|
1514
1418
|
// src/components/ui/empty.tsx
|
|
1515
1419
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
1516
|
-
var
|
|
1420
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1517
1421
|
function Empty({ className, ...props }) {
|
|
1518
|
-
return /* @__PURE__ */ (0,
|
|
1422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1519
1423
|
"div",
|
|
1520
1424
|
{
|
|
1521
1425
|
"data-slot": "empty",
|
|
@@ -1528,7 +1432,7 @@ function Empty({ className, ...props }) {
|
|
|
1528
1432
|
);
|
|
1529
1433
|
}
|
|
1530
1434
|
function EmptyHeader({ className, ...props }) {
|
|
1531
|
-
return /* @__PURE__ */ (0,
|
|
1435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1532
1436
|
"div",
|
|
1533
1437
|
{
|
|
1534
1438
|
"data-slot": "empty-header",
|
|
@@ -1555,7 +1459,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
|
|
|
1555
1459
|
}
|
|
1556
1460
|
);
|
|
1557
1461
|
function EmptyTitle({ className, ...props }) {
|
|
1558
|
-
return /* @__PURE__ */ (0,
|
|
1462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1559
1463
|
"div",
|
|
1560
1464
|
{
|
|
1561
1465
|
"data-slot": "empty-title",
|
|
@@ -1566,16 +1470,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1566
1470
|
}
|
|
1567
1471
|
|
|
1568
1472
|
// src/components/ReportEmpty.tsx
|
|
1569
|
-
var
|
|
1473
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1570
1474
|
function ReportEmpty({ message }) {
|
|
1571
|
-
return /* @__PURE__ */ (0,
|
|
1475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1572
1476
|
}
|
|
1573
1477
|
|
|
1574
1478
|
// src/components/ReportSummary.tsx
|
|
1575
|
-
var
|
|
1479
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1576
1480
|
function ReportSummary({ className }) {
|
|
1577
1481
|
const report = useReport();
|
|
1578
|
-
return /* @__PURE__ */ (0,
|
|
1482
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1579
1483
|
ReportSummaryView,
|
|
1580
1484
|
{
|
|
1581
1485
|
summary: report.summary,
|
|
@@ -1601,7 +1505,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1601
1505
|
if (summary.pending > 0) {
|
|
1602
1506
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1603
1507
|
}
|
|
1604
|
-
return /* @__PURE__ */ (0,
|
|
1508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1605
1509
|
"dl",
|
|
1606
1510
|
{
|
|
1607
1511
|
className: cn(
|
|
@@ -1614,17 +1518,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1614
1518
|
"aria-label": ariaLabel,
|
|
1615
1519
|
children: cards.map((c) => {
|
|
1616
1520
|
const tone = TONE[c.status];
|
|
1617
|
-
return /* @__PURE__ */ (0,
|
|
1521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1618
1522
|
"div",
|
|
1619
1523
|
{
|
|
1620
1524
|
"data-status": c.status,
|
|
1621
1525
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1622
1526
|
children: [
|
|
1623
|
-
/* @__PURE__ */ (0,
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1625
1529
|
c.label
|
|
1626
1530
|
] }),
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1531
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1628
1532
|
]
|
|
1629
1533
|
},
|
|
1630
1534
|
c.status
|
|
@@ -1634,6 +1538,9 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1634
1538
|
);
|
|
1635
1539
|
}
|
|
1636
1540
|
|
|
1541
|
+
// src/components/ReportMeta.tsx
|
|
1542
|
+
var import_duration4 = require("executable-stories-core/utils/duration");
|
|
1543
|
+
|
|
1637
1544
|
// src/lib/provenance.ts
|
|
1638
1545
|
var CI_DISPLAY_NAMES = {
|
|
1639
1546
|
github: "GitHub Actions",
|
|
@@ -1665,7 +1572,7 @@ function prUrl(ci) {
|
|
|
1665
1572
|
}
|
|
1666
1573
|
|
|
1667
1574
|
// src/components/ReportMeta.tsx
|
|
1668
|
-
var
|
|
1575
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1669
1576
|
function ReportMeta() {
|
|
1670
1577
|
const report = useReport();
|
|
1671
1578
|
const items = [];
|
|
@@ -1674,7 +1581,7 @@ function ReportMeta() {
|
|
|
1674
1581
|
items.push({ label: "Started", value: new Date(report.startedAtMs).toLocaleString() });
|
|
1675
1582
|
}
|
|
1676
1583
|
if (report.durationMs) {
|
|
1677
|
-
items.push({ label: "Duration", value: formatDuration(report.durationMs) });
|
|
1584
|
+
items.push({ label: "Duration", value: (0, import_duration4.formatDuration)(report.durationMs) });
|
|
1678
1585
|
}
|
|
1679
1586
|
if (report.packageVersion) {
|
|
1680
1587
|
items.push({ label: "Version", value: report.packageVersion });
|
|
@@ -1688,13 +1595,13 @@ function ReportMeta() {
|
|
|
1688
1595
|
const short = sha.slice(0, 8);
|
|
1689
1596
|
items.push({
|
|
1690
1597
|
label: "Commit",
|
|
1691
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1598
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1692
1599
|
});
|
|
1693
1600
|
}
|
|
1694
1601
|
if (report.ci) {
|
|
1695
1602
|
items.push({
|
|
1696
1603
|
label: "CI",
|
|
1697
|
-
value: report.ci.url ? /* @__PURE__ */ (0,
|
|
1604
|
+
value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1698
1605
|
ciDisplayName(report.ci.name),
|
|
1699
1606
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1700
1607
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1705,7 +1612,7 @@ function ReportMeta() {
|
|
|
1705
1612
|
const label = `#${report.ci.prNumber}`;
|
|
1706
1613
|
items.push({
|
|
1707
1614
|
label: "PR",
|
|
1708
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1615
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1709
1616
|
});
|
|
1710
1617
|
}
|
|
1711
1618
|
if (items.length === 0) return null;
|
|
@@ -1713,48 +1620,48 @@ function ReportMeta() {
|
|
|
1713
1620
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1714
1621
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1715
1622
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
1625
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1719
1626
|
"Run details"
|
|
1720
1627
|
] }),
|
|
1721
|
-
/* @__PURE__ */ (0,
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1723
|
-
/* @__PURE__ */ (0,
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dt", { className: "font-medium", children: item.label }),
|
|
1630
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1724
1631
|
] }, item.label)) })
|
|
1725
1632
|
] })
|
|
1726
1633
|
);
|
|
1727
1634
|
}
|
|
1728
1635
|
|
|
1729
1636
|
// src/components/ReportSchemaError.tsx
|
|
1730
|
-
var
|
|
1637
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1731
1638
|
function ReportSchemaError({ error }) {
|
|
1732
|
-
return /* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
1735
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0,
|
|
1639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: "Report could not be displayed." }) }),
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: error.message }),
|
|
1642
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
|
|
1736
1643
|
"The report bundle is newer than this version of ",
|
|
1737
|
-
/* @__PURE__ */ (0,
|
|
1644
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("code", { children: "executable-stories-react" }),
|
|
1738
1645
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1739
1646
|
] }) : null,
|
|
1740
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0,
|
|
1741
|
-
/* @__PURE__ */ (0,
|
|
1647
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("details", { children: [
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("summary", { children: [
|
|
1742
1649
|
error.issues.length,
|
|
1743
1650
|
" validation issue",
|
|
1744
1651
|
error.issues.length === 1 ? "" : "s"
|
|
1745
1652
|
] }),
|
|
1746
|
-
/* @__PURE__ */ (0,
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1747
1654
|
] }) : null
|
|
1748
1655
|
] });
|
|
1749
1656
|
}
|
|
1750
1657
|
|
|
1751
1658
|
// src/components/ReportShell.tsx
|
|
1752
|
-
var
|
|
1659
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1753
1660
|
function ReportTitleBlock({ title }) {
|
|
1754
|
-
return /* @__PURE__ */ (0,
|
|
1755
|
-
/* @__PURE__ */ (0,
|
|
1756
|
-
/* @__PURE__ */ (0,
|
|
1757
|
-
/* @__PURE__ */ (0,
|
|
1661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
1662
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h1", { children: title ?? "Story Report" }),
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportSummary, {}),
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportMeta, {})
|
|
1758
1665
|
] });
|
|
1759
1666
|
}
|
|
1760
1667
|
function ReportErrorShell({
|
|
@@ -1763,22 +1670,22 @@ function ReportErrorShell({
|
|
|
1763
1670
|
title,
|
|
1764
1671
|
dataTheme
|
|
1765
1672
|
}) {
|
|
1766
|
-
return /* @__PURE__ */ (0,
|
|
1673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportSchemaError, { error }) });
|
|
1767
1674
|
}
|
|
1768
1675
|
|
|
1769
1676
|
// src/components/Report.tsx
|
|
1770
|
-
var
|
|
1677
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1771
1678
|
function Report(props) {
|
|
1772
1679
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1773
1680
|
const result = unwrapReport(report);
|
|
1774
1681
|
if (!result.ok) {
|
|
1775
|
-
return /* @__PURE__ */ (0,
|
|
1682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1776
1683
|
}
|
|
1777
1684
|
const data = result.data;
|
|
1778
1685
|
const hasContent = data.features.length > 0;
|
|
1779
|
-
return /* @__PURE__ */ (0,
|
|
1780
|
-
/* @__PURE__ */ (0,
|
|
1781
|
-
hasContent ? /* @__PURE__ */ (0,
|
|
1686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1687
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("header", { className: "es-report-header", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportTitleBlock, { title }) }),
|
|
1688
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportFeatureList, {}) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportEmpty, {})
|
|
1782
1689
|
] }) });
|
|
1783
1690
|
}
|
|
1784
1691
|
|