executable-stories-react 0.7.0 → 0.8.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 +418 -226
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -6
- package/dist/index.d.ts +17 -6
- package/dist/index.js +369 -177
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +492 -318
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +10 -1
- package/dist/interactive.d.ts +10 -1
- package/dist/interactive.js +416 -242
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +30 -0
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +10 -1
- package/dist/parse.d.ts +10 -1
- package/dist/parse.js +30 -0
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +23 -23
- package/dist/ssr.cjs +356 -194
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.d.cts +10 -1
- package/dist/ssr.d.ts +10 -1
- package/dist/ssr.js +316 -154
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -374,17 +374,29 @@ function DocHtml({ entry }) {
|
|
|
374
374
|
] });
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
// src/components/doc/DocState.tsx
|
|
378
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
379
|
+
function DocState({ entry }) {
|
|
380
|
+
let json;
|
|
381
|
+
try {
|
|
382
|
+
json = JSON.stringify(entry.value, null, 2) ?? String(entry.value);
|
|
383
|
+
} catch {
|
|
384
|
+
json = String(entry.value);
|
|
385
|
+
}
|
|
386
|
+
return /* @__PURE__ */ jsx13(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx13("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
387
|
+
}
|
|
388
|
+
|
|
377
389
|
// src/components/doc/DocCustom.tsx
|
|
378
|
-
import { Fragment as Fragment4, jsx as
|
|
390
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
379
391
|
function DocCustom({ entry }) {
|
|
380
392
|
const renderers = useCustomRenderers();
|
|
381
393
|
const renderer = renderers[entry.type];
|
|
382
394
|
if (renderer) {
|
|
383
|
-
return /* @__PURE__ */
|
|
395
|
+
return /* @__PURE__ */ jsx14(Fragment4, { children: renderer(entry) });
|
|
384
396
|
}
|
|
385
397
|
return /* @__PURE__ */ jsxs9("div", { className: "my-2", "data-type": entry.type, children: [
|
|
386
|
-
/* @__PURE__ */
|
|
387
|
-
/* @__PURE__ */
|
|
398
|
+
/* @__PURE__ */ jsx14("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
|
|
399
|
+
/* @__PURE__ */ jsx14("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify(entry.data) })
|
|
388
400
|
] });
|
|
389
401
|
}
|
|
390
402
|
function safeStringify(value) {
|
|
@@ -396,45 +408,47 @@ function safeStringify(value) {
|
|
|
396
408
|
}
|
|
397
409
|
|
|
398
410
|
// src/components/doc/DocEntry.tsx
|
|
399
|
-
import { jsx as
|
|
411
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
400
412
|
function DocEntry({ entry }) {
|
|
401
413
|
switch (entry.kind) {
|
|
402
414
|
case "note":
|
|
403
|
-
return /* @__PURE__ */
|
|
415
|
+
return /* @__PURE__ */ jsx15(DocNote, { entry });
|
|
404
416
|
case "tag":
|
|
405
|
-
return /* @__PURE__ */
|
|
417
|
+
return /* @__PURE__ */ jsx15(DocTag, { entry });
|
|
406
418
|
case "kv":
|
|
407
|
-
return /* @__PURE__ */
|
|
419
|
+
return /* @__PURE__ */ jsx15(DocKv, { entry });
|
|
408
420
|
case "code":
|
|
409
|
-
return /* @__PURE__ */
|
|
421
|
+
return /* @__PURE__ */ jsx15(DocCode, { entry });
|
|
410
422
|
case "table":
|
|
411
|
-
return /* @__PURE__ */
|
|
423
|
+
return /* @__PURE__ */ jsx15(DocTable, { entry });
|
|
412
424
|
case "link":
|
|
413
|
-
return /* @__PURE__ */
|
|
425
|
+
return /* @__PURE__ */ jsx15(DocLink, { entry });
|
|
414
426
|
case "section":
|
|
415
|
-
return /* @__PURE__ */
|
|
427
|
+
return /* @__PURE__ */ jsx15(DocSection, { entry });
|
|
416
428
|
case "mermaid":
|
|
417
|
-
return /* @__PURE__ */
|
|
429
|
+
return /* @__PURE__ */ jsx15(DocMermaid, { entry });
|
|
418
430
|
case "screenshot":
|
|
419
|
-
return /* @__PURE__ */
|
|
431
|
+
return /* @__PURE__ */ jsx15(DocScreenshot, { entry });
|
|
420
432
|
case "video":
|
|
421
|
-
return /* @__PURE__ */
|
|
433
|
+
return /* @__PURE__ */ jsx15(DocVideo, { entry });
|
|
422
434
|
case "html":
|
|
423
|
-
return /* @__PURE__ */
|
|
435
|
+
return /* @__PURE__ */ jsx15(DocHtml, { entry });
|
|
436
|
+
case "state":
|
|
437
|
+
return /* @__PURE__ */ jsx15(DocState, { entry });
|
|
424
438
|
case "custom":
|
|
425
|
-
return /* @__PURE__ */
|
|
439
|
+
return /* @__PURE__ */ jsx15(DocCustom, { entry });
|
|
426
440
|
}
|
|
427
441
|
}
|
|
428
442
|
|
|
429
443
|
// src/components/ReportDocEntries.tsx
|
|
430
|
-
import { Fragment as Fragment5, jsx as
|
|
444
|
+
import { Fragment as Fragment5, jsx as jsx16 } from "react/jsx-runtime";
|
|
431
445
|
function ReportDocEntries({ entries }) {
|
|
432
446
|
if (entries.length === 0) return null;
|
|
433
|
-
return /* @__PURE__ */
|
|
447
|
+
return /* @__PURE__ */ jsx16(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx16(DocEntry, { entry }, i)) });
|
|
434
448
|
}
|
|
435
449
|
|
|
436
450
|
// src/lib/step-params.tsx
|
|
437
|
-
import { jsx as
|
|
451
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
438
452
|
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
439
453
|
function highlightStepParams(text) {
|
|
440
454
|
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
@@ -446,7 +460,7 @@ function highlightStepParams(text) {
|
|
|
446
460
|
const end = start + match[0].length;
|
|
447
461
|
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
448
462
|
nodes.push(
|
|
449
|
-
/* @__PURE__ */
|
|
463
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
450
464
|
);
|
|
451
465
|
lastIndex = end;
|
|
452
466
|
});
|
|
@@ -455,7 +469,7 @@ function highlightStepParams(text) {
|
|
|
455
469
|
}
|
|
456
470
|
|
|
457
471
|
// src/components/ReportSteps.tsx
|
|
458
|
-
import { jsx as
|
|
472
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
459
473
|
var STEP_GLYPH = {
|
|
460
474
|
passed: "\u2713",
|
|
461
475
|
failed: "\u2717",
|
|
@@ -470,7 +484,7 @@ var STEP_GLYPH_COLOR = {
|
|
|
470
484
|
};
|
|
471
485
|
function ReportSteps({ scenario }) {
|
|
472
486
|
if (scenario.steps.length === 0) return null;
|
|
473
|
-
return /* @__PURE__ */
|
|
487
|
+
return /* @__PURE__ */ jsx18("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ jsx18(ReportStepItem, { step }, step.id)) });
|
|
474
488
|
}
|
|
475
489
|
function ReportStepItem({ step }) {
|
|
476
490
|
const kw = step.keyword.toLowerCase();
|
|
@@ -483,8 +497,8 @@ function ReportStepItem({ step }) {
|
|
|
483
497
|
className: cn("py-1.5 text-[0.8125rem] leading-normal", continuation && "pl-5"),
|
|
484
498
|
children: [
|
|
485
499
|
/* @__PURE__ */ jsxs10("div", { className: "flex items-baseline gap-2", children: [
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
/* @__PURE__ */
|
|
500
|
+
/* @__PURE__ */ jsx18("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" }),
|
|
501
|
+
/* @__PURE__ */ jsx18(
|
|
488
502
|
"span",
|
|
489
503
|
{
|
|
490
504
|
className: cn(
|
|
@@ -494,10 +508,10 @@ function ReportStepItem({ step }) {
|
|
|
494
508
|
children: step.keyword
|
|
495
509
|
}
|
|
496
510
|
),
|
|
497
|
-
/* @__PURE__ */
|
|
498
|
-
step.durationMs > 0 ? /* @__PURE__ */
|
|
511
|
+
/* @__PURE__ */ jsx18("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
512
|
+
step.durationMs > 0 ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
|
|
499
513
|
] }),
|
|
500
|
-
step.errorMessage ? /* @__PURE__ */
|
|
514
|
+
step.errorMessage ? /* @__PURE__ */ jsx18(
|
|
501
515
|
"pre",
|
|
502
516
|
{
|
|
503
517
|
role: "alert",
|
|
@@ -505,12 +519,72 @@ function ReportStepItem({ step }) {
|
|
|
505
519
|
children: step.errorMessage
|
|
506
520
|
}
|
|
507
521
|
) : null,
|
|
508
|
-
step.docEntries.length > 0 ? /* @__PURE__ */
|
|
522
|
+
step.docEntries.length > 0 ? /* @__PURE__ */ jsx18("div", { "data-es-docs": true, className: "mt-2 ml-6", children: /* @__PURE__ */ jsx18(ReportDocEntries, { entries: step.docEntries }) }) : null
|
|
509
523
|
]
|
|
510
524
|
}
|
|
511
525
|
);
|
|
512
526
|
}
|
|
513
527
|
|
|
528
|
+
// ../executable-stories-core/dist/state-diff.js
|
|
529
|
+
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
530
|
+
function deepEqual(a, b) {
|
|
531
|
+
if (Object.is(a, b)) return true;
|
|
532
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
533
|
+
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
534
|
+
}
|
|
535
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
536
|
+
const ak = Object.keys(a);
|
|
537
|
+
const bk = Object.keys(b);
|
|
538
|
+
return ak.length === bk.length && ak.every((k) => k in b && deepEqual(a[k], b[k]));
|
|
539
|
+
}
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
var joinKey = (path, key) => path === "" ? key : `${path}.${key}`;
|
|
543
|
+
function walk(path, before, after, out) {
|
|
544
|
+
if (Object.is(before, after)) return;
|
|
545
|
+
if (Array.isArray(before) && Array.isArray(after)) {
|
|
546
|
+
const shared = Math.min(before.length, after.length);
|
|
547
|
+
for (let i = 0; i < shared; i++) walk(`${path}[${i}]`, before[i], after[i], out);
|
|
548
|
+
for (let i = shared; i < after.length; i++) out.push({ path: `${path}[${i}]`, kind: "added", after: after[i] });
|
|
549
|
+
for (let i = shared; i < before.length; i++) out.push({ path: `${path}[${i}]`, kind: "removed", before: before[i] });
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (isPlainObject(before) && isPlainObject(after)) {
|
|
553
|
+
for (const key of Object.keys(after)) {
|
|
554
|
+
const p = joinKey(path, key);
|
|
555
|
+
if (key in before) walk(p, before[key], after[key], out);
|
|
556
|
+
else out.push({ path: p, kind: "added", after: after[key] });
|
|
557
|
+
}
|
|
558
|
+
for (const key of Object.keys(before)) {
|
|
559
|
+
if (!(key in after)) out.push({ path: joinKey(path, key), kind: "removed", before: before[key] });
|
|
560
|
+
}
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
if (!deepEqual(before, after)) out.push({ path, kind: "changed", before, after });
|
|
564
|
+
}
|
|
565
|
+
function diffStateValues(before, after) {
|
|
566
|
+
const out = [];
|
|
567
|
+
walk("", before, after, out);
|
|
568
|
+
return out;
|
|
569
|
+
}
|
|
570
|
+
function formatStateValue(value, maxLen = 60) {
|
|
571
|
+
const s = value === void 0 ? "undefined" : JSON.stringify(value);
|
|
572
|
+
return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
|
|
573
|
+
}
|
|
574
|
+
function summarizeStateChanges(changes) {
|
|
575
|
+
return changes.map((c) => {
|
|
576
|
+
const at = c.path === "" ? "(root)" : c.path;
|
|
577
|
+
switch (c.kind) {
|
|
578
|
+
case "added":
|
|
579
|
+
return `+ ${at}: ${formatStateValue(c.after)}`;
|
|
580
|
+
case "removed":
|
|
581
|
+
return `\u2212 ${at}`;
|
|
582
|
+
case "changed":
|
|
583
|
+
return `${at}: ${formatStateValue(c.before)} \u2192 ${formatStateValue(c.after)}`;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
514
588
|
// ../executable-stories-core/dist/storyboard.js
|
|
515
589
|
function findScreenshot(entries) {
|
|
516
590
|
for (const entry of entries) {
|
|
@@ -522,26 +596,55 @@ function findScreenshot(entries) {
|
|
|
522
596
|
}
|
|
523
597
|
return void 0;
|
|
524
598
|
}
|
|
599
|
+
function findStates(entries, out = []) {
|
|
600
|
+
for (const entry of entries) {
|
|
601
|
+
if (entry.kind === "state") out.push(entry);
|
|
602
|
+
if (entry.children) findStates(entry.children, out);
|
|
603
|
+
}
|
|
604
|
+
return out;
|
|
605
|
+
}
|
|
606
|
+
var laneOf = (label) => label ?? "";
|
|
525
607
|
function extractStoryboardFrames(scenario) {
|
|
526
608
|
const frames = [];
|
|
609
|
+
const laneOrder = [];
|
|
610
|
+
const previous = /* @__PURE__ */ new Map();
|
|
527
611
|
for (const step of scenario.steps) {
|
|
528
612
|
const shot = findScreenshot(step.docEntries);
|
|
529
|
-
|
|
613
|
+
const stateDocs = findStates(step.docEntries);
|
|
614
|
+
if (!shot && stateDocs.length === 0) continue;
|
|
615
|
+
const byLane = /* @__PURE__ */ new Map();
|
|
616
|
+
for (const doc of stateDocs) {
|
|
617
|
+
const lane = laneOf(doc.label);
|
|
618
|
+
if (!byLane.has(lane) && !laneOrder.includes(lane)) laneOrder.push(lane);
|
|
619
|
+
byLane.set(lane, doc);
|
|
620
|
+
}
|
|
621
|
+
const states = [];
|
|
622
|
+
for (const lane of laneOrder) {
|
|
623
|
+
const doc = byLane.get(lane);
|
|
624
|
+
if (!doc) continue;
|
|
625
|
+
const card = {
|
|
626
|
+
...doc.label !== void 0 && { label: doc.label },
|
|
627
|
+
value: doc.value
|
|
628
|
+
};
|
|
629
|
+
if (previous.has(lane)) card.changes = diffStateValues(previous.get(lane), doc.value);
|
|
630
|
+
previous.set(lane, doc.value);
|
|
631
|
+
states.push(card);
|
|
632
|
+
}
|
|
530
633
|
frames.push({
|
|
531
634
|
stepId: step.id,
|
|
532
635
|
stepIndex: step.index,
|
|
533
636
|
keyword: step.keyword,
|
|
534
637
|
text: step.text,
|
|
535
638
|
status: step.status,
|
|
536
|
-
path: shot.path,
|
|
537
|
-
|
|
639
|
+
...shot && { screenshot: { path: shot.path, ...shot.alt !== void 0 && { alt: shot.alt } } },
|
|
640
|
+
states
|
|
538
641
|
});
|
|
539
642
|
}
|
|
540
643
|
return frames;
|
|
541
644
|
}
|
|
542
645
|
|
|
543
646
|
// src/components/ReportStoryboard.tsx
|
|
544
|
-
import { jsx as
|
|
647
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
545
648
|
var FRAME_GLYPH = {
|
|
546
649
|
passed: "\u2713",
|
|
547
650
|
failed: "\u2717",
|
|
@@ -558,54 +661,113 @@ function ReportStoryboard({ scenario }) {
|
|
|
558
661
|
const frames = extractStoryboardFrames(scenario);
|
|
559
662
|
if (frames.length < 2) return null;
|
|
560
663
|
return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
664
|
+
/* @__PURE__ */ jsx19("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
665
|
+
/* @__PURE__ */ jsx19("ol", { className: "flex items-start gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx19(StoryboardFrameItem, { frame }, frame.stepId)) })
|
|
563
666
|
] });
|
|
564
667
|
}
|
|
565
668
|
function StoryboardFrameItem({ frame }) {
|
|
566
|
-
const src = isLocalFsPath(frame.path) ? void 0 : safeImageUrl(frame.path);
|
|
567
669
|
const label = `${frame.keyword} ${frame.text}`;
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
670
|
+
const hasStates = frame.states.length > 0;
|
|
671
|
+
const caption = /* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
672
|
+
/* @__PURE__ */ jsx19("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
673
|
+
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
674
|
+
/* @__PURE__ */ jsx19("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
675
|
+
" ",
|
|
676
|
+
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: frame.screenshot?.alt ?? frame.text })
|
|
677
|
+
] })
|
|
678
|
+
] });
|
|
679
|
+
return (
|
|
680
|
+
// State cards need room for diff rows; screenshot-only frames keep the
|
|
681
|
+
// original narrow film-cell width (and DOM) unchanged.
|
|
682
|
+
/* @__PURE__ */ jsxs11("li", { className: cn("shrink-0", hasStates ? "w-64" : "w-40"), children: [
|
|
683
|
+
frame.screenshot ? /* @__PURE__ */ jsx19(FrameScreenshot, { frame, label }) : null,
|
|
684
|
+
hasStates ? /* @__PURE__ */ jsx19("div", { className: cn("flex flex-col gap-1.5", frame.screenshot && "mt-1.5"), children: frame.states.map((card, i) => /* @__PURE__ */ jsx19(StateCardView, { card }, card.label ?? i)) }) : null,
|
|
685
|
+
frame.screenshot ? caption : (
|
|
686
|
+
// No screenshot means no image anchor, so the caption carries the
|
|
687
|
+
// jump-to-step link instead.
|
|
688
|
+
/* @__PURE__ */ jsx19("a", { href: `#${frame.stepId}`, "aria-label": `Jump to step: ${label}`, className: "block hover:underline", children: caption })
|
|
689
|
+
)
|
|
690
|
+
] })
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
function FrameScreenshot({ frame, label }) {
|
|
694
|
+
const path = frame.screenshot?.path ?? "";
|
|
695
|
+
const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
|
|
696
|
+
return /* @__PURE__ */ jsx19(
|
|
697
|
+
"a",
|
|
698
|
+
{
|
|
699
|
+
href: `#${frame.stepId}`,
|
|
700
|
+
"aria-label": `Jump to step: ${label}`,
|
|
701
|
+
className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
|
|
702
|
+
children: src ? /* @__PURE__ */ jsx19(
|
|
703
|
+
"img",
|
|
704
|
+
{
|
|
705
|
+
src,
|
|
706
|
+
alt: frame.screenshot?.alt ?? label,
|
|
707
|
+
loading: "lazy",
|
|
708
|
+
className: "h-24 w-full bg-muted object-cover object-top"
|
|
709
|
+
}
|
|
710
|
+
) : /* @__PURE__ */ jsx19("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" })
|
|
711
|
+
}
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
var CHANGE_TONE = {
|
|
715
|
+
added: "bg-pass-bg text-pass",
|
|
716
|
+
removed: "bg-fail-bg text-fail",
|
|
717
|
+
changed: "bg-skip-bg text-skip"
|
|
718
|
+
};
|
|
719
|
+
function prettyJson(value) {
|
|
720
|
+
try {
|
|
721
|
+
return JSON.stringify(value, null, 2) ?? String(value);
|
|
722
|
+
} catch {
|
|
723
|
+
return String(value);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
function StateCardView({ card }) {
|
|
727
|
+
const json = prettyJson(card.value);
|
|
728
|
+
const firstCapture = card.changes === void 0;
|
|
729
|
+
return /* @__PURE__ */ jsxs11("div", { "data-slot": "state-card", className: "rounded-md border border-border bg-card p-2", children: [
|
|
730
|
+
/* @__PURE__ */ jsxs11("p", { className: "flex flex-wrap items-baseline gap-1.5", children: [
|
|
731
|
+
/* @__PURE__ */ jsx19("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" }),
|
|
732
|
+
firstCapture ? /* @__PURE__ */ jsx19("span", { className: "text-[0.625rem] text-muted-foreground italic", children: "first capture" }) : null
|
|
733
|
+
] }),
|
|
734
|
+
!firstCapture && (card.changes && card.changes.length > 0 ? /* @__PURE__ */ jsx19("ul", { className: "mt-1.5 flex flex-col gap-0.5", children: card.changes.map((change, i) => /* @__PURE__ */ jsx19(
|
|
735
|
+
"li",
|
|
571
736
|
{
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
737
|
+
className: cn(
|
|
738
|
+
"rounded-sm px-1.5 py-0.5 font-mono text-[0.625rem] leading-snug break-all",
|
|
739
|
+
CHANGE_TONE[change.kind]
|
|
740
|
+
),
|
|
741
|
+
children: summarizeStateChanges([change])[0]
|
|
742
|
+
},
|
|
743
|
+
i
|
|
744
|
+
)) }) : /* @__PURE__ */ jsx19("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
|
|
745
|
+
/* @__PURE__ */ jsxs11(
|
|
746
|
+
"details",
|
|
747
|
+
{
|
|
748
|
+
open: firstCapture && json.length <= 240,
|
|
749
|
+
className: cn(firstCapture ? "mt-1.5" : "mt-1"),
|
|
750
|
+
children: [
|
|
751
|
+
/* @__PURE__ */ jsx19("summary", { className: "cursor-pointer text-[0.625rem] text-muted-foreground hover:text-foreground", children: "Snapshot" }),
|
|
752
|
+
/* @__PURE__ */ jsx19("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 })
|
|
753
|
+
]
|
|
584
754
|
}
|
|
585
|
-
)
|
|
586
|
-
/* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
587
|
-
/* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
588
|
-
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
589
|
-
/* @__PURE__ */ jsx18("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
590
|
-
" ",
|
|
591
|
-
/* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: frame.alt ?? frame.text })
|
|
592
|
-
] })
|
|
593
|
-
] })
|
|
755
|
+
)
|
|
594
756
|
] });
|
|
595
757
|
}
|
|
596
758
|
|
|
597
759
|
// src/components/ReportAttachments.tsx
|
|
598
|
-
import { Fragment as Fragment6, jsx as
|
|
760
|
+
import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
599
761
|
function ReportAttachments({ attachments }) {
|
|
600
762
|
if (attachments.length === 0) return null;
|
|
601
763
|
return (
|
|
602
764
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
603
765
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
604
|
-
/* @__PURE__ */
|
|
766
|
+
/* @__PURE__ */ jsx20("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
605
767
|
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
606
768
|
const isImage = att.mediaType.startsWith("image/");
|
|
607
|
-
return /* @__PURE__ */
|
|
608
|
-
/* @__PURE__ */
|
|
769
|
+
return /* @__PURE__ */ jsx20("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
770
|
+
/* @__PURE__ */ jsx20(
|
|
609
771
|
"img",
|
|
610
772
|
{
|
|
611
773
|
src: dataUri,
|
|
@@ -614,7 +776,7 @@ function ReportAttachments({ attachments }) {
|
|
|
614
776
|
className: "max-w-full rounded-md border border-border"
|
|
615
777
|
}
|
|
616
778
|
),
|
|
617
|
-
/* @__PURE__ */
|
|
779
|
+
/* @__PURE__ */ jsx20("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
618
780
|
] }) : /* @__PURE__ */ jsxs12(
|
|
619
781
|
"a",
|
|
620
782
|
{
|
|
@@ -688,15 +850,15 @@ function toTraceRows(spans) {
|
|
|
688
850
|
roots.sort((a, b) => a.span.startTimeMs - b.span.startTimeMs);
|
|
689
851
|
const rows = [];
|
|
690
852
|
const seen = /* @__PURE__ */ new Set();
|
|
691
|
-
const
|
|
853
|
+
const walk2 = (node, depth) => {
|
|
692
854
|
if (seen.has(node.span.spanId)) return;
|
|
693
855
|
seen.add(node.span.spanId);
|
|
694
856
|
rows.push({ ...node.span, depth });
|
|
695
|
-
for (const child of node.children)
|
|
857
|
+
for (const child of node.children) walk2(child, depth + 1);
|
|
696
858
|
};
|
|
697
|
-
for (const root of roots)
|
|
859
|
+
for (const root of roots) walk2(root, 0);
|
|
698
860
|
for (const node of byId.values()) {
|
|
699
|
-
if (!seen.has(node.span.spanId))
|
|
861
|
+
if (!seen.has(node.span.spanId)) walk2(node, 0);
|
|
700
862
|
}
|
|
701
863
|
return rows;
|
|
702
864
|
}
|
|
@@ -712,7 +874,7 @@ function traceWindow(rows) {
|
|
|
712
874
|
}
|
|
713
875
|
|
|
714
876
|
// src/components/ReportTrace.tsx
|
|
715
|
-
import { jsx as
|
|
877
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
716
878
|
var BAR_COLOR = {
|
|
717
879
|
ok: "bg-pass",
|
|
718
880
|
error: "bg-fail",
|
|
@@ -733,11 +895,11 @@ function ReportTrace({ spans }) {
|
|
|
733
895
|
formatDuration(totalMs),
|
|
734
896
|
")"
|
|
735
897
|
] }),
|
|
736
|
-
/* @__PURE__ */
|
|
898
|
+
/* @__PURE__ */ jsx21("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
737
899
|
const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
|
|
738
900
|
const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
|
|
739
901
|
return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
|
|
740
|
-
/* @__PURE__ */
|
|
902
|
+
/* @__PURE__ */ jsx21(
|
|
741
903
|
"span",
|
|
742
904
|
{
|
|
743
905
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
@@ -746,14 +908,14 @@ function ReportTrace({ spans }) {
|
|
|
746
908
|
children: row.name
|
|
747
909
|
}
|
|
748
910
|
),
|
|
749
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ jsx21("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx21(
|
|
750
912
|
"span",
|
|
751
913
|
{
|
|
752
914
|
className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
|
|
753
915
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
754
916
|
}
|
|
755
917
|
) }),
|
|
756
|
-
/* @__PURE__ */
|
|
918
|
+
/* @__PURE__ */ jsx21("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
757
919
|
] }, `${row.spanId}-${i}`);
|
|
758
920
|
}) })
|
|
759
921
|
] });
|
|
@@ -804,7 +966,7 @@ function flakinessOf(entries) {
|
|
|
804
966
|
}
|
|
805
967
|
|
|
806
968
|
// src/components/ScenarioRunHistory.tsx
|
|
807
|
-
import { Fragment as Fragment7, jsx as
|
|
969
|
+
import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
808
970
|
var MAX_DOTS = 10;
|
|
809
971
|
var DOT_COLOR = {
|
|
810
972
|
passed: "bg-pass",
|
|
@@ -825,15 +987,15 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
825
987
|
const flaky = flakinessOf(recent) === "flaky";
|
|
826
988
|
const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
|
|
827
989
|
return /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
828
|
-
flaky ? /* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
990
|
+
flaky ? /* @__PURE__ */ jsx22(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
|
|
991
|
+
/* @__PURE__ */ jsx22(
|
|
830
992
|
"span",
|
|
831
993
|
{
|
|
832
994
|
role: "img",
|
|
833
995
|
"aria-label": `Run history: ${summary}`,
|
|
834
996
|
title: summary,
|
|
835
997
|
className: "flex shrink-0 items-center gap-[3px]",
|
|
836
|
-
children: recent.map((e, i) => /* @__PURE__ */
|
|
998
|
+
children: recent.map((e, i) => /* @__PURE__ */ jsx22(
|
|
837
999
|
"span",
|
|
838
1000
|
{
|
|
839
1001
|
"aria-hidden": true,
|
|
@@ -872,9 +1034,9 @@ function useScenarioActions() {
|
|
|
872
1034
|
|
|
873
1035
|
// src/components/ui/card.tsx
|
|
874
1036
|
import "react";
|
|
875
|
-
import { jsx as
|
|
1037
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
876
1038
|
function Card({ className, ...props }) {
|
|
877
|
-
return /* @__PURE__ */
|
|
1039
|
+
return /* @__PURE__ */ jsx23(
|
|
878
1040
|
"div",
|
|
879
1041
|
{
|
|
880
1042
|
"data-slot": "card",
|
|
@@ -887,7 +1049,7 @@ function Card({ className, ...props }) {
|
|
|
887
1049
|
);
|
|
888
1050
|
}
|
|
889
1051
|
function CardHeader({ className, ...props }) {
|
|
890
|
-
return /* @__PURE__ */
|
|
1052
|
+
return /* @__PURE__ */ jsx23(
|
|
891
1053
|
"div",
|
|
892
1054
|
{
|
|
893
1055
|
"data-slot": "card-header",
|
|
@@ -900,7 +1062,7 @@ function CardHeader({ className, ...props }) {
|
|
|
900
1062
|
);
|
|
901
1063
|
}
|
|
902
1064
|
function CardContent({ className, ...props }) {
|
|
903
|
-
return /* @__PURE__ */
|
|
1065
|
+
return /* @__PURE__ */ jsx23(
|
|
904
1066
|
"div",
|
|
905
1067
|
{
|
|
906
1068
|
"data-slot": "card-content",
|
|
@@ -914,13 +1076,13 @@ function CardContent({ className, ...props }) {
|
|
|
914
1076
|
import "react";
|
|
915
1077
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
916
1078
|
import { CheckIcon } from "lucide-react";
|
|
917
|
-
import { jsx as
|
|
1079
|
+
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
918
1080
|
var itemClasses = "relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg:not([class*='text-'])]:text-muted-foreground";
|
|
919
1081
|
function DropdownMenu(props) {
|
|
920
|
-
return /* @__PURE__ */
|
|
1082
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
921
1083
|
}
|
|
922
1084
|
function DropdownMenuTrigger(props) {
|
|
923
|
-
return /* @__PURE__ */
|
|
1085
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
924
1086
|
}
|
|
925
1087
|
function DropdownMenuContent({
|
|
926
1088
|
className,
|
|
@@ -928,14 +1090,14 @@ function DropdownMenuContent({
|
|
|
928
1090
|
sideOffset = 4,
|
|
929
1091
|
...props
|
|
930
1092
|
}) {
|
|
931
|
-
return /* @__PURE__ */
|
|
1093
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx24(
|
|
932
1094
|
MenuPrimitive.Positioner,
|
|
933
1095
|
{
|
|
934
1096
|
"data-slot": "dropdown-menu-positioner",
|
|
935
1097
|
className: "z-50",
|
|
936
1098
|
align,
|
|
937
1099
|
sideOffset,
|
|
938
|
-
children: /* @__PURE__ */
|
|
1100
|
+
children: /* @__PURE__ */ jsx24(
|
|
939
1101
|
MenuPrimitive.Popup,
|
|
940
1102
|
{
|
|
941
1103
|
"data-slot": "dropdown-menu-content",
|
|
@@ -953,7 +1115,7 @@ function DropdownMenuItem({
|
|
|
953
1115
|
className,
|
|
954
1116
|
...props
|
|
955
1117
|
}) {
|
|
956
|
-
return /* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsx24(
|
|
957
1119
|
MenuPrimitive.Item,
|
|
958
1120
|
{
|
|
959
1121
|
"data-slot": "dropdown-menu-item",
|
|
@@ -965,7 +1127,7 @@ function DropdownMenuItem({
|
|
|
965
1127
|
|
|
966
1128
|
// src/components/ReportScenario.tsx
|
|
967
1129
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
968
|
-
import { jsx as
|
|
1130
|
+
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
969
1131
|
var STATUS_META = {
|
|
970
1132
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
971
1133
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -992,7 +1154,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
992
1154
|
/* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
|
|
993
1155
|
/* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
994
1156
|
hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
995
|
-
collapsible ? /* @__PURE__ */
|
|
1157
|
+
collapsible ? /* @__PURE__ */ jsx25(
|
|
996
1158
|
"button",
|
|
997
1159
|
{
|
|
998
1160
|
type: "button",
|
|
@@ -1001,36 +1163,36 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1001
1163
|
"aria-controls": bodyId,
|
|
1002
1164
|
"aria-label": `Toggle ${scenario.title}`,
|
|
1003
1165
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
1004
|
-
children: /* @__PURE__ */
|
|
1166
|
+
children: /* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
1005
1167
|
}
|
|
1006
1168
|
) : null,
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1169
|
+
/* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1170
|
+
/* @__PURE__ */ jsx25("span", { children: scenario.title })
|
|
1009
1171
|
] }),
|
|
1010
1172
|
/* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
scenario.durationMs > 0 ? /* @__PURE__ */
|
|
1013
|
-
meta.showPill ? /* @__PURE__ */
|
|
1173
|
+
/* @__PURE__ */ jsx25(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1174
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ jsx25("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1175
|
+
meta.showPill ? /* @__PURE__ */ jsx25(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx25("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1014
1176
|
actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1015
|
-
/* @__PURE__ */
|
|
1177
|
+
/* @__PURE__ */ jsx25(
|
|
1016
1178
|
DropdownMenuTrigger,
|
|
1017
1179
|
{
|
|
1018
1180
|
"aria-label": `Actions for ${scenario.title}`,
|
|
1019
1181
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1020
|
-
children: /* @__PURE__ */
|
|
1182
|
+
children: /* @__PURE__ */ jsx25(MoreHorizontalIcon, { "aria-hidden": true })
|
|
1021
1183
|
}
|
|
1022
1184
|
),
|
|
1023
1185
|
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
|
|
1024
1186
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1025
|
-
/* @__PURE__ */
|
|
1187
|
+
/* @__PURE__ */ jsx25(LinkIcon, {}),
|
|
1026
1188
|
" Copy link"
|
|
1027
1189
|
] }),
|
|
1028
1190
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1029
|
-
/* @__PURE__ */
|
|
1191
|
+
/* @__PURE__ */ jsx25(FileTextIcon, {}),
|
|
1030
1192
|
" Copy as Markdown"
|
|
1031
1193
|
] }),
|
|
1032
1194
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1033
|
-
/* @__PURE__ */
|
|
1195
|
+
/* @__PURE__ */ jsx25(SparklesIcon, {}),
|
|
1034
1196
|
" Explain with AI"
|
|
1035
1197
|
] })
|
|
1036
1198
|
] })
|
|
@@ -1038,12 +1200,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1038
1200
|
] })
|
|
1039
1201
|
] }),
|
|
1040
1202
|
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs16("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1041
|
-
scenario.tags.map((t) => /* @__PURE__ */
|
|
1042
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */
|
|
1203
|
+
scenario.tags.map((t) => /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsx25(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1204
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx25("li", { children: ticket.url ? /* @__PURE__ */ jsx25("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1043
1205
|
] }) : null
|
|
1044
1206
|
] }),
|
|
1045
1207
|
/* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1046
|
-
scenario.errorMessage ? /* @__PURE__ */
|
|
1208
|
+
scenario.errorMessage ? /* @__PURE__ */ jsx25(
|
|
1047
1209
|
"pre",
|
|
1048
1210
|
{
|
|
1049
1211
|
role: "alert",
|
|
@@ -1051,11 +1213,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1051
1213
|
children: scenario.errorMessage
|
|
1052
1214
|
}
|
|
1053
1215
|
) : null,
|
|
1054
|
-
/* @__PURE__ */
|
|
1055
|
-
/* @__PURE__ */
|
|
1056
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1216
|
+
/* @__PURE__ */ jsx25(ReportStoryboard, { scenario }),
|
|
1217
|
+
/* @__PURE__ */ jsx25(ReportSteps, { scenario }),
|
|
1218
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx25("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx25(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1219
|
+
/* @__PURE__ */ jsx25(ReportAttachments, { attachments: scenario.attachments }),
|
|
1220
|
+
/* @__PURE__ */ jsx25(ReportTrace, { spans: scenario.otelSpans })
|
|
1059
1221
|
] })
|
|
1060
1222
|
]
|
|
1061
1223
|
}
|
|
@@ -1063,13 +1225,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1063
1225
|
}
|
|
1064
1226
|
|
|
1065
1227
|
// src/components/ReportScenarioList.tsx
|
|
1066
|
-
import { Fragment as Fragment8, jsx as
|
|
1228
|
+
import { Fragment as Fragment8, jsx as jsx26 } from "react/jsx-runtime";
|
|
1067
1229
|
function ReportScenarioList({ feature }) {
|
|
1068
|
-
return /* @__PURE__ */
|
|
1230
|
+
return /* @__PURE__ */ jsx26(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx26(ReportScenario, { scenario }, scenario.id)) });
|
|
1069
1231
|
}
|
|
1070
1232
|
|
|
1071
1233
|
// src/components/ReportFeature.tsx
|
|
1072
|
-
import { Fragment as Fragment9, jsx as
|
|
1234
|
+
import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1073
1235
|
function ReportFeature({ feature }) {
|
|
1074
1236
|
const titleId = `${feature.id}-title`;
|
|
1075
1237
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1090,7 +1252,7 @@ function ReportFeature({ feature }) {
|
|
|
1090
1252
|
children: [
|
|
1091
1253
|
/* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1092
1254
|
/* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
|
|
1093
|
-
/* @__PURE__ */
|
|
1255
|
+
/* @__PURE__ */ jsx27("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
|
|
1094
1256
|
"button",
|
|
1095
1257
|
{
|
|
1096
1258
|
type: "button",
|
|
@@ -1099,12 +1261,12 @@ function ReportFeature({ feature }) {
|
|
|
1099
1261
|
"aria-controls": bodyId,
|
|
1100
1262
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1101
1263
|
children: [
|
|
1102
|
-
/* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
1264
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1265
|
+
/* @__PURE__ */ jsx27("span", { className: "truncate", children: feature.title })
|
|
1104
1266
|
]
|
|
1105
1267
|
}
|
|
1106
1268
|
) : feature.title }),
|
|
1107
|
-
/* @__PURE__ */
|
|
1269
|
+
/* @__PURE__ */ jsx27("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1108
1270
|
] }),
|
|
1109
1271
|
/* @__PURE__ */ jsxs17(
|
|
1110
1272
|
"p",
|
|
@@ -1116,13 +1278,13 @@ function ReportFeature({ feature }) {
|
|
|
1116
1278
|
s.passed,
|
|
1117
1279
|
" passed"
|
|
1118
1280
|
] }),
|
|
1119
|
-
/* @__PURE__ */
|
|
1281
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1120
1282
|
/* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1121
1283
|
s.failed,
|
|
1122
1284
|
" failed"
|
|
1123
1285
|
] }),
|
|
1124
1286
|
skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
1125
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1126
1288
|
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1127
1289
|
skipped,
|
|
1128
1290
|
" skipped"
|
|
@@ -1132,7 +1294,7 @@ function ReportFeature({ feature }) {
|
|
|
1132
1294
|
}
|
|
1133
1295
|
)
|
|
1134
1296
|
] }),
|
|
1135
|
-
/* @__PURE__ */
|
|
1297
|
+
/* @__PURE__ */ jsx27("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx27(ReportScenarioList, { feature }) })
|
|
1136
1298
|
]
|
|
1137
1299
|
}
|
|
1138
1300
|
)
|
|
@@ -1140,17 +1302,17 @@ function ReportFeature({ feature }) {
|
|
|
1140
1302
|
}
|
|
1141
1303
|
|
|
1142
1304
|
// src/components/ReportFeatureList.tsx
|
|
1143
|
-
import { jsx as
|
|
1305
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1144
1306
|
function ReportFeatureList() {
|
|
1145
1307
|
const report = useReport();
|
|
1146
|
-
return /* @__PURE__ */
|
|
1308
|
+
return /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx28(ReportFeature, { feature }, feature.id)) });
|
|
1147
1309
|
}
|
|
1148
1310
|
|
|
1149
1311
|
// src/components/ui/empty.tsx
|
|
1150
1312
|
import { cva as cva2 } from "class-variance-authority";
|
|
1151
|
-
import { jsx as
|
|
1313
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1152
1314
|
function Empty({ className, ...props }) {
|
|
1153
|
-
return /* @__PURE__ */
|
|
1315
|
+
return /* @__PURE__ */ jsx29(
|
|
1154
1316
|
"div",
|
|
1155
1317
|
{
|
|
1156
1318
|
"data-slot": "empty",
|
|
@@ -1163,7 +1325,7 @@ function Empty({ className, ...props }) {
|
|
|
1163
1325
|
);
|
|
1164
1326
|
}
|
|
1165
1327
|
function EmptyHeader({ className, ...props }) {
|
|
1166
|
-
return /* @__PURE__ */
|
|
1328
|
+
return /* @__PURE__ */ jsx29(
|
|
1167
1329
|
"div",
|
|
1168
1330
|
{
|
|
1169
1331
|
"data-slot": "empty-header",
|
|
@@ -1190,7 +1352,7 @@ var emptyMediaVariants = cva2(
|
|
|
1190
1352
|
}
|
|
1191
1353
|
);
|
|
1192
1354
|
function EmptyTitle({ className, ...props }) {
|
|
1193
|
-
return /* @__PURE__ */
|
|
1355
|
+
return /* @__PURE__ */ jsx29(
|
|
1194
1356
|
"div",
|
|
1195
1357
|
{
|
|
1196
1358
|
"data-slot": "empty-title",
|
|
@@ -1201,16 +1363,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1201
1363
|
}
|
|
1202
1364
|
|
|
1203
1365
|
// src/components/ReportEmpty.tsx
|
|
1204
|
-
import { jsx as
|
|
1366
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1205
1367
|
function ReportEmpty({ message }) {
|
|
1206
|
-
return /* @__PURE__ */
|
|
1368
|
+
return /* @__PURE__ */ jsx30(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx30(EmptyHeader, { children: /* @__PURE__ */ jsx30(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1207
1369
|
}
|
|
1208
1370
|
|
|
1209
1371
|
// src/components/ReportSummary.tsx
|
|
1210
|
-
import { jsx as
|
|
1372
|
+
import { jsx as jsx31, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1211
1373
|
function ReportSummary({ className }) {
|
|
1212
1374
|
const report = useReport();
|
|
1213
|
-
return /* @__PURE__ */
|
|
1375
|
+
return /* @__PURE__ */ jsx31(
|
|
1214
1376
|
ReportSummaryView,
|
|
1215
1377
|
{
|
|
1216
1378
|
summary: report.summary,
|
|
@@ -1236,7 +1398,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1236
1398
|
if (summary.pending > 0) {
|
|
1237
1399
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1238
1400
|
}
|
|
1239
|
-
return /* @__PURE__ */
|
|
1401
|
+
return /* @__PURE__ */ jsx31(
|
|
1240
1402
|
"dl",
|
|
1241
1403
|
{
|
|
1242
1404
|
className: cn(
|
|
@@ -1256,10 +1418,10 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1256
1418
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1257
1419
|
children: [
|
|
1258
1420
|
/* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1259
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ jsx31("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1260
1422
|
c.label
|
|
1261
1423
|
] }),
|
|
1262
|
-
/* @__PURE__ */
|
|
1424
|
+
/* @__PURE__ */ jsx31("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1263
1425
|
]
|
|
1264
1426
|
},
|
|
1265
1427
|
c.status
|
|
@@ -1319,7 +1481,7 @@ function prUrl(ci) {
|
|
|
1319
1481
|
}
|
|
1320
1482
|
|
|
1321
1483
|
// src/components/ReportMeta.tsx
|
|
1322
|
-
import { jsx as
|
|
1484
|
+
import { jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1323
1485
|
function ReportMeta() {
|
|
1324
1486
|
const report = useReport();
|
|
1325
1487
|
const items = [];
|
|
@@ -1342,7 +1504,7 @@ function ReportMeta() {
|
|
|
1342
1504
|
const short = sha.slice(0, 8);
|
|
1343
1505
|
items.push({
|
|
1344
1506
|
label: "Commit",
|
|
1345
|
-
value: url ? /* @__PURE__ */
|
|
1507
|
+
value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1346
1508
|
});
|
|
1347
1509
|
}
|
|
1348
1510
|
if (report.ci) {
|
|
@@ -1359,7 +1521,7 @@ function ReportMeta() {
|
|
|
1359
1521
|
const label = `#${report.ci.prNumber}`;
|
|
1360
1522
|
items.push({
|
|
1361
1523
|
label: "PR",
|
|
1362
|
-
value: url ? /* @__PURE__ */
|
|
1524
|
+
value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1363
1525
|
});
|
|
1364
1526
|
}
|
|
1365
1527
|
if (items.length === 0) return null;
|
|
@@ -1369,26 +1531,26 @@ function ReportMeta() {
|
|
|
1369
1531
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1370
1532
|
/* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1371
1533
|
/* @__PURE__ */ jsxs19("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
1372
|
-
/* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx32("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1373
1535
|
"Run details"
|
|
1374
1536
|
] }),
|
|
1375
|
-
/* @__PURE__ */
|
|
1376
|
-
/* @__PURE__ */
|
|
1377
|
-
/* @__PURE__ */
|
|
1537
|
+
/* @__PURE__ */ jsx32("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ jsxs19("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1538
|
+
/* @__PURE__ */ jsx32("dt", { className: "font-medium", children: item.label }),
|
|
1539
|
+
/* @__PURE__ */ jsx32("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1378
1540
|
] }, item.label)) })
|
|
1379
1541
|
] })
|
|
1380
1542
|
);
|
|
1381
1543
|
}
|
|
1382
1544
|
|
|
1383
1545
|
// src/components/ReportSchemaError.tsx
|
|
1384
|
-
import { jsx as
|
|
1546
|
+
import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1385
1547
|
function ReportSchemaError({ error }) {
|
|
1386
1548
|
return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1387
|
-
/* @__PURE__ */
|
|
1388
|
-
/* @__PURE__ */
|
|
1549
|
+
/* @__PURE__ */ jsx33("p", { children: /* @__PURE__ */ jsx33("strong", { children: "Report could not be displayed." }) }),
|
|
1550
|
+
/* @__PURE__ */ jsx33("p", { children: error.message }),
|
|
1389
1551
|
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
|
|
1390
1552
|
"The report bundle is newer than this version of ",
|
|
1391
|
-
/* @__PURE__ */
|
|
1553
|
+
/* @__PURE__ */ jsx33("code", { children: "executable-stories-react" }),
|
|
1392
1554
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1393
1555
|
] }) : null,
|
|
1394
1556
|
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
|
|
@@ -1397,18 +1559,18 @@ function ReportSchemaError({ error }) {
|
|
|
1397
1559
|
" validation issue",
|
|
1398
1560
|
error.issues.length === 1 ? "" : "s"
|
|
1399
1561
|
] }),
|
|
1400
|
-
/* @__PURE__ */
|
|
1562
|
+
/* @__PURE__ */ jsx33("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1401
1563
|
] }) : null
|
|
1402
1564
|
] });
|
|
1403
1565
|
}
|
|
1404
1566
|
|
|
1405
1567
|
// src/components/ReportShell.tsx
|
|
1406
|
-
import { Fragment as Fragment10, jsx as
|
|
1568
|
+
import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1407
1569
|
function ReportTitleBlock({ title }) {
|
|
1408
1570
|
return /* @__PURE__ */ jsxs21(Fragment10, { children: [
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
1571
|
+
/* @__PURE__ */ jsx34("h1", { children: title ?? "Story Report" }),
|
|
1572
|
+
/* @__PURE__ */ jsx34(ReportSummary, {}),
|
|
1573
|
+
/* @__PURE__ */ jsx34(ReportMeta, {})
|
|
1412
1574
|
] });
|
|
1413
1575
|
}
|
|
1414
1576
|
function ReportErrorShell({
|
|
@@ -1417,28 +1579,28 @@ function ReportErrorShell({
|
|
|
1417
1579
|
title,
|
|
1418
1580
|
dataTheme
|
|
1419
1581
|
}) {
|
|
1420
|
-
return /* @__PURE__ */
|
|
1582
|
+
return /* @__PURE__ */ jsx34("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx34(ReportSchemaError, { error }) });
|
|
1421
1583
|
}
|
|
1422
1584
|
|
|
1423
1585
|
// src/components/Report.tsx
|
|
1424
|
-
import { jsx as
|
|
1586
|
+
import { jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1425
1587
|
function Report(props) {
|
|
1426
1588
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1427
1589
|
const result = unwrapReport(report);
|
|
1428
1590
|
if (!result.ok) {
|
|
1429
|
-
return /* @__PURE__ */
|
|
1591
|
+
return /* @__PURE__ */ jsx35(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1430
1592
|
}
|
|
1431
1593
|
const data = result.data;
|
|
1432
1594
|
const hasContent = data.features.length > 0;
|
|
1433
|
-
return /* @__PURE__ */
|
|
1434
|
-
/* @__PURE__ */
|
|
1435
|
-
hasContent ? /* @__PURE__ */
|
|
1595
|
+
return /* @__PURE__ */ jsx35(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs22("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1596
|
+
/* @__PURE__ */ jsx35("header", { className: "es-report-header", children: /* @__PURE__ */ jsx35(ReportTitleBlock, { title }) }),
|
|
1597
|
+
hasContent ? /* @__PURE__ */ jsx35(ReportFeatureList, {}) : /* @__PURE__ */ jsx35(ReportEmpty, {})
|
|
1436
1598
|
] }) });
|
|
1437
1599
|
}
|
|
1438
1600
|
|
|
1439
1601
|
// src/components/doc/MermaidView.tsx
|
|
1440
1602
|
import { useEffect, useRef, useState as useState2 } from "react";
|
|
1441
|
-
import { jsx as
|
|
1603
|
+
import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1442
1604
|
function prefersDark(el) {
|
|
1443
1605
|
const themed = el?.closest("[data-theme]");
|
|
1444
1606
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1476,8 +1638,8 @@ function MermaidView({ entry, load }) {
|
|
|
1476
1638
|
}, [entry.code, load]);
|
|
1477
1639
|
if (svg) {
|
|
1478
1640
|
return /* @__PURE__ */ jsxs23("figure", { ref, className: "my-3", children: [
|
|
1479
|
-
entry.title ? /* @__PURE__ */
|
|
1480
|
-
/* @__PURE__ */
|
|
1641
|
+
entry.title ? /* @__PURE__ */ jsx36("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1642
|
+
/* @__PURE__ */ jsx36(
|
|
1481
1643
|
"div",
|
|
1482
1644
|
{
|
|
1483
1645
|
role: "img",
|
|
@@ -1488,18 +1650,18 @@ function MermaidView({ entry, load }) {
|
|
|
1488
1650
|
)
|
|
1489
1651
|
] });
|
|
1490
1652
|
}
|
|
1491
|
-
return /* @__PURE__ */
|
|
1653
|
+
return /* @__PURE__ */ jsx36(MermaidSource, { entry, ref });
|
|
1492
1654
|
}
|
|
1493
1655
|
|
|
1494
1656
|
// src/components/doc/MermaidDiagram.tsx
|
|
1495
|
-
import { jsx as
|
|
1657
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1496
1658
|
var mermaidLoader;
|
|
1497
1659
|
function loadMermaid() {
|
|
1498
1660
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1499
1661
|
return mermaidLoader;
|
|
1500
1662
|
}
|
|
1501
1663
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1502
|
-
return /* @__PURE__ */
|
|
1664
|
+
return /* @__PURE__ */ jsx37(MermaidView, { entry, load });
|
|
1503
1665
|
}
|
|
1504
1666
|
|
|
1505
1667
|
// src/components/ScenarioExplorer.tsx
|
|
@@ -1509,12 +1671,12 @@ import { useState as useState3 } from "react";
|
|
|
1509
1671
|
import "react";
|
|
1510
1672
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1511
1673
|
import { SearchIcon } from "lucide-react";
|
|
1512
|
-
import { jsx as
|
|
1674
|
+
import { jsx as jsx38, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1513
1675
|
function Command({
|
|
1514
1676
|
className,
|
|
1515
1677
|
...props
|
|
1516
1678
|
}) {
|
|
1517
|
-
return /* @__PURE__ */
|
|
1679
|
+
return /* @__PURE__ */ jsx38(
|
|
1518
1680
|
CommandPrimitive,
|
|
1519
1681
|
{
|
|
1520
1682
|
"data-slot": "command",
|
|
@@ -1536,8 +1698,8 @@ function CommandInput({
|
|
|
1536
1698
|
"data-slot": "command-input-wrapper",
|
|
1537
1699
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1538
1700
|
children: [
|
|
1539
|
-
/* @__PURE__ */
|
|
1540
|
-
/* @__PURE__ */
|
|
1701
|
+
/* @__PURE__ */ jsx38(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1702
|
+
/* @__PURE__ */ jsx38(
|
|
1541
1703
|
CommandPrimitive.Input,
|
|
1542
1704
|
{
|
|
1543
1705
|
"data-slot": "command-input",
|
|
@@ -1556,7 +1718,7 @@ function CommandList({
|
|
|
1556
1718
|
className,
|
|
1557
1719
|
...props
|
|
1558
1720
|
}) {
|
|
1559
|
-
return /* @__PURE__ */
|
|
1721
|
+
return /* @__PURE__ */ jsx38(
|
|
1560
1722
|
CommandPrimitive.List,
|
|
1561
1723
|
{
|
|
1562
1724
|
"data-slot": "command-list",
|
|
@@ -1571,7 +1733,7 @@ function CommandList({
|
|
|
1571
1733
|
function CommandEmpty({
|
|
1572
1734
|
...props
|
|
1573
1735
|
}) {
|
|
1574
|
-
return /* @__PURE__ */
|
|
1736
|
+
return /* @__PURE__ */ jsx38(
|
|
1575
1737
|
CommandPrimitive.Empty,
|
|
1576
1738
|
{
|
|
1577
1739
|
"data-slot": "command-empty",
|
|
@@ -1584,7 +1746,7 @@ function CommandGroup({
|
|
|
1584
1746
|
className,
|
|
1585
1747
|
...props
|
|
1586
1748
|
}) {
|
|
1587
|
-
return /* @__PURE__ */
|
|
1749
|
+
return /* @__PURE__ */ jsx38(
|
|
1588
1750
|
CommandPrimitive.Group,
|
|
1589
1751
|
{
|
|
1590
1752
|
"data-slot": "command-group",
|
|
@@ -1600,7 +1762,7 @@ function CommandItem({
|
|
|
1600
1762
|
className,
|
|
1601
1763
|
...props
|
|
1602
1764
|
}) {
|
|
1603
|
-
return /* @__PURE__ */
|
|
1765
|
+
return /* @__PURE__ */ jsx38(
|
|
1604
1766
|
CommandPrimitive.Item,
|
|
1605
1767
|
{
|
|
1606
1768
|
"data-slot": "command-item",
|
|
@@ -1614,7 +1776,7 @@ function CommandItem({
|
|
|
1614
1776
|
}
|
|
1615
1777
|
|
|
1616
1778
|
// src/components/ScenarioExplorer.tsx
|
|
1617
|
-
import { jsx as
|
|
1779
|
+
import { jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1618
1780
|
var STATUS_FILTERS = [
|
|
1619
1781
|
{ value: "all", label: "All" },
|
|
1620
1782
|
{ value: "passed", label: "Passed" },
|
|
@@ -1640,7 +1802,7 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1640
1802
|
" failed"
|
|
1641
1803
|
] })
|
|
1642
1804
|
] }) : null,
|
|
1643
|
-
/* @__PURE__ */
|
|
1805
|
+
/* @__PURE__ */ jsx39("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx39(
|
|
1644
1806
|
"button",
|
|
1645
1807
|
{
|
|
1646
1808
|
type: "button",
|
|
@@ -1661,20 +1823,20 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1661
1823
|
className: "rounded-lg border border-border bg-card",
|
|
1662
1824
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1663
1825
|
children: [
|
|
1664
|
-
/* @__PURE__ */
|
|
1826
|
+
/* @__PURE__ */ jsx39(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
1665
1827
|
/* @__PURE__ */ jsxs25(CommandList, { className: "max-h-none", children: [
|
|
1666
|
-
/* @__PURE__ */
|
|
1667
|
-
/* @__PURE__ */
|
|
1828
|
+
/* @__PURE__ */ jsx39(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
1829
|
+
/* @__PURE__ */ jsx39(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx39(
|
|
1668
1830
|
CommandItem,
|
|
1669
1831
|
{
|
|
1670
1832
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1671
1833
|
asChild: true,
|
|
1672
1834
|
className: "cursor-pointer",
|
|
1673
1835
|
children: /* @__PURE__ */ jsxs25("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
1676
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */
|
|
1677
|
-
/* @__PURE__ */
|
|
1836
|
+
/* @__PURE__ */ jsx39(Badge, { variant: s.status, children: s.status }),
|
|
1837
|
+
/* @__PURE__ */ jsx39("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
1838
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx39(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
1839
|
+
/* @__PURE__ */ jsx39("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
1678
1840
|
] })
|
|
1679
1841
|
},
|
|
1680
1842
|
s.id
|
|
@@ -2170,6 +2332,9 @@ var story_report_v1_default = {
|
|
|
2170
2332
|
{
|
|
2171
2333
|
$ref: "#/$defs/DocHtml"
|
|
2172
2334
|
},
|
|
2335
|
+
{
|
|
2336
|
+
$ref: "#/$defs/DocState"
|
|
2337
|
+
},
|
|
2173
2338
|
{
|
|
2174
2339
|
$ref: "#/$defs/DocCustom"
|
|
2175
2340
|
}
|
|
@@ -2545,6 +2710,33 @@ var story_report_v1_default = {
|
|
|
2545
2710
|
}
|
|
2546
2711
|
]
|
|
2547
2712
|
},
|
|
2713
|
+
DocState: {
|
|
2714
|
+
type: "object",
|
|
2715
|
+
properties: {
|
|
2716
|
+
kind: {
|
|
2717
|
+
const: "state"
|
|
2718
|
+
},
|
|
2719
|
+
label: {
|
|
2720
|
+
type: "string"
|
|
2721
|
+
},
|
|
2722
|
+
value: {},
|
|
2723
|
+
phase: {
|
|
2724
|
+
$ref: "#/$defs/DocPhase"
|
|
2725
|
+
},
|
|
2726
|
+
children: {
|
|
2727
|
+
type: "array",
|
|
2728
|
+
items: {
|
|
2729
|
+
$ref: "#/$defs/DocEntry"
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
},
|
|
2733
|
+
required: [
|
|
2734
|
+
"kind",
|
|
2735
|
+
"value",
|
|
2736
|
+
"phase"
|
|
2737
|
+
],
|
|
2738
|
+
additionalProperties: false
|
|
2739
|
+
},
|
|
2548
2740
|
DocCustom: {
|
|
2549
2741
|
type: "object",
|
|
2550
2742
|
properties: {
|