executable-stories-react 0.8.0 → 0.10.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 +558 -335
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +551 -335
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +772 -476
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +25 -3
- package/dist/interactive.d.ts +25 -3
- package/dist/interactive.js +762 -466
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +28 -28
- package/dist/ssr.cjs +477 -299
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +477 -299
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
package/dist/ssr.cjs
CHANGED
|
@@ -42,63 +42,6 @@ var import_react2 = require("react");
|
|
|
42
42
|
var import_react = require("react");
|
|
43
43
|
var ReportContext = (0, import_react.createContext)(null);
|
|
44
44
|
|
|
45
|
-
// src/context/ReportRoot.tsx
|
|
46
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
47
|
-
var EMPTY_CUSTOM = {};
|
|
48
|
-
var EMPTY_RENDERERS = {};
|
|
49
|
-
function ReportRoot({
|
|
50
|
-
report,
|
|
51
|
-
customRenderers,
|
|
52
|
-
renderers,
|
|
53
|
-
children
|
|
54
|
-
}) {
|
|
55
|
-
const value = (0, import_react2.useMemo)(
|
|
56
|
-
() => ({
|
|
57
|
-
report,
|
|
58
|
-
customRenderers: customRenderers ?? EMPTY_CUSTOM,
|
|
59
|
-
renderers: renderers ?? EMPTY_RENDERERS
|
|
60
|
-
}),
|
|
61
|
-
[report, customRenderers, renderers]
|
|
62
|
-
);
|
|
63
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReportContext.Provider, { value, children });
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/hooks/useReport.ts
|
|
67
|
-
var import_react3 = require("react");
|
|
68
|
-
function useReport() {
|
|
69
|
-
const ctx = (0, import_react3.useContext)(ReportContext);
|
|
70
|
-
if (!ctx) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
"useReport must be used inside <ReportRoot> or <Report>. Wrap your tree with one of those."
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
return ctx.report;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ../executable-stories-core/dist/utils/duration.js
|
|
79
|
-
function formatDuration(ms) {
|
|
80
|
-
if (ms < 1e3) {
|
|
81
|
-
return `${Math.round(ms)} ms`;
|
|
82
|
-
}
|
|
83
|
-
if (ms < 6e4) {
|
|
84
|
-
return `${(ms / 1e3).toFixed(2)} s`;
|
|
85
|
-
}
|
|
86
|
-
const minutes = Math.floor(ms / 6e4);
|
|
87
|
-
const seconds = Math.floor(ms % 6e4 / 1e3);
|
|
88
|
-
if (minutes < 60) {
|
|
89
|
-
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
90
|
-
}
|
|
91
|
-
const hours = Math.floor(minutes / 60);
|
|
92
|
-
const remainingMinutes = minutes % 60;
|
|
93
|
-
return `${hours}h ${remainingMinutes}m`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// src/components/doc/DocNote.tsx
|
|
97
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
98
|
-
function DocNote({ entry }) {
|
|
99
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
|
|
100
|
-
}
|
|
101
|
-
|
|
102
45
|
// src/components/ui/badge.tsx
|
|
103
46
|
var React = require("react");
|
|
104
47
|
var import_class_variance_authority = require("class-variance-authority");
|
|
@@ -157,14 +100,249 @@ function Badge({
|
|
|
157
100
|
});
|
|
158
101
|
}
|
|
159
102
|
|
|
160
|
-
// src/components/doc/
|
|
103
|
+
// src/components/doc/NarrativeBlocks.tsx
|
|
104
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
105
|
+
var FILE_TREE_TYPE = "file-tree";
|
|
106
|
+
var DATA_MODEL_TYPE = "data-model";
|
|
107
|
+
function isChangeKind(value) {
|
|
108
|
+
return value === "added" || value === "modified" || value === "removed" || value === "renamed";
|
|
109
|
+
}
|
|
110
|
+
function isRecord(value) {
|
|
111
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
112
|
+
}
|
|
113
|
+
function str(value) {
|
|
114
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
115
|
+
}
|
|
116
|
+
function AuthoredMarker({ authored }) {
|
|
117
|
+
if (authored !== "agent") return null;
|
|
118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, { variant: "outline", className: "border-border text-[10px] text-muted-foreground", children: "AI-authored, not verified by a run" });
|
|
119
|
+
}
|
|
120
|
+
function BlockFrame({
|
|
121
|
+
title,
|
|
122
|
+
authored,
|
|
123
|
+
children
|
|
124
|
+
}) {
|
|
125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("figure", { className: "my-3", children: [
|
|
126
|
+
title || authored === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("figcaption", { className: "mb-1.5 flex flex-wrap items-center gap-2", children: [
|
|
127
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: title }) : null,
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthoredMarker, { authored })
|
|
129
|
+
] }) : null,
|
|
130
|
+
children
|
|
131
|
+
] });
|
|
132
|
+
}
|
|
133
|
+
function ChangeBadge({ change }) {
|
|
134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, { variant: "tag", className: "text-[10px]", children: change });
|
|
135
|
+
}
|
|
136
|
+
function parseFileTree(data) {
|
|
137
|
+
if (!isRecord(data) || !Array.isArray(data.files)) return void 0;
|
|
138
|
+
const files = [];
|
|
139
|
+
for (const raw of data.files) {
|
|
140
|
+
if (typeof raw === "string") {
|
|
141
|
+
if (raw) files.push({ path: raw });
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (!isRecord(raw)) continue;
|
|
145
|
+
const path = str(raw.path);
|
|
146
|
+
if (!path) continue;
|
|
147
|
+
files.push({
|
|
148
|
+
path,
|
|
149
|
+
change: isChangeKind(raw.change) ? raw.change : void 0,
|
|
150
|
+
note: str(raw.note)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (files.length === 0) return void 0;
|
|
154
|
+
return { title: str(data.title), authored: str(data.authored), files };
|
|
155
|
+
}
|
|
156
|
+
function buildTree(files) {
|
|
157
|
+
const root = { name: "", children: /* @__PURE__ */ new Map() };
|
|
158
|
+
for (const file of files) {
|
|
159
|
+
const segments = file.path.split("/").filter(Boolean);
|
|
160
|
+
let node = root;
|
|
161
|
+
segments.forEach((segment, index) => {
|
|
162
|
+
let child = node.children.get(segment);
|
|
163
|
+
if (!child) {
|
|
164
|
+
child = { name: segment, children: /* @__PURE__ */ new Map() };
|
|
165
|
+
node.children.set(segment, child);
|
|
166
|
+
}
|
|
167
|
+
if (index === segments.length - 1) child.file = file;
|
|
168
|
+
node = child;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return root;
|
|
172
|
+
}
|
|
173
|
+
function sortedChildren(node) {
|
|
174
|
+
return [...node.children.values()].sort((a, b) => {
|
|
175
|
+
const aDir = a.children.size > 0;
|
|
176
|
+
const bDir = b.children.size > 0;
|
|
177
|
+
if (aDir !== bDir) return aDir ? -1 : 1;
|
|
178
|
+
return a.name.localeCompare(b.name);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function TreeBranch({ node, depth }) {
|
|
182
|
+
const children = sortedChildren(node);
|
|
183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: cn("space-y-0.5", depth > 0 && "ml-3 border-l border-border/60 pl-3"), children: children.map((child) => {
|
|
184
|
+
const isDir = child.children.size > 0;
|
|
185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { children: [
|
|
186
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-baseline gap-2", children: [
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
188
|
+
"span",
|
|
189
|
+
{
|
|
190
|
+
className: cn(
|
|
191
|
+
"font-mono text-xs",
|
|
192
|
+
isDir ? "text-muted-foreground" : "text-foreground"
|
|
193
|
+
),
|
|
194
|
+
children: isDir ? `${child.name}/` : child.name
|
|
195
|
+
}
|
|
196
|
+
),
|
|
197
|
+
child.file?.change ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeBadge, { change: child.file.change }) : null,
|
|
198
|
+
child.file?.note ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-muted-foreground", children: child.file.note }) : null
|
|
199
|
+
] }),
|
|
200
|
+
isDir ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeBranch, { node: child, depth: depth + 1 }) : null
|
|
201
|
+
] }, child.name);
|
|
202
|
+
}) });
|
|
203
|
+
}
|
|
204
|
+
function FileTreeBlock({ entry }) {
|
|
205
|
+
const data = parseFileTree(entry.data);
|
|
206
|
+
if (!data) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UnreadableBlock, { entry });
|
|
207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockFrame, { title: data.title ?? "Files changed", authored: data.authored, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border bg-card p-3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeBranch, { node: buildTree(data.files), depth: 0 }) }) });
|
|
208
|
+
}
|
|
209
|
+
function parseDataModel(data) {
|
|
210
|
+
if (!isRecord(data) || !Array.isArray(data.fields)) return void 0;
|
|
211
|
+
const fields = [];
|
|
212
|
+
for (const raw of data.fields) {
|
|
213
|
+
if (!isRecord(raw)) continue;
|
|
214
|
+
const name = str(raw.name);
|
|
215
|
+
if (!name) continue;
|
|
216
|
+
fields.push({
|
|
217
|
+
name,
|
|
218
|
+
type: str(raw.type),
|
|
219
|
+
note: str(raw.note),
|
|
220
|
+
change: isChangeKind(raw.change) ? raw.change : void 0
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
if (fields.length === 0) return void 0;
|
|
224
|
+
return {
|
|
225
|
+
title: str(data.title),
|
|
226
|
+
authored: str(data.authored),
|
|
227
|
+
name: str(data.name),
|
|
228
|
+
fields
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function DataModelBlock({ entry }) {
|
|
232
|
+
const data = parseDataModel(entry.data);
|
|
233
|
+
if (!data) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UnreadableBlock, { entry });
|
|
234
|
+
const hasNotes = data.fields.some((f) => f.note);
|
|
235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockFrame, { title: data.title ?? data.name ?? "Data model", authored: data.authored, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "w-full border-collapse text-sm", children: [
|
|
236
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "bg-muted/50", children: [
|
|
237
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Field" }),
|
|
238
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Type" }),
|
|
239
|
+
hasNotes ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: "Note" }) : null
|
|
240
|
+
] }) }),
|
|
241
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: data.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
242
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex flex-wrap items-center gap-2", children: [
|
|
243
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-mono text-xs text-foreground", children: field.name }),
|
|
244
|
+
field.change ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeBadge, { change: field.change }) : null
|
|
245
|
+
] }) }),
|
|
246
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "border-b border-border px-3 py-2 font-mono text-xs text-muted-foreground", children: field.type ?? "" }),
|
|
247
|
+
hasNotes ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "border-b border-border px-3 py-2 text-foreground", children: field.note ?? "" }) : null
|
|
248
|
+
] }, field.name)) })
|
|
249
|
+
] }) }) });
|
|
250
|
+
}
|
|
251
|
+
function UnreadableBlock({ entry }) {
|
|
252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "my-2", "data-type": entry.type, children: [
|
|
253
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: [
|
|
254
|
+
entry.type,
|
|
255
|
+
" (unrecognised shape)"
|
|
256
|
+
] }),
|
|
257
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
258
|
+
"pre",
|
|
259
|
+
{
|
|
260
|
+
tabIndex: 0,
|
|
261
|
+
className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground",
|
|
262
|
+
children: safeStringify(entry.data)
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
] });
|
|
266
|
+
}
|
|
267
|
+
function safeStringify(value) {
|
|
268
|
+
try {
|
|
269
|
+
return JSON.stringify(value, null, 2);
|
|
270
|
+
} catch {
|
|
271
|
+
return String(value);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
var narrativeBlockRenderers = {
|
|
275
|
+
[FILE_TREE_TYPE]: (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileTreeBlock, { entry }),
|
|
276
|
+
[DATA_MODEL_TYPE]: (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataModelBlock, { entry })
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// src/context/ReportRoot.tsx
|
|
280
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
281
|
+
var EMPTY_RENDERERS = {};
|
|
282
|
+
function ReportRoot({
|
|
283
|
+
report,
|
|
284
|
+
customRenderers,
|
|
285
|
+
renderers,
|
|
286
|
+
children
|
|
287
|
+
}) {
|
|
288
|
+
const value = (0, import_react2.useMemo)(
|
|
289
|
+
() => ({
|
|
290
|
+
report,
|
|
291
|
+
// Narrative blocks render everywhere the report does (static SSR, the
|
|
292
|
+
// island, Astro) without every host wiring them up. A host renderer for
|
|
293
|
+
// the same type still wins.
|
|
294
|
+
customRenderers: { ...narrativeBlockRenderers, ...customRenderers },
|
|
295
|
+
renderers: renderers ?? EMPTY_RENDERERS
|
|
296
|
+
}),
|
|
297
|
+
[report, customRenderers, renderers]
|
|
298
|
+
);
|
|
299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReportContext.Provider, { value, children });
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/hooks/useReport.ts
|
|
303
|
+
var import_react3 = require("react");
|
|
304
|
+
function useReport() {
|
|
305
|
+
const ctx = (0, import_react3.useContext)(ReportContext);
|
|
306
|
+
if (!ctx) {
|
|
307
|
+
throw new Error(
|
|
308
|
+
"useReport must be used inside <ReportRoot> or <Report>. Wrap your tree with one of those."
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
return ctx.report;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ../executable-stories-core/dist/utils/duration.js
|
|
315
|
+
function formatDuration(ms) {
|
|
316
|
+
if (ms < 1e3) {
|
|
317
|
+
return `${Math.round(ms)} ms`;
|
|
318
|
+
}
|
|
319
|
+
if (ms < 6e4) {
|
|
320
|
+
return `${(ms / 1e3).toFixed(2)} s`;
|
|
321
|
+
}
|
|
322
|
+
const minutes = Math.floor(ms / 6e4);
|
|
323
|
+
const seconds = Math.floor(ms % 6e4 / 1e3);
|
|
324
|
+
if (minutes < 60) {
|
|
325
|
+
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
326
|
+
}
|
|
327
|
+
const hours = Math.floor(minutes / 60);
|
|
328
|
+
const remainingMinutes = minutes % 60;
|
|
329
|
+
return `${hours}h ${remainingMinutes}m`;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/components/doc/DocNote.tsx
|
|
161
333
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
334
|
+
function DocNote({ entry }) {
|
|
335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/components/doc/DocTag.tsx
|
|
339
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
162
340
|
function DocTag({ entry }) {
|
|
163
|
-
return /* @__PURE__ */ (0,
|
|
341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "my-2 flex flex-wrap gap-1.5", "aria-label": "Tags", children: entry.names.map((n) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Badge, { variant: "tag", children: n }) }, n)) });
|
|
164
342
|
}
|
|
165
343
|
|
|
166
344
|
// src/components/doc/DocKv.tsx
|
|
167
|
-
var
|
|
345
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
168
346
|
function formatValue(value) {
|
|
169
347
|
if (value === null) return "null";
|
|
170
348
|
if (typeof value === "string") return value;
|
|
@@ -176,19 +354,19 @@ function formatValue(value) {
|
|
|
176
354
|
}
|
|
177
355
|
}
|
|
178
356
|
function DocKv({ entry }) {
|
|
179
|
-
return /* @__PURE__ */ (0,
|
|
180
|
-
/* @__PURE__ */ (0,
|
|
181
|
-
/* @__PURE__ */ (0,
|
|
357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
|
|
358
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
|
|
359
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { className: "font-mono text-foreground", children: formatValue(entry.value) })
|
|
182
360
|
] });
|
|
183
361
|
}
|
|
184
362
|
|
|
185
363
|
// src/hooks/useRenderers.ts
|
|
186
364
|
var import_react4 = require("react");
|
|
187
|
-
var
|
|
365
|
+
var EMPTY_CUSTOM = {};
|
|
188
366
|
var EMPTY_RENDERERS2 = {};
|
|
189
367
|
function useCustomRenderers() {
|
|
190
368
|
const ctx = (0, import_react4.useContext)(ReportContext);
|
|
191
|
-
return ctx?.customRenderers ??
|
|
369
|
+
return ctx?.customRenderers ?? EMPTY_CUSTOM;
|
|
192
370
|
}
|
|
193
371
|
function useBuiltinRenderers() {
|
|
194
372
|
const ctx = (0, import_react4.useContext)(ReportContext);
|
|
@@ -196,37 +374,37 @@ function useBuiltinRenderers() {
|
|
|
196
374
|
}
|
|
197
375
|
|
|
198
376
|
// src/components/doc/DocCode.tsx
|
|
199
|
-
var
|
|
377
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
200
378
|
function CodeFigure({ label, children }) {
|
|
201
|
-
return /* @__PURE__ */ (0,
|
|
202
|
-
label ? /* @__PURE__ */ (0,
|
|
203
|
-
/* @__PURE__ */ (0,
|
|
379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("figure", { className: "my-3", children: [
|
|
380
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: label }) : null,
|
|
381
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3", children })
|
|
204
382
|
] });
|
|
205
383
|
}
|
|
206
384
|
function DocCode({ entry }) {
|
|
207
385
|
const renderers = useBuiltinRenderers();
|
|
208
386
|
if (renderers.code) {
|
|
209
|
-
return /* @__PURE__ */ (0,
|
|
387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: renderers.code(entry) });
|
|
210
388
|
}
|
|
211
|
-
return /* @__PURE__ */ (0,
|
|
389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CodeFigure, { label: entry.label, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
212
390
|
}
|
|
213
391
|
|
|
214
392
|
// src/components/doc/DocTable.tsx
|
|
215
|
-
var
|
|
393
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
216
394
|
function DocTable({ entry }) {
|
|
217
|
-
return /* @__PURE__ */ (0,
|
|
218
|
-
entry.label ? /* @__PURE__ */ (0,
|
|
219
|
-
/* @__PURE__ */ (0,
|
|
220
|
-
/* @__PURE__ */ (0,
|
|
221
|
-
/* @__PURE__ */ (0,
|
|
395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("figure", { className: "my-3", children: [
|
|
396
|
+
entry.label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { className: "w-full border-collapse text-sm", children: [
|
|
398
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
399
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { children: row.map((cell, j) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
|
|
222
400
|
] }) })
|
|
223
401
|
] });
|
|
224
402
|
}
|
|
225
403
|
|
|
226
404
|
// src/components/doc/DocLink.tsx
|
|
227
|
-
var
|
|
405
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
228
406
|
function DocLink({ entry }) {
|
|
229
|
-
return /* @__PURE__ */ (0,
|
|
407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
230
408
|
"a",
|
|
231
409
|
{
|
|
232
410
|
className: "text-sm font-medium text-primary underline underline-offset-2 hover:no-underline",
|
|
@@ -260,7 +438,7 @@ function isLocalFsPath(value) {
|
|
|
260
438
|
}
|
|
261
439
|
|
|
262
440
|
// src/components/doc/DocSection.tsx
|
|
263
|
-
var
|
|
441
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
264
442
|
function neutralizeUrl(value) {
|
|
265
443
|
return safeUrl(value) ?? "#";
|
|
266
444
|
}
|
|
@@ -271,12 +449,12 @@ function safeMarkdownHtml(markdown) {
|
|
|
271
449
|
function DocSection({ entry }) {
|
|
272
450
|
const renderers = useBuiltinRenderers();
|
|
273
451
|
if (renderers.section) {
|
|
274
|
-
return /* @__PURE__ */ (0,
|
|
452
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: renderers.section(entry) });
|
|
275
453
|
}
|
|
276
454
|
const html = safeMarkdownHtml(entry.markdown);
|
|
277
|
-
return /* @__PURE__ */ (0,
|
|
278
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
279
|
-
/* @__PURE__ */ (0,
|
|
455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
|
|
456
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
|
|
457
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
280
458
|
"div",
|
|
281
459
|
{
|
|
282
460
|
className: "es-doc-prose prose prose-sm max-w-none",
|
|
@@ -287,11 +465,11 @@ function DocSection({ entry }) {
|
|
|
287
465
|
}
|
|
288
466
|
|
|
289
467
|
// src/components/doc/DocMermaid.tsx
|
|
290
|
-
var
|
|
468
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
291
469
|
function MermaidSource({ entry, ref }) {
|
|
292
|
-
return /* @__PURE__ */ (0,
|
|
293
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
294
|
-
/* @__PURE__ */ (0,
|
|
470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
|
|
471
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
295
473
|
"pre",
|
|
296
474
|
{
|
|
297
475
|
"data-mermaid": true,
|
|
@@ -305,24 +483,24 @@ function MermaidSource({ entry, ref }) {
|
|
|
305
483
|
function DocMermaid({ entry }) {
|
|
306
484
|
const renderers = useBuiltinRenderers();
|
|
307
485
|
if (renderers.mermaid) {
|
|
308
|
-
return /* @__PURE__ */ (0,
|
|
486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: renderers.mermaid(entry) });
|
|
309
487
|
}
|
|
310
|
-
return /* @__PURE__ */ (0,
|
|
488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MermaidSource, { entry });
|
|
311
489
|
}
|
|
312
490
|
|
|
313
491
|
// src/components/doc/DocScreenshot.tsx
|
|
314
|
-
var
|
|
492
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
315
493
|
function DocScreenshot({ entry }) {
|
|
316
494
|
const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
|
|
317
495
|
if (!src) {
|
|
318
|
-
return /* @__PURE__ */ (0,
|
|
319
|
-
/* @__PURE__ */ (0,
|
|
320
|
-
/* @__PURE__ */ (0,
|
|
321
|
-
entry.alt ? /* @__PURE__ */ (0,
|
|
496
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
497
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-medium", children: "Screenshot unavailable" }),
|
|
498
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
499
|
+
entry.alt ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.alt }) : null
|
|
322
500
|
] });
|
|
323
501
|
}
|
|
324
|
-
return /* @__PURE__ */ (0,
|
|
325
|
-
/* @__PURE__ */ (0,
|
|
502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { className: "my-3", children: [
|
|
503
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
326
504
|
"img",
|
|
327
505
|
{
|
|
328
506
|
src,
|
|
@@ -331,24 +509,24 @@ function DocScreenshot({ entry }) {
|
|
|
331
509
|
className: "max-w-full rounded-md border border-border"
|
|
332
510
|
}
|
|
333
511
|
),
|
|
334
|
-
entry.alt ? /* @__PURE__ */ (0,
|
|
512
|
+
entry.alt ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
|
|
335
513
|
] });
|
|
336
514
|
}
|
|
337
515
|
|
|
338
516
|
// src/components/doc/DocVideo.tsx
|
|
339
|
-
var
|
|
517
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
340
518
|
function DocVideo({ entry }) {
|
|
341
519
|
if (isLocalFsPath(entry.path)) {
|
|
342
|
-
return /* @__PURE__ */ (0,
|
|
343
|
-
/* @__PURE__ */ (0,
|
|
344
|
-
/* @__PURE__ */ (0,
|
|
345
|
-
entry.caption ? /* @__PURE__ */ (0,
|
|
520
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
521
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "font-medium", children: "Video unavailable" }),
|
|
522
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
523
|
+
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
|
|
346
524
|
] });
|
|
347
525
|
}
|
|
348
526
|
const src = safeUrl(entry.path);
|
|
349
527
|
const poster = safeUrl(entry.poster);
|
|
350
|
-
return /* @__PURE__ */ (0,
|
|
351
|
-
/* @__PURE__ */ (0,
|
|
528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3", children: [
|
|
529
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
352
530
|
"video",
|
|
353
531
|
{
|
|
354
532
|
controls: true,
|
|
@@ -358,21 +536,21 @@ function DocVideo({ entry }) {
|
|
|
358
536
|
className: "max-w-full rounded-md border border-border"
|
|
359
537
|
}
|
|
360
538
|
),
|
|
361
|
-
entry.caption ? /* @__PURE__ */ (0,
|
|
539
|
+
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
|
|
362
540
|
] });
|
|
363
541
|
}
|
|
364
542
|
|
|
365
543
|
// src/components/doc/DocHtml.tsx
|
|
366
|
-
var
|
|
544
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
367
545
|
function DocHtml({ entry }) {
|
|
368
546
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
369
547
|
const title = entry.title ?? "Embedded HTML";
|
|
370
548
|
const safeHref = safeUrl(entry.url ?? entry.path);
|
|
371
549
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
372
|
-
return /* @__PURE__ */ (0,
|
|
373
|
-
/* @__PURE__ */ (0,
|
|
374
|
-
/* @__PURE__ */ (0,
|
|
375
|
-
safeHref ? /* @__PURE__ */ (0,
|
|
550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
551
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figcaption", { className: "flex items-center justify-between border-b border-border bg-muted/40 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
552
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: entry.title ?? "HTML" }),
|
|
553
|
+
safeHref ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
376
554
|
"a",
|
|
377
555
|
{
|
|
378
556
|
href: safeHref,
|
|
@@ -385,7 +563,7 @@ function DocHtml({ entry }) {
|
|
|
385
563
|
}
|
|
386
564
|
) : null
|
|
387
565
|
] }),
|
|
388
|
-
/* @__PURE__ */ (0,
|
|
566
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
389
567
|
"iframe",
|
|
390
568
|
{
|
|
391
569
|
...frameProps,
|
|
@@ -400,7 +578,7 @@ function DocHtml({ entry }) {
|
|
|
400
578
|
}
|
|
401
579
|
|
|
402
580
|
// src/components/doc/DocState.tsx
|
|
403
|
-
var
|
|
581
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
404
582
|
function DocState({ entry }) {
|
|
405
583
|
let json;
|
|
406
584
|
try {
|
|
@@ -408,23 +586,23 @@ function DocState({ entry }) {
|
|
|
408
586
|
} catch {
|
|
409
587
|
json = String(entry.value);
|
|
410
588
|
}
|
|
411
|
-
return /* @__PURE__ */ (0,
|
|
589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
412
590
|
}
|
|
413
591
|
|
|
414
592
|
// src/components/doc/DocCustom.tsx
|
|
415
|
-
var
|
|
593
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
416
594
|
function DocCustom({ entry }) {
|
|
417
595
|
const renderers = useCustomRenderers();
|
|
418
596
|
const renderer = renderers[entry.type];
|
|
419
597
|
if (renderer) {
|
|
420
|
-
return /* @__PURE__ */ (0,
|
|
598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: renderer(entry) });
|
|
421
599
|
}
|
|
422
|
-
return /* @__PURE__ */ (0,
|
|
423
|
-
/* @__PURE__ */ (0,
|
|
424
|
-
/* @__PURE__ */ (0,
|
|
600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "my-2", "data-type": entry.type, children: [
|
|
601
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
|
|
602
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify2(entry.data) })
|
|
425
603
|
] });
|
|
426
604
|
}
|
|
427
|
-
function
|
|
605
|
+
function safeStringify2(value) {
|
|
428
606
|
try {
|
|
429
607
|
return JSON.stringify(value, null, 2);
|
|
430
608
|
} catch {
|
|
@@ -433,47 +611,47 @@ function safeStringify(value) {
|
|
|
433
611
|
}
|
|
434
612
|
|
|
435
613
|
// src/components/doc/DocEntry.tsx
|
|
436
|
-
var
|
|
614
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
437
615
|
function DocEntry({ entry }) {
|
|
438
616
|
switch (entry.kind) {
|
|
439
617
|
case "note":
|
|
440
|
-
return /* @__PURE__ */ (0,
|
|
618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocNote, { entry });
|
|
441
619
|
case "tag":
|
|
442
|
-
return /* @__PURE__ */ (0,
|
|
620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocTag, { entry });
|
|
443
621
|
case "kv":
|
|
444
|
-
return /* @__PURE__ */ (0,
|
|
622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocKv, { entry });
|
|
445
623
|
case "code":
|
|
446
|
-
return /* @__PURE__ */ (0,
|
|
624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocCode, { entry });
|
|
447
625
|
case "table":
|
|
448
|
-
return /* @__PURE__ */ (0,
|
|
626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocTable, { entry });
|
|
449
627
|
case "link":
|
|
450
|
-
return /* @__PURE__ */ (0,
|
|
628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocLink, { entry });
|
|
451
629
|
case "section":
|
|
452
|
-
return /* @__PURE__ */ (0,
|
|
630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocSection, { entry });
|
|
453
631
|
case "mermaid":
|
|
454
|
-
return /* @__PURE__ */ (0,
|
|
632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocMermaid, { entry });
|
|
455
633
|
case "screenshot":
|
|
456
|
-
return /* @__PURE__ */ (0,
|
|
634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocScreenshot, { entry });
|
|
457
635
|
case "video":
|
|
458
|
-
return /* @__PURE__ */ (0,
|
|
636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocVideo, { entry });
|
|
459
637
|
case "html":
|
|
460
|
-
return /* @__PURE__ */ (0,
|
|
638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocHtml, { entry });
|
|
461
639
|
case "state":
|
|
462
|
-
return /* @__PURE__ */ (0,
|
|
640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocState, { entry });
|
|
463
641
|
case "custom":
|
|
464
|
-
return /* @__PURE__ */ (0,
|
|
642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DocCustom, { entry });
|
|
465
643
|
}
|
|
466
644
|
}
|
|
467
645
|
|
|
468
646
|
// src/components/ReportDocEntries.tsx
|
|
469
|
-
var
|
|
647
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
470
648
|
function ReportDocEntries({ entries }) {
|
|
471
649
|
if (entries.length === 0) return null;
|
|
472
|
-
return /* @__PURE__ */ (0,
|
|
650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocEntry, { entry }, i)) });
|
|
473
651
|
}
|
|
474
652
|
|
|
475
653
|
// src/lib/step-params.tsx
|
|
476
|
-
var
|
|
654
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
477
655
|
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
478
656
|
function highlightStepParams(text) {
|
|
479
657
|
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
@@ -485,7 +663,7 @@ function highlightStepParams(text) {
|
|
|
485
663
|
const end = start + match[0].length;
|
|
486
664
|
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
487
665
|
nodes.push(
|
|
488
|
-
/* @__PURE__ */ (0,
|
|
666
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
489
667
|
);
|
|
490
668
|
lastIndex = end;
|
|
491
669
|
});
|
|
@@ -494,7 +672,7 @@ function highlightStepParams(text) {
|
|
|
494
672
|
}
|
|
495
673
|
|
|
496
674
|
// src/components/ReportSteps.tsx
|
|
497
|
-
var
|
|
675
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
498
676
|
var STEP_GLYPH = {
|
|
499
677
|
passed: "\u2713",
|
|
500
678
|
failed: "\u2717",
|
|
@@ -509,21 +687,21 @@ var STEP_GLYPH_COLOR = {
|
|
|
509
687
|
};
|
|
510
688
|
function ReportSteps({ scenario }) {
|
|
511
689
|
if (scenario.steps.length === 0) return null;
|
|
512
|
-
return /* @__PURE__ */ (0,
|
|
690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ReportStepItem, { step }, step.id)) });
|
|
513
691
|
}
|
|
514
692
|
function ReportStepItem({ step }) {
|
|
515
693
|
const kw = step.keyword.toLowerCase();
|
|
516
694
|
const continuation = kw === "and" || kw === "but";
|
|
517
|
-
return /* @__PURE__ */ (0,
|
|
695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
518
696
|
"li",
|
|
519
697
|
{
|
|
520
698
|
id: step.id,
|
|
521
699
|
"data-status": step.status,
|
|
522
700
|
className: cn("py-1.5 text-[0.8125rem] leading-normal", continuation && "pl-5"),
|
|
523
701
|
children: [
|
|
524
|
-
/* @__PURE__ */ (0,
|
|
525
|
-
/* @__PURE__ */ (0,
|
|
526
|
-
/* @__PURE__ */ (0,
|
|
702
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-baseline gap-2", children: [
|
|
703
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": true, className: cn("w-4 shrink-0 text-center text-xs", STEP_GLYPH_COLOR[step.status]), children: STEP_GLYPH[step.status] ?? "\u25CB" }),
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
527
705
|
"span",
|
|
528
706
|
{
|
|
529
707
|
className: cn(
|
|
@@ -533,10 +711,10 @@ function ReportStepItem({ step }) {
|
|
|
533
711
|
children: step.keyword
|
|
534
712
|
}
|
|
535
713
|
),
|
|
536
|
-
/* @__PURE__ */ (0,
|
|
537
|
-
step.durationMs > 0 ? /* @__PURE__ */ (0,
|
|
714
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
715
|
+
step.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
|
|
538
716
|
] }),
|
|
539
|
-
step.errorMessage ? /* @__PURE__ */ (0,
|
|
717
|
+
step.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
540
718
|
"pre",
|
|
541
719
|
{
|
|
542
720
|
role: "alert",
|
|
@@ -544,7 +722,7 @@ function ReportStepItem({ step }) {
|
|
|
544
722
|
children: step.errorMessage
|
|
545
723
|
}
|
|
546
724
|
) : null,
|
|
547
|
-
step.docEntries.length > 0 ? /* @__PURE__ */ (0,
|
|
725
|
+
step.docEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { "data-es-docs": true, className: "mt-2 ml-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ReportDocEntries, { entries: step.docEntries }) }) : null
|
|
548
726
|
]
|
|
549
727
|
}
|
|
550
728
|
);
|
|
@@ -669,7 +847,7 @@ function extractStoryboardFrames(scenario) {
|
|
|
669
847
|
}
|
|
670
848
|
|
|
671
849
|
// src/components/ReportStoryboard.tsx
|
|
672
|
-
var
|
|
850
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
673
851
|
var FRAME_GLYPH = {
|
|
674
852
|
passed: "\u2713",
|
|
675
853
|
failed: "\u2717",
|
|
@@ -685,32 +863,32 @@ var FRAME_GLYPH_COLOR = {
|
|
|
685
863
|
function ReportStoryboard({ scenario }) {
|
|
686
864
|
const frames = extractStoryboardFrames(scenario);
|
|
687
865
|
if (frames.length < 2) return null;
|
|
688
|
-
return /* @__PURE__ */ (0,
|
|
689
|
-
/* @__PURE__ */ (0,
|
|
690
|
-
/* @__PURE__ */ (0,
|
|
866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ol", { className: "flex items-start gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StoryboardFrameItem, { frame }, frame.stepId)) })
|
|
691
869
|
] });
|
|
692
870
|
}
|
|
693
871
|
function StoryboardFrameItem({ frame }) {
|
|
694
872
|
const label = `${frame.keyword} ${frame.text}`;
|
|
695
873
|
const hasStates = frame.states.length > 0;
|
|
696
|
-
const caption = /* @__PURE__ */ (0,
|
|
697
|
-
/* @__PURE__ */ (0,
|
|
698
|
-
/* @__PURE__ */ (0,
|
|
699
|
-
/* @__PURE__ */ (0,
|
|
874
|
+
const caption = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "min-w-0", children: [
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
700
878
|
" ",
|
|
701
|
-
/* @__PURE__ */ (0,
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-muted-foreground", children: frame.screenshot?.alt ?? frame.text })
|
|
702
880
|
] })
|
|
703
881
|
] });
|
|
704
882
|
return (
|
|
705
883
|
// State cards need room for diff rows; screenshot-only frames keep the
|
|
706
884
|
// original narrow film-cell width (and DOM) unchanged.
|
|
707
|
-
/* @__PURE__ */ (0,
|
|
708
|
-
frame.screenshot ? /* @__PURE__ */ (0,
|
|
709
|
-
hasStates ? /* @__PURE__ */ (0,
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("li", { className: cn("shrink-0", hasStates ? "w-64" : "w-40"), children: [
|
|
886
|
+
frame.screenshot ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FrameScreenshot, { frame, label }) : null,
|
|
887
|
+
hasStates ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", frame.screenshot && "mt-1.5"), children: frame.states.map((card, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StateCardView, { card }, card.label ?? i)) }) : null,
|
|
710
888
|
frame.screenshot ? caption : (
|
|
711
889
|
// No screenshot means no image anchor, so the caption carries the
|
|
712
890
|
// jump-to-step link instead.
|
|
713
|
-
/* @__PURE__ */ (0,
|
|
891
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { href: `#${frame.stepId}`, "aria-label": `Jump to step: ${label}`, className: "block hover:underline", children: caption })
|
|
714
892
|
)
|
|
715
893
|
] })
|
|
716
894
|
);
|
|
@@ -718,13 +896,13 @@ function StoryboardFrameItem({ frame }) {
|
|
|
718
896
|
function FrameScreenshot({ frame, label }) {
|
|
719
897
|
const path = frame.screenshot?.path ?? "";
|
|
720
898
|
const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
|
|
721
|
-
return /* @__PURE__ */ (0,
|
|
899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
722
900
|
"a",
|
|
723
901
|
{
|
|
724
902
|
href: `#${frame.stepId}`,
|
|
725
903
|
"aria-label": `Jump to step: ${label}`,
|
|
726
904
|
className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
|
|
727
|
-
children: src ? /* @__PURE__ */ (0,
|
|
905
|
+
children: src ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
728
906
|
"img",
|
|
729
907
|
{
|
|
730
908
|
src,
|
|
@@ -732,7 +910,7 @@ function FrameScreenshot({ frame, label }) {
|
|
|
732
910
|
loading: "lazy",
|
|
733
911
|
className: "h-24 w-full bg-muted object-cover object-top"
|
|
734
912
|
}
|
|
735
|
-
) : /* @__PURE__ */ (0,
|
|
913
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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" })
|
|
736
914
|
}
|
|
737
915
|
);
|
|
738
916
|
}
|
|
@@ -751,12 +929,12 @@ function prettyJson(value) {
|
|
|
751
929
|
function StateCardView({ card }) {
|
|
752
930
|
const json = prettyJson(card.value);
|
|
753
931
|
const firstCapture = card.changes === void 0;
|
|
754
|
-
return /* @__PURE__ */ (0,
|
|
755
|
-
/* @__PURE__ */ (0,
|
|
756
|
-
/* @__PURE__ */ (0,
|
|
757
|
-
firstCapture ? /* @__PURE__ */ (0,
|
|
932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "data-slot": "state-card", className: "rounded-md border border-border bg-card p-2", children: [
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { className: "flex flex-wrap items-baseline gap-1.5", children: [
|
|
934
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex rounded-full border border-border px-1.5 font-mono text-[0.625rem] font-medium text-muted-foreground", children: card.label ?? "State" }),
|
|
935
|
+
firstCapture ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[0.625rem] text-muted-foreground italic", children: "first capture" }) : null
|
|
758
936
|
] }),
|
|
759
|
-
!firstCapture && (card.changes && card.changes.length > 0 ? /* @__PURE__ */ (0,
|
|
937
|
+
!firstCapture && (card.changes && card.changes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "mt-1.5 flex flex-col gap-0.5", children: card.changes.map((change, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
760
938
|
"li",
|
|
761
939
|
{
|
|
762
940
|
className: cn(
|
|
@@ -766,15 +944,15 @@ function StateCardView({ card }) {
|
|
|
766
944
|
children: summarizeStateChanges([change])[0]
|
|
767
945
|
},
|
|
768
946
|
i
|
|
769
|
-
)) }) : /* @__PURE__ */ (0,
|
|
770
|
-
/* @__PURE__ */ (0,
|
|
947
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
771
949
|
"details",
|
|
772
950
|
{
|
|
773
951
|
open: firstCapture && json.length <= 240,
|
|
774
952
|
className: cn(firstCapture ? "mt-1.5" : "mt-1"),
|
|
775
953
|
children: [
|
|
776
|
-
/* @__PURE__ */ (0,
|
|
777
|
-
/* @__PURE__ */ (0,
|
|
954
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("summary", { className: "cursor-pointer text-[0.625rem] text-muted-foreground hover:text-foreground", children: "Snapshot" }),
|
|
955
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { tabIndex: 0, className: "mt-1 max-h-48 overflow-auto rounded-sm bg-muted p-1.5 font-mono text-[0.625rem] leading-snug", children: json })
|
|
778
956
|
]
|
|
779
957
|
}
|
|
780
958
|
)
|
|
@@ -782,17 +960,17 @@ function StateCardView({ card }) {
|
|
|
782
960
|
}
|
|
783
961
|
|
|
784
962
|
// src/components/ReportAttachments.tsx
|
|
785
|
-
var
|
|
963
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
786
964
|
function ReportAttachments({ attachments }) {
|
|
787
965
|
if (attachments.length === 0) return null;
|
|
788
966
|
return (
|
|
789
967
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
790
968
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
791
|
-
/* @__PURE__ */ (0,
|
|
969
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
792
970
|
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
793
971
|
const isImage = att.mediaType.startsWith("image/");
|
|
794
|
-
return /* @__PURE__ */ (0,
|
|
795
|
-
/* @__PURE__ */ (0,
|
|
972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
796
974
|
"img",
|
|
797
975
|
{
|
|
798
976
|
src: dataUri,
|
|
@@ -801,8 +979,8 @@ function ReportAttachments({ attachments }) {
|
|
|
801
979
|
className: "max-w-full rounded-md border border-border"
|
|
802
980
|
}
|
|
803
981
|
),
|
|
804
|
-
/* @__PURE__ */ (0,
|
|
805
|
-
] }) : /* @__PURE__ */ (0,
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
983
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
806
984
|
"a",
|
|
807
985
|
{
|
|
808
986
|
href: dataUri,
|
|
@@ -811,7 +989,7 @@ function ReportAttachments({ attachments }) {
|
|
|
811
989
|
children: [
|
|
812
990
|
att.name,
|
|
813
991
|
" ",
|
|
814
|
-
/* @__PURE__ */ (0,
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
815
993
|
"(",
|
|
816
994
|
att.mediaType,
|
|
817
995
|
")"
|
|
@@ -899,7 +1077,7 @@ function traceWindow(rows) {
|
|
|
899
1077
|
}
|
|
900
1078
|
|
|
901
1079
|
// src/components/ReportTrace.tsx
|
|
902
|
-
var
|
|
1080
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
903
1081
|
var BAR_COLOR = {
|
|
904
1082
|
ok: "bg-pass",
|
|
905
1083
|
error: "bg-fail",
|
|
@@ -910,8 +1088,8 @@ function ReportTrace({ spans }) {
|
|
|
910
1088
|
const rows = toTraceRows(spans);
|
|
911
1089
|
if (rows.length === 0) return null;
|
|
912
1090
|
const { minStartMs, totalMs } = traceWindow(rows);
|
|
913
|
-
return /* @__PURE__ */ (0,
|
|
914
|
-
/* @__PURE__ */ (0,
|
|
1091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("details", { className: "mt-3 rounded-md border border-border bg-muted/30", children: [
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("summary", { className: "cursor-pointer px-3 py-2 text-xs font-medium text-muted-foreground", children: [
|
|
915
1093
|
"Trace (",
|
|
916
1094
|
rows.length,
|
|
917
1095
|
" span",
|
|
@@ -920,11 +1098,11 @@ function ReportTrace({ spans }) {
|
|
|
920
1098
|
formatDuration(totalMs),
|
|
921
1099
|
")"
|
|
922
1100
|
] }),
|
|
923
|
-
/* @__PURE__ */ (0,
|
|
1101
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
924
1102
|
const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
|
|
925
1103
|
const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
|
|
926
|
-
return /* @__PURE__ */ (0,
|
|
927
|
-
/* @__PURE__ */ (0,
|
|
1104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: "flex items-center gap-2", children: [
|
|
1105
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
928
1106
|
"span",
|
|
929
1107
|
{
|
|
930
1108
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
@@ -933,14 +1111,14 @@ function ReportTrace({ spans }) {
|
|
|
933
1111
|
children: row.name
|
|
934
1112
|
}
|
|
935
1113
|
),
|
|
936
|
-
/* @__PURE__ */ (0,
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
937
1115
|
"span",
|
|
938
1116
|
{
|
|
939
1117
|
className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
|
|
940
1118
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
941
1119
|
}
|
|
942
1120
|
) }),
|
|
943
|
-
/* @__PURE__ */ (0,
|
|
1121
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
944
1122
|
] }, `${row.spanId}-${i}`);
|
|
945
1123
|
}) })
|
|
946
1124
|
] });
|
|
@@ -991,7 +1169,7 @@ function flakinessOf(entries) {
|
|
|
991
1169
|
}
|
|
992
1170
|
|
|
993
1171
|
// src/components/ScenarioRunHistory.tsx
|
|
994
|
-
var
|
|
1172
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
995
1173
|
var MAX_DOTS = 10;
|
|
996
1174
|
var DOT_COLOR = {
|
|
997
1175
|
passed: "bg-pass",
|
|
@@ -1011,16 +1189,16 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1011
1189
|
const recent = entries.slice(-MAX_DOTS);
|
|
1012
1190
|
const flaky = flakinessOf(recent) === "flaky";
|
|
1013
1191
|
const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
|
|
1014
|
-
return /* @__PURE__ */ (0,
|
|
1015
|
-
flaky ? /* @__PURE__ */ (0,
|
|
1016
|
-
/* @__PURE__ */ (0,
|
|
1192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
1193
|
+
flaky ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
|
|
1194
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1017
1195
|
"span",
|
|
1018
1196
|
{
|
|
1019
1197
|
role: "img",
|
|
1020
1198
|
"aria-label": `Run history: ${summary}`,
|
|
1021
1199
|
title: summary,
|
|
1022
1200
|
className: "flex shrink-0 items-center gap-[3px]",
|
|
1023
|
-
children: recent.map((e, i) => /* @__PURE__ */ (0,
|
|
1201
|
+
children: recent.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1024
1202
|
"span",
|
|
1025
1203
|
{
|
|
1026
1204
|
"aria-hidden": true,
|
|
@@ -1059,9 +1237,9 @@ function useScenarioActions() {
|
|
|
1059
1237
|
|
|
1060
1238
|
// src/components/ui/card.tsx
|
|
1061
1239
|
var React2 = require("react");
|
|
1062
|
-
var
|
|
1240
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1063
1241
|
function Card({ className, ...props }) {
|
|
1064
|
-
return /* @__PURE__ */ (0,
|
|
1242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1065
1243
|
"div",
|
|
1066
1244
|
{
|
|
1067
1245
|
"data-slot": "card",
|
|
@@ -1074,7 +1252,7 @@ function Card({ className, ...props }) {
|
|
|
1074
1252
|
);
|
|
1075
1253
|
}
|
|
1076
1254
|
function CardHeader({ className, ...props }) {
|
|
1077
|
-
return /* @__PURE__ */ (0,
|
|
1255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1078
1256
|
"div",
|
|
1079
1257
|
{
|
|
1080
1258
|
"data-slot": "card-header",
|
|
@@ -1087,7 +1265,7 @@ function CardHeader({ className, ...props }) {
|
|
|
1087
1265
|
);
|
|
1088
1266
|
}
|
|
1089
1267
|
function CardContent({ className, ...props }) {
|
|
1090
|
-
return /* @__PURE__ */ (0,
|
|
1268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1091
1269
|
"div",
|
|
1092
1270
|
{
|
|
1093
1271
|
"data-slot": "card-content",
|
|
@@ -1101,13 +1279,13 @@ function CardContent({ className, ...props }) {
|
|
|
1101
1279
|
var React3 = require("react");
|
|
1102
1280
|
var import_menu = require("@base-ui/react/menu");
|
|
1103
1281
|
var import_lucide_react = require("lucide-react");
|
|
1104
|
-
var
|
|
1282
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1105
1283
|
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";
|
|
1106
1284
|
function DropdownMenu(props) {
|
|
1107
|
-
return /* @__PURE__ */ (0,
|
|
1285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
1108
1286
|
}
|
|
1109
1287
|
function DropdownMenuTrigger(props) {
|
|
1110
|
-
return /* @__PURE__ */ (0,
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
1111
1289
|
}
|
|
1112
1290
|
function DropdownMenuContent({
|
|
1113
1291
|
className,
|
|
@@ -1115,14 +1293,14 @@ function DropdownMenuContent({
|
|
|
1115
1293
|
sideOffset = 4,
|
|
1116
1294
|
...props
|
|
1117
1295
|
}) {
|
|
1118
|
-
return /* @__PURE__ */ (0,
|
|
1296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_menu.Menu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1119
1297
|
import_menu.Menu.Positioner,
|
|
1120
1298
|
{
|
|
1121
1299
|
"data-slot": "dropdown-menu-positioner",
|
|
1122
1300
|
className: "z-50",
|
|
1123
1301
|
align,
|
|
1124
1302
|
sideOffset,
|
|
1125
|
-
children: /* @__PURE__ */ (0,
|
|
1303
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1126
1304
|
import_menu.Menu.Popup,
|
|
1127
1305
|
{
|
|
1128
1306
|
"data-slot": "dropdown-menu-content",
|
|
@@ -1140,7 +1318,7 @@ function DropdownMenuItem({
|
|
|
1140
1318
|
className,
|
|
1141
1319
|
...props
|
|
1142
1320
|
}) {
|
|
1143
|
-
return /* @__PURE__ */ (0,
|
|
1321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1144
1322
|
import_menu.Menu.Item,
|
|
1145
1323
|
{
|
|
1146
1324
|
"data-slot": "dropdown-menu-item",
|
|
@@ -1152,7 +1330,7 @@ function DropdownMenuItem({
|
|
|
1152
1330
|
|
|
1153
1331
|
// src/components/ReportScenario.tsx
|
|
1154
1332
|
var import_lucide_react2 = require("lucide-react");
|
|
1155
|
-
var
|
|
1333
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1156
1334
|
var STATUS_META = {
|
|
1157
1335
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
1158
1336
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1168,7 +1346,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1168
1346
|
const collapsible = collapse !== null && !hideTitle;
|
|
1169
1347
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
1170
1348
|
const actions = useScenarioActions();
|
|
1171
|
-
return /* @__PURE__ */ (0,
|
|
1349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
1172
1350
|
Card,
|
|
1173
1351
|
{
|
|
1174
1352
|
id: scenario.id,
|
|
@@ -1176,10 +1354,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1176
1354
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
1177
1355
|
className: "gap-0 py-0",
|
|
1178
1356
|
children: [
|
|
1179
|
-
/* @__PURE__ */ (0,
|
|
1180
|
-
/* @__PURE__ */ (0,
|
|
1181
|
-
hideTitle ? null : /* @__PURE__ */ (0,
|
|
1182
|
-
collapsible ? /* @__PURE__ */ (0,
|
|
1357
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardHeader, { className: "px-4 py-3", children: [
|
|
1358
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
1359
|
+
hideTitle ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1360
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1183
1361
|
"button",
|
|
1184
1362
|
{
|
|
1185
1363
|
type: "button",
|
|
@@ -1188,49 +1366,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1188
1366
|
"aria-controls": bodyId,
|
|
1189
1367
|
"aria-label": `Toggle ${scenario.title}`,
|
|
1190
1368
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
1191
|
-
children: /* @__PURE__ */ (0,
|
|
1369
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
1192
1370
|
}
|
|
1193
1371
|
) : null,
|
|
1194
|
-
/* @__PURE__ */ (0,
|
|
1195
|
-
/* @__PURE__ */ (0,
|
|
1372
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: scenario.title })
|
|
1196
1374
|
] }),
|
|
1197
|
-
/* @__PURE__ */ (0,
|
|
1198
|
-
/* @__PURE__ */ (0,
|
|
1199
|
-
scenario.durationMs > 0 ? /* @__PURE__ */ (0,
|
|
1200
|
-
meta.showPill ? /* @__PURE__ */ (0,
|
|
1201
|
-
actions ? /* @__PURE__ */ (0,
|
|
1202
|
-
/* @__PURE__ */ (0,
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1376
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1377
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1378
|
+
meta.showPill ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1379
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenu, { children: [
|
|
1380
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1203
1381
|
DropdownMenuTrigger,
|
|
1204
1382
|
{
|
|
1205
1383
|
"aria-label": `Actions for ${scenario.title}`,
|
|
1206
1384
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1207
|
-
children: /* @__PURE__ */ (0,
|
|
1385
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react2.MoreHorizontalIcon, { "aria-hidden": true })
|
|
1208
1386
|
}
|
|
1209
1387
|
),
|
|
1210
|
-
/* @__PURE__ */ (0,
|
|
1211
|
-
/* @__PURE__ */ (0,
|
|
1212
|
-
/* @__PURE__ */ (0,
|
|
1388
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1389
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1390
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react2.LinkIcon, {}),
|
|
1213
1391
|
" Copy link"
|
|
1214
1392
|
] }),
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1393
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react2.FileTextIcon, {}),
|
|
1217
1395
|
" Copy as Markdown"
|
|
1218
1396
|
] }),
|
|
1219
|
-
/* @__PURE__ */ (0,
|
|
1220
|
-
/* @__PURE__ */ (0,
|
|
1397
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1398
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react2.SparklesIcon, {}),
|
|
1221
1399
|
" Explain with AI"
|
|
1222
1400
|
] })
|
|
1223
1401
|
] })
|
|
1224
1402
|
] }) : null
|
|
1225
1403
|
] })
|
|
1226
1404
|
] }),
|
|
1227
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0,
|
|
1228
|
-
scenario.tags.map((t) => /* @__PURE__ */ (0,
|
|
1229
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0,
|
|
1405
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1406
|
+
scenario.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1407
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: ticket.url ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1230
1408
|
] }) : null
|
|
1231
1409
|
] }),
|
|
1232
|
-
/* @__PURE__ */ (0,
|
|
1233
|
-
scenario.errorMessage ? /* @__PURE__ */ (0,
|
|
1410
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1411
|
+
scenario.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1234
1412
|
"pre",
|
|
1235
1413
|
{
|
|
1236
1414
|
role: "alert",
|
|
@@ -1238,11 +1416,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1238
1416
|
children: scenario.errorMessage
|
|
1239
1417
|
}
|
|
1240
1418
|
) : null,
|
|
1241
|
-
/* @__PURE__ */ (0,
|
|
1242
|
-
/* @__PURE__ */ (0,
|
|
1243
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0,
|
|
1244
|
-
/* @__PURE__ */ (0,
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportStoryboard, { scenario }),
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportSteps, { scenario }),
|
|
1421
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportAttachments, { attachments: scenario.attachments }),
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ReportTrace, { spans: scenario.otelSpans })
|
|
1246
1424
|
] })
|
|
1247
1425
|
]
|
|
1248
1426
|
}
|
|
@@ -1250,13 +1428,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1250
1428
|
}
|
|
1251
1429
|
|
|
1252
1430
|
// src/components/ReportScenarioList.tsx
|
|
1253
|
-
var
|
|
1431
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1254
1432
|
function ReportScenarioList({ feature }) {
|
|
1255
|
-
return /* @__PURE__ */ (0,
|
|
1433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_jsx_runtime27.Fragment, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportScenario, { scenario }, scenario.id)) });
|
|
1256
1434
|
}
|
|
1257
1435
|
|
|
1258
1436
|
// src/components/ReportFeature.tsx
|
|
1259
|
-
var
|
|
1437
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1260
1438
|
function ReportFeature({ feature }) {
|
|
1261
1439
|
const titleId = `${feature.id}-title`;
|
|
1262
1440
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1267,7 +1445,7 @@ function ReportFeature({ feature }) {
|
|
|
1267
1445
|
return (
|
|
1268
1446
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1269
1447
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1270
|
-
/* @__PURE__ */ (0,
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1271
1449
|
"section",
|
|
1272
1450
|
{
|
|
1273
1451
|
id: feature.id,
|
|
@@ -1275,9 +1453,9 @@ function ReportFeature({ feature }) {
|
|
|
1275
1453
|
"aria-labelledby": titleId,
|
|
1276
1454
|
className: "flex flex-col gap-3",
|
|
1277
1455
|
children: [
|
|
1278
|
-
/* @__PURE__ */ (0,
|
|
1279
|
-
/* @__PURE__ */ (0,
|
|
1280
|
-
/* @__PURE__ */ (0,
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0", children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1281
1459
|
"button",
|
|
1282
1460
|
{
|
|
1283
1461
|
type: "button",
|
|
@@ -1286,31 +1464,31 @@ function ReportFeature({ feature }) {
|
|
|
1286
1464
|
"aria-controls": bodyId,
|
|
1287
1465
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1288
1466
|
children: [
|
|
1289
|
-
/* @__PURE__ */ (0,
|
|
1290
|
-
/* @__PURE__ */ (0,
|
|
1467
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "truncate", children: feature.title })
|
|
1291
1469
|
]
|
|
1292
1470
|
}
|
|
1293
1471
|
) : feature.title }),
|
|
1294
|
-
/* @__PURE__ */ (0,
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1295
1473
|
] }),
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1474
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1297
1475
|
"p",
|
|
1298
1476
|
{
|
|
1299
1477
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1300
1478
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1301
1479
|
children: [
|
|
1302
|
-
/* @__PURE__ */ (0,
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { children: [
|
|
1303
1481
|
s.passed,
|
|
1304
1482
|
" passed"
|
|
1305
1483
|
] }),
|
|
1306
|
-
/* @__PURE__ */ (0,
|
|
1307
|
-
/* @__PURE__ */ (0,
|
|
1484
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1485
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1308
1486
|
s.failed,
|
|
1309
1487
|
" failed"
|
|
1310
1488
|
] }),
|
|
1311
|
-
skipped > 0 ? /* @__PURE__ */ (0,
|
|
1312
|
-
/* @__PURE__ */ (0,
|
|
1313
|
-
/* @__PURE__ */ (0,
|
|
1489
|
+
skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1490
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { children: [
|
|
1314
1492
|
skipped,
|
|
1315
1493
|
" skipped"
|
|
1316
1494
|
] })
|
|
@@ -1319,7 +1497,7 @@ function ReportFeature({ feature }) {
|
|
|
1319
1497
|
}
|
|
1320
1498
|
)
|
|
1321
1499
|
] }),
|
|
1322
|
-
/* @__PURE__ */ (0,
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ReportScenarioList, { feature }) })
|
|
1323
1501
|
]
|
|
1324
1502
|
}
|
|
1325
1503
|
)
|
|
@@ -1327,17 +1505,17 @@ function ReportFeature({ feature }) {
|
|
|
1327
1505
|
}
|
|
1328
1506
|
|
|
1329
1507
|
// src/components/ReportFeatureList.tsx
|
|
1330
|
-
var
|
|
1508
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1331
1509
|
function ReportFeatureList() {
|
|
1332
1510
|
const report = useReport();
|
|
1333
|
-
return /* @__PURE__ */ (0,
|
|
1511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportFeature, { feature }, feature.id)) });
|
|
1334
1512
|
}
|
|
1335
1513
|
|
|
1336
1514
|
// src/components/ui/empty.tsx
|
|
1337
1515
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
1338
|
-
var
|
|
1516
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1339
1517
|
function Empty({ className, ...props }) {
|
|
1340
|
-
return /* @__PURE__ */ (0,
|
|
1518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1341
1519
|
"div",
|
|
1342
1520
|
{
|
|
1343
1521
|
"data-slot": "empty",
|
|
@@ -1350,7 +1528,7 @@ function Empty({ className, ...props }) {
|
|
|
1350
1528
|
);
|
|
1351
1529
|
}
|
|
1352
1530
|
function EmptyHeader({ className, ...props }) {
|
|
1353
|
-
return /* @__PURE__ */ (0,
|
|
1531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1354
1532
|
"div",
|
|
1355
1533
|
{
|
|
1356
1534
|
"data-slot": "empty-header",
|
|
@@ -1377,7 +1555,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
|
|
|
1377
1555
|
}
|
|
1378
1556
|
);
|
|
1379
1557
|
function EmptyTitle({ className, ...props }) {
|
|
1380
|
-
return /* @__PURE__ */ (0,
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1381
1559
|
"div",
|
|
1382
1560
|
{
|
|
1383
1561
|
"data-slot": "empty-title",
|
|
@@ -1388,16 +1566,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1388
1566
|
}
|
|
1389
1567
|
|
|
1390
1568
|
// src/components/ReportEmpty.tsx
|
|
1391
|
-
var
|
|
1569
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1392
1570
|
function ReportEmpty({ message }) {
|
|
1393
|
-
return /* @__PURE__ */ (0,
|
|
1571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1394
1572
|
}
|
|
1395
1573
|
|
|
1396
1574
|
// src/components/ReportSummary.tsx
|
|
1397
|
-
var
|
|
1575
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1398
1576
|
function ReportSummary({ className }) {
|
|
1399
1577
|
const report = useReport();
|
|
1400
|
-
return /* @__PURE__ */ (0,
|
|
1578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1401
1579
|
ReportSummaryView,
|
|
1402
1580
|
{
|
|
1403
1581
|
summary: report.summary,
|
|
@@ -1423,7 +1601,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1423
1601
|
if (summary.pending > 0) {
|
|
1424
1602
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1425
1603
|
}
|
|
1426
|
-
return /* @__PURE__ */ (0,
|
|
1604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1427
1605
|
"dl",
|
|
1428
1606
|
{
|
|
1429
1607
|
className: cn(
|
|
@@ -1436,17 +1614,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1436
1614
|
"aria-label": ariaLabel,
|
|
1437
1615
|
children: cards.map((c) => {
|
|
1438
1616
|
const tone = TONE[c.status];
|
|
1439
|
-
return /* @__PURE__ */ (0,
|
|
1617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
1440
1618
|
"div",
|
|
1441
1619
|
{
|
|
1442
1620
|
"data-status": c.status,
|
|
1443
1621
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1444
1622
|
children: [
|
|
1445
|
-
/* @__PURE__ */ (0,
|
|
1446
|
-
/* @__PURE__ */ (0,
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1447
1625
|
c.label
|
|
1448
1626
|
] }),
|
|
1449
|
-
/* @__PURE__ */ (0,
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1450
1628
|
]
|
|
1451
1629
|
},
|
|
1452
1630
|
c.status
|
|
@@ -1487,7 +1665,7 @@ function prUrl(ci) {
|
|
|
1487
1665
|
}
|
|
1488
1666
|
|
|
1489
1667
|
// src/components/ReportMeta.tsx
|
|
1490
|
-
var
|
|
1668
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1491
1669
|
function ReportMeta() {
|
|
1492
1670
|
const report = useReport();
|
|
1493
1671
|
const items = [];
|
|
@@ -1510,13 +1688,13 @@ function ReportMeta() {
|
|
|
1510
1688
|
const short = sha.slice(0, 8);
|
|
1511
1689
|
items.push({
|
|
1512
1690
|
label: "Commit",
|
|
1513
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1691
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1514
1692
|
});
|
|
1515
1693
|
}
|
|
1516
1694
|
if (report.ci) {
|
|
1517
1695
|
items.push({
|
|
1518
1696
|
label: "CI",
|
|
1519
|
-
value: report.ci.url ? /* @__PURE__ */ (0,
|
|
1697
|
+
value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1520
1698
|
ciDisplayName(report.ci.name),
|
|
1521
1699
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1522
1700
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1527,7 +1705,7 @@ function ReportMeta() {
|
|
|
1527
1705
|
const label = `#${report.ci.prNumber}`;
|
|
1528
1706
|
items.push({
|
|
1529
1707
|
label: "PR",
|
|
1530
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1708
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1531
1709
|
});
|
|
1532
1710
|
}
|
|
1533
1711
|
if (items.length === 0) return null;
|
|
@@ -1535,48 +1713,48 @@ function ReportMeta() {
|
|
|
1535
1713
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1536
1714
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1537
1715
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1539
|
-
/* @__PURE__ */ (0,
|
|
1540
|
-
/* @__PURE__ */ (0,
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.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: [
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1541
1719
|
"Run details"
|
|
1542
1720
|
] }),
|
|
1543
|
-
/* @__PURE__ */ (0,
|
|
1544
|
-
/* @__PURE__ */ (0,
|
|
1545
|
-
/* @__PURE__ */ (0,
|
|
1721
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.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_runtime33.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1722
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dt", { className: "font-medium", children: item.label }),
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1546
1724
|
] }, item.label)) })
|
|
1547
1725
|
] })
|
|
1548
1726
|
);
|
|
1549
1727
|
}
|
|
1550
1728
|
|
|
1551
1729
|
// src/components/ReportSchemaError.tsx
|
|
1552
|
-
var
|
|
1730
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1553
1731
|
function ReportSchemaError({ error }) {
|
|
1554
|
-
return /* @__PURE__ */ (0,
|
|
1555
|
-
/* @__PURE__ */ (0,
|
|
1556
|
-
/* @__PURE__ */ (0,
|
|
1557
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0,
|
|
1732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("strong", { children: "Report could not be displayed." }) }),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { children: error.message }),
|
|
1735
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { children: [
|
|
1558
1736
|
"The report bundle is newer than this version of ",
|
|
1559
|
-
/* @__PURE__ */ (0,
|
|
1737
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("code", { children: "executable-stories-react" }),
|
|
1560
1738
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1561
1739
|
] }) : null,
|
|
1562
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0,
|
|
1563
|
-
/* @__PURE__ */ (0,
|
|
1740
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("details", { children: [
|
|
1741
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("summary", { children: [
|
|
1564
1742
|
error.issues.length,
|
|
1565
1743
|
" validation issue",
|
|
1566
1744
|
error.issues.length === 1 ? "" : "s"
|
|
1567
1745
|
] }),
|
|
1568
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1569
1747
|
] }) : null
|
|
1570
1748
|
] });
|
|
1571
1749
|
}
|
|
1572
1750
|
|
|
1573
1751
|
// src/components/ReportShell.tsx
|
|
1574
|
-
var
|
|
1752
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1575
1753
|
function ReportTitleBlock({ title }) {
|
|
1576
|
-
return /* @__PURE__ */ (0,
|
|
1577
|
-
/* @__PURE__ */ (0,
|
|
1578
|
-
/* @__PURE__ */ (0,
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", { children: title ?? "Story Report" }),
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ReportSummary, {}),
|
|
1757
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ReportMeta, {})
|
|
1580
1758
|
] });
|
|
1581
1759
|
}
|
|
1582
1760
|
function ReportErrorShell({
|
|
@@ -1585,22 +1763,22 @@ function ReportErrorShell({
|
|
|
1585
1763
|
title,
|
|
1586
1764
|
dataTheme
|
|
1587
1765
|
}) {
|
|
1588
|
-
return /* @__PURE__ */ (0,
|
|
1766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ReportSchemaError, { error }) });
|
|
1589
1767
|
}
|
|
1590
1768
|
|
|
1591
1769
|
// src/components/Report.tsx
|
|
1592
|
-
var
|
|
1770
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1593
1771
|
function Report(props) {
|
|
1594
1772
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1595
1773
|
const result = unwrapReport(report);
|
|
1596
1774
|
if (!result.ok) {
|
|
1597
|
-
return /* @__PURE__ */ (0,
|
|
1775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1598
1776
|
}
|
|
1599
1777
|
const data = result.data;
|
|
1600
1778
|
const hasContent = data.features.length > 0;
|
|
1601
|
-
return /* @__PURE__ */ (0,
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
1603
|
-
hasContent ? /* @__PURE__ */ (0,
|
|
1779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("header", { className: "es-report-header", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportTitleBlock, { title }) }),
|
|
1781
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportFeatureList, {}) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportEmpty, {})
|
|
1604
1782
|
] }) });
|
|
1605
1783
|
}
|
|
1606
1784
|
|