executable-stories-react 0.5.0 → 0.7.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 +244 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +243 -158
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +469 -258
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.js +469 -258
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +29 -24
- package/dist/ssr.cjs +210 -126
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +210 -126
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
package/dist/interactive.js
CHANGED
|
@@ -202,7 +202,7 @@ function DocTable({ entry }) {
|
|
|
202
202
|
entry.label ? /* @__PURE__ */ jsx6("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
203
203
|
/* @__PURE__ */ jsx6("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs3("table", { className: "w-full border-collapse text-sm", children: [
|
|
204
204
|
/* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsx6("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ jsx6("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
205
|
-
/* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((
|
|
205
|
+
/* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((cell2, j) => /* @__PURE__ */ jsx6("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell2 }, j)) }, i)) })
|
|
206
206
|
] }) })
|
|
207
207
|
] });
|
|
208
208
|
}
|
|
@@ -225,7 +225,7 @@ function DocLink({ entry }) {
|
|
|
225
225
|
// src/components/doc/DocSection.tsx
|
|
226
226
|
import { marked } from "marked";
|
|
227
227
|
|
|
228
|
-
//
|
|
228
|
+
// ../executable-stories-core/dist/utils/url.js
|
|
229
229
|
function safeUrl(value) {
|
|
230
230
|
if (!value) return void 0;
|
|
231
231
|
const trimmed = value.trim();
|
|
@@ -520,18 +520,101 @@ function ReportStepItem({ step }) {
|
|
|
520
520
|
);
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
+
// ../executable-stories-core/dist/storyboard.js
|
|
524
|
+
function findScreenshot(entries) {
|
|
525
|
+
for (const entry of entries) {
|
|
526
|
+
if (entry.kind === "screenshot") return entry;
|
|
527
|
+
if (entry.children) {
|
|
528
|
+
const nested = findScreenshot(entry.children);
|
|
529
|
+
if (nested) return nested;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return void 0;
|
|
533
|
+
}
|
|
534
|
+
function extractStoryboardFrames(scenario) {
|
|
535
|
+
const frames = [];
|
|
536
|
+
for (const step of scenario.steps) {
|
|
537
|
+
const shot = findScreenshot(step.docEntries);
|
|
538
|
+
if (!shot) continue;
|
|
539
|
+
frames.push({
|
|
540
|
+
stepId: step.id,
|
|
541
|
+
stepIndex: step.index,
|
|
542
|
+
keyword: step.keyword,
|
|
543
|
+
text: step.text,
|
|
544
|
+
status: step.status,
|
|
545
|
+
path: shot.path,
|
|
546
|
+
...shot.alt !== void 0 && { alt: shot.alt }
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
return frames;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// src/components/ReportStoryboard.tsx
|
|
553
|
+
import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
554
|
+
var FRAME_GLYPH = {
|
|
555
|
+
passed: "\u2713",
|
|
556
|
+
failed: "\u2717",
|
|
557
|
+
skipped: "\u25CB",
|
|
558
|
+
pending: "\u25CB"
|
|
559
|
+
};
|
|
560
|
+
var FRAME_GLYPH_COLOR = {
|
|
561
|
+
passed: "text-pass",
|
|
562
|
+
failed: "text-fail",
|
|
563
|
+
skipped: "text-skip",
|
|
564
|
+
pending: "text-pend"
|
|
565
|
+
};
|
|
566
|
+
function ReportStoryboard({ scenario }) {
|
|
567
|
+
const frames = extractStoryboardFrames(scenario);
|
|
568
|
+
if (frames.length < 2) return null;
|
|
569
|
+
return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
570
|
+
/* @__PURE__ */ jsx18("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
571
|
+
/* @__PURE__ */ jsx18("ol", { className: "flex gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx18(StoryboardFrameItem, { frame }, frame.stepId)) })
|
|
572
|
+
] });
|
|
573
|
+
}
|
|
574
|
+
function StoryboardFrameItem({ frame }) {
|
|
575
|
+
const src = isLocalFsPath(frame.path) ? void 0 : safeImageUrl(frame.path);
|
|
576
|
+
const label = `${frame.keyword} ${frame.text}`;
|
|
577
|
+
return /* @__PURE__ */ jsxs11("li", { className: "w-40 shrink-0", children: [
|
|
578
|
+
/* @__PURE__ */ jsx18(
|
|
579
|
+
"a",
|
|
580
|
+
{
|
|
581
|
+
href: `#${frame.stepId}`,
|
|
582
|
+
"aria-label": `Jump to step: ${label}`,
|
|
583
|
+
className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
|
|
584
|
+
children: src ? /* @__PURE__ */ jsx18(
|
|
585
|
+
"img",
|
|
586
|
+
{
|
|
587
|
+
src,
|
|
588
|
+
alt: frame.alt ?? label,
|
|
589
|
+
loading: "lazy",
|
|
590
|
+
className: "h-24 w-full bg-muted object-cover object-top"
|
|
591
|
+
}
|
|
592
|
+
) : /* @__PURE__ */ jsx18("span", { className: "flex h-24 w-full items-center justify-center border-b border-dashed border-border bg-muted px-2 text-center text-[0.6875rem] text-muted-foreground", children: "Screenshot unavailable" })
|
|
593
|
+
}
|
|
594
|
+
),
|
|
595
|
+
/* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
596
|
+
/* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
597
|
+
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
598
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
599
|
+
" ",
|
|
600
|
+
/* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: frame.alt ?? frame.text })
|
|
601
|
+
] })
|
|
602
|
+
] })
|
|
603
|
+
] });
|
|
604
|
+
}
|
|
605
|
+
|
|
523
606
|
// src/components/ReportAttachments.tsx
|
|
524
|
-
import { Fragment as Fragment6, jsx as
|
|
607
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
525
608
|
function ReportAttachments({ attachments }) {
|
|
526
609
|
if (attachments.length === 0) return null;
|
|
527
610
|
return (
|
|
528
611
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
529
612
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
530
|
-
/* @__PURE__ */
|
|
613
|
+
/* @__PURE__ */ jsx19("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
531
614
|
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
532
615
|
const isImage = att.mediaType.startsWith("image/");
|
|
533
|
-
return /* @__PURE__ */
|
|
534
|
-
/* @__PURE__ */
|
|
616
|
+
return /* @__PURE__ */ jsx19("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
617
|
+
/* @__PURE__ */ jsx19(
|
|
535
618
|
"img",
|
|
536
619
|
{
|
|
537
620
|
src: dataUri,
|
|
@@ -540,8 +623,8 @@ function ReportAttachments({ attachments }) {
|
|
|
540
623
|
className: "max-w-full rounded-md border border-border"
|
|
541
624
|
}
|
|
542
625
|
),
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
] }) : /* @__PURE__ */
|
|
626
|
+
/* @__PURE__ */ jsx19("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
627
|
+
] }) : /* @__PURE__ */ jsxs12(
|
|
545
628
|
"a",
|
|
546
629
|
{
|
|
547
630
|
href: dataUri,
|
|
@@ -550,7 +633,7 @@ function ReportAttachments({ attachments }) {
|
|
|
550
633
|
children: [
|
|
551
634
|
att.name,
|
|
552
635
|
" ",
|
|
553
|
-
/* @__PURE__ */
|
|
636
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
|
|
554
637
|
"(",
|
|
555
638
|
att.mediaType,
|
|
556
639
|
")"
|
|
@@ -638,7 +721,7 @@ function traceWindow(rows) {
|
|
|
638
721
|
}
|
|
639
722
|
|
|
640
723
|
// src/components/ReportTrace.tsx
|
|
641
|
-
import { jsx as
|
|
724
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
642
725
|
var BAR_COLOR = {
|
|
643
726
|
ok: "bg-pass",
|
|
644
727
|
error: "bg-fail",
|
|
@@ -649,8 +732,8 @@ function ReportTrace({ spans }) {
|
|
|
649
732
|
const rows = toTraceRows(spans);
|
|
650
733
|
if (rows.length === 0) return null;
|
|
651
734
|
const { minStartMs, totalMs } = traceWindow(rows);
|
|
652
|
-
return /* @__PURE__ */
|
|
653
|
-
/* @__PURE__ */
|
|
735
|
+
return /* @__PURE__ */ jsxs13("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
|
|
736
|
+
/* @__PURE__ */ jsxs13("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
|
|
654
737
|
"Trace (",
|
|
655
738
|
rows.length,
|
|
656
739
|
" span",
|
|
@@ -659,11 +742,11 @@ function ReportTrace({ spans }) {
|
|
|
659
742
|
formatDuration(totalMs),
|
|
660
743
|
")"
|
|
661
744
|
] }),
|
|
662
|
-
/* @__PURE__ */
|
|
745
|
+
/* @__PURE__ */ jsx20("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
663
746
|
const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
|
|
664
747
|
const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
|
|
665
|
-
return /* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
748
|
+
return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
|
|
749
|
+
/* @__PURE__ */ jsx20(
|
|
667
750
|
"span",
|
|
668
751
|
{
|
|
669
752
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
@@ -672,14 +755,14 @@ function ReportTrace({ spans }) {
|
|
|
672
755
|
children: row.name
|
|
673
756
|
}
|
|
674
757
|
),
|
|
675
|
-
/* @__PURE__ */
|
|
758
|
+
/* @__PURE__ */ jsx20("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx20(
|
|
676
759
|
"span",
|
|
677
760
|
{
|
|
678
761
|
className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
|
|
679
762
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
680
763
|
}
|
|
681
764
|
) }),
|
|
682
|
-
/* @__PURE__ */
|
|
765
|
+
/* @__PURE__ */ jsx20("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
683
766
|
] }, `${row.spanId}-${i}`);
|
|
684
767
|
}) })
|
|
685
768
|
] });
|
|
@@ -748,7 +831,7 @@ function diffSinceLastRun(history2, scenarios) {
|
|
|
748
831
|
}
|
|
749
832
|
|
|
750
833
|
// src/components/ScenarioRunHistory.tsx
|
|
751
|
-
import { Fragment as Fragment7, jsx as
|
|
834
|
+
import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
752
835
|
var MAX_DOTS = 10;
|
|
753
836
|
var DOT_COLOR = {
|
|
754
837
|
passed: "bg-pass",
|
|
@@ -768,16 +851,16 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
768
851
|
const recent = entries.slice(-MAX_DOTS);
|
|
769
852
|
const flaky = flakinessOf(recent) === "flaky";
|
|
770
853
|
const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
|
|
771
|
-
return /* @__PURE__ */
|
|
772
|
-
flaky ? /* @__PURE__ */
|
|
773
|
-
/* @__PURE__ */
|
|
854
|
+
return /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
855
|
+
flaky ? /* @__PURE__ */ jsx21(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
|
|
856
|
+
/* @__PURE__ */ jsx21(
|
|
774
857
|
"span",
|
|
775
858
|
{
|
|
776
859
|
role: "img",
|
|
777
860
|
"aria-label": `Run history: ${summary}`,
|
|
778
861
|
title: summary,
|
|
779
862
|
className: "flex shrink-0 items-center gap-[3px]",
|
|
780
|
-
children: recent.map((e, i) => /* @__PURE__ */
|
|
863
|
+
children: recent.map((e, i) => /* @__PURE__ */ jsx21(
|
|
781
864
|
"span",
|
|
782
865
|
{
|
|
783
866
|
"aria-hidden": true,
|
|
@@ -855,20 +938,118 @@ function useCollapseState(computeDefault) {
|
|
|
855
938
|
|
|
856
939
|
// src/interactive/scenario-actions.tsx
|
|
857
940
|
import { createContext as createContext4, useContext as useContext5 } from "react";
|
|
941
|
+
|
|
942
|
+
// ../executable-stories-core/dist/utils/scenario-markdown.js
|
|
943
|
+
function cell(value) {
|
|
944
|
+
return value.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
945
|
+
}
|
|
946
|
+
function stringify(value) {
|
|
947
|
+
if (typeof value === "string") return value;
|
|
948
|
+
try {
|
|
949
|
+
return JSON.stringify(value, null, 2) ?? String(value);
|
|
950
|
+
} catch {
|
|
951
|
+
return String(value);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
function docEntryToMarkdown(entry) {
|
|
955
|
+
const lines = [];
|
|
956
|
+
switch (entry.kind) {
|
|
957
|
+
case "note":
|
|
958
|
+
lines.push(entry.text);
|
|
959
|
+
break;
|
|
960
|
+
case "tag":
|
|
961
|
+
lines.push(entry.names.map((n) => `\`@${n}\``).join(" "));
|
|
962
|
+
break;
|
|
963
|
+
case "kv":
|
|
964
|
+
lines.push(`**${entry.label}:** ${stringify(entry.value)}`);
|
|
965
|
+
break;
|
|
966
|
+
case "code":
|
|
967
|
+
lines.push(`**${entry.label}**`, "", "```" + (entry.lang ?? ""), entry.content, "```");
|
|
968
|
+
break;
|
|
969
|
+
case "table": {
|
|
970
|
+
lines.push(`**${entry.label}**`, "");
|
|
971
|
+
lines.push(`| ${entry.columns.map(cell).join(" | ")} |`);
|
|
972
|
+
lines.push(`| ${entry.columns.map(() => "---").join(" | ")} |`);
|
|
973
|
+
for (const row of entry.rows) lines.push(`| ${row.map(cell).join(" | ")} |`);
|
|
974
|
+
break;
|
|
975
|
+
}
|
|
976
|
+
case "link":
|
|
977
|
+
lines.push(`[${entry.label}](${entry.url})`);
|
|
978
|
+
break;
|
|
979
|
+
case "section":
|
|
980
|
+
lines.push(`### ${entry.title}`, "", entry.markdown);
|
|
981
|
+
break;
|
|
982
|
+
case "mermaid":
|
|
983
|
+
if (entry.title) lines.push(`**${entry.title}**`, "");
|
|
984
|
+
lines.push("```mermaid", entry.code, "```");
|
|
985
|
+
break;
|
|
986
|
+
case "screenshot":
|
|
987
|
+
lines.push(``);
|
|
988
|
+
break;
|
|
989
|
+
case "video":
|
|
990
|
+
lines.push(`Video: ${entry.path}${entry.caption ? ` \u2014 ${entry.caption}` : ""}`);
|
|
991
|
+
break;
|
|
992
|
+
case "html": {
|
|
993
|
+
const htmlTitle = entry.title ?? "Embedded HTML";
|
|
994
|
+
if (entry.content) {
|
|
995
|
+
lines.push(`**${htmlTitle}**`, "", "```html", entry.content, "```");
|
|
996
|
+
} else if (entry.url) {
|
|
997
|
+
lines.push(`[${htmlTitle}](${entry.url})`);
|
|
998
|
+
} else {
|
|
999
|
+
lines.push(`Embedded HTML: ${entry.path ?? "(inline)"}`);
|
|
1000
|
+
}
|
|
1001
|
+
break;
|
|
1002
|
+
}
|
|
1003
|
+
case "custom":
|
|
1004
|
+
lines.push(`**${entry.type}**`, "", "```json", stringify(entry.data), "```");
|
|
1005
|
+
break;
|
|
1006
|
+
}
|
|
1007
|
+
for (const child of entry.children ?? []) {
|
|
1008
|
+
lines.push("", ...docEntryToMarkdown(child));
|
|
1009
|
+
}
|
|
1010
|
+
return lines;
|
|
1011
|
+
}
|
|
1012
|
+
function stepLines(step, ordinal, full) {
|
|
1013
|
+
const status = step.status === "passed" ? "" : ` \u2014 **${step.status}**`;
|
|
1014
|
+
const lines = [`${ordinal}. **${step.keyword}** ${step.text}${status}`];
|
|
1015
|
+
if (!full) return lines;
|
|
1016
|
+
if (step.errorMessage) {
|
|
1017
|
+
lines.push(...step.errorMessage.split("\n").map((l) => ` > ${l}`));
|
|
1018
|
+
}
|
|
1019
|
+
for (const entry of step.docEntries) {
|
|
1020
|
+
lines.push("", ...docEntryToMarkdown(entry).map((l) => l === "" ? l : ` ${l}`));
|
|
1021
|
+
}
|
|
1022
|
+
return lines;
|
|
1023
|
+
}
|
|
1024
|
+
function scenarioToMarkdown(scenario, options = {}) {
|
|
1025
|
+
const { variant = "full", meta = [] } = options;
|
|
1026
|
+
const full = variant === "full";
|
|
1027
|
+
const lines = full ? [`# ${scenario.title}`, ""] : [`## ${scenario.title} _(${scenario.status})_`, ""];
|
|
1028
|
+
if (full && meta.length > 0) lines.push(...meta);
|
|
1029
|
+
if (scenario.steps.length > 0) {
|
|
1030
|
+
if (full) lines.push("", "## Steps", "");
|
|
1031
|
+
scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full)));
|
|
1032
|
+
}
|
|
1033
|
+
if (scenario.errorMessage) {
|
|
1034
|
+
if (full) lines.push("", "## Failure", "");
|
|
1035
|
+
else lines.push("");
|
|
1036
|
+
lines.push("```", scenario.errorMessage.trim(), "```");
|
|
1037
|
+
}
|
|
1038
|
+
if (full && scenario.docEntries.length > 0) {
|
|
1039
|
+
lines.push("", "## Docs", "");
|
|
1040
|
+
for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry), "");
|
|
1041
|
+
}
|
|
1042
|
+
return lines.join("\n").replaceAll(/\n{3,}/g, "\n\n").trimEnd() + (full ? "\n" : "");
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
// src/interactive/scenario-actions.tsx
|
|
858
1046
|
var ScenarioActionsContext = createContext4(null);
|
|
859
1047
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
860
1048
|
function useScenarioActions() {
|
|
861
1049
|
return useContext5(ScenarioActionsContext);
|
|
862
1050
|
}
|
|
863
|
-
function
|
|
864
|
-
|
|
865
|
-
for (const step of scenario.steps) {
|
|
866
|
-
lines.push(`- **${step.keyword}** ${step.text}`);
|
|
867
|
-
}
|
|
868
|
-
if (scenario.errorMessage) {
|
|
869
|
-
lines.push("", "```", scenario.errorMessage.trim(), "```");
|
|
870
|
-
}
|
|
871
|
-
return lines.join("\n");
|
|
1051
|
+
function scenarioToMarkdown2(scenario) {
|
|
1052
|
+
return scenarioToMarkdown(scenario, { variant: "compact" });
|
|
872
1053
|
}
|
|
873
1054
|
function scenarioToPrompt(scenario) {
|
|
874
1055
|
const lines = [
|
|
@@ -896,9 +1077,9 @@ function scenarioPermalink(scenario) {
|
|
|
896
1077
|
|
|
897
1078
|
// src/components/ui/card.tsx
|
|
898
1079
|
import "react";
|
|
899
|
-
import { jsx as
|
|
1080
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
900
1081
|
function Card({ className, ...props }) {
|
|
901
|
-
return /* @__PURE__ */
|
|
1082
|
+
return /* @__PURE__ */ jsx22(
|
|
902
1083
|
"div",
|
|
903
1084
|
{
|
|
904
1085
|
"data-slot": "card",
|
|
@@ -911,7 +1092,7 @@ function Card({ className, ...props }) {
|
|
|
911
1092
|
);
|
|
912
1093
|
}
|
|
913
1094
|
function CardHeader({ className, ...props }) {
|
|
914
|
-
return /* @__PURE__ */
|
|
1095
|
+
return /* @__PURE__ */ jsx22(
|
|
915
1096
|
"div",
|
|
916
1097
|
{
|
|
917
1098
|
"data-slot": "card-header",
|
|
@@ -924,7 +1105,7 @@ function CardHeader({ className, ...props }) {
|
|
|
924
1105
|
);
|
|
925
1106
|
}
|
|
926
1107
|
function CardContent({ className, ...props }) {
|
|
927
|
-
return /* @__PURE__ */
|
|
1108
|
+
return /* @__PURE__ */ jsx22(
|
|
928
1109
|
"div",
|
|
929
1110
|
{
|
|
930
1111
|
"data-slot": "card-content",
|
|
@@ -938,13 +1119,13 @@ function CardContent({ className, ...props }) {
|
|
|
938
1119
|
import "react";
|
|
939
1120
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
940
1121
|
import { CheckIcon } from "lucide-react";
|
|
941
|
-
import { jsx as
|
|
1122
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
942
1123
|
var itemClasses = "relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg:not([class*='text-'])]:text-muted-foreground";
|
|
943
1124
|
function DropdownMenu(props) {
|
|
944
|
-
return /* @__PURE__ */
|
|
1125
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
945
1126
|
}
|
|
946
1127
|
function DropdownMenuTrigger(props) {
|
|
947
|
-
return /* @__PURE__ */
|
|
1128
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
948
1129
|
}
|
|
949
1130
|
function DropdownMenuContent({
|
|
950
1131
|
className,
|
|
@@ -952,14 +1133,14 @@ function DropdownMenuContent({
|
|
|
952
1133
|
sideOffset = 4,
|
|
953
1134
|
...props
|
|
954
1135
|
}) {
|
|
955
|
-
return /* @__PURE__ */
|
|
1136
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx23(
|
|
956
1137
|
MenuPrimitive.Positioner,
|
|
957
1138
|
{
|
|
958
1139
|
"data-slot": "dropdown-menu-positioner",
|
|
959
1140
|
className: "z-50",
|
|
960
1141
|
align,
|
|
961
1142
|
sideOffset,
|
|
962
|
-
children: /* @__PURE__ */
|
|
1143
|
+
children: /* @__PURE__ */ jsx23(
|
|
963
1144
|
MenuPrimitive.Popup,
|
|
964
1145
|
{
|
|
965
1146
|
"data-slot": "dropdown-menu-content",
|
|
@@ -977,7 +1158,7 @@ function DropdownMenuItem({
|
|
|
977
1158
|
className,
|
|
978
1159
|
...props
|
|
979
1160
|
}) {
|
|
980
|
-
return /* @__PURE__ */
|
|
1161
|
+
return /* @__PURE__ */ jsx23(
|
|
981
1162
|
MenuPrimitive.Item,
|
|
982
1163
|
{
|
|
983
1164
|
"data-slot": "dropdown-menu-item",
|
|
@@ -989,7 +1170,7 @@ function DropdownMenuItem({
|
|
|
989
1170
|
|
|
990
1171
|
// src/components/ReportScenario.tsx
|
|
991
1172
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
992
|
-
import { jsx as
|
|
1173
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
993
1174
|
var STATUS_META = {
|
|
994
1175
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
995
1176
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1005,7 +1186,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1005
1186
|
const collapsible = collapse !== null && !hideTitle;
|
|
1006
1187
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
1007
1188
|
const actions = useScenarioActions();
|
|
1008
|
-
return /* @__PURE__ */
|
|
1189
|
+
return /* @__PURE__ */ jsxs16(
|
|
1009
1190
|
Card,
|
|
1010
1191
|
{
|
|
1011
1192
|
id: scenario.id,
|
|
@@ -1013,10 +1194,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1013
1194
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
1014
1195
|
className: "gap-0 py-0",
|
|
1015
1196
|
children: [
|
|
1016
|
-
/* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
hideTitle ? null : /* @__PURE__ */
|
|
1019
|
-
collapsible ? /* @__PURE__ */
|
|
1197
|
+
/* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
|
|
1198
|
+
/* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
1199
|
+
hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1200
|
+
collapsible ? /* @__PURE__ */ jsx24(
|
|
1020
1201
|
"button",
|
|
1021
1202
|
{
|
|
1022
1203
|
type: "button",
|
|
@@ -1025,49 +1206,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1025
1206
|
"aria-controls": bodyId,
|
|
1026
1207
|
"aria-label": `Toggle ${scenario.title}`,
|
|
1027
1208
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
1028
|
-
children: /* @__PURE__ */
|
|
1209
|
+
children: /* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
1029
1210
|
}
|
|
1030
1211
|
) : null,
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
1212
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1213
|
+
/* @__PURE__ */ jsx24("span", { children: scenario.title })
|
|
1033
1214
|
] }),
|
|
1034
|
-
/* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1036
|
-
scenario.durationMs > 0 ? /* @__PURE__ */
|
|
1037
|
-
meta.showPill ? /* @__PURE__ */
|
|
1038
|
-
actions ? /* @__PURE__ */
|
|
1039
|
-
/* @__PURE__ */
|
|
1215
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1216
|
+
/* @__PURE__ */ jsx24(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1217
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ jsx24("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1218
|
+
meta.showPill ? /* @__PURE__ */ jsx24(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx24("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1219
|
+
actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1220
|
+
/* @__PURE__ */ jsx24(
|
|
1040
1221
|
DropdownMenuTrigger,
|
|
1041
1222
|
{
|
|
1042
1223
|
"aria-label": `Actions for ${scenario.title}`,
|
|
1043
1224
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1044
|
-
children: /* @__PURE__ */
|
|
1225
|
+
children: /* @__PURE__ */ jsx24(MoreHorizontalIcon, { "aria-hidden": true })
|
|
1045
1226
|
}
|
|
1046
1227
|
),
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1228
|
+
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
|
|
1229
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1230
|
+
/* @__PURE__ */ jsx24(LinkIcon, {}),
|
|
1050
1231
|
" Copy link"
|
|
1051
1232
|
] }),
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1233
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1234
|
+
/* @__PURE__ */ jsx24(FileTextIcon, {}),
|
|
1054
1235
|
" Copy as Markdown"
|
|
1055
1236
|
] }),
|
|
1056
|
-
/* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1237
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1238
|
+
/* @__PURE__ */ jsx24(SparklesIcon, {}),
|
|
1058
1239
|
" Explain with AI"
|
|
1059
1240
|
] })
|
|
1060
1241
|
] })
|
|
1061
1242
|
] }) : null
|
|
1062
1243
|
] })
|
|
1063
1244
|
] }),
|
|
1064
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
1065
|
-
scenario.tags.map((t) => /* @__PURE__ */
|
|
1066
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */
|
|
1245
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs16("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1246
|
+
scenario.tags.map((t) => /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsx24(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1247
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx24("li", { children: ticket.url ? /* @__PURE__ */ jsx24("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx24(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx24(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1067
1248
|
] }) : null
|
|
1068
1249
|
] }),
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
scenario.errorMessage ? /* @__PURE__ */
|
|
1250
|
+
/* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1251
|
+
scenario.errorMessage ? /* @__PURE__ */ jsx24(
|
|
1071
1252
|
"pre",
|
|
1072
1253
|
{
|
|
1073
1254
|
role: "alert",
|
|
@@ -1075,10 +1256,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1075
1256
|
children: scenario.errorMessage
|
|
1076
1257
|
}
|
|
1077
1258
|
) : null,
|
|
1078
|
-
/* @__PURE__ */
|
|
1079
|
-
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1259
|
+
/* @__PURE__ */ jsx24(ReportStoryboard, { scenario }),
|
|
1260
|
+
/* @__PURE__ */ jsx24(ReportSteps, { scenario }),
|
|
1261
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx24("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx24(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1262
|
+
/* @__PURE__ */ jsx24(ReportAttachments, { attachments: scenario.attachments }),
|
|
1263
|
+
/* @__PURE__ */ jsx24(ReportTrace, { spans: scenario.otelSpans })
|
|
1082
1264
|
] })
|
|
1083
1265
|
]
|
|
1084
1266
|
}
|
|
@@ -1086,13 +1268,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1086
1268
|
}
|
|
1087
1269
|
|
|
1088
1270
|
// src/components/ReportScenarioList.tsx
|
|
1089
|
-
import { Fragment as Fragment8, jsx as
|
|
1271
|
+
import { Fragment as Fragment8, jsx as jsx25 } from "react/jsx-runtime";
|
|
1090
1272
|
function ReportScenarioList({ feature }) {
|
|
1091
|
-
return /* @__PURE__ */
|
|
1273
|
+
return /* @__PURE__ */ jsx25(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx25(ReportScenario, { scenario }, scenario.id)) });
|
|
1092
1274
|
}
|
|
1093
1275
|
|
|
1094
1276
|
// src/components/ReportFeature.tsx
|
|
1095
|
-
import { Fragment as Fragment9, jsx as
|
|
1277
|
+
import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1096
1278
|
function ReportFeature({ feature }) {
|
|
1097
1279
|
const titleId = `${feature.id}-title`;
|
|
1098
1280
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1103,7 +1285,7 @@ function ReportFeature({ feature }) {
|
|
|
1103
1285
|
return (
|
|
1104
1286
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1105
1287
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1106
|
-
/* @__PURE__ */
|
|
1288
|
+
/* @__PURE__ */ jsxs17(
|
|
1107
1289
|
"section",
|
|
1108
1290
|
{
|
|
1109
1291
|
id: feature.id,
|
|
@@ -1111,9 +1293,9 @@ function ReportFeature({ feature }) {
|
|
|
1111
1293
|
"aria-labelledby": titleId,
|
|
1112
1294
|
className: "flex flex-col gap-3",
|
|
1113
1295
|
children: [
|
|
1114
|
-
/* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1116
|
-
/* @__PURE__ */
|
|
1296
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1297
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
|
|
1298
|
+
/* @__PURE__ */ jsx26("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
|
|
1117
1299
|
"button",
|
|
1118
1300
|
{
|
|
1119
1301
|
type: "button",
|
|
@@ -1122,31 +1304,31 @@ function ReportFeature({ feature }) {
|
|
|
1122
1304
|
"aria-controls": bodyId,
|
|
1123
1305
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1124
1306
|
children: [
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
/* @__PURE__ */
|
|
1307
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1308
|
+
/* @__PURE__ */ jsx26("span", { className: "truncate", children: feature.title })
|
|
1127
1309
|
]
|
|
1128
1310
|
}
|
|
1129
1311
|
) : feature.title }),
|
|
1130
|
-
/* @__PURE__ */
|
|
1312
|
+
/* @__PURE__ */ jsx26("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1131
1313
|
] }),
|
|
1132
|
-
/* @__PURE__ */
|
|
1314
|
+
/* @__PURE__ */ jsxs17(
|
|
1133
1315
|
"p",
|
|
1134
1316
|
{
|
|
1135
1317
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1136
1318
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1137
1319
|
children: [
|
|
1138
|
-
/* @__PURE__ */
|
|
1320
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1139
1321
|
s.passed,
|
|
1140
1322
|
" passed"
|
|
1141
1323
|
] }),
|
|
1142
|
-
/* @__PURE__ */
|
|
1143
|
-
/* @__PURE__ */
|
|
1324
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1325
|
+
/* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1144
1326
|
s.failed,
|
|
1145
1327
|
" failed"
|
|
1146
1328
|
] }),
|
|
1147
|
-
skipped > 0 ? /* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1329
|
+
skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
1330
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1331
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1150
1332
|
skipped,
|
|
1151
1333
|
" skipped"
|
|
1152
1334
|
] })
|
|
@@ -1155,7 +1337,7 @@ function ReportFeature({ feature }) {
|
|
|
1155
1337
|
}
|
|
1156
1338
|
)
|
|
1157
1339
|
] }),
|
|
1158
|
-
/* @__PURE__ */
|
|
1340
|
+
/* @__PURE__ */ jsx26("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx26(ReportScenarioList, { feature }) })
|
|
1159
1341
|
]
|
|
1160
1342
|
}
|
|
1161
1343
|
)
|
|
@@ -1163,17 +1345,17 @@ function ReportFeature({ feature }) {
|
|
|
1163
1345
|
}
|
|
1164
1346
|
|
|
1165
1347
|
// src/components/ReportFeatureList.tsx
|
|
1166
|
-
import { jsx as
|
|
1348
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1167
1349
|
function ReportFeatureList() {
|
|
1168
1350
|
const report = useReport();
|
|
1169
|
-
return /* @__PURE__ */
|
|
1351
|
+
return /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx27(ReportFeature, { feature }, feature.id)) });
|
|
1170
1352
|
}
|
|
1171
1353
|
|
|
1172
1354
|
// src/components/ui/empty.tsx
|
|
1173
1355
|
import { cva as cva2 } from "class-variance-authority";
|
|
1174
|
-
import { jsx as
|
|
1356
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1175
1357
|
function Empty({ className, ...props }) {
|
|
1176
|
-
return /* @__PURE__ */
|
|
1358
|
+
return /* @__PURE__ */ jsx28(
|
|
1177
1359
|
"div",
|
|
1178
1360
|
{
|
|
1179
1361
|
"data-slot": "empty",
|
|
@@ -1186,7 +1368,7 @@ function Empty({ className, ...props }) {
|
|
|
1186
1368
|
);
|
|
1187
1369
|
}
|
|
1188
1370
|
function EmptyHeader({ className, ...props }) {
|
|
1189
|
-
return /* @__PURE__ */
|
|
1371
|
+
return /* @__PURE__ */ jsx28(
|
|
1190
1372
|
"div",
|
|
1191
1373
|
{
|
|
1192
1374
|
"data-slot": "empty-header",
|
|
@@ -1213,7 +1395,7 @@ var emptyMediaVariants = cva2(
|
|
|
1213
1395
|
}
|
|
1214
1396
|
);
|
|
1215
1397
|
function EmptyTitle({ className, ...props }) {
|
|
1216
|
-
return /* @__PURE__ */
|
|
1398
|
+
return /* @__PURE__ */ jsx28(
|
|
1217
1399
|
"div",
|
|
1218
1400
|
{
|
|
1219
1401
|
"data-slot": "empty-title",
|
|
@@ -1224,16 +1406,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1224
1406
|
}
|
|
1225
1407
|
|
|
1226
1408
|
// src/components/ReportEmpty.tsx
|
|
1227
|
-
import { jsx as
|
|
1409
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1228
1410
|
function ReportEmpty({ message }) {
|
|
1229
|
-
return /* @__PURE__ */
|
|
1411
|
+
return /* @__PURE__ */ jsx29(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx29(EmptyHeader, { children: /* @__PURE__ */ jsx29(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1230
1412
|
}
|
|
1231
1413
|
|
|
1232
1414
|
// src/components/ReportSummary.tsx
|
|
1233
|
-
import { jsx as
|
|
1415
|
+
import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1234
1416
|
function ReportSummary({ className }) {
|
|
1235
1417
|
const report = useReport();
|
|
1236
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsx30(
|
|
1237
1419
|
ReportSummaryView,
|
|
1238
1420
|
{
|
|
1239
1421
|
summary: report.summary,
|
|
@@ -1259,7 +1441,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1259
1441
|
if (summary.pending > 0) {
|
|
1260
1442
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1261
1443
|
}
|
|
1262
|
-
return /* @__PURE__ */
|
|
1444
|
+
return /* @__PURE__ */ jsx30(
|
|
1263
1445
|
"dl",
|
|
1264
1446
|
{
|
|
1265
1447
|
className: cn(
|
|
@@ -1272,17 +1454,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1272
1454
|
"aria-label": ariaLabel,
|
|
1273
1455
|
children: cards.map((c) => {
|
|
1274
1456
|
const tone = TONE[c.status];
|
|
1275
|
-
return /* @__PURE__ */
|
|
1457
|
+
return /* @__PURE__ */ jsxs18(
|
|
1276
1458
|
"div",
|
|
1277
1459
|
{
|
|
1278
1460
|
"data-status": c.status,
|
|
1279
1461
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1280
1462
|
children: [
|
|
1281
|
-
/* @__PURE__ */
|
|
1282
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1464
|
+
/* @__PURE__ */ jsx30("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1283
1465
|
c.label
|
|
1284
1466
|
] }),
|
|
1285
|
-
/* @__PURE__ */
|
|
1467
|
+
/* @__PURE__ */ jsx30("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1286
1468
|
]
|
|
1287
1469
|
},
|
|
1288
1470
|
c.status
|
|
@@ -1342,7 +1524,7 @@ function prUrl(ci) {
|
|
|
1342
1524
|
}
|
|
1343
1525
|
|
|
1344
1526
|
// src/components/ReportMeta.tsx
|
|
1345
|
-
import { jsx as
|
|
1527
|
+
import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1346
1528
|
function ReportMeta() {
|
|
1347
1529
|
const report = useReport();
|
|
1348
1530
|
const items = [];
|
|
@@ -1365,13 +1547,13 @@ function ReportMeta() {
|
|
|
1365
1547
|
const short = sha.slice(0, 8);
|
|
1366
1548
|
items.push({
|
|
1367
1549
|
label: "Commit",
|
|
1368
|
-
value: url ? /* @__PURE__ */
|
|
1550
|
+
value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1369
1551
|
});
|
|
1370
1552
|
}
|
|
1371
1553
|
if (report.ci) {
|
|
1372
1554
|
items.push({
|
|
1373
1555
|
label: "CI",
|
|
1374
|
-
value: report.ci.url ? /* @__PURE__ */
|
|
1556
|
+
value: report.ci.url ? /* @__PURE__ */ jsxs19("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1375
1557
|
ciDisplayName(report.ci.name),
|
|
1376
1558
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1377
1559
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1382,7 +1564,7 @@ function ReportMeta() {
|
|
|
1382
1564
|
const label = `#${report.ci.prNumber}`;
|
|
1383
1565
|
items.push({
|
|
1384
1566
|
label: "PR",
|
|
1385
|
-
value: url ? /* @__PURE__ */
|
|
1567
|
+
value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1386
1568
|
});
|
|
1387
1569
|
}
|
|
1388
1570
|
if (items.length === 0) return null;
|
|
@@ -1390,50 +1572,50 @@ function ReportMeta() {
|
|
|
1390
1572
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1391
1573
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1392
1574
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1395
|
-
/* @__PURE__ */
|
|
1575
|
+
/* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1576
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
1577
|
+
/* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1396
1578
|
"Run details"
|
|
1397
1579
|
] }),
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1580
|
+
/* @__PURE__ */ jsx31("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__ */ jsxs19("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1581
|
+
/* @__PURE__ */ jsx31("dt", { className: "font-medium", children: item.label }),
|
|
1582
|
+
/* @__PURE__ */ jsx31("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1401
1583
|
] }, item.label)) })
|
|
1402
1584
|
] })
|
|
1403
1585
|
);
|
|
1404
1586
|
}
|
|
1405
1587
|
|
|
1406
1588
|
// src/components/ReportSchemaError.tsx
|
|
1407
|
-
import { jsx as
|
|
1589
|
+
import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1408
1590
|
function ReportSchemaError({ error }) {
|
|
1409
|
-
return /* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
1412
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */
|
|
1591
|
+
return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1592
|
+
/* @__PURE__ */ jsx32("p", { children: /* @__PURE__ */ jsx32("strong", { children: "Report could not be displayed." }) }),
|
|
1593
|
+
/* @__PURE__ */ jsx32("p", { children: error.message }),
|
|
1594
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
|
|
1413
1595
|
"The report bundle is newer than this version of ",
|
|
1414
|
-
/* @__PURE__ */
|
|
1596
|
+
/* @__PURE__ */ jsx32("code", { children: "executable-stories-react" }),
|
|
1415
1597
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1416
1598
|
] }) : null,
|
|
1417
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */
|
|
1418
|
-
/* @__PURE__ */
|
|
1599
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
|
|
1600
|
+
/* @__PURE__ */ jsxs20("summary", { children: [
|
|
1419
1601
|
error.issues.length,
|
|
1420
1602
|
" validation issue",
|
|
1421
1603
|
error.issues.length === 1 ? "" : "s"
|
|
1422
1604
|
] }),
|
|
1423
|
-
/* @__PURE__ */
|
|
1605
|
+
/* @__PURE__ */ jsx32("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1424
1606
|
] }) : null
|
|
1425
1607
|
] });
|
|
1426
1608
|
}
|
|
1427
1609
|
|
|
1428
1610
|
// src/components/ReportShell.tsx
|
|
1429
|
-
import { Fragment as Fragment10, jsx as
|
|
1611
|
+
import { Fragment as Fragment10, jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1430
1612
|
function ReportErrorShell({
|
|
1431
1613
|
error,
|
|
1432
1614
|
className,
|
|
1433
1615
|
title,
|
|
1434
1616
|
dataTheme
|
|
1435
1617
|
}) {
|
|
1436
|
-
return /* @__PURE__ */
|
|
1618
|
+
return /* @__PURE__ */ jsx33("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx33(ReportSchemaError, { error }) });
|
|
1437
1619
|
}
|
|
1438
1620
|
|
|
1439
1621
|
// src/interactive/ReportInteractive.tsx
|
|
@@ -1442,12 +1624,12 @@ import { Monitor, Moon, Sun } from "lucide-react";
|
|
|
1442
1624
|
// src/components/ui/switch.tsx
|
|
1443
1625
|
import "react";
|
|
1444
1626
|
import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
|
|
1445
|
-
import { jsx as
|
|
1627
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
1446
1628
|
function Switch({
|
|
1447
1629
|
className,
|
|
1448
1630
|
...props
|
|
1449
1631
|
}) {
|
|
1450
|
-
return /* @__PURE__ */
|
|
1632
|
+
return /* @__PURE__ */ jsx34(
|
|
1451
1633
|
SwitchPrimitive.Root,
|
|
1452
1634
|
{
|
|
1453
1635
|
"data-slot": "switch",
|
|
@@ -1456,7 +1638,7 @@ function Switch({
|
|
|
1456
1638
|
className
|
|
1457
1639
|
),
|
|
1458
1640
|
...props,
|
|
1459
|
-
children: /* @__PURE__ */
|
|
1641
|
+
children: /* @__PURE__ */ jsx34(
|
|
1460
1642
|
SwitchPrimitive.Thumb,
|
|
1461
1643
|
{
|
|
1462
1644
|
"data-slot": "switch-thumb",
|
|
@@ -1472,7 +1654,7 @@ import * as React5 from "react";
|
|
|
1472
1654
|
import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
|
|
1473
1655
|
import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
|
|
1474
1656
|
import { cva as cva3 } from "class-variance-authority";
|
|
1475
|
-
import { jsx as
|
|
1657
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1476
1658
|
var toggleItemVariants = cva3(
|
|
1477
1659
|
"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",
|
|
1478
1660
|
{
|
|
@@ -1494,13 +1676,13 @@ function ToggleGroup({
|
|
|
1494
1676
|
children,
|
|
1495
1677
|
...props
|
|
1496
1678
|
}) {
|
|
1497
|
-
return /* @__PURE__ */
|
|
1679
|
+
return /* @__PURE__ */ jsx35(
|
|
1498
1680
|
ToggleGroupPrimitive,
|
|
1499
1681
|
{
|
|
1500
1682
|
"data-slot": "toggle-group",
|
|
1501
1683
|
className: cn("flex w-fit items-center gap-0.5 rounded-lg bg-muted p-0.5", className),
|
|
1502
1684
|
...props,
|
|
1503
|
-
children: /* @__PURE__ */
|
|
1685
|
+
children: /* @__PURE__ */ jsx35(ToggleGroupContext.Provider, { value: { size }, children })
|
|
1504
1686
|
}
|
|
1505
1687
|
);
|
|
1506
1688
|
}
|
|
@@ -1511,7 +1693,7 @@ function ToggleGroupItem({
|
|
|
1511
1693
|
...props
|
|
1512
1694
|
}) {
|
|
1513
1695
|
const context = React5.useContext(ToggleGroupContext);
|
|
1514
|
-
return /* @__PURE__ */
|
|
1696
|
+
return /* @__PURE__ */ jsx35(
|
|
1515
1697
|
TogglePrimitive,
|
|
1516
1698
|
{
|
|
1517
1699
|
"data-slot": "toggle-group-item",
|
|
@@ -1531,9 +1713,9 @@ import { Search } from "lucide-react";
|
|
|
1531
1713
|
|
|
1532
1714
|
// src/components/ui/input.tsx
|
|
1533
1715
|
import "react";
|
|
1534
|
-
import { jsx as
|
|
1716
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
1535
1717
|
function Input({ className, type, ...props }) {
|
|
1536
|
-
return /* @__PURE__ */
|
|
1718
|
+
return /* @__PURE__ */ jsx36(
|
|
1537
1719
|
"input",
|
|
1538
1720
|
{
|
|
1539
1721
|
type,
|
|
@@ -1550,7 +1732,7 @@ function Input({ className, type, ...props }) {
|
|
|
1550
1732
|
}
|
|
1551
1733
|
|
|
1552
1734
|
// src/interactive/ReportSearch.tsx
|
|
1553
|
-
import { jsx as
|
|
1735
|
+
import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1554
1736
|
var ReportSearch = forwardRef(
|
|
1555
1737
|
function ReportSearch2(props, ref) {
|
|
1556
1738
|
const {
|
|
@@ -1572,17 +1754,17 @@ var ReportSearch = forwardRef(
|
|
|
1572
1754
|
e.preventDefault();
|
|
1573
1755
|
}
|
|
1574
1756
|
}
|
|
1575
|
-
return /* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
/* @__PURE__ */
|
|
1757
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("es-search flex flex-col gap-1", className), children: [
|
|
1758
|
+
/* @__PURE__ */ jsx37("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
|
|
1759
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative w-full sm:w-72", children: [
|
|
1760
|
+
/* @__PURE__ */ jsx37(
|
|
1579
1761
|
Search,
|
|
1580
1762
|
{
|
|
1581
1763
|
"aria-hidden": true,
|
|
1582
1764
|
className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
|
|
1583
1765
|
}
|
|
1584
1766
|
),
|
|
1585
|
-
/* @__PURE__ */
|
|
1767
|
+
/* @__PURE__ */ jsx37(
|
|
1586
1768
|
Input,
|
|
1587
1769
|
{
|
|
1588
1770
|
ref,
|
|
@@ -1599,7 +1781,7 @@ var ReportSearch = forwardRef(
|
|
|
1599
1781
|
}
|
|
1600
1782
|
)
|
|
1601
1783
|
] }),
|
|
1602
|
-
showCounts ? /* @__PURE__ */
|
|
1784
|
+
showCounts ? /* @__PURE__ */ jsxs22(
|
|
1603
1785
|
"span",
|
|
1604
1786
|
{
|
|
1605
1787
|
className: "text-xs tabular-nums text-muted-foreground",
|
|
@@ -1640,7 +1822,7 @@ function scrollToScenarioId(scenarioId, options = {}) {
|
|
|
1640
1822
|
}
|
|
1641
1823
|
|
|
1642
1824
|
// src/interactive/ReportFailureBanner.tsx
|
|
1643
|
-
import { jsx as
|
|
1825
|
+
import { jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1644
1826
|
function ReportFailureBanner({ failures }) {
|
|
1645
1827
|
const first = failures[0];
|
|
1646
1828
|
const jumpToFirst = useCallback2(() => {
|
|
@@ -1648,7 +1830,7 @@ function ReportFailureBanner({ failures }) {
|
|
|
1648
1830
|
scrollToScenarioId(first.scenarioId);
|
|
1649
1831
|
}, [first]);
|
|
1650
1832
|
if (failures.length === 0) return null;
|
|
1651
|
-
return /* @__PURE__ */
|
|
1833
|
+
return /* @__PURE__ */ jsxs23(
|
|
1652
1834
|
"div",
|
|
1653
1835
|
{
|
|
1654
1836
|
className: "es-failure-banner",
|
|
@@ -1656,13 +1838,13 @@ function ReportFailureBanner({ failures }) {
|
|
|
1656
1838
|
"aria-live": "polite",
|
|
1657
1839
|
"aria-label": "Failure summary",
|
|
1658
1840
|
children: [
|
|
1659
|
-
/* @__PURE__ */
|
|
1660
|
-
/* @__PURE__ */
|
|
1841
|
+
/* @__PURE__ */ jsxs23("span", { className: "es-failure-banner-text", children: [
|
|
1842
|
+
/* @__PURE__ */ jsx38("strong", { children: failures.length }),
|
|
1661
1843
|
" ",
|
|
1662
1844
|
"failure",
|
|
1663
1845
|
failures.length === 1 ? "" : "s"
|
|
1664
1846
|
] }),
|
|
1665
|
-
/* @__PURE__ */
|
|
1847
|
+
/* @__PURE__ */ jsx38(
|
|
1666
1848
|
"button",
|
|
1667
1849
|
{
|
|
1668
1850
|
type: "button",
|
|
@@ -1679,7 +1861,7 @@ function ReportFailureBanner({ failures }) {
|
|
|
1679
1861
|
|
|
1680
1862
|
// src/interactive/ReportFreshness.tsx
|
|
1681
1863
|
import { useEffect, useState as useState2 } from "react";
|
|
1682
|
-
import { Fragment as Fragment11, jsx as
|
|
1864
|
+
import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1683
1865
|
function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
1684
1866
|
const [now, setNow] = useState2(nowMs);
|
|
1685
1867
|
useEffect(() => {
|
|
@@ -1687,7 +1869,7 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1687
1869
|
}, [nowMs]);
|
|
1688
1870
|
if (lastRunMs === void 0 || now === void 0) return null;
|
|
1689
1871
|
const age = formatRelativeAge(lastRunMs, now);
|
|
1690
|
-
const runLink = ciUrl ? /* @__PURE__ */
|
|
1872
|
+
const runLink = ciUrl ? /* @__PURE__ */ jsx39(
|
|
1691
1873
|
"a",
|
|
1692
1874
|
{
|
|
1693
1875
|
href: ciUrl,
|
|
@@ -1698,9 +1880,9 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1698
1880
|
}
|
|
1699
1881
|
) : null;
|
|
1700
1882
|
if (isReportStale(lastRunMs, staleAfterDays, now)) {
|
|
1701
|
-
return /* @__PURE__ */
|
|
1702
|
-
/* @__PURE__ */
|
|
1703
|
-
/* @__PURE__ */
|
|
1883
|
+
return /* @__PURE__ */ jsxs24("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
|
|
1884
|
+
/* @__PURE__ */ jsxs24("span", { children: [
|
|
1885
|
+
/* @__PURE__ */ jsxs24("strong", { children: [
|
|
1704
1886
|
"Last verified ",
|
|
1705
1887
|
age,
|
|
1706
1888
|
"."
|
|
@@ -1710,10 +1892,10 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1710
1892
|
runLink
|
|
1711
1893
|
] });
|
|
1712
1894
|
}
|
|
1713
|
-
return /* @__PURE__ */
|
|
1895
|
+
return /* @__PURE__ */ jsxs24("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
|
|
1714
1896
|
"Verified ",
|
|
1715
1897
|
age,
|
|
1716
|
-
runLink ? /* @__PURE__ */
|
|
1898
|
+
runLink ? /* @__PURE__ */ jsxs24(Fragment11, { children: [
|
|
1717
1899
|
" \xB7 ",
|
|
1718
1900
|
runLink
|
|
1719
1901
|
] }) : null
|
|
@@ -1721,15 +1903,15 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1721
1903
|
}
|
|
1722
1904
|
|
|
1723
1905
|
// src/interactive/ReportLastRunDelta.tsx
|
|
1724
|
-
import { Fragment as Fragment12, jsx as
|
|
1906
|
+
import { Fragment as Fragment12, jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1725
1907
|
var MAX_LINKS = 5;
|
|
1726
1908
|
function ScenarioLinks({ scenarios, tone }) {
|
|
1727
|
-
return /* @__PURE__ */
|
|
1728
|
-
scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */
|
|
1909
|
+
return /* @__PURE__ */ jsxs25(Fragment12, { children: [
|
|
1910
|
+
scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ jsxs25("span", { children: [
|
|
1729
1911
|
i > 0 ? ", " : "",
|
|
1730
|
-
/* @__PURE__ */
|
|
1912
|
+
/* @__PURE__ */ jsx40("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
|
|
1731
1913
|
] }, s.id)),
|
|
1732
|
-
scenarios.length > MAX_LINKS ? /* @__PURE__ */
|
|
1914
|
+
scenarios.length > MAX_LINKS ? /* @__PURE__ */ jsxs25("span", { children: [
|
|
1733
1915
|
" and ",
|
|
1734
1916
|
scenarios.length - MAX_LINKS,
|
|
1735
1917
|
" more"
|
|
@@ -1746,23 +1928,23 @@ function ReportLastRunDelta({
|
|
|
1746
1928
|
if (!delta) return null;
|
|
1747
1929
|
const { newlyFailing, newlyPassing, added } = delta;
|
|
1748
1930
|
if (newlyFailing.length === 0 && newlyPassing.length === 0 && added.length === 0) {
|
|
1749
|
-
return /* @__PURE__ */
|
|
1931
|
+
return /* @__PURE__ */ jsx40("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
|
|
1750
1932
|
}
|
|
1751
|
-
return /* @__PURE__ */
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
newlyFailing.length > 0 ? /* @__PURE__ */
|
|
1933
|
+
return /* @__PURE__ */ jsxs25("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
|
|
1934
|
+
/* @__PURE__ */ jsx40("span", { className: "font-medium text-foreground", children: "Since last run:" }),
|
|
1935
|
+
newlyFailing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-fail", children: [
|
|
1754
1936
|
newlyFailing.length,
|
|
1755
1937
|
" newly failing (",
|
|
1756
|
-
/* @__PURE__ */
|
|
1938
|
+
/* @__PURE__ */ jsx40(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
|
|
1757
1939
|
")"
|
|
1758
1940
|
] }) : null,
|
|
1759
|
-
newlyPassing.length > 0 ? /* @__PURE__ */
|
|
1941
|
+
newlyPassing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-pass", children: [
|
|
1760
1942
|
newlyPassing.length,
|
|
1761
1943
|
" fixed (",
|
|
1762
|
-
/* @__PURE__ */
|
|
1944
|
+
/* @__PURE__ */ jsx40(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
|
|
1763
1945
|
")"
|
|
1764
1946
|
] }) : null,
|
|
1765
|
-
added.length > 0 ? /* @__PURE__ */
|
|
1947
|
+
added.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2", children: [
|
|
1766
1948
|
added.length,
|
|
1767
1949
|
" new"
|
|
1768
1950
|
] }) : null
|
|
@@ -1826,7 +2008,7 @@ function Button({
|
|
|
1826
2008
|
}
|
|
1827
2009
|
|
|
1828
2010
|
// src/interactive/ReportShortcutsHelp.tsx
|
|
1829
|
-
import { jsx as
|
|
2011
|
+
import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1830
2012
|
var SHORTCUTS = [
|
|
1831
2013
|
{ keys: "/", description: "Focus search" },
|
|
1832
2014
|
{ keys: "f", description: "Jump to next failure" },
|
|
@@ -1838,9 +2020,9 @@ var SHORTCUTS = [
|
|
|
1838
2020
|
];
|
|
1839
2021
|
function Keys({ keys }) {
|
|
1840
2022
|
const parts = keys.split(" ");
|
|
1841
|
-
return /* @__PURE__ */
|
|
1842
|
-
i > 0 ? /* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
2023
|
+
return /* @__PURE__ */ jsx41("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1", children: [
|
|
2024
|
+
i > 0 ? /* @__PURE__ */ jsx41("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
|
|
2025
|
+
/* @__PURE__ */ jsx41("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 })
|
|
1844
2026
|
] }, k)) });
|
|
1845
2027
|
}
|
|
1846
2028
|
function ReportShortcutsHelp({ open, onClose }) {
|
|
@@ -1851,7 +2033,7 @@ function ReportShortcutsHelp({ open, onClose }) {
|
|
|
1851
2033
|
if (open && !dialog.open) dialog.showModal();
|
|
1852
2034
|
else if (!open && dialog.open) dialog.close();
|
|
1853
2035
|
}, [open]);
|
|
1854
|
-
return /* @__PURE__ */
|
|
2036
|
+
return /* @__PURE__ */ jsxs26(
|
|
1855
2037
|
"dialog",
|
|
1856
2038
|
{
|
|
1857
2039
|
ref: dialogRef,
|
|
@@ -1859,12 +2041,12 @@ function ReportShortcutsHelp({ open, onClose }) {
|
|
|
1859
2041
|
"aria-label": "Keyboard shortcuts",
|
|
1860
2042
|
onClose,
|
|
1861
2043
|
children: [
|
|
1862
|
-
/* @__PURE__ */
|
|
1863
|
-
/* @__PURE__ */
|
|
1864
|
-
/* @__PURE__ */
|
|
1865
|
-
/* @__PURE__ */
|
|
2044
|
+
/* @__PURE__ */ jsx41("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
|
|
2045
|
+
/* @__PURE__ */ jsx41("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs26("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
|
|
2046
|
+
/* @__PURE__ */ jsx41("dt", { className: "justify-self-start", children: /* @__PURE__ */ jsx41(Keys, { keys: s.keys }) }),
|
|
2047
|
+
/* @__PURE__ */ jsx41("dd", { className: "text-sm text-muted-foreground", children: s.description })
|
|
1866
2048
|
] }, s.keys)) }),
|
|
1867
|
-
/* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsx41("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ jsx41(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
|
|
1868
2050
|
]
|
|
1869
2051
|
}
|
|
1870
2052
|
);
|
|
@@ -2036,9 +2218,36 @@ function listFailures(report) {
|
|
|
2036
2218
|
return out;
|
|
2037
2219
|
}
|
|
2038
2220
|
|
|
2221
|
+
// src/interactive/triage-default.ts
|
|
2222
|
+
function needsAttention(status) {
|
|
2223
|
+
return status === "failed";
|
|
2224
|
+
}
|
|
2225
|
+
function defaultCollapsedIds(report) {
|
|
2226
|
+
const collapsed = /* @__PURE__ */ new Set();
|
|
2227
|
+
if (report.summary.failed === 0) return collapsed;
|
|
2228
|
+
for (const feature of report.features) {
|
|
2229
|
+
const featureHasFailure = feature.scenarios.some((s) => needsAttention(s.status));
|
|
2230
|
+
if (!featureHasFailure) collapsed.add(feature.id);
|
|
2231
|
+
for (const scenario of feature.scenarios) {
|
|
2232
|
+
if (!needsAttention(scenario.status)) collapsed.add(scenario.id);
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
return collapsed;
|
|
2236
|
+
}
|
|
2237
|
+
function failuresFirst(report) {
|
|
2238
|
+
if (report.summary.failed === 0) return report;
|
|
2239
|
+
const withFailures = [];
|
|
2240
|
+
const rest = [];
|
|
2241
|
+
for (const feature of report.features) {
|
|
2242
|
+
(feature.scenarios.some((s) => needsAttention(s.status)) ? withFailures : rest).push(feature);
|
|
2243
|
+
}
|
|
2244
|
+
if (withFailures.length === 0) return report;
|
|
2245
|
+
return { ...report, features: [...withFailures, ...rest] };
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2039
2248
|
// src/interactive/ReportFilters.tsx
|
|
2040
2249
|
import { useState as useState3 } from "react";
|
|
2041
|
-
import { jsx as
|
|
2250
|
+
import { jsx as jsx42, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2042
2251
|
var TAG_LIMIT = 12;
|
|
2043
2252
|
function ReportFilters({
|
|
2044
2253
|
statuses,
|
|
@@ -2052,10 +2261,10 @@ function ReportFilters({
|
|
|
2052
2261
|
if (statuses.length === 0 && tags.length === 0) return null;
|
|
2053
2262
|
const tagsCollapsed = tags.length > TAG_LIMIT && !showAllTags;
|
|
2054
2263
|
const visibleTags = tagsCollapsed ? tags.slice(0, TAG_LIMIT) : tags;
|
|
2055
|
-
return /* @__PURE__ */
|
|
2056
|
-
statuses.length > 0 ? /* @__PURE__ */
|
|
2264
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-2", children: [
|
|
2265
|
+
statuses.length > 0 ? /* @__PURE__ */ jsx42("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
|
|
2057
2266
|
const active = status === opt.key;
|
|
2058
|
-
return /* @__PURE__ */
|
|
2267
|
+
return /* @__PURE__ */ jsxs27(
|
|
2059
2268
|
"button",
|
|
2060
2269
|
{
|
|
2061
2270
|
type: "button",
|
|
@@ -2067,23 +2276,23 @@ function ReportFilters({
|
|
|
2067
2276
|
),
|
|
2068
2277
|
children: [
|
|
2069
2278
|
opt.label,
|
|
2070
|
-
/* @__PURE__ */
|
|
2279
|
+
/* @__PURE__ */ jsx42("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
|
|
2071
2280
|
]
|
|
2072
2281
|
},
|
|
2073
2282
|
opt.key
|
|
2074
2283
|
);
|
|
2075
2284
|
}) }) : null,
|
|
2076
|
-
tags.length > 0 ? /* @__PURE__ */
|
|
2285
|
+
tags.length > 0 ? /* @__PURE__ */ jsxs27("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
|
|
2077
2286
|
visibleTags.map((tag) => {
|
|
2078
2287
|
const active = activeTags.includes(tag);
|
|
2079
|
-
return /* @__PURE__ */
|
|
2288
|
+
return /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42(
|
|
2080
2289
|
"button",
|
|
2081
2290
|
{
|
|
2082
2291
|
type: "button",
|
|
2083
2292
|
"aria-pressed": active,
|
|
2084
2293
|
onClick: () => onToggleTag(tag),
|
|
2085
2294
|
className: "cursor-pointer",
|
|
2086
|
-
children: /* @__PURE__ */
|
|
2295
|
+
children: /* @__PURE__ */ jsx42(
|
|
2087
2296
|
Badge,
|
|
2088
2297
|
{
|
|
2089
2298
|
variant: "tag",
|
|
@@ -2096,7 +2305,7 @@ function ReportFilters({
|
|
|
2096
2305
|
}
|
|
2097
2306
|
) }, tag);
|
|
2098
2307
|
}),
|
|
2099
|
-
tags.length > TAG_LIMIT ? /* @__PURE__ */
|
|
2308
|
+
tags.length > TAG_LIMIT ? /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42(
|
|
2100
2309
|
"button",
|
|
2101
2310
|
{
|
|
2102
2311
|
type: "button",
|
|
@@ -2112,7 +2321,7 @@ function ReportFilters({
|
|
|
2112
2321
|
|
|
2113
2322
|
// src/interactive/ReportToc.tsx
|
|
2114
2323
|
import { useEffect as useEffect5, useMemo as useMemo2, useState as useState4 } from "react";
|
|
2115
|
-
import { jsx as
|
|
2324
|
+
import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2116
2325
|
var DOT = {
|
|
2117
2326
|
passed: "bg-pass",
|
|
2118
2327
|
failed: "bg-fail",
|
|
@@ -2141,11 +2350,11 @@ function TocContent({ onNavigate }) {
|
|
|
2141
2350
|
return () => observer.disconnect();
|
|
2142
2351
|
}, [scenarioIds]);
|
|
2143
2352
|
if (report.features.length === 0) return null;
|
|
2144
|
-
return /* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2353
|
+
return /* @__PURE__ */ jsx43("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ jsxs28("li", { children: [
|
|
2354
|
+
/* @__PURE__ */ jsx43("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
|
|
2355
|
+
/* @__PURE__ */ jsx43("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
|
|
2147
2356
|
const active = activeId === scenario.id;
|
|
2148
|
-
return /* @__PURE__ */
|
|
2357
|
+
return /* @__PURE__ */ jsx43("li", { children: /* @__PURE__ */ jsxs28(
|
|
2149
2358
|
"a",
|
|
2150
2359
|
{
|
|
2151
2360
|
href: `#${scenario.id}`,
|
|
@@ -2160,14 +2369,14 @@ function TocContent({ onNavigate }) {
|
|
|
2160
2369
|
active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
|
|
2161
2370
|
),
|
|
2162
2371
|
children: [
|
|
2163
|
-
/* @__PURE__ */
|
|
2372
|
+
/* @__PURE__ */ jsx43(
|
|
2164
2373
|
"span",
|
|
2165
2374
|
{
|
|
2166
2375
|
"aria-hidden": true,
|
|
2167
2376
|
className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
|
|
2168
2377
|
}
|
|
2169
2378
|
),
|
|
2170
|
-
/* @__PURE__ */
|
|
2379
|
+
/* @__PURE__ */ jsx43("span", { className: "break-words", children: scenario.title })
|
|
2171
2380
|
]
|
|
2172
2381
|
}
|
|
2173
2382
|
) }, scenario.id);
|
|
@@ -2177,14 +2386,14 @@ function TocContent({ onNavigate }) {
|
|
|
2177
2386
|
function ReportToc() {
|
|
2178
2387
|
const report = useReport();
|
|
2179
2388
|
if (report.features.length === 0) return null;
|
|
2180
|
-
return /* @__PURE__ */
|
|
2389
|
+
return /* @__PURE__ */ jsxs28(
|
|
2181
2390
|
"nav",
|
|
2182
2391
|
{
|
|
2183
2392
|
"aria-label": "Table of contents",
|
|
2184
2393
|
className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
|
|
2185
2394
|
children: [
|
|
2186
|
-
/* @__PURE__ */
|
|
2187
|
-
/* @__PURE__ */
|
|
2395
|
+
/* @__PURE__ */ jsx43("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
|
|
2396
|
+
/* @__PURE__ */ jsx43(TocContent, {})
|
|
2188
2397
|
]
|
|
2189
2398
|
}
|
|
2190
2399
|
);
|
|
@@ -2194,31 +2403,31 @@ function ReportToc() {
|
|
|
2194
2403
|
import { useState as useState5 } from "react";
|
|
2195
2404
|
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
|
2196
2405
|
import { ListIcon, XIcon } from "lucide-react";
|
|
2197
|
-
import { jsx as
|
|
2406
|
+
import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2198
2407
|
function ReportTocDrawer() {
|
|
2199
2408
|
const report = useReport();
|
|
2200
2409
|
const [open, setOpen] = useState5(false);
|
|
2201
2410
|
if (report.features.length === 0) return null;
|
|
2202
|
-
return /* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
2411
|
+
return /* @__PURE__ */ jsxs29(DialogPrimitive.Root, { open, onOpenChange: setOpen, children: [
|
|
2412
|
+
/* @__PURE__ */ jsxs29(DialogPrimitive.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: [
|
|
2413
|
+
/* @__PURE__ */ jsx44(ListIcon, { "aria-hidden": true }),
|
|
2205
2414
|
" Contents"
|
|
2206
2415
|
] }),
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
/* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2210
|
-
/* @__PURE__ */
|
|
2211
|
-
/* @__PURE__ */
|
|
2212
|
-
/* @__PURE__ */
|
|
2416
|
+
/* @__PURE__ */ jsxs29(DialogPrimitive.Portal, { children: [
|
|
2417
|
+
/* @__PURE__ */ jsx44(DialogPrimitive.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
|
|
2418
|
+
/* @__PURE__ */ jsxs29(DialogPrimitive.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: [
|
|
2419
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between", children: [
|
|
2420
|
+
/* @__PURE__ */ jsx44(DialogPrimitive.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
|
|
2421
|
+
/* @__PURE__ */ jsx44(
|
|
2213
2422
|
DialogPrimitive.Close,
|
|
2214
2423
|
{
|
|
2215
2424
|
"aria-label": "Close contents",
|
|
2216
2425
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
2217
|
-
children: /* @__PURE__ */
|
|
2426
|
+
children: /* @__PURE__ */ jsx44(XIcon, { "aria-hidden": true })
|
|
2218
2427
|
}
|
|
2219
2428
|
)
|
|
2220
2429
|
] }),
|
|
2221
|
-
/* @__PURE__ */
|
|
2430
|
+
/* @__PURE__ */ jsx44(TocContent, { onNavigate: () => setOpen(false) })
|
|
2222
2431
|
] })
|
|
2223
2432
|
] })
|
|
2224
2433
|
] });
|
|
@@ -2273,14 +2482,14 @@ function useTheme() {
|
|
|
2273
2482
|
}
|
|
2274
2483
|
|
|
2275
2484
|
// src/interactive/ReportInteractive.tsx
|
|
2276
|
-
import { Fragment as Fragment13, jsx as
|
|
2485
|
+
import { Fragment as Fragment13, jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2277
2486
|
function ReportInteractive(props) {
|
|
2278
2487
|
const { report, className, title, dataTheme } = props;
|
|
2279
2488
|
const result = unwrapReport(report);
|
|
2280
2489
|
if (!result.ok) {
|
|
2281
|
-
return /* @__PURE__ */
|
|
2490
|
+
return /* @__PURE__ */ jsx45(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
2282
2491
|
}
|
|
2283
|
-
return /* @__PURE__ */
|
|
2492
|
+
return /* @__PURE__ */ jsx45(ReportInteractiveView, { ...props, report: result.data });
|
|
2284
2493
|
}
|
|
2285
2494
|
var THEME_OPTIONS = [
|
|
2286
2495
|
{ value: "light", label: "Light", Icon: Sun },
|
|
@@ -2288,7 +2497,7 @@ var THEME_OPTIONS = [
|
|
|
2288
2497
|
{ value: "dark", label: "Dark", Icon: Moon }
|
|
2289
2498
|
];
|
|
2290
2499
|
function ThemeSegment({ pref, onPref }) {
|
|
2291
|
-
return /* @__PURE__ */
|
|
2500
|
+
return /* @__PURE__ */ jsx45(
|
|
2292
2501
|
ToggleGroup,
|
|
2293
2502
|
{
|
|
2294
2503
|
size: "sm",
|
|
@@ -2298,7 +2507,7 @@ function ThemeSegment({ pref, onPref }) {
|
|
|
2298
2507
|
if (next) onPref(next);
|
|
2299
2508
|
},
|
|
2300
2509
|
"aria-label": "Color theme",
|
|
2301
|
-
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */
|
|
2510
|
+
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx45(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ jsx45(Icon, {}) }, value))
|
|
2302
2511
|
}
|
|
2303
2512
|
);
|
|
2304
2513
|
}
|
|
@@ -2326,7 +2535,9 @@ function ReportInteractiveView({
|
|
|
2326
2535
|
const deferredQuery = useDeferredValue(query);
|
|
2327
2536
|
const failures = useMemo3(() => listFailures(report), [report]);
|
|
2328
2537
|
const filtered = useMemo3(
|
|
2329
|
-
|
|
2538
|
+
// Features carrying failures float to the top so the first thing on screen
|
|
2539
|
+
// is the thing that needs attention; an all-green run keeps source order.
|
|
2540
|
+
() => failuresFirst(filterReport(report, { query: deferredQuery, status: statusFilter, tags: activeTags })),
|
|
2330
2541
|
[report, deferredQuery, statusFilter, activeTags]
|
|
2331
2542
|
);
|
|
2332
2543
|
const isFiltering = query !== deferredQuery;
|
|
@@ -2364,7 +2575,7 @@ function ReportInteractiveView({
|
|
|
2364
2575
|
const scenarioActions = useMemo3(
|
|
2365
2576
|
() => ({
|
|
2366
2577
|
copyLink: (s) => copy(scenarioPermalink(s), "Link copied"),
|
|
2367
|
-
copyMarkdown: (s) => copy(
|
|
2578
|
+
copyMarkdown: (s) => copy(scenarioToMarkdown2(s), "Markdown copied"),
|
|
2368
2579
|
copyPrompt: (s) => copy(scenarioToPrompt(s), "Prompt copied")
|
|
2369
2580
|
}),
|
|
2370
2581
|
[copy]
|
|
@@ -2374,9 +2585,9 @@ function ReportInteractiveView({
|
|
|
2374
2585
|
() => report.features.flatMap((f) => [f.id, ...f.scenarios.map((s) => s.id)]),
|
|
2375
2586
|
[report]
|
|
2376
2587
|
);
|
|
2377
|
-
const collapse = useCollapseState();
|
|
2588
|
+
const collapse = useCollapseState(useCallback4(() => defaultCollapsedIds(report), [report]));
|
|
2378
2589
|
const collapseAll = useCallback4(() => collapse.collapseAll(allCollapsibleIds), [collapse, allCollapsibleIds]);
|
|
2379
|
-
const [expandedAll, setExpandedAll] = useState7(
|
|
2590
|
+
const [expandedAll, setExpandedAll] = useState7(() => report.summary.failed === 0);
|
|
2380
2591
|
const setExpanded = useCallback4(
|
|
2381
2592
|
(expanded) => {
|
|
2382
2593
|
if (expanded) collapse.expandAll();
|
|
@@ -2418,13 +2629,13 @@ function ReportInteractiveView({
|
|
|
2418
2629
|
const totalScenarios = report.summary.total;
|
|
2419
2630
|
const matchedScenarios = filtered.summary.total;
|
|
2420
2631
|
const showToc = !hideToc && totalScenarios > 3;
|
|
2421
|
-
return /* @__PURE__ */
|
|
2632
|
+
return /* @__PURE__ */ jsx45(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ jsx45(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ jsx45(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ jsx45(
|
|
2422
2633
|
ReportRoot,
|
|
2423
2634
|
{
|
|
2424
2635
|
report: filtered,
|
|
2425
2636
|
customRenderers,
|
|
2426
2637
|
renderers,
|
|
2427
|
-
children: /* @__PURE__ */
|
|
2638
|
+
children: /* @__PURE__ */ jsxs30(
|
|
2428
2639
|
"main",
|
|
2429
2640
|
{
|
|
2430
2641
|
className: cn("es-report", "es-report-interactive", className),
|
|
@@ -2433,8 +2644,8 @@ function ReportInteractiveView({
|
|
|
2433
2644
|
"data-theme": dataTheme,
|
|
2434
2645
|
"data-detail-level": detail,
|
|
2435
2646
|
children: [
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
/* @__PURE__ */
|
|
2647
|
+
/* @__PURE__ */ jsxs30("header", { className: "es-report-header", children: [
|
|
2648
|
+
/* @__PURE__ */ jsxs30(
|
|
2438
2649
|
"div",
|
|
2439
2650
|
{
|
|
2440
2651
|
"data-es-navbar": true,
|
|
@@ -2443,9 +2654,9 @@ function ReportInteractiveView({
|
|
|
2443
2654
|
hideHeader ? "justify-end" : "justify-between"
|
|
2444
2655
|
),
|
|
2445
2656
|
children: [
|
|
2446
|
-
hideHeader ? null : /* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
2448
|
-
/* @__PURE__ */
|
|
2657
|
+
hideHeader ? null : /* @__PURE__ */ jsx45("h1", { className: "min-w-0", children: title ?? "Story Report" }),
|
|
2658
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2659
|
+
/* @__PURE__ */ jsx45(
|
|
2449
2660
|
ReportSearch,
|
|
2450
2661
|
{
|
|
2451
2662
|
ref: searchRef,
|
|
@@ -2455,16 +2666,16 @@ function ReportInteractiveView({
|
|
|
2455
2666
|
totalCount: totalScenarios
|
|
2456
2667
|
}
|
|
2457
2668
|
),
|
|
2458
|
-
/* @__PURE__ */
|
|
2669
|
+
/* @__PURE__ */ jsx45(ThemeSegment, { pref: themePref, onPref: setThemePref })
|
|
2459
2670
|
] })
|
|
2460
2671
|
]
|
|
2461
2672
|
}
|
|
2462
2673
|
),
|
|
2463
|
-
hideHeader ? null : /* @__PURE__ */
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2674
|
+
hideHeader ? null : /* @__PURE__ */ jsxs30(Fragment13, { children: [
|
|
2675
|
+
/* @__PURE__ */ jsx45(ReportSummary, {}),
|
|
2676
|
+
/* @__PURE__ */ jsx45(ReportMeta, {})
|
|
2466
2677
|
] }),
|
|
2467
|
-
/* @__PURE__ */
|
|
2678
|
+
/* @__PURE__ */ jsx45(
|
|
2468
2679
|
ReportFreshness,
|
|
2469
2680
|
{
|
|
2470
2681
|
lastRunMs: reportLastRunMs(report),
|
|
@@ -2472,8 +2683,8 @@ function ReportInteractiveView({
|
|
|
2472
2683
|
staleAfterDays
|
|
2473
2684
|
}
|
|
2474
2685
|
),
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2686
|
+
/* @__PURE__ */ jsx45(ReportLastRunDelta, { history: scenarioHistory, report }),
|
|
2687
|
+
/* @__PURE__ */ jsx45(
|
|
2477
2688
|
ReportFilters,
|
|
2478
2689
|
{
|
|
2479
2690
|
statuses: statusOptions,
|
|
@@ -2484,14 +2695,14 @@ function ReportInteractiveView({
|
|
|
2484
2695
|
onToggleTag: toggleTag
|
|
2485
2696
|
}
|
|
2486
2697
|
),
|
|
2487
|
-
/* @__PURE__ */
|
|
2488
|
-
showToc ? /* @__PURE__ */
|
|
2489
|
-
/* @__PURE__ */
|
|
2490
|
-
/* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
|
|
2699
|
+
showToc ? /* @__PURE__ */ jsx45(ReportTocDrawer, {}) : null,
|
|
2700
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2701
|
+
/* @__PURE__ */ jsx45(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
|
|
2702
|
+
/* @__PURE__ */ jsx45("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
|
|
2492
2703
|
] }),
|
|
2493
|
-
/* @__PURE__ */
|
|
2494
|
-
/* @__PURE__ */
|
|
2704
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2705
|
+
/* @__PURE__ */ jsx45(
|
|
2495
2706
|
Switch,
|
|
2496
2707
|
{
|
|
2497
2708
|
id: docsId,
|
|
@@ -2499,16 +2710,16 @@ function ReportInteractiveView({
|
|
|
2499
2710
|
onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
|
|
2500
2711
|
}
|
|
2501
2712
|
),
|
|
2502
|
-
/* @__PURE__ */
|
|
2713
|
+
/* @__PURE__ */ jsx45("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
|
|
2503
2714
|
] })
|
|
2504
2715
|
] })
|
|
2505
2716
|
] }),
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
hasContent ? showToc ? /* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2509
|
-
/* @__PURE__ */
|
|
2510
|
-
] }) : /* @__PURE__ */
|
|
2511
|
-
/* @__PURE__ */
|
|
2717
|
+
/* @__PURE__ */ jsx45(ReportFailureBanner, { failures }),
|
|
2718
|
+
hasContent ? showToc ? /* @__PURE__ */ jsxs30("div", { className: "flex gap-6", children: [
|
|
2719
|
+
/* @__PURE__ */ jsx45(ReportToc, {}),
|
|
2720
|
+
/* @__PURE__ */ jsx45("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ jsx45(ReportFeatureList, {}) })
|
|
2721
|
+
] }) : /* @__PURE__ */ jsx45("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsx45(ReportFeatureList, {}) }) : /* @__PURE__ */ jsx45(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
|
|
2722
|
+
/* @__PURE__ */ jsx45(
|
|
2512
2723
|
"button",
|
|
2513
2724
|
{
|
|
2514
2725
|
type: "button",
|
|
@@ -2519,8 +2730,8 @@ function ReportInteractiveView({
|
|
|
2519
2730
|
children: "?"
|
|
2520
2731
|
}
|
|
2521
2732
|
),
|
|
2522
|
-
/* @__PURE__ */
|
|
2523
|
-
toast ? /* @__PURE__ */
|
|
2733
|
+
/* @__PURE__ */ jsx45(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
|
|
2734
|
+
toast ? /* @__PURE__ */ jsx45(
|
|
2524
2735
|
"div",
|
|
2525
2736
|
{
|
|
2526
2737
|
role: "status",
|
|
@@ -2544,7 +2755,7 @@ import { createElement, useEffect as useEffect8, useState as useState9 } from "r
|
|
|
2544
2755
|
|
|
2545
2756
|
// src/components/doc/MermaidView.tsx
|
|
2546
2757
|
import { useEffect as useEffect7, useRef as useRef4, useState as useState8 } from "react";
|
|
2547
|
-
import { jsx as
|
|
2758
|
+
import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2548
2759
|
function prefersDark(el) {
|
|
2549
2760
|
const themed = el?.closest("[data-theme]");
|
|
2550
2761
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -2581,9 +2792,9 @@ function MermaidView({ entry, load }) {
|
|
|
2581
2792
|
};
|
|
2582
2793
|
}, [entry.code, load]);
|
|
2583
2794
|
if (svg) {
|
|
2584
|
-
return /* @__PURE__ */
|
|
2585
|
-
entry.title ? /* @__PURE__ */
|
|
2586
|
-
/* @__PURE__ */
|
|
2795
|
+
return /* @__PURE__ */ jsxs31("figure", { ref, className: "my-3", children: [
|
|
2796
|
+
entry.title ? /* @__PURE__ */ jsx46("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
2797
|
+
/* @__PURE__ */ jsx46(
|
|
2587
2798
|
"div",
|
|
2588
2799
|
{
|
|
2589
2800
|
role: "img",
|
|
@@ -2594,11 +2805,11 @@ function MermaidView({ entry, load }) {
|
|
|
2594
2805
|
)
|
|
2595
2806
|
] });
|
|
2596
2807
|
}
|
|
2597
|
-
return /* @__PURE__ */
|
|
2808
|
+
return /* @__PURE__ */ jsx46(MermaidSource, { entry, ref });
|
|
2598
2809
|
}
|
|
2599
2810
|
|
|
2600
2811
|
// src/interactive/island-renderers.tsx
|
|
2601
|
-
import { jsx as
|
|
2812
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2602
2813
|
var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
|
|
2603
2814
|
var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
|
|
2604
2815
|
function cachedCdnModule(url) {
|
|
@@ -2632,13 +2843,13 @@ function CdnHighlightedCode({ entry }) {
|
|
|
2632
2843
|
cancelled = true;
|
|
2633
2844
|
};
|
|
2634
2845
|
}, [entry.content, entry.lang]);
|
|
2635
|
-
return /* @__PURE__ */
|
|
2846
|
+
return /* @__PURE__ */ jsx47(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ jsx47(
|
|
2636
2847
|
"code",
|
|
2637
2848
|
{
|
|
2638
2849
|
className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
|
|
2639
2850
|
dangerouslySetInnerHTML: { __html: html }
|
|
2640
2851
|
}
|
|
2641
|
-
) : /* @__PURE__ */
|
|
2852
|
+
) : /* @__PURE__ */ jsx47("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
2642
2853
|
}
|
|
2643
2854
|
function buildIslandRenderers(opts) {
|
|
2644
2855
|
const renderers = {};
|
|
@@ -2652,7 +2863,7 @@ function buildIslandRenderers(opts) {
|
|
|
2652
2863
|
}
|
|
2653
2864
|
|
|
2654
2865
|
// src/interactive/ReportInteractiveIsland.tsx
|
|
2655
|
-
import { jsx as
|
|
2866
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2656
2867
|
function ReportInteractiveIsland({
|
|
2657
2868
|
report,
|
|
2658
2869
|
title,
|
|
@@ -2666,7 +2877,7 @@ function ReportInteractiveIsland({
|
|
|
2666
2877
|
() => buildIslandRenderers({ syntaxHighlighting, mermaid }),
|
|
2667
2878
|
[syntaxHighlighting, mermaid]
|
|
2668
2879
|
);
|
|
2669
|
-
return /* @__PURE__ */
|
|
2880
|
+
return /* @__PURE__ */ jsx48(
|
|
2670
2881
|
ReportInteractive,
|
|
2671
2882
|
{
|
|
2672
2883
|
report,
|