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/index.js
CHANGED
|
@@ -216,7 +216,7 @@ function DocLink({ entry }) {
|
|
|
216
216
|
// src/components/doc/DocSection.tsx
|
|
217
217
|
import { marked } from "marked";
|
|
218
218
|
|
|
219
|
-
//
|
|
219
|
+
// ../executable-stories-core/dist/utils/url.js
|
|
220
220
|
function safeUrl(value) {
|
|
221
221
|
if (!value) return void 0;
|
|
222
222
|
const trimmed = value.trim();
|
|
@@ -511,18 +511,101 @@ function ReportStepItem({ step }) {
|
|
|
511
511
|
);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
+
// ../executable-stories-core/dist/storyboard.js
|
|
515
|
+
function findScreenshot(entries) {
|
|
516
|
+
for (const entry of entries) {
|
|
517
|
+
if (entry.kind === "screenshot") return entry;
|
|
518
|
+
if (entry.children) {
|
|
519
|
+
const nested = findScreenshot(entry.children);
|
|
520
|
+
if (nested) return nested;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return void 0;
|
|
524
|
+
}
|
|
525
|
+
function extractStoryboardFrames(scenario) {
|
|
526
|
+
const frames = [];
|
|
527
|
+
for (const step of scenario.steps) {
|
|
528
|
+
const shot = findScreenshot(step.docEntries);
|
|
529
|
+
if (!shot) continue;
|
|
530
|
+
frames.push({
|
|
531
|
+
stepId: step.id,
|
|
532
|
+
stepIndex: step.index,
|
|
533
|
+
keyword: step.keyword,
|
|
534
|
+
text: step.text,
|
|
535
|
+
status: step.status,
|
|
536
|
+
path: shot.path,
|
|
537
|
+
...shot.alt !== void 0 && { alt: shot.alt }
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return frames;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/components/ReportStoryboard.tsx
|
|
544
|
+
import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
545
|
+
var FRAME_GLYPH = {
|
|
546
|
+
passed: "\u2713",
|
|
547
|
+
failed: "\u2717",
|
|
548
|
+
skipped: "\u25CB",
|
|
549
|
+
pending: "\u25CB"
|
|
550
|
+
};
|
|
551
|
+
var FRAME_GLYPH_COLOR = {
|
|
552
|
+
passed: "text-pass",
|
|
553
|
+
failed: "text-fail",
|
|
554
|
+
skipped: "text-skip",
|
|
555
|
+
pending: "text-pend"
|
|
556
|
+
};
|
|
557
|
+
function ReportStoryboard({ scenario }) {
|
|
558
|
+
const frames = extractStoryboardFrames(scenario);
|
|
559
|
+
if (frames.length < 2) return null;
|
|
560
|
+
return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
561
|
+
/* @__PURE__ */ jsx18("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
562
|
+
/* @__PURE__ */ jsx18("ol", { className: "flex gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx18(StoryboardFrameItem, { frame }, frame.stepId)) })
|
|
563
|
+
] });
|
|
564
|
+
}
|
|
565
|
+
function StoryboardFrameItem({ frame }) {
|
|
566
|
+
const src = isLocalFsPath(frame.path) ? void 0 : safeImageUrl(frame.path);
|
|
567
|
+
const label = `${frame.keyword} ${frame.text}`;
|
|
568
|
+
return /* @__PURE__ */ jsxs11("li", { className: "w-40 shrink-0", children: [
|
|
569
|
+
/* @__PURE__ */ jsx18(
|
|
570
|
+
"a",
|
|
571
|
+
{
|
|
572
|
+
href: `#${frame.stepId}`,
|
|
573
|
+
"aria-label": `Jump to step: ${label}`,
|
|
574
|
+
className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
|
|
575
|
+
children: src ? /* @__PURE__ */ jsx18(
|
|
576
|
+
"img",
|
|
577
|
+
{
|
|
578
|
+
src,
|
|
579
|
+
alt: frame.alt ?? label,
|
|
580
|
+
loading: "lazy",
|
|
581
|
+
className: "h-24 w-full bg-muted object-cover object-top"
|
|
582
|
+
}
|
|
583
|
+
) : /* @__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" })
|
|
584
|
+
}
|
|
585
|
+
),
|
|
586
|
+
/* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
587
|
+
/* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
588
|
+
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
589
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
590
|
+
" ",
|
|
591
|
+
/* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: frame.alt ?? frame.text })
|
|
592
|
+
] })
|
|
593
|
+
] })
|
|
594
|
+
] });
|
|
595
|
+
}
|
|
596
|
+
|
|
514
597
|
// src/components/ReportAttachments.tsx
|
|
515
|
-
import { Fragment as Fragment6, jsx as
|
|
598
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
516
599
|
function ReportAttachments({ attachments }) {
|
|
517
600
|
if (attachments.length === 0) return null;
|
|
518
601
|
return (
|
|
519
602
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
520
603
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
521
|
-
/* @__PURE__ */
|
|
604
|
+
/* @__PURE__ */ jsx19("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
522
605
|
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
523
606
|
const isImage = att.mediaType.startsWith("image/");
|
|
524
|
-
return /* @__PURE__ */
|
|
525
|
-
/* @__PURE__ */
|
|
607
|
+
return /* @__PURE__ */ jsx19("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
608
|
+
/* @__PURE__ */ jsx19(
|
|
526
609
|
"img",
|
|
527
610
|
{
|
|
528
611
|
src: dataUri,
|
|
@@ -531,8 +614,8 @@ function ReportAttachments({ attachments }) {
|
|
|
531
614
|
className: "max-w-full rounded-md border border-border"
|
|
532
615
|
}
|
|
533
616
|
),
|
|
534
|
-
/* @__PURE__ */
|
|
535
|
-
] }) : /* @__PURE__ */
|
|
617
|
+
/* @__PURE__ */ jsx19("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
618
|
+
] }) : /* @__PURE__ */ jsxs12(
|
|
536
619
|
"a",
|
|
537
620
|
{
|
|
538
621
|
href: dataUri,
|
|
@@ -541,7 +624,7 @@ function ReportAttachments({ attachments }) {
|
|
|
541
624
|
children: [
|
|
542
625
|
att.name,
|
|
543
626
|
" ",
|
|
544
|
-
/* @__PURE__ */
|
|
627
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
|
|
545
628
|
"(",
|
|
546
629
|
att.mediaType,
|
|
547
630
|
")"
|
|
@@ -629,7 +712,7 @@ function traceWindow(rows) {
|
|
|
629
712
|
}
|
|
630
713
|
|
|
631
714
|
// src/components/ReportTrace.tsx
|
|
632
|
-
import { jsx as
|
|
715
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
633
716
|
var BAR_COLOR = {
|
|
634
717
|
ok: "bg-pass",
|
|
635
718
|
error: "bg-fail",
|
|
@@ -640,8 +723,8 @@ function ReportTrace({ spans }) {
|
|
|
640
723
|
const rows = toTraceRows(spans);
|
|
641
724
|
if (rows.length === 0) return null;
|
|
642
725
|
const { minStartMs, totalMs } = traceWindow(rows);
|
|
643
|
-
return /* @__PURE__ */
|
|
644
|
-
/* @__PURE__ */
|
|
726
|
+
return /* @__PURE__ */ jsxs13("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
|
|
727
|
+
/* @__PURE__ */ jsxs13("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
|
|
645
728
|
"Trace (",
|
|
646
729
|
rows.length,
|
|
647
730
|
" span",
|
|
@@ -650,11 +733,11 @@ function ReportTrace({ spans }) {
|
|
|
650
733
|
formatDuration(totalMs),
|
|
651
734
|
")"
|
|
652
735
|
] }),
|
|
653
|
-
/* @__PURE__ */
|
|
736
|
+
/* @__PURE__ */ jsx20("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
654
737
|
const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
|
|
655
738
|
const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
|
|
656
|
-
return /* @__PURE__ */
|
|
657
|
-
/* @__PURE__ */
|
|
739
|
+
return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
|
|
740
|
+
/* @__PURE__ */ jsx20(
|
|
658
741
|
"span",
|
|
659
742
|
{
|
|
660
743
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
@@ -663,14 +746,14 @@ function ReportTrace({ spans }) {
|
|
|
663
746
|
children: row.name
|
|
664
747
|
}
|
|
665
748
|
),
|
|
666
|
-
/* @__PURE__ */
|
|
749
|
+
/* @__PURE__ */ jsx20("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx20(
|
|
667
750
|
"span",
|
|
668
751
|
{
|
|
669
752
|
className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
|
|
670
753
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
671
754
|
}
|
|
672
755
|
) }),
|
|
673
|
-
/* @__PURE__ */
|
|
756
|
+
/* @__PURE__ */ jsx20("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
674
757
|
] }, `${row.spanId}-${i}`);
|
|
675
758
|
}) })
|
|
676
759
|
] });
|
|
@@ -721,7 +804,7 @@ function flakinessOf(entries) {
|
|
|
721
804
|
}
|
|
722
805
|
|
|
723
806
|
// src/components/ScenarioRunHistory.tsx
|
|
724
|
-
import { Fragment as Fragment7, jsx as
|
|
807
|
+
import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
725
808
|
var MAX_DOTS = 10;
|
|
726
809
|
var DOT_COLOR = {
|
|
727
810
|
passed: "bg-pass",
|
|
@@ -741,16 +824,16 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
741
824
|
const recent = entries.slice(-MAX_DOTS);
|
|
742
825
|
const flaky = flakinessOf(recent) === "flaky";
|
|
743
826
|
const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
|
|
744
|
-
return /* @__PURE__ */
|
|
745
|
-
flaky ? /* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
827
|
+
return /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
828
|
+
flaky ? /* @__PURE__ */ jsx21(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
|
|
829
|
+
/* @__PURE__ */ jsx21(
|
|
747
830
|
"span",
|
|
748
831
|
{
|
|
749
832
|
role: "img",
|
|
750
833
|
"aria-label": `Run history: ${summary}`,
|
|
751
834
|
title: summary,
|
|
752
835
|
className: "flex shrink-0 items-center gap-[3px]",
|
|
753
|
-
children: recent.map((e, i) => /* @__PURE__ */
|
|
836
|
+
children: recent.map((e, i) => /* @__PURE__ */ jsx21(
|
|
754
837
|
"span",
|
|
755
838
|
{
|
|
756
839
|
"aria-hidden": true,
|
|
@@ -789,9 +872,9 @@ function useScenarioActions() {
|
|
|
789
872
|
|
|
790
873
|
// src/components/ui/card.tsx
|
|
791
874
|
import "react";
|
|
792
|
-
import { jsx as
|
|
875
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
793
876
|
function Card({ className, ...props }) {
|
|
794
|
-
return /* @__PURE__ */
|
|
877
|
+
return /* @__PURE__ */ jsx22(
|
|
795
878
|
"div",
|
|
796
879
|
{
|
|
797
880
|
"data-slot": "card",
|
|
@@ -804,7 +887,7 @@ function Card({ className, ...props }) {
|
|
|
804
887
|
);
|
|
805
888
|
}
|
|
806
889
|
function CardHeader({ className, ...props }) {
|
|
807
|
-
return /* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsx22(
|
|
808
891
|
"div",
|
|
809
892
|
{
|
|
810
893
|
"data-slot": "card-header",
|
|
@@ -817,7 +900,7 @@ function CardHeader({ className, ...props }) {
|
|
|
817
900
|
);
|
|
818
901
|
}
|
|
819
902
|
function CardContent({ className, ...props }) {
|
|
820
|
-
return /* @__PURE__ */
|
|
903
|
+
return /* @__PURE__ */ jsx22(
|
|
821
904
|
"div",
|
|
822
905
|
{
|
|
823
906
|
"data-slot": "card-content",
|
|
@@ -831,13 +914,13 @@ function CardContent({ className, ...props }) {
|
|
|
831
914
|
import "react";
|
|
832
915
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
833
916
|
import { CheckIcon } from "lucide-react";
|
|
834
|
-
import { jsx as
|
|
917
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
835
918
|
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";
|
|
836
919
|
function DropdownMenu(props) {
|
|
837
|
-
return /* @__PURE__ */
|
|
920
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
838
921
|
}
|
|
839
922
|
function DropdownMenuTrigger(props) {
|
|
840
|
-
return /* @__PURE__ */
|
|
923
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
841
924
|
}
|
|
842
925
|
function DropdownMenuContent({
|
|
843
926
|
className,
|
|
@@ -845,14 +928,14 @@ function DropdownMenuContent({
|
|
|
845
928
|
sideOffset = 4,
|
|
846
929
|
...props
|
|
847
930
|
}) {
|
|
848
|
-
return /* @__PURE__ */
|
|
931
|
+
return /* @__PURE__ */ jsx23(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx23(
|
|
849
932
|
MenuPrimitive.Positioner,
|
|
850
933
|
{
|
|
851
934
|
"data-slot": "dropdown-menu-positioner",
|
|
852
935
|
className: "z-50",
|
|
853
936
|
align,
|
|
854
937
|
sideOffset,
|
|
855
|
-
children: /* @__PURE__ */
|
|
938
|
+
children: /* @__PURE__ */ jsx23(
|
|
856
939
|
MenuPrimitive.Popup,
|
|
857
940
|
{
|
|
858
941
|
"data-slot": "dropdown-menu-content",
|
|
@@ -870,7 +953,7 @@ function DropdownMenuItem({
|
|
|
870
953
|
className,
|
|
871
954
|
...props
|
|
872
955
|
}) {
|
|
873
|
-
return /* @__PURE__ */
|
|
956
|
+
return /* @__PURE__ */ jsx23(
|
|
874
957
|
MenuPrimitive.Item,
|
|
875
958
|
{
|
|
876
959
|
"data-slot": "dropdown-menu-item",
|
|
@@ -882,7 +965,7 @@ function DropdownMenuItem({
|
|
|
882
965
|
|
|
883
966
|
// src/components/ReportScenario.tsx
|
|
884
967
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
885
|
-
import { jsx as
|
|
968
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
886
969
|
var STATUS_META = {
|
|
887
970
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
888
971
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -898,7 +981,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
898
981
|
const collapsible = collapse !== null && !hideTitle;
|
|
899
982
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
900
983
|
const actions = useScenarioActions();
|
|
901
|
-
return /* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsxs16(
|
|
902
985
|
Card,
|
|
903
986
|
{
|
|
904
987
|
id: scenario.id,
|
|
@@ -906,10 +989,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
906
989
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
907
990
|
className: "gap-0 py-0",
|
|
908
991
|
children: [
|
|
909
|
-
/* @__PURE__ */
|
|
910
|
-
/* @__PURE__ */
|
|
911
|
-
hideTitle ? null : /* @__PURE__ */
|
|
912
|
-
collapsible ? /* @__PURE__ */
|
|
992
|
+
/* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
|
|
993
|
+
/* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
994
|
+
hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
995
|
+
collapsible ? /* @__PURE__ */ jsx24(
|
|
913
996
|
"button",
|
|
914
997
|
{
|
|
915
998
|
type: "button",
|
|
@@ -918,49 +1001,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
918
1001
|
"aria-controls": bodyId,
|
|
919
1002
|
"aria-label": `Toggle ${scenario.title}`,
|
|
920
1003
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
921
|
-
children: /* @__PURE__ */
|
|
1004
|
+
children: /* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
922
1005
|
}
|
|
923
1006
|
) : null,
|
|
924
|
-
/* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
1007
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1008
|
+
/* @__PURE__ */ jsx24("span", { children: scenario.title })
|
|
926
1009
|
] }),
|
|
927
|
-
/* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
scenario.durationMs > 0 ? /* @__PURE__ */
|
|
930
|
-
meta.showPill ? /* @__PURE__ */
|
|
931
|
-
actions ? /* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
1010
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1011
|
+
/* @__PURE__ */ jsx24(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1012
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ jsx24("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1013
|
+
meta.showPill ? /* @__PURE__ */ jsx24(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx24("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1014
|
+
actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1015
|
+
/* @__PURE__ */ jsx24(
|
|
933
1016
|
DropdownMenuTrigger,
|
|
934
1017
|
{
|
|
935
1018
|
"aria-label": `Actions for ${scenario.title}`,
|
|
936
1019
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
937
|
-
children: /* @__PURE__ */
|
|
1020
|
+
children: /* @__PURE__ */ jsx24(MoreHorizontalIcon, { "aria-hidden": true })
|
|
938
1021
|
}
|
|
939
1022
|
),
|
|
940
|
-
/* @__PURE__ */
|
|
941
|
-
/* @__PURE__ */
|
|
942
|
-
/* @__PURE__ */
|
|
1023
|
+
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
|
|
1024
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1025
|
+
/* @__PURE__ */ jsx24(LinkIcon, {}),
|
|
943
1026
|
" Copy link"
|
|
944
1027
|
] }),
|
|
945
|
-
/* @__PURE__ */
|
|
946
|
-
/* @__PURE__ */
|
|
1028
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1029
|
+
/* @__PURE__ */ jsx24(FileTextIcon, {}),
|
|
947
1030
|
" Copy as Markdown"
|
|
948
1031
|
] }),
|
|
949
|
-
/* @__PURE__ */
|
|
950
|
-
/* @__PURE__ */
|
|
1032
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1033
|
+
/* @__PURE__ */ jsx24(SparklesIcon, {}),
|
|
951
1034
|
" Explain with AI"
|
|
952
1035
|
] })
|
|
953
1036
|
] })
|
|
954
1037
|
] }) : null
|
|
955
1038
|
] })
|
|
956
1039
|
] }),
|
|
957
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
958
|
-
scenario.tags.map((t) => /* @__PURE__ */
|
|
959
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */
|
|
1040
|
+
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: [
|
|
1041
|
+
scenario.tags.map((t) => /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsx24(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1042
|
+
(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}`))
|
|
960
1043
|
] }) : null
|
|
961
1044
|
] }),
|
|
962
|
-
/* @__PURE__ */
|
|
963
|
-
scenario.errorMessage ? /* @__PURE__ */
|
|
1045
|
+
/* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1046
|
+
scenario.errorMessage ? /* @__PURE__ */ jsx24(
|
|
964
1047
|
"pre",
|
|
965
1048
|
{
|
|
966
1049
|
role: "alert",
|
|
@@ -968,10 +1051,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
968
1051
|
children: scenario.errorMessage
|
|
969
1052
|
}
|
|
970
1053
|
) : null,
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
|
|
973
|
-
/* @__PURE__ */
|
|
974
|
-
/* @__PURE__ */
|
|
1054
|
+
/* @__PURE__ */ jsx24(ReportStoryboard, { scenario }),
|
|
1055
|
+
/* @__PURE__ */ jsx24(ReportSteps, { scenario }),
|
|
1056
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx24("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx24(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1057
|
+
/* @__PURE__ */ jsx24(ReportAttachments, { attachments: scenario.attachments }),
|
|
1058
|
+
/* @__PURE__ */ jsx24(ReportTrace, { spans: scenario.otelSpans })
|
|
975
1059
|
] })
|
|
976
1060
|
]
|
|
977
1061
|
}
|
|
@@ -979,13 +1063,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
979
1063
|
}
|
|
980
1064
|
|
|
981
1065
|
// src/components/ReportScenarioList.tsx
|
|
982
|
-
import { Fragment as Fragment8, jsx as
|
|
1066
|
+
import { Fragment as Fragment8, jsx as jsx25 } from "react/jsx-runtime";
|
|
983
1067
|
function ReportScenarioList({ feature }) {
|
|
984
|
-
return /* @__PURE__ */
|
|
1068
|
+
return /* @__PURE__ */ jsx25(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx25(ReportScenario, { scenario }, scenario.id)) });
|
|
985
1069
|
}
|
|
986
1070
|
|
|
987
1071
|
// src/components/ReportFeature.tsx
|
|
988
|
-
import { Fragment as Fragment9, jsx as
|
|
1072
|
+
import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
989
1073
|
function ReportFeature({ feature }) {
|
|
990
1074
|
const titleId = `${feature.id}-title`;
|
|
991
1075
|
const bodyId = `${feature.id}-body`;
|
|
@@ -996,7 +1080,7 @@ function ReportFeature({ feature }) {
|
|
|
996
1080
|
return (
|
|
997
1081
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
998
1082
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
999
|
-
/* @__PURE__ */
|
|
1083
|
+
/* @__PURE__ */ jsxs17(
|
|
1000
1084
|
"section",
|
|
1001
1085
|
{
|
|
1002
1086
|
id: feature.id,
|
|
@@ -1004,9 +1088,9 @@ function ReportFeature({ feature }) {
|
|
|
1004
1088
|
"aria-labelledby": titleId,
|
|
1005
1089
|
className: "flex flex-col gap-3",
|
|
1006
1090
|
children: [
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1091
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1092
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
|
|
1093
|
+
/* @__PURE__ */ jsx26("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
|
|
1010
1094
|
"button",
|
|
1011
1095
|
{
|
|
1012
1096
|
type: "button",
|
|
@@ -1015,31 +1099,31 @@ function ReportFeature({ feature }) {
|
|
|
1015
1099
|
"aria-controls": bodyId,
|
|
1016
1100
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1017
1101
|
children: [
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1102
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1103
|
+
/* @__PURE__ */ jsx26("span", { className: "truncate", children: feature.title })
|
|
1020
1104
|
]
|
|
1021
1105
|
}
|
|
1022
1106
|
) : feature.title }),
|
|
1023
|
-
/* @__PURE__ */
|
|
1107
|
+
/* @__PURE__ */ jsx26("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1024
1108
|
] }),
|
|
1025
|
-
/* @__PURE__ */
|
|
1109
|
+
/* @__PURE__ */ jsxs17(
|
|
1026
1110
|
"p",
|
|
1027
1111
|
{
|
|
1028
1112
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1029
1113
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1030
1114
|
children: [
|
|
1031
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1032
1116
|
s.passed,
|
|
1033
1117
|
" passed"
|
|
1034
1118
|
] }),
|
|
1035
|
-
/* @__PURE__ */
|
|
1036
|
-
/* @__PURE__ */
|
|
1119
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1120
|
+
/* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1037
1121
|
s.failed,
|
|
1038
1122
|
" failed"
|
|
1039
1123
|
] }),
|
|
1040
|
-
skipped > 0 ? /* @__PURE__ */
|
|
1041
|
-
/* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
1124
|
+
skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
1125
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1126
|
+
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1043
1127
|
skipped,
|
|
1044
1128
|
" skipped"
|
|
1045
1129
|
] })
|
|
@@ -1048,7 +1132,7 @@ function ReportFeature({ feature }) {
|
|
|
1048
1132
|
}
|
|
1049
1133
|
)
|
|
1050
1134
|
] }),
|
|
1051
|
-
/* @__PURE__ */
|
|
1135
|
+
/* @__PURE__ */ jsx26("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx26(ReportScenarioList, { feature }) })
|
|
1052
1136
|
]
|
|
1053
1137
|
}
|
|
1054
1138
|
)
|
|
@@ -1056,17 +1140,17 @@ function ReportFeature({ feature }) {
|
|
|
1056
1140
|
}
|
|
1057
1141
|
|
|
1058
1142
|
// src/components/ReportFeatureList.tsx
|
|
1059
|
-
import { jsx as
|
|
1143
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1060
1144
|
function ReportFeatureList() {
|
|
1061
1145
|
const report = useReport();
|
|
1062
|
-
return /* @__PURE__ */
|
|
1146
|
+
return /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx27(ReportFeature, { feature }, feature.id)) });
|
|
1063
1147
|
}
|
|
1064
1148
|
|
|
1065
1149
|
// src/components/ui/empty.tsx
|
|
1066
1150
|
import { cva as cva2 } from "class-variance-authority";
|
|
1067
|
-
import { jsx as
|
|
1151
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1068
1152
|
function Empty({ className, ...props }) {
|
|
1069
|
-
return /* @__PURE__ */
|
|
1153
|
+
return /* @__PURE__ */ jsx28(
|
|
1070
1154
|
"div",
|
|
1071
1155
|
{
|
|
1072
1156
|
"data-slot": "empty",
|
|
@@ -1079,7 +1163,7 @@ function Empty({ className, ...props }) {
|
|
|
1079
1163
|
);
|
|
1080
1164
|
}
|
|
1081
1165
|
function EmptyHeader({ className, ...props }) {
|
|
1082
|
-
return /* @__PURE__ */
|
|
1166
|
+
return /* @__PURE__ */ jsx28(
|
|
1083
1167
|
"div",
|
|
1084
1168
|
{
|
|
1085
1169
|
"data-slot": "empty-header",
|
|
@@ -1106,7 +1190,7 @@ var emptyMediaVariants = cva2(
|
|
|
1106
1190
|
}
|
|
1107
1191
|
);
|
|
1108
1192
|
function EmptyTitle({ className, ...props }) {
|
|
1109
|
-
return /* @__PURE__ */
|
|
1193
|
+
return /* @__PURE__ */ jsx28(
|
|
1110
1194
|
"div",
|
|
1111
1195
|
{
|
|
1112
1196
|
"data-slot": "empty-title",
|
|
@@ -1117,16 +1201,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1117
1201
|
}
|
|
1118
1202
|
|
|
1119
1203
|
// src/components/ReportEmpty.tsx
|
|
1120
|
-
import { jsx as
|
|
1204
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1121
1205
|
function ReportEmpty({ message }) {
|
|
1122
|
-
return /* @__PURE__ */
|
|
1206
|
+
return /* @__PURE__ */ jsx29(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx29(EmptyHeader, { children: /* @__PURE__ */ jsx29(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1123
1207
|
}
|
|
1124
1208
|
|
|
1125
1209
|
// src/components/ReportSummary.tsx
|
|
1126
|
-
import { jsx as
|
|
1210
|
+
import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1127
1211
|
function ReportSummary({ className }) {
|
|
1128
1212
|
const report = useReport();
|
|
1129
|
-
return /* @__PURE__ */
|
|
1213
|
+
return /* @__PURE__ */ jsx30(
|
|
1130
1214
|
ReportSummaryView,
|
|
1131
1215
|
{
|
|
1132
1216
|
summary: report.summary,
|
|
@@ -1152,7 +1236,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1152
1236
|
if (summary.pending > 0) {
|
|
1153
1237
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1154
1238
|
}
|
|
1155
|
-
return /* @__PURE__ */
|
|
1239
|
+
return /* @__PURE__ */ jsx30(
|
|
1156
1240
|
"dl",
|
|
1157
1241
|
{
|
|
1158
1242
|
className: cn(
|
|
@@ -1165,17 +1249,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1165
1249
|
"aria-label": ariaLabel,
|
|
1166
1250
|
children: cards.map((c) => {
|
|
1167
1251
|
const tone = TONE[c.status];
|
|
1168
|
-
return /* @__PURE__ */
|
|
1252
|
+
return /* @__PURE__ */ jsxs18(
|
|
1169
1253
|
"div",
|
|
1170
1254
|
{
|
|
1171
1255
|
"data-status": c.status,
|
|
1172
1256
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1173
1257
|
children: [
|
|
1174
|
-
/* @__PURE__ */
|
|
1175
|
-
/* @__PURE__ */
|
|
1258
|
+
/* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1259
|
+
/* @__PURE__ */ jsx30("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1176
1260
|
c.label
|
|
1177
1261
|
] }),
|
|
1178
|
-
/* @__PURE__ */
|
|
1262
|
+
/* @__PURE__ */ jsx30("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1179
1263
|
]
|
|
1180
1264
|
},
|
|
1181
1265
|
c.status
|
|
@@ -1235,7 +1319,7 @@ function prUrl(ci) {
|
|
|
1235
1319
|
}
|
|
1236
1320
|
|
|
1237
1321
|
// src/components/ReportMeta.tsx
|
|
1238
|
-
import { jsx as
|
|
1322
|
+
import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1239
1323
|
function ReportMeta() {
|
|
1240
1324
|
const report = useReport();
|
|
1241
1325
|
const items = [];
|
|
@@ -1258,13 +1342,13 @@ function ReportMeta() {
|
|
|
1258
1342
|
const short = sha.slice(0, 8);
|
|
1259
1343
|
items.push({
|
|
1260
1344
|
label: "Commit",
|
|
1261
|
-
value: url ? /* @__PURE__ */
|
|
1345
|
+
value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1262
1346
|
});
|
|
1263
1347
|
}
|
|
1264
1348
|
if (report.ci) {
|
|
1265
1349
|
items.push({
|
|
1266
1350
|
label: "CI",
|
|
1267
|
-
value: report.ci.url ? /* @__PURE__ */
|
|
1351
|
+
value: report.ci.url ? /* @__PURE__ */ jsxs19("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1268
1352
|
ciDisplayName(report.ci.name),
|
|
1269
1353
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1270
1354
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1275,7 +1359,7 @@ function ReportMeta() {
|
|
|
1275
1359
|
const label = `#${report.ci.prNumber}`;
|
|
1276
1360
|
items.push({
|
|
1277
1361
|
label: "PR",
|
|
1278
|
-
value: url ? /* @__PURE__ */
|
|
1362
|
+
value: url ? /* @__PURE__ */ jsx31("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1279
1363
|
});
|
|
1280
1364
|
}
|
|
1281
1365
|
if (items.length === 0) return null;
|
|
@@ -1283,48 +1367,48 @@ function ReportMeta() {
|
|
|
1283
1367
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1284
1368
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1285
1369
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1371
|
+
/* @__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: [
|
|
1372
|
+
/* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1289
1373
|
"Run details"
|
|
1290
1374
|
] }),
|
|
1291
|
-
/* @__PURE__ */
|
|
1292
|
-
/* @__PURE__ */
|
|
1293
|
-
/* @__PURE__ */
|
|
1375
|
+
/* @__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: [
|
|
1376
|
+
/* @__PURE__ */ jsx31("dt", { className: "font-medium", children: item.label }),
|
|
1377
|
+
/* @__PURE__ */ jsx31("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1294
1378
|
] }, item.label)) })
|
|
1295
1379
|
] })
|
|
1296
1380
|
);
|
|
1297
1381
|
}
|
|
1298
1382
|
|
|
1299
1383
|
// src/components/ReportSchemaError.tsx
|
|
1300
|
-
import { jsx as
|
|
1384
|
+
import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1301
1385
|
function ReportSchemaError({ error }) {
|
|
1302
|
-
return /* @__PURE__ */
|
|
1303
|
-
/* @__PURE__ */
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */
|
|
1386
|
+
return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1387
|
+
/* @__PURE__ */ jsx32("p", { children: /* @__PURE__ */ jsx32("strong", { children: "Report could not be displayed." }) }),
|
|
1388
|
+
/* @__PURE__ */ jsx32("p", { children: error.message }),
|
|
1389
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
|
|
1306
1390
|
"The report bundle is newer than this version of ",
|
|
1307
|
-
/* @__PURE__ */
|
|
1391
|
+
/* @__PURE__ */ jsx32("code", { children: "executable-stories-react" }),
|
|
1308
1392
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1309
1393
|
] }) : null,
|
|
1310
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */
|
|
1311
|
-
/* @__PURE__ */
|
|
1394
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
|
|
1395
|
+
/* @__PURE__ */ jsxs20("summary", { children: [
|
|
1312
1396
|
error.issues.length,
|
|
1313
1397
|
" validation issue",
|
|
1314
1398
|
error.issues.length === 1 ? "" : "s"
|
|
1315
1399
|
] }),
|
|
1316
|
-
/* @__PURE__ */
|
|
1400
|
+
/* @__PURE__ */ jsx32("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1317
1401
|
] }) : null
|
|
1318
1402
|
] });
|
|
1319
1403
|
}
|
|
1320
1404
|
|
|
1321
1405
|
// src/components/ReportShell.tsx
|
|
1322
|
-
import { Fragment as Fragment10, jsx as
|
|
1406
|
+
import { Fragment as Fragment10, jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1323
1407
|
function ReportTitleBlock({ title }) {
|
|
1324
|
-
return /* @__PURE__ */
|
|
1325
|
-
/* @__PURE__ */
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1408
|
+
return /* @__PURE__ */ jsxs21(Fragment10, { children: [
|
|
1409
|
+
/* @__PURE__ */ jsx33("h1", { children: title ?? "Story Report" }),
|
|
1410
|
+
/* @__PURE__ */ jsx33(ReportSummary, {}),
|
|
1411
|
+
/* @__PURE__ */ jsx33(ReportMeta, {})
|
|
1328
1412
|
] });
|
|
1329
1413
|
}
|
|
1330
1414
|
function ReportErrorShell({
|
|
@@ -1333,28 +1417,28 @@ function ReportErrorShell({
|
|
|
1333
1417
|
title,
|
|
1334
1418
|
dataTheme
|
|
1335
1419
|
}) {
|
|
1336
|
-
return /* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ jsx33("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx33(ReportSchemaError, { error }) });
|
|
1337
1421
|
}
|
|
1338
1422
|
|
|
1339
1423
|
// src/components/Report.tsx
|
|
1340
|
-
import { jsx as
|
|
1424
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1341
1425
|
function Report(props) {
|
|
1342
1426
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1343
1427
|
const result = unwrapReport(report);
|
|
1344
1428
|
if (!result.ok) {
|
|
1345
|
-
return /* @__PURE__ */
|
|
1429
|
+
return /* @__PURE__ */ jsx34(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1346
1430
|
}
|
|
1347
1431
|
const data = result.data;
|
|
1348
1432
|
const hasContent = data.features.length > 0;
|
|
1349
|
-
return /* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
hasContent ? /* @__PURE__ */
|
|
1433
|
+
return /* @__PURE__ */ jsx34(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs22("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1434
|
+
/* @__PURE__ */ jsx34("header", { className: "es-report-header", children: /* @__PURE__ */ jsx34(ReportTitleBlock, { title }) }),
|
|
1435
|
+
hasContent ? /* @__PURE__ */ jsx34(ReportFeatureList, {}) : /* @__PURE__ */ jsx34(ReportEmpty, {})
|
|
1352
1436
|
] }) });
|
|
1353
1437
|
}
|
|
1354
1438
|
|
|
1355
1439
|
// src/components/doc/MermaidView.tsx
|
|
1356
1440
|
import { useEffect, useRef, useState as useState2 } from "react";
|
|
1357
|
-
import { jsx as
|
|
1441
|
+
import { jsx as jsx35, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1358
1442
|
function prefersDark(el) {
|
|
1359
1443
|
const themed = el?.closest("[data-theme]");
|
|
1360
1444
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1391,9 +1475,9 @@ function MermaidView({ entry, load }) {
|
|
|
1391
1475
|
};
|
|
1392
1476
|
}, [entry.code, load]);
|
|
1393
1477
|
if (svg) {
|
|
1394
|
-
return /* @__PURE__ */
|
|
1395
|
-
entry.title ? /* @__PURE__ */
|
|
1396
|
-
/* @__PURE__ */
|
|
1478
|
+
return /* @__PURE__ */ jsxs23("figure", { ref, className: "my-3", children: [
|
|
1479
|
+
entry.title ? /* @__PURE__ */ jsx35("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1480
|
+
/* @__PURE__ */ jsx35(
|
|
1397
1481
|
"div",
|
|
1398
1482
|
{
|
|
1399
1483
|
role: "img",
|
|
@@ -1404,18 +1488,18 @@ function MermaidView({ entry, load }) {
|
|
|
1404
1488
|
)
|
|
1405
1489
|
] });
|
|
1406
1490
|
}
|
|
1407
|
-
return /* @__PURE__ */
|
|
1491
|
+
return /* @__PURE__ */ jsx35(MermaidSource, { entry, ref });
|
|
1408
1492
|
}
|
|
1409
1493
|
|
|
1410
1494
|
// src/components/doc/MermaidDiagram.tsx
|
|
1411
|
-
import { jsx as
|
|
1495
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
1412
1496
|
var mermaidLoader;
|
|
1413
1497
|
function loadMermaid() {
|
|
1414
1498
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1415
1499
|
return mermaidLoader;
|
|
1416
1500
|
}
|
|
1417
1501
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1418
|
-
return /* @__PURE__ */
|
|
1502
|
+
return /* @__PURE__ */ jsx36(MermaidView, { entry, load });
|
|
1419
1503
|
}
|
|
1420
1504
|
|
|
1421
1505
|
// src/components/ScenarioExplorer.tsx
|
|
@@ -1425,12 +1509,12 @@ import { useState as useState3 } from "react";
|
|
|
1425
1509
|
import "react";
|
|
1426
1510
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1427
1511
|
import { SearchIcon } from "lucide-react";
|
|
1428
|
-
import { jsx as
|
|
1512
|
+
import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1429
1513
|
function Command({
|
|
1430
1514
|
className,
|
|
1431
1515
|
...props
|
|
1432
1516
|
}) {
|
|
1433
|
-
return /* @__PURE__ */
|
|
1517
|
+
return /* @__PURE__ */ jsx37(
|
|
1434
1518
|
CommandPrimitive,
|
|
1435
1519
|
{
|
|
1436
1520
|
"data-slot": "command",
|
|
@@ -1446,14 +1530,14 @@ function CommandInput({
|
|
|
1446
1530
|
className,
|
|
1447
1531
|
...props
|
|
1448
1532
|
}) {
|
|
1449
|
-
return /* @__PURE__ */
|
|
1533
|
+
return /* @__PURE__ */ jsxs24(
|
|
1450
1534
|
"div",
|
|
1451
1535
|
{
|
|
1452
1536
|
"data-slot": "command-input-wrapper",
|
|
1453
1537
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1454
1538
|
children: [
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1539
|
+
/* @__PURE__ */ jsx37(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1540
|
+
/* @__PURE__ */ jsx37(
|
|
1457
1541
|
CommandPrimitive.Input,
|
|
1458
1542
|
{
|
|
1459
1543
|
"data-slot": "command-input",
|
|
@@ -1472,7 +1556,7 @@ function CommandList({
|
|
|
1472
1556
|
className,
|
|
1473
1557
|
...props
|
|
1474
1558
|
}) {
|
|
1475
|
-
return /* @__PURE__ */
|
|
1559
|
+
return /* @__PURE__ */ jsx37(
|
|
1476
1560
|
CommandPrimitive.List,
|
|
1477
1561
|
{
|
|
1478
1562
|
"data-slot": "command-list",
|
|
@@ -1487,7 +1571,7 @@ function CommandList({
|
|
|
1487
1571
|
function CommandEmpty({
|
|
1488
1572
|
...props
|
|
1489
1573
|
}) {
|
|
1490
|
-
return /* @__PURE__ */
|
|
1574
|
+
return /* @__PURE__ */ jsx37(
|
|
1491
1575
|
CommandPrimitive.Empty,
|
|
1492
1576
|
{
|
|
1493
1577
|
"data-slot": "command-empty",
|
|
@@ -1500,7 +1584,7 @@ function CommandGroup({
|
|
|
1500
1584
|
className,
|
|
1501
1585
|
...props
|
|
1502
1586
|
}) {
|
|
1503
|
-
return /* @__PURE__ */
|
|
1587
|
+
return /* @__PURE__ */ jsx37(
|
|
1504
1588
|
CommandPrimitive.Group,
|
|
1505
1589
|
{
|
|
1506
1590
|
"data-slot": "command-group",
|
|
@@ -1516,7 +1600,7 @@ function CommandItem({
|
|
|
1516
1600
|
className,
|
|
1517
1601
|
...props
|
|
1518
1602
|
}) {
|
|
1519
|
-
return /* @__PURE__ */
|
|
1603
|
+
return /* @__PURE__ */ jsx37(
|
|
1520
1604
|
CommandPrimitive.Item,
|
|
1521
1605
|
{
|
|
1522
1606
|
"data-slot": "command-item",
|
|
@@ -1530,7 +1614,7 @@ function CommandItem({
|
|
|
1530
1614
|
}
|
|
1531
1615
|
|
|
1532
1616
|
// src/components/ScenarioExplorer.tsx
|
|
1533
|
-
import { jsx as
|
|
1617
|
+
import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1534
1618
|
var STATUS_FILTERS = [
|
|
1535
1619
|
{ value: "all", label: "All" },
|
|
1536
1620
|
{ value: "passed", label: "Passed" },
|
|
@@ -1541,22 +1625,22 @@ var STATUS_FILTERS = [
|
|
|
1541
1625
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1542
1626
|
const [status, setStatus] = useState3("all");
|
|
1543
1627
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1544
|
-
return /* @__PURE__ */
|
|
1545
|
-
summary ? /* @__PURE__ */
|
|
1628
|
+
return /* @__PURE__ */ jsxs25("div", { className: "font-sans text-foreground", children: [
|
|
1629
|
+
summary ? /* @__PURE__ */ jsxs25("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1546
1630
|
summary.total,
|
|
1547
1631
|
" scenarios \xB7 ",
|
|
1548
|
-
/* @__PURE__ */
|
|
1632
|
+
/* @__PURE__ */ jsxs25("span", { className: "text-pass", children: [
|
|
1549
1633
|
summary.passed,
|
|
1550
1634
|
" passed"
|
|
1551
1635
|
] }),
|
|
1552
1636
|
" \xB7",
|
|
1553
1637
|
" ",
|
|
1554
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsxs25("span", { className: "text-fail", children: [
|
|
1555
1639
|
summary.failed,
|
|
1556
1640
|
" failed"
|
|
1557
1641
|
] })
|
|
1558
1642
|
] }) : null,
|
|
1559
|
-
/* @__PURE__ */
|
|
1643
|
+
/* @__PURE__ */ jsx38("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx38(
|
|
1560
1644
|
"button",
|
|
1561
1645
|
{
|
|
1562
1646
|
type: "button",
|
|
@@ -1571,26 +1655,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1571
1655
|
},
|
|
1572
1656
|
f.value
|
|
1573
1657
|
)) }),
|
|
1574
|
-
/* @__PURE__ */
|
|
1658
|
+
/* @__PURE__ */ jsxs25(
|
|
1575
1659
|
Command,
|
|
1576
1660
|
{
|
|
1577
1661
|
className: "rounded-lg border border-border bg-card",
|
|
1578
1662
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1579
1663
|
children: [
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
1664
|
+
/* @__PURE__ */ jsx38(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
1665
|
+
/* @__PURE__ */ jsxs25(CommandList, { className: "max-h-none", children: [
|
|
1666
|
+
/* @__PURE__ */ jsx38(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
1667
|
+
/* @__PURE__ */ jsx38(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx38(
|
|
1584
1668
|
CommandItem,
|
|
1585
1669
|
{
|
|
1586
1670
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1587
1671
|
asChild: true,
|
|
1588
1672
|
className: "cursor-pointer",
|
|
1589
|
-
children: /* @__PURE__ */
|
|
1590
|
-
/* @__PURE__ */
|
|
1591
|
-
/* @__PURE__ */
|
|
1592
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1673
|
+
children: /* @__PURE__ */ jsxs25("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
1674
|
+
/* @__PURE__ */ jsx38(Badge, { variant: s.status, children: s.status }),
|
|
1675
|
+
/* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
1676
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx38(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
1677
|
+
/* @__PURE__ */ jsx38("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
1594
1678
|
] })
|
|
1595
1679
|
},
|
|
1596
1680
|
s.id
|
|
@@ -2610,6 +2694,7 @@ export {
|
|
|
2610
2694
|
ReportSchemaError,
|
|
2611
2695
|
ReportStepItem,
|
|
2612
2696
|
ReportSteps,
|
|
2697
|
+
ReportStoryboard,
|
|
2613
2698
|
ReportSummary,
|
|
2614
2699
|
ReportSummaryView,
|
|
2615
2700
|
ReportTrace,
|