executable-stories-react 0.5.0 → 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.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +141 -14
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.js +141 -14
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +26 -21
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js.map +1 -1
- package/package.json +1 -1
package/dist/interactive.js
CHANGED
|
@@ -202,7 +202,7 @@ function DocTable({ entry }) {
|
|
|
202
202
|
entry.label ? /* @__PURE__ */ jsx6("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
203
203
|
/* @__PURE__ */ jsx6("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs3("table", { className: "w-full border-collapse text-sm", children: [
|
|
204
204
|
/* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsx6("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ jsx6("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
205
|
-
/* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((
|
|
205
|
+
/* @__PURE__ */ jsx6("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx6("tr", { children: row.map((cell2, j) => /* @__PURE__ */ jsx6("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell2 }, j)) }, i)) })
|
|
206
206
|
] }) })
|
|
207
207
|
] });
|
|
208
208
|
}
|
|
@@ -855,20 +855,118 @@ function useCollapseState(computeDefault) {
|
|
|
855
855
|
|
|
856
856
|
// src/interactive/scenario-actions.tsx
|
|
857
857
|
import { createContext as createContext4, useContext as useContext5 } from "react";
|
|
858
|
+
|
|
859
|
+
// ../executable-stories-core/dist/utils/scenario-markdown.js
|
|
860
|
+
function cell(value) {
|
|
861
|
+
return value.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
862
|
+
}
|
|
863
|
+
function stringify(value) {
|
|
864
|
+
if (typeof value === "string") return value;
|
|
865
|
+
try {
|
|
866
|
+
return JSON.stringify(value, null, 2) ?? String(value);
|
|
867
|
+
} catch {
|
|
868
|
+
return String(value);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
function docEntryToMarkdown(entry) {
|
|
872
|
+
const lines = [];
|
|
873
|
+
switch (entry.kind) {
|
|
874
|
+
case "note":
|
|
875
|
+
lines.push(entry.text);
|
|
876
|
+
break;
|
|
877
|
+
case "tag":
|
|
878
|
+
lines.push(entry.names.map((n) => `\`@${n}\``).join(" "));
|
|
879
|
+
break;
|
|
880
|
+
case "kv":
|
|
881
|
+
lines.push(`**${entry.label}:** ${stringify(entry.value)}`);
|
|
882
|
+
break;
|
|
883
|
+
case "code":
|
|
884
|
+
lines.push(`**${entry.label}**`, "", "```" + (entry.lang ?? ""), entry.content, "```");
|
|
885
|
+
break;
|
|
886
|
+
case "table": {
|
|
887
|
+
lines.push(`**${entry.label}**`, "");
|
|
888
|
+
lines.push(`| ${entry.columns.map(cell).join(" | ")} |`);
|
|
889
|
+
lines.push(`| ${entry.columns.map(() => "---").join(" | ")} |`);
|
|
890
|
+
for (const row of entry.rows) lines.push(`| ${row.map(cell).join(" | ")} |`);
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
case "link":
|
|
894
|
+
lines.push(`[${entry.label}](${entry.url})`);
|
|
895
|
+
break;
|
|
896
|
+
case "section":
|
|
897
|
+
lines.push(`### ${entry.title}`, "", entry.markdown);
|
|
898
|
+
break;
|
|
899
|
+
case "mermaid":
|
|
900
|
+
if (entry.title) lines.push(`**${entry.title}**`, "");
|
|
901
|
+
lines.push("```mermaid", entry.code, "```");
|
|
902
|
+
break;
|
|
903
|
+
case "screenshot":
|
|
904
|
+
lines.push(``);
|
|
905
|
+
break;
|
|
906
|
+
case "video":
|
|
907
|
+
lines.push(`Video: ${entry.path}${entry.caption ? ` \u2014 ${entry.caption}` : ""}`);
|
|
908
|
+
break;
|
|
909
|
+
case "html": {
|
|
910
|
+
const htmlTitle = entry.title ?? "Embedded HTML";
|
|
911
|
+
if (entry.content) {
|
|
912
|
+
lines.push(`**${htmlTitle}**`, "", "```html", entry.content, "```");
|
|
913
|
+
} else if (entry.url) {
|
|
914
|
+
lines.push(`[${htmlTitle}](${entry.url})`);
|
|
915
|
+
} else {
|
|
916
|
+
lines.push(`Embedded HTML: ${entry.path ?? "(inline)"}`);
|
|
917
|
+
}
|
|
918
|
+
break;
|
|
919
|
+
}
|
|
920
|
+
case "custom":
|
|
921
|
+
lines.push(`**${entry.type}**`, "", "```json", stringify(entry.data), "```");
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
for (const child of entry.children ?? []) {
|
|
925
|
+
lines.push("", ...docEntryToMarkdown(child));
|
|
926
|
+
}
|
|
927
|
+
return lines;
|
|
928
|
+
}
|
|
929
|
+
function stepLines(step, ordinal, full) {
|
|
930
|
+
const status = step.status === "passed" ? "" : ` \u2014 **${step.status}**`;
|
|
931
|
+
const lines = [`${ordinal}. **${step.keyword}** ${step.text}${status}`];
|
|
932
|
+
if (!full) return lines;
|
|
933
|
+
if (step.errorMessage) {
|
|
934
|
+
lines.push(...step.errorMessage.split("\n").map((l) => ` > ${l}`));
|
|
935
|
+
}
|
|
936
|
+
for (const entry of step.docEntries) {
|
|
937
|
+
lines.push("", ...docEntryToMarkdown(entry).map((l) => l === "" ? l : ` ${l}`));
|
|
938
|
+
}
|
|
939
|
+
return lines;
|
|
940
|
+
}
|
|
941
|
+
function scenarioToMarkdown(scenario, options = {}) {
|
|
942
|
+
const { variant = "full", meta = [] } = options;
|
|
943
|
+
const full = variant === "full";
|
|
944
|
+
const lines = full ? [`# ${scenario.title}`, ""] : [`## ${scenario.title} _(${scenario.status})_`, ""];
|
|
945
|
+
if (full && meta.length > 0) lines.push(...meta);
|
|
946
|
+
if (scenario.steps.length > 0) {
|
|
947
|
+
if (full) lines.push("", "## Steps", "");
|
|
948
|
+
scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full)));
|
|
949
|
+
}
|
|
950
|
+
if (scenario.errorMessage) {
|
|
951
|
+
if (full) lines.push("", "## Failure", "");
|
|
952
|
+
else lines.push("");
|
|
953
|
+
lines.push("```", scenario.errorMessage.trim(), "```");
|
|
954
|
+
}
|
|
955
|
+
if (full && scenario.docEntries.length > 0) {
|
|
956
|
+
lines.push("", "## Docs", "");
|
|
957
|
+
for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry), "");
|
|
958
|
+
}
|
|
959
|
+
return lines.join("\n").replaceAll(/\n{3,}/g, "\n\n").trimEnd() + (full ? "\n" : "");
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// src/interactive/scenario-actions.tsx
|
|
858
963
|
var ScenarioActionsContext = createContext4(null);
|
|
859
964
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
860
965
|
function useScenarioActions() {
|
|
861
966
|
return useContext5(ScenarioActionsContext);
|
|
862
967
|
}
|
|
863
|
-
function
|
|
864
|
-
|
|
865
|
-
for (const step of scenario.steps) {
|
|
866
|
-
lines.push(`- **${step.keyword}** ${step.text}`);
|
|
867
|
-
}
|
|
868
|
-
if (scenario.errorMessage) {
|
|
869
|
-
lines.push("", "```", scenario.errorMessage.trim(), "```");
|
|
870
|
-
}
|
|
871
|
-
return lines.join("\n");
|
|
968
|
+
function scenarioToMarkdown2(scenario) {
|
|
969
|
+
return scenarioToMarkdown(scenario, { variant: "compact" });
|
|
872
970
|
}
|
|
873
971
|
function scenarioToPrompt(scenario) {
|
|
874
972
|
const lines = [
|
|
@@ -2036,6 +2134,33 @@ function listFailures(report) {
|
|
|
2036
2134
|
return out;
|
|
2037
2135
|
}
|
|
2038
2136
|
|
|
2137
|
+
// src/interactive/triage-default.ts
|
|
2138
|
+
function needsAttention(status) {
|
|
2139
|
+
return status === "failed";
|
|
2140
|
+
}
|
|
2141
|
+
function defaultCollapsedIds(report) {
|
|
2142
|
+
const collapsed = /* @__PURE__ */ new Set();
|
|
2143
|
+
if (report.summary.failed === 0) return collapsed;
|
|
2144
|
+
for (const feature of report.features) {
|
|
2145
|
+
const featureHasFailure = feature.scenarios.some((s) => needsAttention(s.status));
|
|
2146
|
+
if (!featureHasFailure) collapsed.add(feature.id);
|
|
2147
|
+
for (const scenario of feature.scenarios) {
|
|
2148
|
+
if (!needsAttention(scenario.status)) collapsed.add(scenario.id);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
return collapsed;
|
|
2152
|
+
}
|
|
2153
|
+
function failuresFirst(report) {
|
|
2154
|
+
if (report.summary.failed === 0) return report;
|
|
2155
|
+
const withFailures = [];
|
|
2156
|
+
const rest = [];
|
|
2157
|
+
for (const feature of report.features) {
|
|
2158
|
+
(feature.scenarios.some((s) => needsAttention(s.status)) ? withFailures : rest).push(feature);
|
|
2159
|
+
}
|
|
2160
|
+
if (withFailures.length === 0) return report;
|
|
2161
|
+
return { ...report, features: [...withFailures, ...rest] };
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2039
2164
|
// src/interactive/ReportFilters.tsx
|
|
2040
2165
|
import { useState as useState3 } from "react";
|
|
2041
2166
|
import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
@@ -2326,7 +2451,9 @@ function ReportInteractiveView({
|
|
|
2326
2451
|
const deferredQuery = useDeferredValue(query);
|
|
2327
2452
|
const failures = useMemo3(() => listFailures(report), [report]);
|
|
2328
2453
|
const filtered = useMemo3(
|
|
2329
|
-
|
|
2454
|
+
// Features carrying failures float to the top so the first thing on screen
|
|
2455
|
+
// is the thing that needs attention; an all-green run keeps source order.
|
|
2456
|
+
() => failuresFirst(filterReport(report, { query: deferredQuery, status: statusFilter, tags: activeTags })),
|
|
2330
2457
|
[report, deferredQuery, statusFilter, activeTags]
|
|
2331
2458
|
);
|
|
2332
2459
|
const isFiltering = query !== deferredQuery;
|
|
@@ -2364,7 +2491,7 @@ function ReportInteractiveView({
|
|
|
2364
2491
|
const scenarioActions = useMemo3(
|
|
2365
2492
|
() => ({
|
|
2366
2493
|
copyLink: (s) => copy(scenarioPermalink(s), "Link copied"),
|
|
2367
|
-
copyMarkdown: (s) => copy(
|
|
2494
|
+
copyMarkdown: (s) => copy(scenarioToMarkdown2(s), "Markdown copied"),
|
|
2368
2495
|
copyPrompt: (s) => copy(scenarioToPrompt(s), "Prompt copied")
|
|
2369
2496
|
}),
|
|
2370
2497
|
[copy]
|
|
@@ -2374,9 +2501,9 @@ function ReportInteractiveView({
|
|
|
2374
2501
|
() => report.features.flatMap((f) => [f.id, ...f.scenarios.map((s) => s.id)]),
|
|
2375
2502
|
[report]
|
|
2376
2503
|
);
|
|
2377
|
-
const collapse = useCollapseState();
|
|
2504
|
+
const collapse = useCollapseState(useCallback4(() => defaultCollapsedIds(report), [report]));
|
|
2378
2505
|
const collapseAll = useCallback4(() => collapse.collapseAll(allCollapsibleIds), [collapse, allCollapsibleIds]);
|
|
2379
|
-
const [expandedAll, setExpandedAll] = useState7(
|
|
2506
|
+
const [expandedAll, setExpandedAll] = useState7(() => report.summary.failed === 0);
|
|
2380
2507
|
const setExpanded = useCallback4(
|
|
2381
2508
|
(expanded) => {
|
|
2382
2509
|
if (expanded) collapse.expandAll();
|