executable-stories-react 0.4.1 → 0.6.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 +303 -240
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +301 -238
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +982 -483
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +10 -1
- package/dist/interactive.d.ts +10 -1
- package/dist/interactive.js +945 -455
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +108 -59
- package/dist/ssr.cjs +269 -206
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +269 -206
- package/dist/ssr.js.map +1 -1
- package/dist/styles.css +18 -42
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -181,11 +181,15 @@ var badgeVariants = (0, import_class_variance_authority.cva)(
|
|
|
181
181
|
outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
182
182
|
ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
183
183
|
link: "text-primary underline-offset-4 [a&]:hover:underline",
|
|
184
|
-
|
|
184
|
+
// Pass/skip/pending are the quiet states: outline + coloured text, no
|
|
185
|
+
// fill, so a green report reads calm. Only `failed` keeps a tinted
|
|
186
|
+
// fill, making it the single loud badge on the page, so red pops the
|
|
187
|
+
// instant something breaks. Colour-as-accent, matching the KPI cards.
|
|
188
|
+
passed: "border-pass-border text-pass font-mono uppercase",
|
|
185
189
|
failed: "border-fail-border bg-fail-bg text-fail font-mono uppercase",
|
|
186
|
-
skipped: "border-skip-border
|
|
187
|
-
pending: "border-pend-border
|
|
188
|
-
tag: "border-
|
|
190
|
+
skipped: "border-skip-border text-skip font-mono uppercase",
|
|
191
|
+
pending: "border-pend-border text-pend font-mono uppercase",
|
|
192
|
+
tag: "border-border text-muted-foreground font-mono font-medium [a&]:hover:bg-muted"
|
|
189
193
|
}
|
|
190
194
|
},
|
|
191
195
|
defaultVariants: {
|
|
@@ -738,7 +742,7 @@ function ReportTrace({ spans }) {
|
|
|
738
742
|
{
|
|
739
743
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
740
744
|
style: { paddingLeft: `${row.depth * 12}px` },
|
|
741
|
-
title: row.statusMessage ? `${row.name}
|
|
745
|
+
title: row.statusMessage ? `${row.name}: ${row.statusMessage}` : row.name,
|
|
742
746
|
children: row.name
|
|
743
747
|
}
|
|
744
748
|
),
|
|
@@ -875,7 +879,7 @@ function Card({ className, ...props }) {
|
|
|
875
879
|
{
|
|
876
880
|
"data-slot": "card",
|
|
877
881
|
className: cn(
|
|
878
|
-
"flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-
|
|
882
|
+
"flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-xs",
|
|
879
883
|
className
|
|
880
884
|
),
|
|
881
885
|
...props
|
|
@@ -906,52 +910,89 @@ function CardContent({ className, ...props }) {
|
|
|
906
910
|
);
|
|
907
911
|
}
|
|
908
912
|
|
|
909
|
-
// src/components/
|
|
913
|
+
// src/components/ui/dropdown-menu.tsx
|
|
914
|
+
var React3 = require("react");
|
|
915
|
+
var import_menu = require("@base-ui/react/menu");
|
|
916
|
+
var import_lucide_react = require("lucide-react");
|
|
910
917
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
911
|
-
var
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
};
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
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";
|
|
919
|
+
function DropdownMenu(props) {
|
|
920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
921
|
+
}
|
|
922
|
+
function DropdownMenuTrigger(props) {
|
|
923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
924
|
+
}
|
|
925
|
+
function DropdownMenuContent({
|
|
926
|
+
className,
|
|
927
|
+
align = "end",
|
|
928
|
+
sideOffset = 4,
|
|
929
|
+
...props
|
|
930
|
+
}) {
|
|
931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_menu.Menu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
932
|
+
import_menu.Menu.Positioner,
|
|
933
|
+
{
|
|
934
|
+
"data-slot": "dropdown-menu-positioner",
|
|
935
|
+
className: "z-50",
|
|
936
|
+
align,
|
|
937
|
+
sideOffset,
|
|
938
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
939
|
+
import_menu.Menu.Popup,
|
|
940
|
+
{
|
|
941
|
+
"data-slot": "dropdown-menu-content",
|
|
942
|
+
className: cn(
|
|
943
|
+
"z-50 min-w-[11rem] origin-[var(--transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 font-sans text-sm text-popover-foreground shadow-md transition-[opacity,transform] data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
|
|
944
|
+
className
|
|
945
|
+
),
|
|
946
|
+
...props
|
|
947
|
+
}
|
|
948
|
+
)
|
|
949
|
+
}
|
|
950
|
+
) });
|
|
951
|
+
}
|
|
952
|
+
function DropdownMenuItem({
|
|
953
|
+
className,
|
|
954
|
+
...props
|
|
955
|
+
}) {
|
|
956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
957
|
+
import_menu.Menu.Item,
|
|
958
|
+
{
|
|
959
|
+
"data-slot": "dropdown-menu-item",
|
|
960
|
+
className: cn(itemClasses, className),
|
|
961
|
+
...props
|
|
962
|
+
}
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
// src/components/ReportScenario.tsx
|
|
967
|
+
var import_lucide_react2 = require("lucide-react");
|
|
968
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
969
|
+
var STATUS_META = {
|
|
970
|
+
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
971
|
+
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
972
|
+
skipped: { label: "Skipped", glyph: "\u25CB", glyphColor: "text-skip", badgeVariant: "skipped", showPill: true },
|
|
973
|
+
pending: { label: "Pending", glyph: "\u25CB", glyphColor: "text-pend", badgeVariant: "pending", showPill: true }
|
|
934
974
|
};
|
|
935
975
|
function ReportScenario({ scenario, hideTitle = false }) {
|
|
936
976
|
const titleId = `${scenario.id}-title`;
|
|
937
977
|
const bodyId = `${scenario.id}-body`;
|
|
938
|
-
const
|
|
978
|
+
const meta = STATUS_META[scenario.status];
|
|
979
|
+
const label = scenario.planned ? "Planned" : meta.label;
|
|
939
980
|
const collapse = useCollapse();
|
|
940
981
|
const collapsible = collapse !== null && !hideTitle;
|
|
941
982
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
942
983
|
const actions = useScenarioActions();
|
|
943
|
-
return /* @__PURE__ */ (0,
|
|
984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
944
985
|
Card,
|
|
945
986
|
{
|
|
946
987
|
id: scenario.id,
|
|
947
988
|
"data-status": scenario.status,
|
|
948
|
-
...hideTitle ? { "aria-label": `${scenario.title}
|
|
989
|
+
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
949
990
|
className: "gap-0 py-0",
|
|
950
991
|
children: [
|
|
951
|
-
/* @__PURE__ */ (0,
|
|
952
|
-
/* @__PURE__ */ (0,
|
|
953
|
-
hideTitle ? null : /* @__PURE__ */ (0,
|
|
954
|
-
collapsible ? /* @__PURE__ */ (0,
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CardHeader, { className: "px-4 py-3", children: [
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
994
|
+
hideTitle ? null : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
995
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
955
996
|
"button",
|
|
956
997
|
{
|
|
957
998
|
type: "button",
|
|
@@ -960,60 +1001,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
960
1001
|
"aria-controls": bodyId,
|
|
961
1002
|
"aria-label": `Toggle ${scenario.title}`,
|
|
962
1003
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
963
|
-
children: /* @__PURE__ */ (0,
|
|
1004
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
964
1005
|
}
|
|
965
1006
|
) : null,
|
|
966
|
-
/* @__PURE__ */ (0,
|
|
967
|
-
/* @__PURE__ */ (0,
|
|
1007
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1008
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: scenario.title })
|
|
968
1009
|
] }),
|
|
969
|
-
/* @__PURE__ */ (0,
|
|
970
|
-
/* @__PURE__ */ (0,
|
|
971
|
-
scenario.durationMs > 0 ? /* @__PURE__ */ (0,
|
|
972
|
-
/* @__PURE__ */ (0,
|
|
973
|
-
actions ? /* @__PURE__ */ (0,
|
|
974
|
-
/* @__PURE__ */ (0,
|
|
975
|
-
|
|
976
|
-
{
|
|
977
|
-
type: "button",
|
|
978
|
-
onClick: () => actions.copyLink(scenario),
|
|
979
|
-
"aria-label": `Copy link to ${scenario.title}`,
|
|
980
|
-
title: "Copy permalink",
|
|
981
|
-
className: "cursor-pointer rounded px-1 py-0.5 font-mono text-[0.625rem] text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
982
|
-
children: "link"
|
|
983
|
-
}
|
|
984
|
-
),
|
|
985
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
986
|
-
"button",
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1012
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1013
|
+
meta.showPill ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1014
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DropdownMenu, { children: [
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1016
|
+
DropdownMenuTrigger,
|
|
987
1017
|
{
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
"aria-
|
|
991
|
-
title: "Copy as Markdown",
|
|
992
|
-
className: "cursor-pointer rounded px-1 py-0.5 font-mono text-[0.625rem] text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
993
|
-
children: "md"
|
|
1018
|
+
"aria-label": `Actions for ${scenario.title}`,
|
|
1019
|
+
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1020
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react2.MoreHorizontalIcon, { "aria-hidden": true })
|
|
994
1021
|
}
|
|
995
1022
|
),
|
|
996
|
-
/* @__PURE__ */ (0,
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1023
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react2.LinkIcon, {}),
|
|
1026
|
+
" Copy link"
|
|
1027
|
+
] }),
|
|
1028
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1029
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react2.FileTextIcon, {}),
|
|
1030
|
+
" Copy as Markdown"
|
|
1031
|
+
] }),
|
|
1032
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react2.SparklesIcon, {}),
|
|
1034
|
+
" Explain with AI"
|
|
1035
|
+
] })
|
|
1036
|
+
] })
|
|
1007
1037
|
] }) : null
|
|
1008
1038
|
] })
|
|
1009
1039
|
] }),
|
|
1010
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0,
|
|
1011
|
-
scenario.tags.map((t) => /* @__PURE__ */ (0,
|
|
1012
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0,
|
|
1040
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1041
|
+
scenario.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1042
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("li", { children: ticket.url ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1013
1043
|
] }) : null
|
|
1014
1044
|
] }),
|
|
1015
|
-
/* @__PURE__ */ (0,
|
|
1016
|
-
scenario.errorMessage ? /* @__PURE__ */ (0,
|
|
1045
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1046
|
+
scenario.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1017
1047
|
"pre",
|
|
1018
1048
|
{
|
|
1019
1049
|
role: "alert",
|
|
@@ -1021,10 +1051,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1021
1051
|
children: scenario.errorMessage
|
|
1022
1052
|
}
|
|
1023
1053
|
) : null,
|
|
1024
|
-
/* @__PURE__ */ (0,
|
|
1025
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0,
|
|
1026
|
-
/* @__PURE__ */ (0,
|
|
1027
|
-
/* @__PURE__ */ (0,
|
|
1054
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReportSteps, { scenario }),
|
|
1055
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1056
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReportAttachments, { attachments: scenario.attachments }),
|
|
1057
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReportTrace, { spans: scenario.otelSpans })
|
|
1028
1058
|
] })
|
|
1029
1059
|
]
|
|
1030
1060
|
}
|
|
@@ -1032,13 +1062,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1032
1062
|
}
|
|
1033
1063
|
|
|
1034
1064
|
// src/components/ReportScenarioList.tsx
|
|
1035
|
-
var
|
|
1065
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1036
1066
|
function ReportScenarioList({ feature }) {
|
|
1037
|
-
return /* @__PURE__ */ (0,
|
|
1067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReportScenario, { scenario }, scenario.id)) });
|
|
1038
1068
|
}
|
|
1039
1069
|
|
|
1040
1070
|
// src/components/ReportFeature.tsx
|
|
1041
|
-
var
|
|
1071
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1042
1072
|
function ReportFeature({ feature }) {
|
|
1043
1073
|
const titleId = `${feature.id}-title`;
|
|
1044
1074
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1046,74 +1076,80 @@ function ReportFeature({ feature }) {
|
|
|
1046
1076
|
const skipped = s.skipped + s.pending;
|
|
1047
1077
|
const collapse = useCollapse();
|
|
1048
1078
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1049
|
-
return
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
"
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1079
|
+
return (
|
|
1080
|
+
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1081
|
+
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1082
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1083
|
+
"section",
|
|
1084
|
+
{
|
|
1085
|
+
id: feature.id,
|
|
1086
|
+
"data-slot": "feature",
|
|
1087
|
+
"aria-labelledby": titleId,
|
|
1088
|
+
className: "flex flex-col gap-3",
|
|
1089
|
+
children: [
|
|
1090
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1091
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0", children: [
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1093
|
+
"button",
|
|
1094
|
+
{
|
|
1095
|
+
type: "button",
|
|
1096
|
+
onClick: () => collapse.toggle(feature.id),
|
|
1097
|
+
"aria-expanded": !collapsed,
|
|
1098
|
+
"aria-controls": bodyId,
|
|
1099
|
+
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1100
|
+
children: [
|
|
1101
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1102
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "truncate", children: feature.title })
|
|
1103
|
+
]
|
|
1104
|
+
}
|
|
1105
|
+
) : feature.title }),
|
|
1106
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1107
|
+
] }),
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1109
|
+
"p",
|
|
1061
1110
|
{
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1111
|
+
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1112
|
+
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1113
|
+
children: [
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
|
|
1115
|
+
s.passed,
|
|
1116
|
+
" passed"
|
|
1117
|
+
] }),
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1119
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1120
|
+
s.failed,
|
|
1121
|
+
" failed"
|
|
1122
|
+
] }),
|
|
1123
|
+
skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
1124
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
|
|
1126
|
+
skipped,
|
|
1127
|
+
" skipped"
|
|
1128
|
+
] })
|
|
1129
|
+
] }) : null
|
|
1130
|
+
]
|
|
1069
1131
|
}
|
|
1070
|
-
)
|
|
1071
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "min-w-0", children: [
|
|
1072
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { id: titleId, className: "text-sm font-semibold tracking-tight text-foreground", children: feature.title }),
|
|
1073
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "mt-0.5 truncate font-mono text-xs text-muted-foreground", children: feature.sourceFile })
|
|
1074
|
-
] })
|
|
1132
|
+
)
|
|
1075
1133
|
] }),
|
|
1076
|
-
/* @__PURE__ */ (0,
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
className: "flex shrink-0 items-center gap-2.5 font-mono text-xs font-medium",
|
|
1081
|
-
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1082
|
-
children: [
|
|
1083
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { "aria-hidden": true, className: "text-pass", children: [
|
|
1084
|
-
"\u2713",
|
|
1085
|
-
s.passed
|
|
1086
|
-
] }),
|
|
1087
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { "aria-hidden": true, className: "text-fail", children: [
|
|
1088
|
-
"\u2717",
|
|
1089
|
-
s.failed
|
|
1090
|
-
] }),
|
|
1091
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { "aria-hidden": true, className: "text-skip", children: [
|
|
1092
|
-
"\u25CB",
|
|
1093
|
-
skipped
|
|
1094
|
-
] })
|
|
1095
|
-
]
|
|
1096
|
-
}
|
|
1097
|
-
)
|
|
1098
|
-
] }),
|
|
1099
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-2 p-3", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReportScenarioList, { feature }) })
|
|
1100
|
-
]
|
|
1101
|
-
}
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReportScenarioList, { feature }) })
|
|
1135
|
+
]
|
|
1136
|
+
}
|
|
1137
|
+
)
|
|
1102
1138
|
);
|
|
1103
1139
|
}
|
|
1104
1140
|
|
|
1105
1141
|
// src/components/ReportFeatureList.tsx
|
|
1106
|
-
var
|
|
1142
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1107
1143
|
function ReportFeatureList() {
|
|
1108
1144
|
const report = useReport();
|
|
1109
|
-
return /* @__PURE__ */ (0,
|
|
1145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportFeature, { feature }, feature.id)) });
|
|
1110
1146
|
}
|
|
1111
1147
|
|
|
1112
1148
|
// src/components/ui/empty.tsx
|
|
1113
1149
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
1114
|
-
var
|
|
1150
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1115
1151
|
function Empty({ className, ...props }) {
|
|
1116
|
-
return /* @__PURE__ */ (0,
|
|
1152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1117
1153
|
"div",
|
|
1118
1154
|
{
|
|
1119
1155
|
"data-slot": "empty",
|
|
@@ -1126,7 +1162,7 @@ function Empty({ className, ...props }) {
|
|
|
1126
1162
|
);
|
|
1127
1163
|
}
|
|
1128
1164
|
function EmptyHeader({ className, ...props }) {
|
|
1129
|
-
return /* @__PURE__ */ (0,
|
|
1165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1130
1166
|
"div",
|
|
1131
1167
|
{
|
|
1132
1168
|
"data-slot": "empty-header",
|
|
@@ -1153,7 +1189,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
|
|
|
1153
1189
|
}
|
|
1154
1190
|
);
|
|
1155
1191
|
function EmptyTitle({ className, ...props }) {
|
|
1156
|
-
return /* @__PURE__ */ (0,
|
|
1192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1157
1193
|
"div",
|
|
1158
1194
|
{
|
|
1159
1195
|
"data-slot": "empty-title",
|
|
@@ -1164,16 +1200,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1164
1200
|
}
|
|
1165
1201
|
|
|
1166
1202
|
// src/components/ReportEmpty.tsx
|
|
1167
|
-
var
|
|
1203
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1168
1204
|
function ReportEmpty({ message }) {
|
|
1169
|
-
return /* @__PURE__ */ (0,
|
|
1205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1170
1206
|
}
|
|
1171
1207
|
|
|
1172
1208
|
// src/components/ReportSummary.tsx
|
|
1173
|
-
var
|
|
1209
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1174
1210
|
function ReportSummary({ className }) {
|
|
1175
1211
|
const report = useReport();
|
|
1176
|
-
return /* @__PURE__ */ (0,
|
|
1212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1177
1213
|
ReportSummaryView,
|
|
1178
1214
|
{
|
|
1179
1215
|
summary: report.summary,
|
|
@@ -1182,38 +1218,54 @@ function ReportSummary({ className }) {
|
|
|
1182
1218
|
}
|
|
1183
1219
|
);
|
|
1184
1220
|
}
|
|
1221
|
+
var TONE = {
|
|
1222
|
+
total: { num: "text-foreground", dot: "bg-muted-foreground/50" },
|
|
1223
|
+
passed: { num: "text-pass", dot: "bg-pass" },
|
|
1224
|
+
failed: { num: "text-fail", dot: "bg-fail" },
|
|
1225
|
+
skipped: { num: "text-skip", dot: "bg-skip" },
|
|
1226
|
+
pending: { num: "text-pend", dot: "bg-pend" }
|
|
1227
|
+
};
|
|
1185
1228
|
function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1229
|
+
const cards = [
|
|
1230
|
+
{ status: "total", label: "Total", value: summary.total },
|
|
1231
|
+
{ status: "passed", label: "Passed", value: summary.passed },
|
|
1232
|
+
{ status: "failed", label: "Failed", value: summary.failed },
|
|
1233
|
+
{ status: "skipped", label: "Skipped", value: summary.skipped }
|
|
1234
|
+
];
|
|
1235
|
+
if (summary.pending > 0) {
|
|
1236
|
+
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1237
|
+
}
|
|
1238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1239
|
+
"dl",
|
|
1240
|
+
{
|
|
1241
|
+
className: cn(
|
|
1242
|
+
"grid grid-cols-2 gap-3",
|
|
1243
|
+
// Columns follow the card count so the row is always full — 5 statuses
|
|
1244
|
+
// (pending present) never leave a lone orphan card below a row of four.
|
|
1245
|
+
cards.length === 5 ? "sm:grid-cols-5" : "sm:grid-cols-4",
|
|
1246
|
+
className
|
|
1247
|
+
),
|
|
1248
|
+
"aria-label": ariaLabel,
|
|
1249
|
+
children: cards.map((c) => {
|
|
1250
|
+
const tone = TONE[c.status];
|
|
1251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1252
|
+
"div",
|
|
1253
|
+
{
|
|
1254
|
+
"data-status": c.status,
|
|
1255
|
+
className: "rounded-lg border bg-card px-4 py-3",
|
|
1256
|
+
children: [
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1258
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1259
|
+
c.label
|
|
1260
|
+
] }),
|
|
1261
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1262
|
+
]
|
|
1263
|
+
},
|
|
1264
|
+
c.status
|
|
1265
|
+
);
|
|
1266
|
+
})
|
|
1267
|
+
}
|
|
1268
|
+
);
|
|
1217
1269
|
}
|
|
1218
1270
|
|
|
1219
1271
|
// src/lib/provenance.ts
|
|
@@ -1266,7 +1318,7 @@ function prUrl(ci) {
|
|
|
1266
1318
|
}
|
|
1267
1319
|
|
|
1268
1320
|
// src/components/ReportMeta.tsx
|
|
1269
|
-
var
|
|
1321
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1270
1322
|
function ReportMeta() {
|
|
1271
1323
|
const report = useReport();
|
|
1272
1324
|
const items = [];
|
|
@@ -1289,13 +1341,13 @@ function ReportMeta() {
|
|
|
1289
1341
|
const short = sha.slice(0, 8);
|
|
1290
1342
|
items.push({
|
|
1291
1343
|
label: "Commit",
|
|
1292
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1344
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1293
1345
|
});
|
|
1294
1346
|
}
|
|
1295
1347
|
if (report.ci) {
|
|
1296
1348
|
items.push({
|
|
1297
1349
|
label: "CI",
|
|
1298
|
-
value: report.ci.url ? /* @__PURE__ */ (0,
|
|
1350
|
+
value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1299
1351
|
ciDisplayName(report.ci.name),
|
|
1300
1352
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1301
1353
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1306,45 +1358,56 @@ function ReportMeta() {
|
|
|
1306
1358
|
const label = `#${report.ci.prNumber}`;
|
|
1307
1359
|
items.push({
|
|
1308
1360
|
label: "PR",
|
|
1309
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1361
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1310
1362
|
});
|
|
1311
1363
|
}
|
|
1312
1364
|
if (items.length === 0) return null;
|
|
1313
|
-
return
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1365
|
+
return (
|
|
1366
|
+
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1367
|
+
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1368
|
+
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1372
|
+
"Run details"
|
|
1373
|
+
] }),
|
|
1374
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dt", { className: "font-medium", children: item.label }),
|
|
1376
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1377
|
+
] }, item.label)) })
|
|
1378
|
+
] })
|
|
1379
|
+
);
|
|
1317
1380
|
}
|
|
1318
1381
|
|
|
1319
1382
|
// src/components/ReportSchemaError.tsx
|
|
1320
|
-
var
|
|
1383
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1321
1384
|
function ReportSchemaError({ error }) {
|
|
1322
|
-
return /* @__PURE__ */ (0,
|
|
1323
|
-
/* @__PURE__ */ (0,
|
|
1324
|
-
/* @__PURE__ */ (0,
|
|
1325
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0,
|
|
1385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: "Report could not be displayed." }) }),
|
|
1387
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { children: error.message }),
|
|
1388
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { children: [
|
|
1326
1389
|
"The report bundle is newer than this version of ",
|
|
1327
|
-
/* @__PURE__ */ (0,
|
|
1390
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("code", { children: "executable-stories-react" }),
|
|
1328
1391
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1329
1392
|
] }) : null,
|
|
1330
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0,
|
|
1331
|
-
/* @__PURE__ */ (0,
|
|
1393
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("details", { children: [
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("summary", { children: [
|
|
1332
1395
|
error.issues.length,
|
|
1333
1396
|
" validation issue",
|
|
1334
1397
|
error.issues.length === 1 ? "" : "s"
|
|
1335
1398
|
] }),
|
|
1336
|
-
/* @__PURE__ */ (0,
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1337
1400
|
] }) : null
|
|
1338
1401
|
] });
|
|
1339
1402
|
}
|
|
1340
1403
|
|
|
1341
1404
|
// src/components/ReportShell.tsx
|
|
1342
|
-
var
|
|
1405
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1343
1406
|
function ReportTitleBlock({ title }) {
|
|
1344
|
-
return /* @__PURE__ */ (0,
|
|
1345
|
-
/* @__PURE__ */ (0,
|
|
1346
|
-
/* @__PURE__ */ (0,
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h1", { children: title ?? "Story Report" }),
|
|
1409
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ReportSummary, {}),
|
|
1410
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ReportMeta, {})
|
|
1348
1411
|
] });
|
|
1349
1412
|
}
|
|
1350
1413
|
function ReportErrorShell({
|
|
@@ -1353,28 +1416,28 @@ function ReportErrorShell({
|
|
|
1353
1416
|
title,
|
|
1354
1417
|
dataTheme
|
|
1355
1418
|
}) {
|
|
1356
|
-
return /* @__PURE__ */ (0,
|
|
1419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ReportSchemaError, { error }) });
|
|
1357
1420
|
}
|
|
1358
1421
|
|
|
1359
1422
|
// src/components/Report.tsx
|
|
1360
|
-
var
|
|
1423
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1361
1424
|
function Report(props) {
|
|
1362
1425
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1363
1426
|
const result = unwrapReport(report);
|
|
1364
1427
|
if (!result.ok) {
|
|
1365
|
-
return /* @__PURE__ */ (0,
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1366
1429
|
}
|
|
1367
1430
|
const data = result.data;
|
|
1368
1431
|
const hasContent = data.features.length > 0;
|
|
1369
|
-
return /* @__PURE__ */ (0,
|
|
1370
|
-
/* @__PURE__ */ (0,
|
|
1371
|
-
hasContent ? /* @__PURE__ */ (0,
|
|
1432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("header", { className: "es-report-header", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ReportTitleBlock, { title }) }),
|
|
1434
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ReportFeatureList, {}) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ReportEmpty, {})
|
|
1372
1435
|
] }) });
|
|
1373
1436
|
}
|
|
1374
1437
|
|
|
1375
1438
|
// src/components/doc/MermaidView.tsx
|
|
1376
1439
|
var import_react8 = require("react");
|
|
1377
|
-
var
|
|
1440
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1378
1441
|
function prefersDark(el) {
|
|
1379
1442
|
const themed = el?.closest("[data-theme]");
|
|
1380
1443
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1411,9 +1474,9 @@ function MermaidView({ entry, load }) {
|
|
|
1411
1474
|
};
|
|
1412
1475
|
}, [entry.code, load]);
|
|
1413
1476
|
if (svg) {
|
|
1414
|
-
return /* @__PURE__ */ (0,
|
|
1415
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
1416
|
-
/* @__PURE__ */ (0,
|
|
1477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("figure", { ref, className: "my-3", children: [
|
|
1478
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1479
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1417
1480
|
"div",
|
|
1418
1481
|
{
|
|
1419
1482
|
role: "img",
|
|
@@ -1424,33 +1487,33 @@ function MermaidView({ entry, load }) {
|
|
|
1424
1487
|
)
|
|
1425
1488
|
] });
|
|
1426
1489
|
}
|
|
1427
|
-
return /* @__PURE__ */ (0,
|
|
1490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MermaidSource, { entry, ref });
|
|
1428
1491
|
}
|
|
1429
1492
|
|
|
1430
1493
|
// src/components/doc/MermaidDiagram.tsx
|
|
1431
|
-
var
|
|
1494
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1432
1495
|
var mermaidLoader;
|
|
1433
1496
|
function loadMermaid() {
|
|
1434
1497
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1435
1498
|
return mermaidLoader;
|
|
1436
1499
|
}
|
|
1437
1500
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1438
|
-
return /* @__PURE__ */ (0,
|
|
1501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MermaidView, { entry, load });
|
|
1439
1502
|
}
|
|
1440
1503
|
|
|
1441
1504
|
// src/components/ScenarioExplorer.tsx
|
|
1442
1505
|
var import_react9 = require("react");
|
|
1443
1506
|
|
|
1444
1507
|
// src/components/ui/command.tsx
|
|
1445
|
-
var
|
|
1508
|
+
var React4 = require("react");
|
|
1446
1509
|
var import_cmdk = require("cmdk");
|
|
1447
|
-
var
|
|
1448
|
-
var
|
|
1510
|
+
var import_lucide_react3 = require("lucide-react");
|
|
1511
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1449
1512
|
function Command({
|
|
1450
1513
|
className,
|
|
1451
1514
|
...props
|
|
1452
1515
|
}) {
|
|
1453
|
-
return /* @__PURE__ */ (0,
|
|
1516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1454
1517
|
import_cmdk.Command,
|
|
1455
1518
|
{
|
|
1456
1519
|
"data-slot": "command",
|
|
@@ -1466,14 +1529,14 @@ function CommandInput({
|
|
|
1466
1529
|
className,
|
|
1467
1530
|
...props
|
|
1468
1531
|
}) {
|
|
1469
|
-
return /* @__PURE__ */ (0,
|
|
1532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
1470
1533
|
"div",
|
|
1471
1534
|
{
|
|
1472
1535
|
"data-slot": "command-input-wrapper",
|
|
1473
1536
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1474
1537
|
children: [
|
|
1475
|
-
/* @__PURE__ */ (0,
|
|
1476
|
-
/* @__PURE__ */ (0,
|
|
1538
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react3.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1539
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1477
1540
|
import_cmdk.Command.Input,
|
|
1478
1541
|
{
|
|
1479
1542
|
"data-slot": "command-input",
|
|
@@ -1492,7 +1555,7 @@ function CommandList({
|
|
|
1492
1555
|
className,
|
|
1493
1556
|
...props
|
|
1494
1557
|
}) {
|
|
1495
|
-
return /* @__PURE__ */ (0,
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1496
1559
|
import_cmdk.Command.List,
|
|
1497
1560
|
{
|
|
1498
1561
|
"data-slot": "command-list",
|
|
@@ -1507,7 +1570,7 @@ function CommandList({
|
|
|
1507
1570
|
function CommandEmpty({
|
|
1508
1571
|
...props
|
|
1509
1572
|
}) {
|
|
1510
|
-
return /* @__PURE__ */ (0,
|
|
1573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1511
1574
|
import_cmdk.Command.Empty,
|
|
1512
1575
|
{
|
|
1513
1576
|
"data-slot": "command-empty",
|
|
@@ -1520,7 +1583,7 @@ function CommandGroup({
|
|
|
1520
1583
|
className,
|
|
1521
1584
|
...props
|
|
1522
1585
|
}) {
|
|
1523
|
-
return /* @__PURE__ */ (0,
|
|
1586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1524
1587
|
import_cmdk.Command.Group,
|
|
1525
1588
|
{
|
|
1526
1589
|
"data-slot": "command-group",
|
|
@@ -1536,7 +1599,7 @@ function CommandItem({
|
|
|
1536
1599
|
className,
|
|
1537
1600
|
...props
|
|
1538
1601
|
}) {
|
|
1539
|
-
return /* @__PURE__ */ (0,
|
|
1602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1540
1603
|
import_cmdk.Command.Item,
|
|
1541
1604
|
{
|
|
1542
1605
|
"data-slot": "command-item",
|
|
@@ -1550,7 +1613,7 @@ function CommandItem({
|
|
|
1550
1613
|
}
|
|
1551
1614
|
|
|
1552
1615
|
// src/components/ScenarioExplorer.tsx
|
|
1553
|
-
var
|
|
1616
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1554
1617
|
var STATUS_FILTERS = [
|
|
1555
1618
|
{ value: "all", label: "All" },
|
|
1556
1619
|
{ value: "passed", label: "Passed" },
|
|
@@ -1561,22 +1624,22 @@ var STATUS_FILTERS = [
|
|
|
1561
1624
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1562
1625
|
const [status, setStatus] = (0, import_react9.useState)("all");
|
|
1563
1626
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1564
|
-
return /* @__PURE__ */ (0,
|
|
1565
|
-
summary ? /* @__PURE__ */ (0,
|
|
1627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "font-sans text-foreground", children: [
|
|
1628
|
+
summary ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1566
1629
|
summary.total,
|
|
1567
1630
|
" scenarios \xB7 ",
|
|
1568
|
-
/* @__PURE__ */ (0,
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-pass", children: [
|
|
1569
1632
|
summary.passed,
|
|
1570
1633
|
" passed"
|
|
1571
1634
|
] }),
|
|
1572
1635
|
" \xB7",
|
|
1573
1636
|
" ",
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1637
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-fail", children: [
|
|
1575
1638
|
summary.failed,
|
|
1576
1639
|
" failed"
|
|
1577
1640
|
] })
|
|
1578
1641
|
] }) : null,
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1642
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1580
1643
|
"button",
|
|
1581
1644
|
{
|
|
1582
1645
|
type: "button",
|
|
@@ -1591,26 +1654,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1591
1654
|
},
|
|
1592
1655
|
f.value
|
|
1593
1656
|
)) }),
|
|
1594
|
-
/* @__PURE__ */ (0,
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
1595
1658
|
Command,
|
|
1596
1659
|
{
|
|
1597
1660
|
className: "rounded-lg border border-border bg-card",
|
|
1598
1661
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1599
1662
|
children: [
|
|
1600
|
-
/* @__PURE__ */ (0,
|
|
1601
|
-
/* @__PURE__ */ (0,
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
1603
|
-
/* @__PURE__ */ (0,
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(CommandList, { className: "max-h-none", children: [
|
|
1665
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1604
1667
|
CommandItem,
|
|
1605
1668
|
{
|
|
1606
1669
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1607
1670
|
asChild: true,
|
|
1608
1671
|
className: "cursor-pointer",
|
|
1609
|
-
children: /* @__PURE__ */ (0,
|
|
1610
|
-
/* @__PURE__ */ (0,
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1612
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0,
|
|
1613
|
-
/* @__PURE__ */ (0,
|
|
1672
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
1673
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Badge, { variant: s.status, children: s.status }),
|
|
1674
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
1675
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
1614
1677
|
] })
|
|
1615
1678
|
},
|
|
1616
1679
|
s.id
|