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/interactive.cjs
CHANGED
|
@@ -334,23 +334,11 @@ function useReport() {
|
|
|
334
334
|
return ctx.report;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (ms < 6e4) {
|
|
343
|
-
return `${(ms / 1e3).toFixed(2)} s`;
|
|
344
|
-
}
|
|
345
|
-
const minutes = Math.floor(ms / 6e4);
|
|
346
|
-
const seconds = Math.floor(ms % 6e4 / 1e3);
|
|
347
|
-
if (minutes < 60) {
|
|
348
|
-
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
349
|
-
}
|
|
350
|
-
const hours = Math.floor(minutes / 60);
|
|
351
|
-
const remainingMinutes = minutes % 60;
|
|
352
|
-
return `${hours}h ${remainingMinutes}m`;
|
|
353
|
-
}
|
|
337
|
+
// src/components/ReportScenario.tsx
|
|
338
|
+
var import_duration3 = require("executable-stories-core/utils/duration");
|
|
339
|
+
|
|
340
|
+
// src/components/ReportSteps.tsx
|
|
341
|
+
var import_duration = require("executable-stories-core/utils/duration");
|
|
354
342
|
|
|
355
343
|
// src/components/doc/DocNote.tsx
|
|
356
344
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -419,7 +407,7 @@ function DocTable({ entry }) {
|
|
|
419
407
|
entry.label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
420
408
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { className: "w-full border-collapse text-sm", children: [
|
|
421
409
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
422
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { children: row.map((
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { children: row.map((cell, j) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
|
|
423
411
|
] }) })
|
|
424
412
|
] });
|
|
425
413
|
}
|
|
@@ -439,36 +427,29 @@ function DocLink({ entry }) {
|
|
|
439
427
|
);
|
|
440
428
|
}
|
|
441
429
|
|
|
442
|
-
// src/
|
|
430
|
+
// src/lib/markdown.ts
|
|
443
431
|
var import_marked = require("marked");
|
|
444
432
|
|
|
445
|
-
//
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
return
|
|
433
|
+
// src/lib/url.ts
|
|
434
|
+
var import_url = require("executable-stories-core/utils/url");
|
|
435
|
+
|
|
436
|
+
// src/lib/markdown.ts
|
|
437
|
+
function safeMarkdownHtml(markdown) {
|
|
438
|
+
const raw = import_marked.marked.parse(markdown, { async: false });
|
|
439
|
+
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)}'`);
|
|
452
440
|
}
|
|
453
|
-
function
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
return
|
|
441
|
+
function dedent(text) {
|
|
442
|
+
const lines = text.replace(/\t/g, " ").split("\n");
|
|
443
|
+
const indents = lines.filter((line) => line.trim().length > 0).map((line) => line.length - line.trimStart().length);
|
|
444
|
+
const shortest = indents.length > 0 ? Math.min(...indents) : 0;
|
|
445
|
+
return lines.map((line) => line.slice(shortest)).join("\n").trim();
|
|
458
446
|
}
|
|
459
|
-
function
|
|
460
|
-
return
|
|
447
|
+
function neutralizeUrl(value) {
|
|
448
|
+
return (0, import_url.safeUrl)(value) ?? "#";
|
|
461
449
|
}
|
|
462
450
|
|
|
463
451
|
// src/components/doc/DocSection.tsx
|
|
464
452
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
465
|
-
function neutralizeUrl(value) {
|
|
466
|
-
return safeUrl(value) ?? "#";
|
|
467
|
-
}
|
|
468
|
-
function safeMarkdownHtml(markdown) {
|
|
469
|
-
const raw = import_marked.marked.parse(markdown, { async: false });
|
|
470
|
-
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)}'`);
|
|
471
|
-
}
|
|
472
453
|
function DocSection({ entry }) {
|
|
473
454
|
const renderers = useBuiltinRenderers();
|
|
474
455
|
if (renderers.section) {
|
|
@@ -514,7 +495,7 @@ function DocMermaid({ entry }) {
|
|
|
514
495
|
// src/components/doc/DocScreenshot.tsx
|
|
515
496
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
516
497
|
function DocScreenshot({ entry }) {
|
|
517
|
-
const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
|
|
498
|
+
const src = (0, import_url.isLocalFsPath)(entry.path) ? void 0 : (0, import_url.safeImageUrl)(entry.path);
|
|
518
499
|
if (!src) {
|
|
519
500
|
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: [
|
|
520
501
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-medium", children: "Screenshot unavailable" }),
|
|
@@ -539,15 +520,15 @@ function DocScreenshot({ entry }) {
|
|
|
539
520
|
// src/components/doc/DocVideo.tsx
|
|
540
521
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
541
522
|
function DocVideo({ entry }) {
|
|
542
|
-
if (isLocalFsPath(entry.path)) {
|
|
523
|
+
if ((0, import_url.isLocalFsPath)(entry.path)) {
|
|
543
524
|
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: [
|
|
544
525
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "font-medium", children: "Video unavailable" }),
|
|
545
526
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
546
527
|
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
|
|
547
528
|
] });
|
|
548
529
|
}
|
|
549
|
-
const src = safeUrl(entry.path);
|
|
550
|
-
const poster = safeUrl(entry.poster);
|
|
530
|
+
const src = (0, import_url.safeUrl)(entry.path);
|
|
531
|
+
const poster = (0, import_url.safeUrl)(entry.poster);
|
|
551
532
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3", children: [
|
|
552
533
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
553
534
|
"video",
|
|
@@ -568,7 +549,7 @@ var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
|
568
549
|
function DocHtml({ entry }) {
|
|
569
550
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
570
551
|
const title = entry.title ?? "Embedded HTML";
|
|
571
|
-
const safeHref = safeUrl(entry.url ?? entry.path);
|
|
552
|
+
const safeHref = (0, import_url.safeUrl)(entry.url ?? entry.path);
|
|
572
553
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
573
554
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
574
555
|
/* @__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: [
|
|
@@ -735,7 +716,7 @@ function ReportStepItem({ step }) {
|
|
|
735
716
|
}
|
|
736
717
|
),
|
|
737
718
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
738
|
-
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
|
|
719
|
+
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
|
|
739
720
|
] }),
|
|
740
721
|
step.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
741
722
|
"pre",
|
|
@@ -751,125 +732,10 @@ function ReportStepItem({ step }) {
|
|
|
751
732
|
);
|
|
752
733
|
}
|
|
753
734
|
|
|
754
|
-
// ../executable-stories-core/dist/state-diff.js
|
|
755
|
-
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
756
|
-
function deepEqual(a, b) {
|
|
757
|
-
if (Object.is(a, b)) return true;
|
|
758
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
759
|
-
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
760
|
-
}
|
|
761
|
-
if (isPlainObject(a) && isPlainObject(b)) {
|
|
762
|
-
const ak = Object.keys(a);
|
|
763
|
-
const bk = Object.keys(b);
|
|
764
|
-
return ak.length === bk.length && ak.every((k) => k in b && deepEqual(a[k], b[k]));
|
|
765
|
-
}
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
var joinKey = (path, key) => path === "" ? key : `${path}.${key}`;
|
|
769
|
-
function walk(path, before, after, out) {
|
|
770
|
-
if (Object.is(before, after)) return;
|
|
771
|
-
if (Array.isArray(before) && Array.isArray(after)) {
|
|
772
|
-
const shared = Math.min(before.length, after.length);
|
|
773
|
-
for (let i = 0; i < shared; i++) walk(`${path}[${i}]`, before[i], after[i], out);
|
|
774
|
-
for (let i = shared; i < after.length; i++) out.push({ path: `${path}[${i}]`, kind: "added", after: after[i] });
|
|
775
|
-
for (let i = shared; i < before.length; i++) out.push({ path: `${path}[${i}]`, kind: "removed", before: before[i] });
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
if (isPlainObject(before) && isPlainObject(after)) {
|
|
779
|
-
for (const key of Object.keys(after)) {
|
|
780
|
-
const p = joinKey(path, key);
|
|
781
|
-
if (key in before) walk(p, before[key], after[key], out);
|
|
782
|
-
else out.push({ path: p, kind: "added", after: after[key] });
|
|
783
|
-
}
|
|
784
|
-
for (const key of Object.keys(before)) {
|
|
785
|
-
if (!(key in after)) out.push({ path: joinKey(path, key), kind: "removed", before: before[key] });
|
|
786
|
-
}
|
|
787
|
-
return;
|
|
788
|
-
}
|
|
789
|
-
if (!deepEqual(before, after)) out.push({ path, kind: "changed", before, after });
|
|
790
|
-
}
|
|
791
|
-
function diffStateValues(before, after) {
|
|
792
|
-
const out = [];
|
|
793
|
-
walk("", before, after, out);
|
|
794
|
-
return out;
|
|
795
|
-
}
|
|
796
|
-
function formatStateValue(value, maxLen = 60) {
|
|
797
|
-
const s = value === void 0 ? "undefined" : JSON.stringify(value);
|
|
798
|
-
return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
|
|
799
|
-
}
|
|
800
|
-
function summarizeStateChanges(changes) {
|
|
801
|
-
return changes.map((c) => {
|
|
802
|
-
const at = c.path === "" ? "(root)" : c.path;
|
|
803
|
-
switch (c.kind) {
|
|
804
|
-
case "added":
|
|
805
|
-
return `+ ${at}: ${formatStateValue(c.after)}`;
|
|
806
|
-
case "removed":
|
|
807
|
-
return `\u2212 ${at}`;
|
|
808
|
-
case "changed":
|
|
809
|
-
return `${at}: ${formatStateValue(c.before)} \u2192 ${formatStateValue(c.after)}`;
|
|
810
|
-
}
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
// ../executable-stories-core/dist/storyboard.js
|
|
815
|
-
function findScreenshot(entries) {
|
|
816
|
-
for (const entry of entries) {
|
|
817
|
-
if (entry.kind === "screenshot") return entry;
|
|
818
|
-
if (entry.children) {
|
|
819
|
-
const nested = findScreenshot(entry.children);
|
|
820
|
-
if (nested) return nested;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
return void 0;
|
|
824
|
-
}
|
|
825
|
-
function findStates(entries, out = []) {
|
|
826
|
-
for (const entry of entries) {
|
|
827
|
-
if (entry.kind === "state") out.push(entry);
|
|
828
|
-
if (entry.children) findStates(entry.children, out);
|
|
829
|
-
}
|
|
830
|
-
return out;
|
|
831
|
-
}
|
|
832
|
-
var laneOf = (label) => label ?? "";
|
|
833
|
-
function extractStoryboardFrames(scenario) {
|
|
834
|
-
const frames = [];
|
|
835
|
-
const laneOrder = [];
|
|
836
|
-
const previous = /* @__PURE__ */ new Map();
|
|
837
|
-
for (const step of scenario.steps) {
|
|
838
|
-
const shot = findScreenshot(step.docEntries);
|
|
839
|
-
const stateDocs = findStates(step.docEntries);
|
|
840
|
-
if (!shot && stateDocs.length === 0) continue;
|
|
841
|
-
const byLane = /* @__PURE__ */ new Map();
|
|
842
|
-
for (const doc of stateDocs) {
|
|
843
|
-
const lane = laneOf(doc.label);
|
|
844
|
-
if (!byLane.has(lane) && !laneOrder.includes(lane)) laneOrder.push(lane);
|
|
845
|
-
byLane.set(lane, doc);
|
|
846
|
-
}
|
|
847
|
-
const states = [];
|
|
848
|
-
for (const lane of laneOrder) {
|
|
849
|
-
const doc = byLane.get(lane);
|
|
850
|
-
if (!doc) continue;
|
|
851
|
-
const card = {
|
|
852
|
-
...doc.label !== void 0 && { label: doc.label },
|
|
853
|
-
value: doc.value
|
|
854
|
-
};
|
|
855
|
-
if (previous.has(lane)) card.changes = diffStateValues(previous.get(lane), doc.value);
|
|
856
|
-
previous.set(lane, doc.value);
|
|
857
|
-
states.push(card);
|
|
858
|
-
}
|
|
859
|
-
frames.push({
|
|
860
|
-
stepId: step.id,
|
|
861
|
-
stepIndex: step.index,
|
|
862
|
-
keyword: step.keyword,
|
|
863
|
-
text: step.text,
|
|
864
|
-
status: step.status,
|
|
865
|
-
...shot && { screenshot: { path: shot.path, ...shot.alt !== void 0 && { alt: shot.alt } } },
|
|
866
|
-
states
|
|
867
|
-
});
|
|
868
|
-
}
|
|
869
|
-
return frames;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
735
|
// src/components/ReportStoryboard.tsx
|
|
736
|
+
var import_storyboard = require("executable-stories-core/storyboard");
|
|
737
|
+
var import_state_diff = require("executable-stories-core/state-diff");
|
|
738
|
+
var import_url6 = require("executable-stories-core/utils/url");
|
|
873
739
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
874
740
|
var FRAME_GLYPH = {
|
|
875
741
|
passed: "\u2713",
|
|
@@ -884,7 +750,7 @@ var FRAME_GLYPH_COLOR = {
|
|
|
884
750
|
pending: "text-pend"
|
|
885
751
|
};
|
|
886
752
|
function ReportStoryboard({ scenario }) {
|
|
887
|
-
const frames = extractStoryboardFrames(scenario);
|
|
753
|
+
const frames = (0, import_storyboard.extractStoryboardFrames)(scenario);
|
|
888
754
|
if (frames.length < 2) return null;
|
|
889
755
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
890
756
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
@@ -918,7 +784,7 @@ function StoryboardFrameItem({ frame }) {
|
|
|
918
784
|
}
|
|
919
785
|
function FrameScreenshot({ frame, label }) {
|
|
920
786
|
const path = frame.screenshot?.path ?? "";
|
|
921
|
-
const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
|
|
787
|
+
const src = (0, import_url6.isLocalFsPath)(path) ? void 0 : (0, import_url6.safeImageUrl)(path);
|
|
922
788
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
923
789
|
"a",
|
|
924
790
|
{
|
|
@@ -964,7 +830,7 @@ function StateCardView({ card }) {
|
|
|
964
830
|
"rounded-sm px-1.5 py-0.5 font-mono text-[0.625rem] leading-snug break-all",
|
|
965
831
|
CHANGE_TONE[change.kind]
|
|
966
832
|
),
|
|
967
|
-
children: summarizeStateChanges([change])[0]
|
|
833
|
+
children: (0, import_state_diff.summarizeStateChanges)([change])[0]
|
|
968
834
|
},
|
|
969
835
|
i
|
|
970
836
|
)) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
|
|
@@ -1024,6 +890,9 @@ function ReportAttachments({ attachments }) {
|
|
|
1024
890
|
);
|
|
1025
891
|
}
|
|
1026
892
|
|
|
893
|
+
// src/components/ReportTrace.tsx
|
|
894
|
+
var import_duration2 = require("executable-stories-core/utils/duration");
|
|
895
|
+
|
|
1027
896
|
// src/lib/trace.ts
|
|
1028
897
|
var VALID = /* @__PURE__ */ new Set(["ok", "error", "unset"]);
|
|
1029
898
|
var safeStatus = (s) => VALID.has(s) ? s : "unset";
|
|
@@ -1076,15 +945,15 @@ function toTraceRows(spans) {
|
|
|
1076
945
|
roots.sort((a, b) => a.span.startTimeMs - b.span.startTimeMs);
|
|
1077
946
|
const rows = [];
|
|
1078
947
|
const seen = /* @__PURE__ */ new Set();
|
|
1079
|
-
const
|
|
948
|
+
const walk = (node, depth) => {
|
|
1080
949
|
if (seen.has(node.span.spanId)) return;
|
|
1081
950
|
seen.add(node.span.spanId);
|
|
1082
951
|
rows.push({ ...node.span, depth });
|
|
1083
|
-
for (const child of node.children)
|
|
952
|
+
for (const child of node.children) walk(child, depth + 1);
|
|
1084
953
|
};
|
|
1085
|
-
for (const root of roots)
|
|
954
|
+
for (const root of roots) walk(root, 0);
|
|
1086
955
|
for (const node of byId.values()) {
|
|
1087
|
-
if (!seen.has(node.span.spanId))
|
|
956
|
+
if (!seen.has(node.span.spanId)) walk(node, 0);
|
|
1088
957
|
}
|
|
1089
958
|
return rows;
|
|
1090
959
|
}
|
|
@@ -1118,7 +987,7 @@ function ReportTrace({ spans }) {
|
|
|
1118
987
|
" span",
|
|
1119
988
|
rows.length === 1 ? "" : "s",
|
|
1120
989
|
", ",
|
|
1121
|
-
formatDuration(totalMs),
|
|
990
|
+
(0, import_duration2.formatDuration)(totalMs),
|
|
1122
991
|
")"
|
|
1123
992
|
] }),
|
|
1124
993
|
/* @__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) => {
|
|
@@ -1141,7 +1010,7 @@ function ReportTrace({ spans }) {
|
|
|
1141
1010
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
1142
1011
|
}
|
|
1143
1012
|
) }),
|
|
1144
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
1013
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: (0, import_duration2.formatDuration)(row.durationMs) })
|
|
1145
1014
|
] }, `${row.spanId}-${i}`);
|
|
1146
1015
|
}) })
|
|
1147
1016
|
] });
|
|
@@ -1317,130 +1186,14 @@ function useCollapseState(computeDefault) {
|
|
|
1317
1186
|
|
|
1318
1187
|
// src/interactive/scenario-actions.tsx
|
|
1319
1188
|
var import_react7 = require("react");
|
|
1320
|
-
|
|
1321
|
-
// ../executable-stories-core/dist/utils/scenario-markdown.js
|
|
1322
|
-
function cell(value) {
|
|
1323
|
-
return value.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
1324
|
-
}
|
|
1325
|
-
function stringify(value) {
|
|
1326
|
-
if (typeof value === "string") return value;
|
|
1327
|
-
try {
|
|
1328
|
-
return JSON.stringify(value, null, 2) ?? String(value);
|
|
1329
|
-
} catch {
|
|
1330
|
-
return String(value);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
function docEntryToMarkdown(entry, stateLanes) {
|
|
1334
|
-
const lines = [];
|
|
1335
|
-
switch (entry.kind) {
|
|
1336
|
-
case "note":
|
|
1337
|
-
lines.push(entry.text);
|
|
1338
|
-
break;
|
|
1339
|
-
case "tag":
|
|
1340
|
-
lines.push(entry.names.map((n) => `\`@${n}\``).join(" "));
|
|
1341
|
-
break;
|
|
1342
|
-
case "kv":
|
|
1343
|
-
lines.push(`**${entry.label}:** ${stringify(entry.value)}`);
|
|
1344
|
-
break;
|
|
1345
|
-
case "code":
|
|
1346
|
-
lines.push(`**${entry.label}**`, "", "```" + (entry.lang ?? ""), entry.content, "```");
|
|
1347
|
-
break;
|
|
1348
|
-
case "table": {
|
|
1349
|
-
lines.push(`**${entry.label}**`, "");
|
|
1350
|
-
lines.push(`| ${entry.columns.map(cell).join(" | ")} |`);
|
|
1351
|
-
lines.push(`| ${entry.columns.map(() => "---").join(" | ")} |`);
|
|
1352
|
-
for (const row of entry.rows) lines.push(`| ${row.map(cell).join(" | ")} |`);
|
|
1353
|
-
break;
|
|
1354
|
-
}
|
|
1355
|
-
case "link":
|
|
1356
|
-
lines.push(`[${entry.label}](${entry.url})`);
|
|
1357
|
-
break;
|
|
1358
|
-
case "section":
|
|
1359
|
-
lines.push(`### ${entry.title}`, "", entry.markdown);
|
|
1360
|
-
break;
|
|
1361
|
-
case "mermaid":
|
|
1362
|
-
if (entry.title) lines.push(`**${entry.title}**`, "");
|
|
1363
|
-
lines.push("```mermaid", entry.code, "```");
|
|
1364
|
-
break;
|
|
1365
|
-
case "screenshot":
|
|
1366
|
-
lines.push(``);
|
|
1367
|
-
break;
|
|
1368
|
-
case "video":
|
|
1369
|
-
lines.push(`Video: ${entry.path}${entry.caption ? ` \u2014 ${entry.caption}` : ""}`);
|
|
1370
|
-
break;
|
|
1371
|
-
case "html": {
|
|
1372
|
-
const htmlTitle = entry.title ?? "Embedded HTML";
|
|
1373
|
-
if (entry.content) {
|
|
1374
|
-
lines.push(`**${htmlTitle}**`, "", "```html", entry.content, "```");
|
|
1375
|
-
} else if (entry.url) {
|
|
1376
|
-
lines.push(`[${htmlTitle}](${entry.url})`);
|
|
1377
|
-
} else {
|
|
1378
|
-
lines.push(`Embedded HTML: ${entry.path ?? "(inline)"}`);
|
|
1379
|
-
}
|
|
1380
|
-
break;
|
|
1381
|
-
}
|
|
1382
|
-
case "custom":
|
|
1383
|
-
lines.push(`**${entry.type}**`, "", "```json", stringify(entry.data), "```");
|
|
1384
|
-
break;
|
|
1385
|
-
case "state": {
|
|
1386
|
-
const lane = entry.label ?? "";
|
|
1387
|
-
lines.push(`**${entry.label ?? "State"}**`);
|
|
1388
|
-
if (stateLanes?.has(lane)) {
|
|
1389
|
-
const summary = summarizeStateChanges(diffStateValues(stateLanes.get(lane), entry.value));
|
|
1390
|
-
if (summary.length > 0) lines.push("", ...summary.map((l) => `- ${l}`));
|
|
1391
|
-
}
|
|
1392
|
-
stateLanes?.set(lane, entry.value);
|
|
1393
|
-
lines.push("", "<details>", "<summary>snapshot</summary>", "", "```json", stringify(entry.value ?? null), "```", "", "</details>");
|
|
1394
|
-
break;
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
for (const child of entry.children ?? []) {
|
|
1398
|
-
lines.push("", ...docEntryToMarkdown(child, stateLanes));
|
|
1399
|
-
}
|
|
1400
|
-
return lines;
|
|
1401
|
-
}
|
|
1402
|
-
function stepLines(step, ordinal, full, stateLanes) {
|
|
1403
|
-
const status = step.status === "passed" ? "" : ` \u2014 **${step.status}**`;
|
|
1404
|
-
const lines = [`${ordinal}. **${step.keyword}** ${step.text}${status}`];
|
|
1405
|
-
if (!full) return lines;
|
|
1406
|
-
if (step.errorMessage) {
|
|
1407
|
-
lines.push(...step.errorMessage.split("\n").map((l) => ` > ${l}`));
|
|
1408
|
-
}
|
|
1409
|
-
for (const entry of step.docEntries) {
|
|
1410
|
-
lines.push("", ...docEntryToMarkdown(entry, stateLanes).map((l) => l === "" ? l : ` ${l}`));
|
|
1411
|
-
}
|
|
1412
|
-
return lines;
|
|
1413
|
-
}
|
|
1414
|
-
function scenarioToMarkdown(scenario, options = {}) {
|
|
1415
|
-
const { variant = "full", meta = [] } = options;
|
|
1416
|
-
const full = variant === "full";
|
|
1417
|
-
const lines = full ? [`# ${scenario.title}`, ""] : [`## ${scenario.title} _(${scenario.status})_`, ""];
|
|
1418
|
-
if (full && meta.length > 0) lines.push(...meta);
|
|
1419
|
-
const stateLanes = /* @__PURE__ */ new Map();
|
|
1420
|
-
if (scenario.steps.length > 0) {
|
|
1421
|
-
if (full) lines.push("", "## Steps", "");
|
|
1422
|
-
scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full, stateLanes)));
|
|
1423
|
-
}
|
|
1424
|
-
if (scenario.errorMessage) {
|
|
1425
|
-
if (full) lines.push("", "## Failure", "");
|
|
1426
|
-
else lines.push("");
|
|
1427
|
-
lines.push("```", scenario.errorMessage.trim(), "```");
|
|
1428
|
-
}
|
|
1429
|
-
if (full && scenario.docEntries.length > 0) {
|
|
1430
|
-
lines.push("", "## Docs", "");
|
|
1431
|
-
for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry, stateLanes), "");
|
|
1432
|
-
}
|
|
1433
|
-
return lines.join("\n").replaceAll(/\n{3,}/g, "\n\n").trimEnd() + (full ? "\n" : "");
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
// src/interactive/scenario-actions.tsx
|
|
1189
|
+
var import_scenario_markdown = require("executable-stories-core/utils/scenario-markdown");
|
|
1437
1190
|
var ScenarioActionsContext = (0, import_react7.createContext)(null);
|
|
1438
1191
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1439
1192
|
function useScenarioActions() {
|
|
1440
1193
|
return (0, import_react7.useContext)(ScenarioActionsContext);
|
|
1441
1194
|
}
|
|
1442
|
-
function
|
|
1443
|
-
return scenarioToMarkdown(scenario, { variant: "compact" });
|
|
1195
|
+
function scenarioToMarkdown(scenario) {
|
|
1196
|
+
return (0, import_scenario_markdown.scenarioToMarkdown)(scenario, { variant: "compact" });
|
|
1444
1197
|
}
|
|
1445
1198
|
function scenarioToPrompt(scenario) {
|
|
1446
1199
|
const lines = [
|
|
@@ -1605,7 +1358,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1605
1358
|
] }),
|
|
1606
1359
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1607
1360
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1608
|
-
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,
|
|
1361
|
+
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,
|
|
1609
1362
|
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}` }),
|
|
1610
1363
|
actions ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenu, { children: [
|
|
1611
1364
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
@@ -1664,8 +1417,35 @@ function ReportScenarioList({ feature }) {
|
|
|
1664
1417
|
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)) });
|
|
1665
1418
|
}
|
|
1666
1419
|
|
|
1667
|
-
// src/components/
|
|
1420
|
+
// src/components/ReportFeatureIntro.tsx
|
|
1668
1421
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1422
|
+
function ReportFeatureIntro({ feature }) {
|
|
1423
|
+
const hasNarrative = Boolean(feature.narrative?.trim());
|
|
1424
|
+
const hasGlossary = Boolean(feature.glossary?.length);
|
|
1425
|
+
if (!hasNarrative && !hasGlossary) return null;
|
|
1426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
|
|
1427
|
+
hasNarrative ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1428
|
+
"div",
|
|
1429
|
+
{
|
|
1430
|
+
className: "es-doc-prose prose prose-sm max-w-none text-muted-foreground",
|
|
1431
|
+
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1432
|
+
}
|
|
1433
|
+
) : null,
|
|
1434
|
+
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: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
|
|
1437
|
+
] }, entry.term)) }) : null
|
|
1438
|
+
] });
|
|
1439
|
+
}
|
|
1440
|
+
function featureKindLabel(kind) {
|
|
1441
|
+
if (kind === "ability") return "Ability";
|
|
1442
|
+
if (kind === "business-need") return "Business need";
|
|
1443
|
+
if (kind === "feature") return "Feature";
|
|
1444
|
+
return null;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
// src/components/ReportFeature.tsx
|
|
1448
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1669
1449
|
function ReportFeature({ feature }) {
|
|
1670
1450
|
const titleId = `${feature.id}-title`;
|
|
1671
1451
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1673,10 +1453,11 @@ function ReportFeature({ feature }) {
|
|
|
1673
1453
|
const skipped = s.skipped + s.pending;
|
|
1674
1454
|
const collapse = useCollapse();
|
|
1675
1455
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1456
|
+
const kindLabel = featureKindLabel(feature.kind);
|
|
1676
1457
|
return (
|
|
1677
1458
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1678
1459
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1679
|
-
/* @__PURE__ */ (0,
|
|
1460
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1680
1461
|
"section",
|
|
1681
1462
|
{
|
|
1682
1463
|
id: feature.id,
|
|
@@ -1684,9 +1465,9 @@ function ReportFeature({ feature }) {
|
|
|
1684
1465
|
"aria-labelledby": titleId,
|
|
1685
1466
|
className: "flex flex-col gap-3",
|
|
1686
1467
|
children: [
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1469
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0", children: [
|
|
1470
|
+
/* @__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)(
|
|
1690
1471
|
"button",
|
|
1691
1472
|
{
|
|
1692
1473
|
type: "button",
|
|
@@ -1695,31 +1476,34 @@ function ReportFeature({ feature }) {
|
|
|
1695
1476
|
"aria-controls": bodyId,
|
|
1696
1477
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1697
1478
|
children: [
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1699
|
-
/* @__PURE__ */ (0,
|
|
1479
|
+
/* @__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" }),
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate", children: feature.title })
|
|
1700
1481
|
]
|
|
1701
1482
|
}
|
|
1702
1483
|
) : feature.title }),
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
1484
|
+
/* @__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: [
|
|
1485
|
+
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,
|
|
1486
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate font-mono", children: feature.sourceFile })
|
|
1487
|
+
] })
|
|
1704
1488
|
] }),
|
|
1705
|
-
/* @__PURE__ */ (0,
|
|
1489
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1706
1490
|
"p",
|
|
1707
1491
|
{
|
|
1708
1492
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1709
1493
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1710
1494
|
children: [
|
|
1711
|
-
/* @__PURE__ */ (0,
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
|
|
1712
1496
|
s.passed,
|
|
1713
1497
|
" passed"
|
|
1714
1498
|
] }),
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1717
1501
|
s.failed,
|
|
1718
1502
|
" failed"
|
|
1719
1503
|
] }),
|
|
1720
|
-
skipped > 0 ? /* @__PURE__ */ (0,
|
|
1721
|
-
/* @__PURE__ */ (0,
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1504
|
+
skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
|
|
1723
1507
|
skipped,
|
|
1724
1508
|
" skipped"
|
|
1725
1509
|
] })
|
|
@@ -1728,7 +1512,10 @@ function ReportFeature({ feature }) {
|
|
|
1728
1512
|
}
|
|
1729
1513
|
)
|
|
1730
1514
|
] }),
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportFeatureIntro, { feature }),
|
|
1517
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportScenarioList, { feature })
|
|
1518
|
+
] })
|
|
1732
1519
|
]
|
|
1733
1520
|
}
|
|
1734
1521
|
)
|
|
@@ -1736,17 +1523,17 @@ function ReportFeature({ feature }) {
|
|
|
1736
1523
|
}
|
|
1737
1524
|
|
|
1738
1525
|
// src/components/ReportFeatureList.tsx
|
|
1739
|
-
var
|
|
1526
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1740
1527
|
function ReportFeatureList() {
|
|
1741
1528
|
const report = useReport();
|
|
1742
|
-
return /* @__PURE__ */ (0,
|
|
1529
|
+
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)) });
|
|
1743
1530
|
}
|
|
1744
1531
|
|
|
1745
1532
|
// src/components/ui/empty.tsx
|
|
1746
1533
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
1747
|
-
var
|
|
1534
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1748
1535
|
function Empty({ className, ...props }) {
|
|
1749
|
-
return /* @__PURE__ */ (0,
|
|
1536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1750
1537
|
"div",
|
|
1751
1538
|
{
|
|
1752
1539
|
"data-slot": "empty",
|
|
@@ -1759,7 +1546,7 @@ function Empty({ className, ...props }) {
|
|
|
1759
1546
|
);
|
|
1760
1547
|
}
|
|
1761
1548
|
function EmptyHeader({ className, ...props }) {
|
|
1762
|
-
return /* @__PURE__ */ (0,
|
|
1549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1763
1550
|
"div",
|
|
1764
1551
|
{
|
|
1765
1552
|
"data-slot": "empty-header",
|
|
@@ -1786,7 +1573,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
|
|
|
1786
1573
|
}
|
|
1787
1574
|
);
|
|
1788
1575
|
function EmptyTitle({ className, ...props }) {
|
|
1789
|
-
return /* @__PURE__ */ (0,
|
|
1576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1790
1577
|
"div",
|
|
1791
1578
|
{
|
|
1792
1579
|
"data-slot": "empty-title",
|
|
@@ -1797,16 +1584,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1797
1584
|
}
|
|
1798
1585
|
|
|
1799
1586
|
// src/components/ReportEmpty.tsx
|
|
1800
|
-
var
|
|
1587
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1801
1588
|
function ReportEmpty({ message }) {
|
|
1802
|
-
return /* @__PURE__ */ (0,
|
|
1589
|
+
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." }) }) });
|
|
1803
1590
|
}
|
|
1804
1591
|
|
|
1805
1592
|
// src/components/ReportSummary.tsx
|
|
1806
|
-
var
|
|
1593
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1807
1594
|
function ReportSummary({ className }) {
|
|
1808
1595
|
const report = useReport();
|
|
1809
|
-
return /* @__PURE__ */ (0,
|
|
1596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1810
1597
|
ReportSummaryView,
|
|
1811
1598
|
{
|
|
1812
1599
|
summary: report.summary,
|
|
@@ -1832,7 +1619,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1832
1619
|
if (summary.pending > 0) {
|
|
1833
1620
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1834
1621
|
}
|
|
1835
|
-
return /* @__PURE__ */ (0,
|
|
1622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1836
1623
|
"dl",
|
|
1837
1624
|
{
|
|
1838
1625
|
className: cn(
|
|
@@ -1845,17 +1632,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1845
1632
|
"aria-label": ariaLabel,
|
|
1846
1633
|
children: cards.map((c) => {
|
|
1847
1634
|
const tone = TONE[c.status];
|
|
1848
|
-
return /* @__PURE__ */ (0,
|
|
1635
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1849
1636
|
"div",
|
|
1850
1637
|
{
|
|
1851
1638
|
"data-status": c.status,
|
|
1852
1639
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1853
1640
|
children: [
|
|
1854
|
-
/* @__PURE__ */ (0,
|
|
1855
|
-
/* @__PURE__ */ (0,
|
|
1641
|
+
/* @__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: [
|
|
1642
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1856
1643
|
c.label
|
|
1857
1644
|
] }),
|
|
1858
|
-
/* @__PURE__ */ (0,
|
|
1645
|
+
/* @__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 })
|
|
1859
1646
|
]
|
|
1860
1647
|
},
|
|
1861
1648
|
c.status
|
|
@@ -1865,6 +1652,9 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1865
1652
|
);
|
|
1866
1653
|
}
|
|
1867
1654
|
|
|
1655
|
+
// src/components/ReportMeta.tsx
|
|
1656
|
+
var import_duration4 = require("executable-stories-core/utils/duration");
|
|
1657
|
+
|
|
1868
1658
|
// src/lib/provenance.ts
|
|
1869
1659
|
function reportLastRunMs(report) {
|
|
1870
1660
|
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
@@ -1915,7 +1705,7 @@ function prUrl(ci) {
|
|
|
1915
1705
|
}
|
|
1916
1706
|
|
|
1917
1707
|
// src/components/ReportMeta.tsx
|
|
1918
|
-
var
|
|
1708
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1919
1709
|
function ReportMeta() {
|
|
1920
1710
|
const report = useReport();
|
|
1921
1711
|
const items = [];
|
|
@@ -1924,7 +1714,7 @@ function ReportMeta() {
|
|
|
1924
1714
|
items.push({ label: "Started", value: new Date(report.startedAtMs).toLocaleString() });
|
|
1925
1715
|
}
|
|
1926
1716
|
if (report.durationMs) {
|
|
1927
|
-
items.push({ label: "Duration", value: formatDuration(report.durationMs) });
|
|
1717
|
+
items.push({ label: "Duration", value: (0, import_duration4.formatDuration)(report.durationMs) });
|
|
1928
1718
|
}
|
|
1929
1719
|
if (report.packageVersion) {
|
|
1930
1720
|
items.push({ label: "Version", value: report.packageVersion });
|
|
@@ -1938,13 +1728,13 @@ function ReportMeta() {
|
|
|
1938
1728
|
const short = sha.slice(0, 8);
|
|
1939
1729
|
items.push({
|
|
1940
1730
|
label: "Commit",
|
|
1941
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1731
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1942
1732
|
});
|
|
1943
1733
|
}
|
|
1944
1734
|
if (report.ci) {
|
|
1945
1735
|
items.push({
|
|
1946
1736
|
label: "CI",
|
|
1947
|
-
value: report.ci.url ? /* @__PURE__ */ (0,
|
|
1737
|
+
value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1948
1738
|
ciDisplayName(report.ci.name),
|
|
1949
1739
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1950
1740
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1955,7 +1745,7 @@ function ReportMeta() {
|
|
|
1955
1745
|
const label = `#${report.ci.prNumber}`;
|
|
1956
1746
|
items.push({
|
|
1957
1747
|
label: "PR",
|
|
1958
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1748
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1959
1749
|
});
|
|
1960
1750
|
}
|
|
1961
1751
|
if (items.length === 0) return null;
|
|
@@ -1963,50 +1753,50 @@ function ReportMeta() {
|
|
|
1963
1753
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1964
1754
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1965
1755
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1966
|
-
/* @__PURE__ */ (0,
|
|
1967
|
-
/* @__PURE__ */ (0,
|
|
1968
|
-
/* @__PURE__ */ (0,
|
|
1756
|
+
/* @__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: [
|
|
1757
|
+
/* @__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: [
|
|
1758
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1969
1759
|
"Run details"
|
|
1970
1760
|
] }),
|
|
1971
|
-
/* @__PURE__ */ (0,
|
|
1972
|
-
/* @__PURE__ */ (0,
|
|
1973
|
-
/* @__PURE__ */ (0,
|
|
1761
|
+
/* @__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: [
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dt", { className: "font-medium", children: item.label }),
|
|
1763
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1974
1764
|
] }, item.label)) })
|
|
1975
1765
|
] })
|
|
1976
1766
|
);
|
|
1977
1767
|
}
|
|
1978
1768
|
|
|
1979
1769
|
// src/components/ReportSchemaError.tsx
|
|
1980
|
-
var
|
|
1770
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1981
1771
|
function ReportSchemaError({ error }) {
|
|
1982
|
-
return /* @__PURE__ */ (0,
|
|
1983
|
-
/* @__PURE__ */ (0,
|
|
1984
|
-
/* @__PURE__ */ (0,
|
|
1985
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0,
|
|
1772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: "Report could not be displayed." }) }),
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: error.message }),
|
|
1775
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
|
|
1986
1776
|
"The report bundle is newer than this version of ",
|
|
1987
|
-
/* @__PURE__ */ (0,
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("code", { children: "executable-stories-react" }),
|
|
1988
1778
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1989
1779
|
] }) : null,
|
|
1990
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0,
|
|
1991
|
-
/* @__PURE__ */ (0,
|
|
1780
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("details", { children: [
|
|
1781
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("summary", { children: [
|
|
1992
1782
|
error.issues.length,
|
|
1993
1783
|
" validation issue",
|
|
1994
1784
|
error.issues.length === 1 ? "" : "s"
|
|
1995
1785
|
] }),
|
|
1996
|
-
/* @__PURE__ */ (0,
|
|
1786
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1997
1787
|
] }) : null
|
|
1998
1788
|
] });
|
|
1999
1789
|
}
|
|
2000
1790
|
|
|
2001
1791
|
// src/components/ReportShell.tsx
|
|
2002
|
-
var
|
|
1792
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
2003
1793
|
function ReportErrorShell({
|
|
2004
1794
|
error,
|
|
2005
1795
|
className,
|
|
2006
1796
|
title,
|
|
2007
1797
|
dataTheme
|
|
2008
1798
|
}) {
|
|
2009
|
-
return /* @__PURE__ */ (0,
|
|
1799
|
+
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 }) });
|
|
2010
1800
|
}
|
|
2011
1801
|
|
|
2012
1802
|
// src/interactive/ReportInteractive.tsx
|
|
@@ -2015,12 +1805,12 @@ var import_lucide_react5 = require("lucide-react");
|
|
|
2015
1805
|
// src/components/ui/switch.tsx
|
|
2016
1806
|
var React4 = require("react");
|
|
2017
1807
|
var import_switch = require("@base-ui/react/switch");
|
|
2018
|
-
var
|
|
1808
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2019
1809
|
function Switch({
|
|
2020
1810
|
className,
|
|
2021
1811
|
...props
|
|
2022
1812
|
}) {
|
|
2023
|
-
return /* @__PURE__ */ (0,
|
|
1813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2024
1814
|
import_switch.Switch.Root,
|
|
2025
1815
|
{
|
|
2026
1816
|
"data-slot": "switch",
|
|
@@ -2029,7 +1819,7 @@ function Switch({
|
|
|
2029
1819
|
className
|
|
2030
1820
|
),
|
|
2031
1821
|
...props,
|
|
2032
|
-
children: /* @__PURE__ */ (0,
|
|
1822
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2033
1823
|
import_switch.Switch.Thumb,
|
|
2034
1824
|
{
|
|
2035
1825
|
"data-slot": "switch-thumb",
|
|
@@ -2045,7 +1835,7 @@ var React5 = __toESM(require("react"), 1);
|
|
|
2045
1835
|
var import_toggle_group = require("@base-ui/react/toggle-group");
|
|
2046
1836
|
var import_toggle = require("@base-ui/react/toggle");
|
|
2047
1837
|
var import_class_variance_authority3 = require("class-variance-authority");
|
|
2048
|
-
var
|
|
1838
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
2049
1839
|
var toggleItemVariants = (0, import_class_variance_authority3.cva)(
|
|
2050
1840
|
"inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap text-muted-foreground transition-[color,background-color,box-shadow] outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-background data-[pressed]:text-foreground data-[pressed]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
2051
1841
|
{
|
|
@@ -2067,13 +1857,13 @@ function ToggleGroup({
|
|
|
2067
1857
|
children,
|
|
2068
1858
|
...props
|
|
2069
1859
|
}) {
|
|
2070
|
-
return /* @__PURE__ */ (0,
|
|
1860
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
2071
1861
|
import_toggle_group.ToggleGroup,
|
|
2072
1862
|
{
|
|
2073
1863
|
"data-slot": "toggle-group",
|
|
2074
1864
|
className: cn("flex w-fit items-center gap-0.5 rounded-lg bg-muted p-0.5", className),
|
|
2075
1865
|
...props,
|
|
2076
|
-
children: /* @__PURE__ */ (0,
|
|
1866
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToggleGroupContext.Provider, { value: { size }, children })
|
|
2077
1867
|
}
|
|
2078
1868
|
);
|
|
2079
1869
|
}
|
|
@@ -2084,7 +1874,7 @@ function ToggleGroupItem({
|
|
|
2084
1874
|
...props
|
|
2085
1875
|
}) {
|
|
2086
1876
|
const context = React5.useContext(ToggleGroupContext);
|
|
2087
|
-
return /* @__PURE__ */ (0,
|
|
1877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
2088
1878
|
import_toggle.Toggle,
|
|
2089
1879
|
{
|
|
2090
1880
|
"data-slot": "toggle-group-item",
|
|
@@ -2101,9 +1891,9 @@ var import_lucide_react3 = require("lucide-react");
|
|
|
2101
1891
|
|
|
2102
1892
|
// src/components/ui/input.tsx
|
|
2103
1893
|
var React6 = require("react");
|
|
2104
|
-
var
|
|
1894
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
2105
1895
|
function Input({ className, type, ...props }) {
|
|
2106
|
-
return /* @__PURE__ */ (0,
|
|
1896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
2107
1897
|
"input",
|
|
2108
1898
|
{
|
|
2109
1899
|
type,
|
|
@@ -2120,7 +1910,7 @@ function Input({ className, type, ...props }) {
|
|
|
2120
1910
|
}
|
|
2121
1911
|
|
|
2122
1912
|
// src/interactive/ReportSearch.tsx
|
|
2123
|
-
var
|
|
1913
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
2124
1914
|
var ReportSearch = (0, import_react8.forwardRef)(
|
|
2125
1915
|
function ReportSearch2(props, ref) {
|
|
2126
1916
|
const {
|
|
@@ -2142,17 +1932,17 @@ var ReportSearch = (0, import_react8.forwardRef)(
|
|
|
2142
1932
|
e.preventDefault();
|
|
2143
1933
|
}
|
|
2144
1934
|
}
|
|
2145
|
-
return /* @__PURE__ */ (0,
|
|
2146
|
-
/* @__PURE__ */ (0,
|
|
2147
|
-
/* @__PURE__ */ (0,
|
|
2148
|
-
/* @__PURE__ */ (0,
|
|
1935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("es-search flex flex-col gap-1", className), children: [
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
|
|
1937
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "relative w-full sm:w-72", children: [
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
2149
1939
|
import_lucide_react3.Search,
|
|
2150
1940
|
{
|
|
2151
1941
|
"aria-hidden": true,
|
|
2152
1942
|
className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
|
|
2153
1943
|
}
|
|
2154
1944
|
),
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
1945
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
2156
1946
|
Input,
|
|
2157
1947
|
{
|
|
2158
1948
|
ref,
|
|
@@ -2169,7 +1959,7 @@ var ReportSearch = (0, import_react8.forwardRef)(
|
|
|
2169
1959
|
}
|
|
2170
1960
|
)
|
|
2171
1961
|
] }),
|
|
2172
|
-
showCounts ? /* @__PURE__ */ (0,
|
|
1962
|
+
showCounts ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
2173
1963
|
"span",
|
|
2174
1964
|
{
|
|
2175
1965
|
className: "text-xs tabular-nums text-muted-foreground",
|
|
@@ -2258,7 +2048,7 @@ function scrollToScenarioId(scenarioId, options = {}) {
|
|
|
2258
2048
|
}
|
|
2259
2049
|
|
|
2260
2050
|
// src/interactive/ReportFailureBanner.tsx
|
|
2261
|
-
var
|
|
2051
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2262
2052
|
function ReportFailureBanner({ failures }) {
|
|
2263
2053
|
const first = failures[0];
|
|
2264
2054
|
const jumpToFirst = (0, import_react9.useCallback)(() => {
|
|
@@ -2266,7 +2056,7 @@ function ReportFailureBanner({ failures }) {
|
|
|
2266
2056
|
scrollToScenarioId(first.scenarioId);
|
|
2267
2057
|
}, [first]);
|
|
2268
2058
|
if (failures.length === 0) return null;
|
|
2269
|
-
return /* @__PURE__ */ (0,
|
|
2059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
2270
2060
|
"div",
|
|
2271
2061
|
{
|
|
2272
2062
|
className: "es-failure-banner",
|
|
@@ -2274,13 +2064,13 @@ function ReportFailureBanner({ failures }) {
|
|
|
2274
2064
|
"aria-live": "polite",
|
|
2275
2065
|
"aria-label": "Failure summary",
|
|
2276
2066
|
children: [
|
|
2277
|
-
/* @__PURE__ */ (0,
|
|
2278
|
-
/* @__PURE__ */ (0,
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "es-failure-banner-text", children: [
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: failures.length }),
|
|
2279
2069
|
" ",
|
|
2280
2070
|
"failure",
|
|
2281
2071
|
failures.length === 1 ? "" : "s"
|
|
2282
2072
|
] }),
|
|
2283
|
-
/* @__PURE__ */ (0,
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
2284
2074
|
"button",
|
|
2285
2075
|
{
|
|
2286
2076
|
type: "button",
|
|
@@ -2297,7 +2087,7 @@ function ReportFailureBanner({ failures }) {
|
|
|
2297
2087
|
|
|
2298
2088
|
// src/interactive/ReportFreshness.tsx
|
|
2299
2089
|
var import_react10 = require("react");
|
|
2300
|
-
var
|
|
2090
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2301
2091
|
function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
2302
2092
|
const [now, setNow] = (0, import_react10.useState)(nowMs);
|
|
2303
2093
|
(0, import_react10.useEffect)(() => {
|
|
@@ -2305,7 +2095,7 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
2305
2095
|
}, [nowMs]);
|
|
2306
2096
|
if (lastRunMs === void 0 || now === void 0) return null;
|
|
2307
2097
|
const age = formatRelativeAge(lastRunMs, now);
|
|
2308
|
-
const runLink = ciUrl ? /* @__PURE__ */ (0,
|
|
2098
|
+
const runLink = ciUrl ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2309
2099
|
"a",
|
|
2310
2100
|
{
|
|
2311
2101
|
href: ciUrl,
|
|
@@ -2316,9 +2106,9 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
2316
2106
|
}
|
|
2317
2107
|
) : null;
|
|
2318
2108
|
if (isReportStale(lastRunMs, staleAfterDays, now)) {
|
|
2319
|
-
return /* @__PURE__ */ (0,
|
|
2320
|
-
/* @__PURE__ */ (0,
|
|
2321
|
-
/* @__PURE__ */ (0,
|
|
2109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { children: [
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("strong", { children: [
|
|
2322
2112
|
"Last verified ",
|
|
2323
2113
|
age,
|
|
2324
2114
|
"."
|
|
@@ -2328,10 +2118,10 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
2328
2118
|
runLink
|
|
2329
2119
|
] });
|
|
2330
2120
|
}
|
|
2331
|
-
return /* @__PURE__ */ (0,
|
|
2121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
|
|
2332
2122
|
"Verified ",
|
|
2333
2123
|
age,
|
|
2334
|
-
runLink ? /* @__PURE__ */ (0,
|
|
2124
|
+
runLink ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
2335
2125
|
" \xB7 ",
|
|
2336
2126
|
runLink
|
|
2337
2127
|
] }) : null
|
|
@@ -2339,15 +2129,15 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
2339
2129
|
}
|
|
2340
2130
|
|
|
2341
2131
|
// src/interactive/ReportLastRunDelta.tsx
|
|
2342
|
-
var
|
|
2132
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2343
2133
|
var MAX_LINKS = 5;
|
|
2344
2134
|
function ScenarioLinks({ scenarios, tone }) {
|
|
2345
|
-
return /* @__PURE__ */ (0,
|
|
2346
|
-
scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ (0,
|
|
2135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
2136
|
+
scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { children: [
|
|
2347
2137
|
i > 0 ? ", " : "",
|
|
2348
|
-
/* @__PURE__ */ (0,
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
|
|
2349
2139
|
] }, s.id)),
|
|
2350
|
-
scenarios.length > MAX_LINKS ? /* @__PURE__ */ (0,
|
|
2140
|
+
scenarios.length > MAX_LINKS ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { children: [
|
|
2351
2141
|
" and ",
|
|
2352
2142
|
scenarios.length - MAX_LINKS,
|
|
2353
2143
|
" more"
|
|
@@ -2364,23 +2154,23 @@ function ReportLastRunDelta({
|
|
|
2364
2154
|
if (!delta) return null;
|
|
2365
2155
|
const { newlyFailing, newlyPassing, added } = delta;
|
|
2366
2156
|
if (newlyFailing.length === 0 && newlyPassing.length === 0 && added.length === 0) {
|
|
2367
|
-
return /* @__PURE__ */ (0,
|
|
2157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
|
|
2368
2158
|
}
|
|
2369
|
-
return /* @__PURE__ */ (0,
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
newlyFailing.length > 0 ? /* @__PURE__ */ (0,
|
|
2159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
|
|
2160
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "font-medium text-foreground", children: "Since last run:" }),
|
|
2161
|
+
newlyFailing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2 text-fail", children: [
|
|
2372
2162
|
newlyFailing.length,
|
|
2373
2163
|
" newly failing (",
|
|
2374
|
-
/* @__PURE__ */ (0,
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
|
|
2375
2165
|
")"
|
|
2376
2166
|
] }) : null,
|
|
2377
|
-
newlyPassing.length > 0 ? /* @__PURE__ */ (0,
|
|
2167
|
+
newlyPassing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2 text-pass", children: [
|
|
2378
2168
|
newlyPassing.length,
|
|
2379
2169
|
" fixed (",
|
|
2380
|
-
/* @__PURE__ */ (0,
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
|
|
2381
2171
|
")"
|
|
2382
2172
|
] }) : null,
|
|
2383
|
-
added.length > 0 ? /* @__PURE__ */ (0,
|
|
2173
|
+
added.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2", children: [
|
|
2384
2174
|
added.length,
|
|
2385
2175
|
" new"
|
|
2386
2176
|
] }) : null
|
|
@@ -2444,7 +2234,7 @@ function Button({
|
|
|
2444
2234
|
}
|
|
2445
2235
|
|
|
2446
2236
|
// src/interactive/ReportShortcutsHelp.tsx
|
|
2447
|
-
var
|
|
2237
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
2448
2238
|
var SHORTCUTS = [
|
|
2449
2239
|
{ keys: "/", description: "Focus search" },
|
|
2450
2240
|
{ keys: "f", description: "Jump to next failure" },
|
|
@@ -2456,9 +2246,9 @@ var SHORTCUTS = [
|
|
|
2456
2246
|
];
|
|
2457
2247
|
function Keys({ keys }) {
|
|
2458
2248
|
const parts = keys.split(" ");
|
|
2459
|
-
return /* @__PURE__ */ (0,
|
|
2460
|
-
i > 0 ? /* @__PURE__ */ (0,
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
|
|
2250
|
+
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
|
|
2251
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
|
|
2462
2252
|
] }, k)) });
|
|
2463
2253
|
}
|
|
2464
2254
|
function ReportShortcutsHelp({ open, onClose }) {
|
|
@@ -2469,7 +2259,7 @@ function ReportShortcutsHelp({ open, onClose }) {
|
|
|
2469
2259
|
if (open && !dialog.open) dialog.showModal();
|
|
2470
2260
|
else if (!open && dialog.open) dialog.close();
|
|
2471
2261
|
}, [open]);
|
|
2472
|
-
return /* @__PURE__ */ (0,
|
|
2262
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
2473
2263
|
"dialog",
|
|
2474
2264
|
{
|
|
2475
2265
|
ref: dialogRef,
|
|
@@ -2477,12 +2267,12 @@ function ReportShortcutsHelp({ open, onClose }) {
|
|
|
2477
2267
|
"aria-label": "Keyboard shortcuts",
|
|
2478
2268
|
onClose,
|
|
2479
2269
|
children: [
|
|
2480
|
-
/* @__PURE__ */ (0,
|
|
2481
|
-
/* @__PURE__ */ (0,
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
2483
|
-
/* @__PURE__ */ (0,
|
|
2270
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
|
|
2271
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dt", { className: "justify-self-start", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Keys, { keys: s.keys }) }),
|
|
2273
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dd", { className: "text-sm text-muted-foreground", children: s.description })
|
|
2484
2274
|
] }, s.keys)) }),
|
|
2485
|
-
/* @__PURE__ */ (0,
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
|
|
2486
2276
|
]
|
|
2487
2277
|
}
|
|
2488
2278
|
);
|
|
@@ -2685,7 +2475,7 @@ function failuresFirst(report) {
|
|
|
2685
2475
|
|
|
2686
2476
|
// src/interactive/ReportFilters.tsx
|
|
2687
2477
|
var import_react14 = require("react");
|
|
2688
|
-
var
|
|
2478
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2689
2479
|
var TAG_LIMIT = 12;
|
|
2690
2480
|
function ReportFilters({
|
|
2691
2481
|
statuses,
|
|
@@ -2699,10 +2489,10 @@ function ReportFilters({
|
|
|
2699
2489
|
if (statuses.length === 0 && tags.length === 0) return null;
|
|
2700
2490
|
const tagsCollapsed = tags.length > TAG_LIMIT && !showAllTags;
|
|
2701
2491
|
const visibleTags = tagsCollapsed ? tags.slice(0, TAG_LIMIT) : tags;
|
|
2702
|
-
return /* @__PURE__ */ (0,
|
|
2703
|
-
statuses.length > 0 ? /* @__PURE__ */ (0,
|
|
2492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
2493
|
+
statuses.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
|
|
2704
2494
|
const active = status === opt.key;
|
|
2705
|
-
return /* @__PURE__ */ (0,
|
|
2495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2706
2496
|
"button",
|
|
2707
2497
|
{
|
|
2708
2498
|
type: "button",
|
|
@@ -2714,23 +2504,23 @@ function ReportFilters({
|
|
|
2714
2504
|
),
|
|
2715
2505
|
children: [
|
|
2716
2506
|
opt.label,
|
|
2717
|
-
/* @__PURE__ */ (0,
|
|
2507
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
|
|
2718
2508
|
]
|
|
2719
2509
|
},
|
|
2720
2510
|
opt.key
|
|
2721
2511
|
);
|
|
2722
2512
|
}) }) : null,
|
|
2723
|
-
tags.length > 0 ? /* @__PURE__ */ (0,
|
|
2513
|
+
tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
|
|
2724
2514
|
visibleTags.map((tag) => {
|
|
2725
2515
|
const active = activeTags.includes(tag);
|
|
2726
|
-
return /* @__PURE__ */ (0,
|
|
2516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2727
2517
|
"button",
|
|
2728
2518
|
{
|
|
2729
2519
|
type: "button",
|
|
2730
2520
|
"aria-pressed": active,
|
|
2731
2521
|
onClick: () => onToggleTag(tag),
|
|
2732
2522
|
className: "cursor-pointer",
|
|
2733
|
-
children: /* @__PURE__ */ (0,
|
|
2523
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2734
2524
|
Badge,
|
|
2735
2525
|
{
|
|
2736
2526
|
variant: "tag",
|
|
@@ -2743,7 +2533,7 @@ function ReportFilters({
|
|
|
2743
2533
|
}
|
|
2744
2534
|
) }, tag);
|
|
2745
2535
|
}),
|
|
2746
|
-
tags.length > TAG_LIMIT ? /* @__PURE__ */ (0,
|
|
2536
|
+
tags.length > TAG_LIMIT ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2747
2537
|
"button",
|
|
2748
2538
|
{
|
|
2749
2539
|
type: "button",
|
|
@@ -2759,7 +2549,7 @@ function ReportFilters({
|
|
|
2759
2549
|
|
|
2760
2550
|
// src/interactive/ReportToc.tsx
|
|
2761
2551
|
var import_react15 = require("react");
|
|
2762
|
-
var
|
|
2552
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
2763
2553
|
var DOT = {
|
|
2764
2554
|
passed: "bg-pass",
|
|
2765
2555
|
failed: "bg-fail",
|
|
@@ -2788,11 +2578,11 @@ function TocContent({ onNavigate }) {
|
|
|
2788
2578
|
return () => observer.disconnect();
|
|
2789
2579
|
}, [scenarioIds]);
|
|
2790
2580
|
if (report.features.length === 0) return null;
|
|
2791
|
-
return /* @__PURE__ */ (0,
|
|
2792
|
-
/* @__PURE__ */ (0,
|
|
2793
|
-
/* @__PURE__ */ (0,
|
|
2581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("li", { children: [
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
|
|
2583
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
|
|
2794
2584
|
const active = activeId === scenario.id;
|
|
2795
|
-
return /* @__PURE__ */ (0,
|
|
2585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
2796
2586
|
"a",
|
|
2797
2587
|
{
|
|
2798
2588
|
href: `#${scenario.id}`,
|
|
@@ -2807,14 +2597,14 @@ function TocContent({ onNavigate }) {
|
|
|
2807
2597
|
active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
|
|
2808
2598
|
),
|
|
2809
2599
|
children: [
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2600
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
2811
2601
|
"span",
|
|
2812
2602
|
{
|
|
2813
2603
|
"aria-hidden": true,
|
|
2814
2604
|
className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
|
|
2815
2605
|
}
|
|
2816
2606
|
),
|
|
2817
|
-
/* @__PURE__ */ (0,
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "break-words", children: scenario.title })
|
|
2818
2608
|
]
|
|
2819
2609
|
}
|
|
2820
2610
|
) }, scenario.id);
|
|
@@ -2824,14 +2614,14 @@ function TocContent({ onNavigate }) {
|
|
|
2824
2614
|
function ReportToc() {
|
|
2825
2615
|
const report = useReport();
|
|
2826
2616
|
if (report.features.length === 0) return null;
|
|
2827
|
-
return /* @__PURE__ */ (0,
|
|
2617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
2828
2618
|
"nav",
|
|
2829
2619
|
{
|
|
2830
2620
|
"aria-label": "Table of contents",
|
|
2831
2621
|
className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
|
|
2832
2622
|
children: [
|
|
2833
|
-
/* @__PURE__ */ (0,
|
|
2834
|
-
/* @__PURE__ */ (0,
|
|
2623
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
|
|
2624
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TocContent, {})
|
|
2835
2625
|
]
|
|
2836
2626
|
}
|
|
2837
2627
|
);
|
|
@@ -2841,31 +2631,31 @@ function ReportToc() {
|
|
|
2841
2631
|
var import_react16 = require("react");
|
|
2842
2632
|
var import_dialog = require("@base-ui/react/dialog");
|
|
2843
2633
|
var import_lucide_react4 = require("lucide-react");
|
|
2844
|
-
var
|
|
2634
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
2845
2635
|
function ReportTocDrawer() {
|
|
2846
2636
|
const report = useReport();
|
|
2847
2637
|
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
2848
2638
|
if (report.features.length === 0) return null;
|
|
2849
|
-
return /* @__PURE__ */ (0,
|
|
2850
|
-
/* @__PURE__ */ (0,
|
|
2851
|
-
/* @__PURE__ */ (0,
|
|
2639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Root, { open, onOpenChange: setOpen, children: [
|
|
2640
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
|
|
2641
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react4.ListIcon, { "aria-hidden": true }),
|
|
2852
2642
|
" Contents"
|
|
2853
2643
|
] }),
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
2855
|
-
/* @__PURE__ */ (0,
|
|
2856
|
-
/* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Portal, { children: [
|
|
2645
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
|
|
2646
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
|
|
2647
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_dialog.Dialog.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
2860
2650
|
import_dialog.Dialog.Close,
|
|
2861
2651
|
{
|
|
2862
2652
|
"aria-label": "Close contents",
|
|
2863
2653
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
2864
|
-
children: /* @__PURE__ */ (0,
|
|
2654
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react4.XIcon, { "aria-hidden": true })
|
|
2865
2655
|
}
|
|
2866
2656
|
)
|
|
2867
2657
|
] }),
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TocContent, { onNavigate: () => setOpen(false) })
|
|
2869
2659
|
] })
|
|
2870
2660
|
] })
|
|
2871
2661
|
] });
|
|
@@ -2948,14 +2738,14 @@ function useUrlState() {
|
|
|
2948
2738
|
}
|
|
2949
2739
|
|
|
2950
2740
|
// src/interactive/ReportInteractive.tsx
|
|
2951
|
-
var
|
|
2741
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
2952
2742
|
function ReportInteractive(props) {
|
|
2953
2743
|
const { report, className, title, dataTheme } = props;
|
|
2954
2744
|
const result = unwrapReport(report);
|
|
2955
2745
|
if (!result.ok) {
|
|
2956
|
-
return /* @__PURE__ */ (0,
|
|
2746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
2957
2747
|
}
|
|
2958
|
-
return /* @__PURE__ */ (0,
|
|
2748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportInteractiveView, { ...props, report: result.data });
|
|
2959
2749
|
}
|
|
2960
2750
|
var THEME_OPTIONS = [
|
|
2961
2751
|
{ value: "light", label: "Light", Icon: import_lucide_react5.Sun },
|
|
@@ -2963,7 +2753,7 @@ var THEME_OPTIONS = [
|
|
|
2963
2753
|
{ value: "dark", label: "Dark", Icon: import_lucide_react5.Moon }
|
|
2964
2754
|
];
|
|
2965
2755
|
function ThemeSegment({ pref, onPref }) {
|
|
2966
|
-
return /* @__PURE__ */ (0,
|
|
2756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
2967
2757
|
ToggleGroup,
|
|
2968
2758
|
{
|
|
2969
2759
|
size: "sm",
|
|
@@ -2973,7 +2763,7 @@ function ThemeSegment({ pref, onPref }) {
|
|
|
2973
2763
|
if (next) onPref(next);
|
|
2974
2764
|
},
|
|
2975
2765
|
"aria-label": "Color theme",
|
|
2976
|
-
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0,
|
|
2766
|
+
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon, {}) }, value))
|
|
2977
2767
|
}
|
|
2978
2768
|
);
|
|
2979
2769
|
}
|
|
@@ -3050,7 +2840,7 @@ function ReportInteractiveView({
|
|
|
3050
2840
|
const scenarioActions = (0, import_react19.useMemo)(
|
|
3051
2841
|
() => ({
|
|
3052
2842
|
copyLink: (s) => copy(scenarioPermalink(s), "Link copied"),
|
|
3053
|
-
copyMarkdown: (s) => copy(
|
|
2843
|
+
copyMarkdown: (s) => copy(scenarioToMarkdown(s), "Markdown copied"),
|
|
3054
2844
|
copyPrompt: (s) => copy(scenarioToPrompt(s), "Prompt copied")
|
|
3055
2845
|
}),
|
|
3056
2846
|
[copy]
|
|
@@ -3104,13 +2894,13 @@ function ReportInteractiveView({
|
|
|
3104
2894
|
const totalScenarios = report.summary.total;
|
|
3105
2895
|
const matchedScenarios = filtered.summary.total;
|
|
3106
2896
|
const showToc = !hideToc && totalScenarios > 3;
|
|
3107
|
-
return /* @__PURE__ */ (0,
|
|
2897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3108
2898
|
ReportRoot,
|
|
3109
2899
|
{
|
|
3110
2900
|
report: filtered,
|
|
3111
2901
|
customRenderers,
|
|
3112
2902
|
renderers,
|
|
3113
|
-
children: /* @__PURE__ */ (0,
|
|
2903
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
3114
2904
|
"main",
|
|
3115
2905
|
{
|
|
3116
2906
|
className: cn("es-report", "es-report-interactive", className),
|
|
@@ -3119,8 +2909,8 @@ function ReportInteractiveView({
|
|
|
3119
2909
|
"data-theme": dataTheme,
|
|
3120
2910
|
"data-detail-level": detail,
|
|
3121
2911
|
children: [
|
|
3122
|
-
/* @__PURE__ */ (0,
|
|
3123
|
-
/* @__PURE__ */ (0,
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("header", { className: "es-report-header", children: [
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
3124
2914
|
"div",
|
|
3125
2915
|
{
|
|
3126
2916
|
"data-es-navbar": true,
|
|
@@ -3129,9 +2919,9 @@ function ReportInteractiveView({
|
|
|
3129
2919
|
hideHeader ? "justify-end" : "justify-between"
|
|
3130
2920
|
),
|
|
3131
2921
|
children: [
|
|
3132
|
-
hideHeader ? null : /* @__PURE__ */ (0,
|
|
3133
|
-
/* @__PURE__ */ (0,
|
|
3134
|
-
/* @__PURE__ */ (0,
|
|
2922
|
+
hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h1", { className: "min-w-0", children: title ?? "Story Report" }),
|
|
2923
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3135
2925
|
ReportSearch,
|
|
3136
2926
|
{
|
|
3137
2927
|
ref: searchRef,
|
|
@@ -3141,16 +2931,16 @@ function ReportInteractiveView({
|
|
|
3141
2931
|
totalCount: totalScenarios
|
|
3142
2932
|
}
|
|
3143
2933
|
),
|
|
3144
|
-
/* @__PURE__ */ (0,
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeSegment, { pref: themePref, onPref: setThemePref })
|
|
3145
2935
|
] })
|
|
3146
2936
|
]
|
|
3147
2937
|
}
|
|
3148
2938
|
),
|
|
3149
|
-
hideHeader ? null : /* @__PURE__ */ (0,
|
|
3150
|
-
/* @__PURE__ */ (0,
|
|
3151
|
-
/* @__PURE__ */ (0,
|
|
2939
|
+
hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportSummary, {}),
|
|
2941
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportMeta, {})
|
|
3152
2942
|
] }),
|
|
3153
|
-
/* @__PURE__ */ (0,
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3154
2944
|
ReportFreshness,
|
|
3155
2945
|
{
|
|
3156
2946
|
lastRunMs: reportLastRunMs(report),
|
|
@@ -3158,8 +2948,8 @@ function ReportInteractiveView({
|
|
|
3158
2948
|
staleAfterDays
|
|
3159
2949
|
}
|
|
3160
2950
|
),
|
|
3161
|
-
/* @__PURE__ */ (0,
|
|
3162
|
-
/* @__PURE__ */ (0,
|
|
2951
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportLastRunDelta, { history: scenarioHistory, report }),
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3163
2953
|
ReportFilters,
|
|
3164
2954
|
{
|
|
3165
2955
|
statuses: statusOptions,
|
|
@@ -3170,14 +2960,14 @@ function ReportInteractiveView({
|
|
|
3170
2960
|
onToggleTag: toggleTag
|
|
3171
2961
|
}
|
|
3172
2962
|
),
|
|
3173
|
-
/* @__PURE__ */ (0,
|
|
3174
|
-
showToc ? /* @__PURE__ */ (0,
|
|
3175
|
-
/* @__PURE__ */ (0,
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
|
|
2964
|
+
showToc ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportTocDrawer, {}) : null,
|
|
2965
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2966
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
|
|
2967
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
|
|
3178
2968
|
] }),
|
|
3179
|
-
/* @__PURE__ */ (0,
|
|
3180
|
-
/* @__PURE__ */ (0,
|
|
2969
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2970
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3181
2971
|
Switch,
|
|
3182
2972
|
{
|
|
3183
2973
|
id: docsId,
|
|
@@ -3185,16 +2975,16 @@ function ReportInteractiveView({
|
|
|
3185
2975
|
onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
|
|
3186
2976
|
}
|
|
3187
2977
|
),
|
|
3188
|
-
/* @__PURE__ */ (0,
|
|
2978
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
|
|
3189
2979
|
] })
|
|
3190
2980
|
] })
|
|
3191
2981
|
] }),
|
|
3192
|
-
/* @__PURE__ */ (0,
|
|
3193
|
-
hasContent ? showToc ? /* @__PURE__ */ (0,
|
|
3194
|
-
/* @__PURE__ */ (0,
|
|
3195
|
-
/* @__PURE__ */ (0,
|
|
3196
|
-
] }) : /* @__PURE__ */ (0,
|
|
3197
|
-
/* @__PURE__ */ (0,
|
|
2982
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFailureBanner, { failures }),
|
|
2983
|
+
hasContent ? showToc ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex gap-6", children: [
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportToc, {}),
|
|
2985
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFeatureList, {}) })
|
|
2986
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFeatureList, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
|
|
2987
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3198
2988
|
"button",
|
|
3199
2989
|
{
|
|
3200
2990
|
type: "button",
|
|
@@ -3205,8 +2995,8 @@ function ReportInteractiveView({
|
|
|
3205
2995
|
children: "?"
|
|
3206
2996
|
}
|
|
3207
2997
|
),
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3209
|
-
toast ? /* @__PURE__ */ (0,
|
|
2998
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
|
|
2999
|
+
toast ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3210
3000
|
"div",
|
|
3211
3001
|
{
|
|
3212
3002
|
role: "status",
|
|
@@ -3230,7 +3020,7 @@ var import_react21 = require("react");
|
|
|
3230
3020
|
|
|
3231
3021
|
// src/components/doc/MermaidView.tsx
|
|
3232
3022
|
var import_react20 = require("react");
|
|
3233
|
-
var
|
|
3023
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3234
3024
|
function prefersDark(el) {
|
|
3235
3025
|
const themed = el?.closest("[data-theme]");
|
|
3236
3026
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -3284,9 +3074,9 @@ function MermaidView({ entry, load }) {
|
|
|
3284
3074
|
};
|
|
3285
3075
|
}, [entry.code, load]);
|
|
3286
3076
|
if (svg) {
|
|
3287
|
-
return /* @__PURE__ */ (0,
|
|
3288
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
3289
|
-
/* @__PURE__ */ (0,
|
|
3077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("figure", { ref, className: "my-3", children: [
|
|
3078
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3290
3080
|
"div",
|
|
3291
3081
|
{
|
|
3292
3082
|
role: "img",
|
|
@@ -3297,8 +3087,8 @@ function MermaidView({ entry, load }) {
|
|
|
3297
3087
|
)
|
|
3298
3088
|
] });
|
|
3299
3089
|
}
|
|
3300
|
-
return /* @__PURE__ */ (0,
|
|
3301
|
-
error ? /* @__PURE__ */ (0,
|
|
3090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
3091
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
3302
3092
|
"p",
|
|
3303
3093
|
{
|
|
3304
3094
|
role: "alert",
|
|
@@ -3310,12 +3100,12 @@ function MermaidView({ entry, load }) {
|
|
|
3310
3100
|
]
|
|
3311
3101
|
}
|
|
3312
3102
|
) : null,
|
|
3313
|
-
/* @__PURE__ */ (0,
|
|
3103
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MermaidSource, { entry, ref })
|
|
3314
3104
|
] });
|
|
3315
3105
|
}
|
|
3316
3106
|
|
|
3317
3107
|
// src/interactive/island-renderers.tsx
|
|
3318
|
-
var
|
|
3108
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3319
3109
|
var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
|
|
3320
3110
|
var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
|
|
3321
3111
|
function cachedCdnModule(url) {
|
|
@@ -3349,13 +3139,13 @@ function CdnHighlightedCode({ entry }) {
|
|
|
3349
3139
|
cancelled = true;
|
|
3350
3140
|
};
|
|
3351
3141
|
}, [entry.content, entry.lang]);
|
|
3352
|
-
return /* @__PURE__ */ (0,
|
|
3142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3353
3143
|
"code",
|
|
3354
3144
|
{
|
|
3355
3145
|
className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
|
|
3356
3146
|
dangerouslySetInnerHTML: { __html: html }
|
|
3357
3147
|
}
|
|
3358
|
-
) : /* @__PURE__ */ (0,
|
|
3148
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
3359
3149
|
}
|
|
3360
3150
|
function buildIslandRenderers(opts) {
|
|
3361
3151
|
const renderers = {};
|
|
@@ -3369,7 +3159,7 @@ function buildIslandRenderers(opts) {
|
|
|
3369
3159
|
}
|
|
3370
3160
|
|
|
3371
3161
|
// src/interactive/ReportInteractiveIsland.tsx
|
|
3372
|
-
var
|
|
3162
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
3373
3163
|
function ReportInteractiveIsland({
|
|
3374
3164
|
report,
|
|
3375
3165
|
title,
|
|
@@ -3383,7 +3173,7 @@ function ReportInteractiveIsland({
|
|
|
3383
3173
|
() => buildIslandRenderers({ syntaxHighlighting, mermaid }),
|
|
3384
3174
|
[syntaxHighlighting, mermaid]
|
|
3385
3175
|
);
|
|
3386
|
-
return /* @__PURE__ */ (0,
|
|
3176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3387
3177
|
ReportInteractive,
|
|
3388
3178
|
{
|
|
3389
3179
|
report,
|