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/interactive.js
CHANGED
|
@@ -383,17 +383,29 @@ function DocHtml({ entry }) {
|
|
|
383
383
|
] });
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
// src/components/doc/DocState.tsx
|
|
387
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
388
|
+
function DocState({ entry }) {
|
|
389
|
+
let json;
|
|
390
|
+
try {
|
|
391
|
+
json = JSON.stringify(entry.value, null, 2) ?? String(entry.value);
|
|
392
|
+
} catch {
|
|
393
|
+
json = String(entry.value);
|
|
394
|
+
}
|
|
395
|
+
return /* @__PURE__ */ jsx13(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx13("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
396
|
+
}
|
|
397
|
+
|
|
386
398
|
// src/components/doc/DocCustom.tsx
|
|
387
|
-
import { Fragment as Fragment4, jsx as
|
|
399
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
388
400
|
function DocCustom({ entry }) {
|
|
389
401
|
const renderers = useCustomRenderers();
|
|
390
402
|
const renderer = renderers[entry.type];
|
|
391
403
|
if (renderer) {
|
|
392
|
-
return /* @__PURE__ */
|
|
404
|
+
return /* @__PURE__ */ jsx14(Fragment4, { children: renderer(entry) });
|
|
393
405
|
}
|
|
394
406
|
return /* @__PURE__ */ jsxs9("div", { className: "my-2", "data-type": entry.type, children: [
|
|
395
|
-
/* @__PURE__ */
|
|
396
|
-
/* @__PURE__ */
|
|
407
|
+
/* @__PURE__ */ jsx14("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
|
|
408
|
+
/* @__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) })
|
|
397
409
|
] });
|
|
398
410
|
}
|
|
399
411
|
function safeStringify(value) {
|
|
@@ -405,45 +417,47 @@ function safeStringify(value) {
|
|
|
405
417
|
}
|
|
406
418
|
|
|
407
419
|
// src/components/doc/DocEntry.tsx
|
|
408
|
-
import { jsx as
|
|
420
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
409
421
|
function DocEntry({ entry }) {
|
|
410
422
|
switch (entry.kind) {
|
|
411
423
|
case "note":
|
|
412
|
-
return /* @__PURE__ */
|
|
424
|
+
return /* @__PURE__ */ jsx15(DocNote, { entry });
|
|
413
425
|
case "tag":
|
|
414
|
-
return /* @__PURE__ */
|
|
426
|
+
return /* @__PURE__ */ jsx15(DocTag, { entry });
|
|
415
427
|
case "kv":
|
|
416
|
-
return /* @__PURE__ */
|
|
428
|
+
return /* @__PURE__ */ jsx15(DocKv, { entry });
|
|
417
429
|
case "code":
|
|
418
|
-
return /* @__PURE__ */
|
|
430
|
+
return /* @__PURE__ */ jsx15(DocCode, { entry });
|
|
419
431
|
case "table":
|
|
420
|
-
return /* @__PURE__ */
|
|
432
|
+
return /* @__PURE__ */ jsx15(DocTable, { entry });
|
|
421
433
|
case "link":
|
|
422
|
-
return /* @__PURE__ */
|
|
434
|
+
return /* @__PURE__ */ jsx15(DocLink, { entry });
|
|
423
435
|
case "section":
|
|
424
|
-
return /* @__PURE__ */
|
|
436
|
+
return /* @__PURE__ */ jsx15(DocSection, { entry });
|
|
425
437
|
case "mermaid":
|
|
426
|
-
return /* @__PURE__ */
|
|
438
|
+
return /* @__PURE__ */ jsx15(DocMermaid, { entry });
|
|
427
439
|
case "screenshot":
|
|
428
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ jsx15(DocScreenshot, { entry });
|
|
429
441
|
case "video":
|
|
430
|
-
return /* @__PURE__ */
|
|
442
|
+
return /* @__PURE__ */ jsx15(DocVideo, { entry });
|
|
431
443
|
case "html":
|
|
432
|
-
return /* @__PURE__ */
|
|
444
|
+
return /* @__PURE__ */ jsx15(DocHtml, { entry });
|
|
445
|
+
case "state":
|
|
446
|
+
return /* @__PURE__ */ jsx15(DocState, { entry });
|
|
433
447
|
case "custom":
|
|
434
|
-
return /* @__PURE__ */
|
|
448
|
+
return /* @__PURE__ */ jsx15(DocCustom, { entry });
|
|
435
449
|
}
|
|
436
450
|
}
|
|
437
451
|
|
|
438
452
|
// src/components/ReportDocEntries.tsx
|
|
439
|
-
import { Fragment as Fragment5, jsx as
|
|
453
|
+
import { Fragment as Fragment5, jsx as jsx16 } from "react/jsx-runtime";
|
|
440
454
|
function ReportDocEntries({ entries }) {
|
|
441
455
|
if (entries.length === 0) return null;
|
|
442
|
-
return /* @__PURE__ */
|
|
456
|
+
return /* @__PURE__ */ jsx16(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx16(DocEntry, { entry }, i)) });
|
|
443
457
|
}
|
|
444
458
|
|
|
445
459
|
// src/lib/step-params.tsx
|
|
446
|
-
import { jsx as
|
|
460
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
447
461
|
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
448
462
|
function highlightStepParams(text) {
|
|
449
463
|
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
@@ -455,7 +469,7 @@ function highlightStepParams(text) {
|
|
|
455
469
|
const end = start + match[0].length;
|
|
456
470
|
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
457
471
|
nodes.push(
|
|
458
|
-
/* @__PURE__ */
|
|
472
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
459
473
|
);
|
|
460
474
|
lastIndex = end;
|
|
461
475
|
});
|
|
@@ -464,7 +478,7 @@ function highlightStepParams(text) {
|
|
|
464
478
|
}
|
|
465
479
|
|
|
466
480
|
// src/components/ReportSteps.tsx
|
|
467
|
-
import { jsx as
|
|
481
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
468
482
|
var STEP_GLYPH = {
|
|
469
483
|
passed: "\u2713",
|
|
470
484
|
failed: "\u2717",
|
|
@@ -479,7 +493,7 @@ var STEP_GLYPH_COLOR = {
|
|
|
479
493
|
};
|
|
480
494
|
function ReportSteps({ scenario }) {
|
|
481
495
|
if (scenario.steps.length === 0) return null;
|
|
482
|
-
return /* @__PURE__ */
|
|
496
|
+
return /* @__PURE__ */ jsx18("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ jsx18(ReportStepItem, { step }, step.id)) });
|
|
483
497
|
}
|
|
484
498
|
function ReportStepItem({ step }) {
|
|
485
499
|
const kw = step.keyword.toLowerCase();
|
|
@@ -492,8 +506,8 @@ function ReportStepItem({ step }) {
|
|
|
492
506
|
className: cn("py-1.5 text-[0.8125rem] leading-normal", continuation && "pl-5"),
|
|
493
507
|
children: [
|
|
494
508
|
/* @__PURE__ */ jsxs10("div", { className: "flex items-baseline gap-2", children: [
|
|
495
|
-
/* @__PURE__ */
|
|
496
|
-
/* @__PURE__ */
|
|
509
|
+
/* @__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" }),
|
|
510
|
+
/* @__PURE__ */ jsx18(
|
|
497
511
|
"span",
|
|
498
512
|
{
|
|
499
513
|
className: cn(
|
|
@@ -503,10 +517,10 @@ function ReportStepItem({ step }) {
|
|
|
503
517
|
children: step.keyword
|
|
504
518
|
}
|
|
505
519
|
),
|
|
506
|
-
/* @__PURE__ */
|
|
507
|
-
step.durationMs > 0 ? /* @__PURE__ */
|
|
520
|
+
/* @__PURE__ */ jsx18("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
521
|
+
step.durationMs > 0 ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
|
|
508
522
|
] }),
|
|
509
|
-
step.errorMessage ? /* @__PURE__ */
|
|
523
|
+
step.errorMessage ? /* @__PURE__ */ jsx18(
|
|
510
524
|
"pre",
|
|
511
525
|
{
|
|
512
526
|
role: "alert",
|
|
@@ -514,12 +528,72 @@ function ReportStepItem({ step }) {
|
|
|
514
528
|
children: step.errorMessage
|
|
515
529
|
}
|
|
516
530
|
) : null,
|
|
517
|
-
step.docEntries.length > 0 ? /* @__PURE__ */
|
|
531
|
+
step.docEntries.length > 0 ? /* @__PURE__ */ jsx18("div", { "data-es-docs": true, className: "mt-2 ml-6", children: /* @__PURE__ */ jsx18(ReportDocEntries, { entries: step.docEntries }) }) : null
|
|
518
532
|
]
|
|
519
533
|
}
|
|
520
534
|
);
|
|
521
535
|
}
|
|
522
536
|
|
|
537
|
+
// ../executable-stories-core/dist/state-diff.js
|
|
538
|
+
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
539
|
+
function deepEqual(a, b) {
|
|
540
|
+
if (Object.is(a, b)) return true;
|
|
541
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
542
|
+
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
543
|
+
}
|
|
544
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
545
|
+
const ak = Object.keys(a);
|
|
546
|
+
const bk = Object.keys(b);
|
|
547
|
+
return ak.length === bk.length && ak.every((k) => k in b && deepEqual(a[k], b[k]));
|
|
548
|
+
}
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
var joinKey = (path, key) => path === "" ? key : `${path}.${key}`;
|
|
552
|
+
function walk(path, before, after, out) {
|
|
553
|
+
if (Object.is(before, after)) return;
|
|
554
|
+
if (Array.isArray(before) && Array.isArray(after)) {
|
|
555
|
+
const shared = Math.min(before.length, after.length);
|
|
556
|
+
for (let i = 0; i < shared; i++) walk(`${path}[${i}]`, before[i], after[i], out);
|
|
557
|
+
for (let i = shared; i < after.length; i++) out.push({ path: `${path}[${i}]`, kind: "added", after: after[i] });
|
|
558
|
+
for (let i = shared; i < before.length; i++) out.push({ path: `${path}[${i}]`, kind: "removed", before: before[i] });
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
if (isPlainObject(before) && isPlainObject(after)) {
|
|
562
|
+
for (const key of Object.keys(after)) {
|
|
563
|
+
const p = joinKey(path, key);
|
|
564
|
+
if (key in before) walk(p, before[key], after[key], out);
|
|
565
|
+
else out.push({ path: p, kind: "added", after: after[key] });
|
|
566
|
+
}
|
|
567
|
+
for (const key of Object.keys(before)) {
|
|
568
|
+
if (!(key in after)) out.push({ path: joinKey(path, key), kind: "removed", before: before[key] });
|
|
569
|
+
}
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (!deepEqual(before, after)) out.push({ path, kind: "changed", before, after });
|
|
573
|
+
}
|
|
574
|
+
function diffStateValues(before, after) {
|
|
575
|
+
const out = [];
|
|
576
|
+
walk("", before, after, out);
|
|
577
|
+
return out;
|
|
578
|
+
}
|
|
579
|
+
function formatStateValue(value, maxLen = 60) {
|
|
580
|
+
const s = value === void 0 ? "undefined" : JSON.stringify(value);
|
|
581
|
+
return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
|
|
582
|
+
}
|
|
583
|
+
function summarizeStateChanges(changes) {
|
|
584
|
+
return changes.map((c) => {
|
|
585
|
+
const at = c.path === "" ? "(root)" : c.path;
|
|
586
|
+
switch (c.kind) {
|
|
587
|
+
case "added":
|
|
588
|
+
return `+ ${at}: ${formatStateValue(c.after)}`;
|
|
589
|
+
case "removed":
|
|
590
|
+
return `\u2212 ${at}`;
|
|
591
|
+
case "changed":
|
|
592
|
+
return `${at}: ${formatStateValue(c.before)} \u2192 ${formatStateValue(c.after)}`;
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
|
|
523
597
|
// ../executable-stories-core/dist/storyboard.js
|
|
524
598
|
function findScreenshot(entries) {
|
|
525
599
|
for (const entry of entries) {
|
|
@@ -531,26 +605,55 @@ function findScreenshot(entries) {
|
|
|
531
605
|
}
|
|
532
606
|
return void 0;
|
|
533
607
|
}
|
|
608
|
+
function findStates(entries, out = []) {
|
|
609
|
+
for (const entry of entries) {
|
|
610
|
+
if (entry.kind === "state") out.push(entry);
|
|
611
|
+
if (entry.children) findStates(entry.children, out);
|
|
612
|
+
}
|
|
613
|
+
return out;
|
|
614
|
+
}
|
|
615
|
+
var laneOf = (label) => label ?? "";
|
|
534
616
|
function extractStoryboardFrames(scenario) {
|
|
535
617
|
const frames = [];
|
|
618
|
+
const laneOrder = [];
|
|
619
|
+
const previous = /* @__PURE__ */ new Map();
|
|
536
620
|
for (const step of scenario.steps) {
|
|
537
621
|
const shot = findScreenshot(step.docEntries);
|
|
538
|
-
|
|
622
|
+
const stateDocs = findStates(step.docEntries);
|
|
623
|
+
if (!shot && stateDocs.length === 0) continue;
|
|
624
|
+
const byLane = /* @__PURE__ */ new Map();
|
|
625
|
+
for (const doc of stateDocs) {
|
|
626
|
+
const lane = laneOf(doc.label);
|
|
627
|
+
if (!byLane.has(lane) && !laneOrder.includes(lane)) laneOrder.push(lane);
|
|
628
|
+
byLane.set(lane, doc);
|
|
629
|
+
}
|
|
630
|
+
const states = [];
|
|
631
|
+
for (const lane of laneOrder) {
|
|
632
|
+
const doc = byLane.get(lane);
|
|
633
|
+
if (!doc) continue;
|
|
634
|
+
const card = {
|
|
635
|
+
...doc.label !== void 0 && { label: doc.label },
|
|
636
|
+
value: doc.value
|
|
637
|
+
};
|
|
638
|
+
if (previous.has(lane)) card.changes = diffStateValues(previous.get(lane), doc.value);
|
|
639
|
+
previous.set(lane, doc.value);
|
|
640
|
+
states.push(card);
|
|
641
|
+
}
|
|
539
642
|
frames.push({
|
|
540
643
|
stepId: step.id,
|
|
541
644
|
stepIndex: step.index,
|
|
542
645
|
keyword: step.keyword,
|
|
543
646
|
text: step.text,
|
|
544
647
|
status: step.status,
|
|
545
|
-
path: shot.path,
|
|
546
|
-
|
|
648
|
+
...shot && { screenshot: { path: shot.path, ...shot.alt !== void 0 && { alt: shot.alt } } },
|
|
649
|
+
states
|
|
547
650
|
});
|
|
548
651
|
}
|
|
549
652
|
return frames;
|
|
550
653
|
}
|
|
551
654
|
|
|
552
655
|
// src/components/ReportStoryboard.tsx
|
|
553
|
-
import { jsx as
|
|
656
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
554
657
|
var FRAME_GLYPH = {
|
|
555
658
|
passed: "\u2713",
|
|
556
659
|
failed: "\u2717",
|
|
@@ -567,54 +670,113 @@ function ReportStoryboard({ scenario }) {
|
|
|
567
670
|
const frames = extractStoryboardFrames(scenario);
|
|
568
671
|
if (frames.length < 2) return null;
|
|
569
672
|
return /* @__PURE__ */ jsxs11("section", { "data-slot": "storyboard", "aria-label": "Storyboard", className: "mb-3", children: [
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
/* @__PURE__ */
|
|
673
|
+
/* @__PURE__ */ jsx19("h4", { className: "mb-1.5 text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Storyboard" }),
|
|
674
|
+
/* @__PURE__ */ jsx19("ol", { className: "flex items-start gap-3 overflow-x-auto pb-2", children: frames.map((frame) => /* @__PURE__ */ jsx19(StoryboardFrameItem, { frame }, frame.stepId)) })
|
|
572
675
|
] });
|
|
573
676
|
}
|
|
574
677
|
function StoryboardFrameItem({ frame }) {
|
|
575
|
-
const src = isLocalFsPath(frame.path) ? void 0 : safeImageUrl(frame.path);
|
|
576
678
|
const label = `${frame.keyword} ${frame.text}`;
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
679
|
+
const hasStates = frame.states.length > 0;
|
|
680
|
+
const caption = /* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
681
|
+
/* @__PURE__ */ jsx19("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
682
|
+
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
683
|
+
/* @__PURE__ */ jsx19("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
684
|
+
" ",
|
|
685
|
+
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: frame.screenshot?.alt ?? frame.text })
|
|
686
|
+
] })
|
|
687
|
+
] });
|
|
688
|
+
return (
|
|
689
|
+
// State cards need room for diff rows; screenshot-only frames keep the
|
|
690
|
+
// original narrow film-cell width (and DOM) unchanged.
|
|
691
|
+
/* @__PURE__ */ jsxs11("li", { className: cn("shrink-0", hasStates ? "w-64" : "w-40"), children: [
|
|
692
|
+
frame.screenshot ? /* @__PURE__ */ jsx19(FrameScreenshot, { frame, label }) : null,
|
|
693
|
+
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,
|
|
694
|
+
frame.screenshot ? caption : (
|
|
695
|
+
// No screenshot means no image anchor, so the caption carries the
|
|
696
|
+
// jump-to-step link instead.
|
|
697
|
+
/* @__PURE__ */ jsx19("a", { href: `#${frame.stepId}`, "aria-label": `Jump to step: ${label}`, className: "block hover:underline", children: caption })
|
|
698
|
+
)
|
|
699
|
+
] })
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
function FrameScreenshot({ frame, label }) {
|
|
703
|
+
const path = frame.screenshot?.path ?? "";
|
|
704
|
+
const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
|
|
705
|
+
return /* @__PURE__ */ jsx19(
|
|
706
|
+
"a",
|
|
707
|
+
{
|
|
708
|
+
href: `#${frame.stepId}`,
|
|
709
|
+
"aria-label": `Jump to step: ${label}`,
|
|
710
|
+
className: "block overflow-hidden rounded-md border border-border transition-colors hover:border-ring",
|
|
711
|
+
children: src ? /* @__PURE__ */ jsx19(
|
|
712
|
+
"img",
|
|
713
|
+
{
|
|
714
|
+
src,
|
|
715
|
+
alt: frame.screenshot?.alt ?? label,
|
|
716
|
+
loading: "lazy",
|
|
717
|
+
className: "h-24 w-full bg-muted object-cover object-top"
|
|
718
|
+
}
|
|
719
|
+
) : /* @__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" })
|
|
720
|
+
}
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
var CHANGE_TONE = {
|
|
724
|
+
added: "bg-pass-bg text-pass",
|
|
725
|
+
removed: "bg-fail-bg text-fail",
|
|
726
|
+
changed: "bg-skip-bg text-skip"
|
|
727
|
+
};
|
|
728
|
+
function prettyJson(value) {
|
|
729
|
+
try {
|
|
730
|
+
return JSON.stringify(value, null, 2) ?? String(value);
|
|
731
|
+
} catch {
|
|
732
|
+
return String(value);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
function StateCardView({ card }) {
|
|
736
|
+
const json = prettyJson(card.value);
|
|
737
|
+
const firstCapture = card.changes === void 0;
|
|
738
|
+
return /* @__PURE__ */ jsxs11("div", { "data-slot": "state-card", className: "rounded-md border border-border bg-card p-2", children: [
|
|
739
|
+
/* @__PURE__ */ jsxs11("p", { className: "flex flex-wrap items-baseline gap-1.5", children: [
|
|
740
|
+
/* @__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" }),
|
|
741
|
+
firstCapture ? /* @__PURE__ */ jsx19("span", { className: "text-[0.625rem] text-muted-foreground italic", children: "first capture" }) : null
|
|
742
|
+
] }),
|
|
743
|
+
!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(
|
|
744
|
+
"li",
|
|
580
745
|
{
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
746
|
+
className: cn(
|
|
747
|
+
"rounded-sm px-1.5 py-0.5 font-mono text-[0.625rem] leading-snug break-all",
|
|
748
|
+
CHANGE_TONE[change.kind]
|
|
749
|
+
),
|
|
750
|
+
children: summarizeStateChanges([change])[0]
|
|
751
|
+
},
|
|
752
|
+
i
|
|
753
|
+
)) }) : /* @__PURE__ */ jsx19("p", { className: "mt-1.5 text-[0.625rem] text-muted-foreground", children: "No changes" })),
|
|
754
|
+
/* @__PURE__ */ jsxs11(
|
|
755
|
+
"details",
|
|
756
|
+
{
|
|
757
|
+
open: firstCapture && json.length <= 240,
|
|
758
|
+
className: cn(firstCapture ? "mt-1.5" : "mt-1"),
|
|
759
|
+
children: [
|
|
760
|
+
/* @__PURE__ */ jsx19("summary", { className: "cursor-pointer text-[0.625rem] text-muted-foreground hover:text-foreground", children: "Snapshot" }),
|
|
761
|
+
/* @__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 })
|
|
762
|
+
]
|
|
593
763
|
}
|
|
594
|
-
)
|
|
595
|
-
/* @__PURE__ */ jsxs11("p", { className: "mt-1 flex items-baseline gap-1.5 text-[0.6875rem] leading-snug", children: [
|
|
596
|
-
/* @__PURE__ */ jsx18("span", { "aria-hidden": true, className: cn("shrink-0", FRAME_GLYPH_COLOR[frame.status]), children: FRAME_GLYPH[frame.status] ?? "\u25CB" }),
|
|
597
|
-
/* @__PURE__ */ jsxs11("span", { className: "min-w-0", children: [
|
|
598
|
-
/* @__PURE__ */ jsx18("span", { className: "font-mono font-semibold text-keyword", children: frame.keyword }),
|
|
599
|
-
" ",
|
|
600
|
-
/* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: frame.alt ?? frame.text })
|
|
601
|
-
] })
|
|
602
|
-
] })
|
|
764
|
+
)
|
|
603
765
|
] });
|
|
604
766
|
}
|
|
605
767
|
|
|
606
768
|
// src/components/ReportAttachments.tsx
|
|
607
|
-
import { Fragment as Fragment6, jsx as
|
|
769
|
+
import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
608
770
|
function ReportAttachments({ attachments }) {
|
|
609
771
|
if (attachments.length === 0) return null;
|
|
610
772
|
return (
|
|
611
773
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
612
774
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
613
|
-
/* @__PURE__ */
|
|
775
|
+
/* @__PURE__ */ jsx20("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
614
776
|
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
615
777
|
const isImage = att.mediaType.startsWith("image/");
|
|
616
|
-
return /* @__PURE__ */
|
|
617
|
-
/* @__PURE__ */
|
|
778
|
+
return /* @__PURE__ */ jsx20("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
779
|
+
/* @__PURE__ */ jsx20(
|
|
618
780
|
"img",
|
|
619
781
|
{
|
|
620
782
|
src: dataUri,
|
|
@@ -623,7 +785,7 @@ function ReportAttachments({ attachments }) {
|
|
|
623
785
|
className: "max-w-full rounded-md border border-border"
|
|
624
786
|
}
|
|
625
787
|
),
|
|
626
|
-
/* @__PURE__ */
|
|
788
|
+
/* @__PURE__ */ jsx20("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
627
789
|
] }) : /* @__PURE__ */ jsxs12(
|
|
628
790
|
"a",
|
|
629
791
|
{
|
|
@@ -697,15 +859,15 @@ function toTraceRows(spans) {
|
|
|
697
859
|
roots.sort((a, b) => a.span.startTimeMs - b.span.startTimeMs);
|
|
698
860
|
const rows = [];
|
|
699
861
|
const seen = /* @__PURE__ */ new Set();
|
|
700
|
-
const
|
|
862
|
+
const walk2 = (node, depth) => {
|
|
701
863
|
if (seen.has(node.span.spanId)) return;
|
|
702
864
|
seen.add(node.span.spanId);
|
|
703
865
|
rows.push({ ...node.span, depth });
|
|
704
|
-
for (const child of node.children)
|
|
866
|
+
for (const child of node.children) walk2(child, depth + 1);
|
|
705
867
|
};
|
|
706
|
-
for (const root of roots)
|
|
868
|
+
for (const root of roots) walk2(root, 0);
|
|
707
869
|
for (const node of byId.values()) {
|
|
708
|
-
if (!seen.has(node.span.spanId))
|
|
870
|
+
if (!seen.has(node.span.spanId)) walk2(node, 0);
|
|
709
871
|
}
|
|
710
872
|
return rows;
|
|
711
873
|
}
|
|
@@ -721,7 +883,7 @@ function traceWindow(rows) {
|
|
|
721
883
|
}
|
|
722
884
|
|
|
723
885
|
// src/components/ReportTrace.tsx
|
|
724
|
-
import { jsx as
|
|
886
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
725
887
|
var BAR_COLOR = {
|
|
726
888
|
ok: "bg-pass",
|
|
727
889
|
error: "bg-fail",
|
|
@@ -742,11 +904,11 @@ function ReportTrace({ spans }) {
|
|
|
742
904
|
formatDuration(totalMs),
|
|
743
905
|
")"
|
|
744
906
|
] }),
|
|
745
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsx21("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
|
|
746
908
|
const leftPct = (row.startTimeMs - minStartMs) / totalMs * 100;
|
|
747
909
|
const widthPct = Math.max(row.durationMs / totalMs * 100, 0.5);
|
|
748
910
|
return /* @__PURE__ */ jsxs13("li", { className: "flex items-center gap-2", children: [
|
|
749
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ jsx21(
|
|
750
912
|
"span",
|
|
751
913
|
{
|
|
752
914
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
@@ -755,14 +917,14 @@ function ReportTrace({ spans }) {
|
|
|
755
917
|
children: row.name
|
|
756
918
|
}
|
|
757
919
|
),
|
|
758
|
-
/* @__PURE__ */
|
|
920
|
+
/* @__PURE__ */ jsx21("span", { className: "relative h-3 w-1/2 shrink-0 overflow-hidden rounded-sm bg-border/40", children: /* @__PURE__ */ jsx21(
|
|
759
921
|
"span",
|
|
760
922
|
{
|
|
761
923
|
className: cn("absolute top-0 h-full rounded-sm", BAR_COLOR[row.status]),
|
|
762
924
|
style: { left: `${leftPct}%`, width: `${widthPct}%` }
|
|
763
925
|
}
|
|
764
926
|
) }),
|
|
765
|
-
/* @__PURE__ */
|
|
927
|
+
/* @__PURE__ */ jsx21("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
|
|
766
928
|
] }, `${row.spanId}-${i}`);
|
|
767
929
|
}) })
|
|
768
930
|
] });
|
|
@@ -831,7 +993,7 @@ function diffSinceLastRun(history2, scenarios) {
|
|
|
831
993
|
}
|
|
832
994
|
|
|
833
995
|
// src/components/ScenarioRunHistory.tsx
|
|
834
|
-
import { Fragment as Fragment7, jsx as
|
|
996
|
+
import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
835
997
|
var MAX_DOTS = 10;
|
|
836
998
|
var DOT_COLOR = {
|
|
837
999
|
passed: "bg-pass",
|
|
@@ -852,15 +1014,15 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
852
1014
|
const flaky = flakinessOf(recent) === "flaky";
|
|
853
1015
|
const summary = flaky ? `${describeRunHistory(recent)} \xB7 Flaky` : describeRunHistory(recent);
|
|
854
1016
|
return /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
855
|
-
flaky ? /* @__PURE__ */
|
|
856
|
-
/* @__PURE__ */
|
|
1017
|
+
flaky ? /* @__PURE__ */ jsx22(Badge, { variant: "pending", "aria-label": "Flaky: status flips between recent runs", title: summary, children: "Flaky" }) : null,
|
|
1018
|
+
/* @__PURE__ */ jsx22(
|
|
857
1019
|
"span",
|
|
858
1020
|
{
|
|
859
1021
|
role: "img",
|
|
860
1022
|
"aria-label": `Run history: ${summary}`,
|
|
861
1023
|
title: summary,
|
|
862
1024
|
className: "flex shrink-0 items-center gap-[3px]",
|
|
863
|
-
children: recent.map((e, i) => /* @__PURE__ */
|
|
1025
|
+
children: recent.map((e, i) => /* @__PURE__ */ jsx22(
|
|
864
1026
|
"span",
|
|
865
1027
|
{
|
|
866
1028
|
"aria-hidden": true,
|
|
@@ -951,7 +1113,7 @@ function stringify(value) {
|
|
|
951
1113
|
return String(value);
|
|
952
1114
|
}
|
|
953
1115
|
}
|
|
954
|
-
function docEntryToMarkdown(entry) {
|
|
1116
|
+
function docEntryToMarkdown(entry, stateLanes) {
|
|
955
1117
|
const lines = [];
|
|
956
1118
|
switch (entry.kind) {
|
|
957
1119
|
case "note":
|
|
@@ -1003,13 +1165,24 @@ function docEntryToMarkdown(entry) {
|
|
|
1003
1165
|
case "custom":
|
|
1004
1166
|
lines.push(`**${entry.type}**`, "", "```json", stringify(entry.data), "```");
|
|
1005
1167
|
break;
|
|
1168
|
+
case "state": {
|
|
1169
|
+
const lane = entry.label ?? "";
|
|
1170
|
+
lines.push(`**${entry.label ?? "State"}**`);
|
|
1171
|
+
if (stateLanes?.has(lane)) {
|
|
1172
|
+
const summary = summarizeStateChanges(diffStateValues(stateLanes.get(lane), entry.value));
|
|
1173
|
+
if (summary.length > 0) lines.push("", ...summary.map((l) => `- ${l}`));
|
|
1174
|
+
}
|
|
1175
|
+
stateLanes?.set(lane, entry.value);
|
|
1176
|
+
lines.push("", "<details>", "<summary>snapshot</summary>", "", "```json", stringify(entry.value ?? null), "```", "", "</details>");
|
|
1177
|
+
break;
|
|
1178
|
+
}
|
|
1006
1179
|
}
|
|
1007
1180
|
for (const child of entry.children ?? []) {
|
|
1008
|
-
lines.push("", ...docEntryToMarkdown(child));
|
|
1181
|
+
lines.push("", ...docEntryToMarkdown(child, stateLanes));
|
|
1009
1182
|
}
|
|
1010
1183
|
return lines;
|
|
1011
1184
|
}
|
|
1012
|
-
function stepLines(step, ordinal, full) {
|
|
1185
|
+
function stepLines(step, ordinal, full, stateLanes) {
|
|
1013
1186
|
const status = step.status === "passed" ? "" : ` \u2014 **${step.status}**`;
|
|
1014
1187
|
const lines = [`${ordinal}. **${step.keyword}** ${step.text}${status}`];
|
|
1015
1188
|
if (!full) return lines;
|
|
@@ -1017,7 +1190,7 @@ function stepLines(step, ordinal, full) {
|
|
|
1017
1190
|
lines.push(...step.errorMessage.split("\n").map((l) => ` > ${l}`));
|
|
1018
1191
|
}
|
|
1019
1192
|
for (const entry of step.docEntries) {
|
|
1020
|
-
lines.push("", ...docEntryToMarkdown(entry).map((l) => l === "" ? l : ` ${l}`));
|
|
1193
|
+
lines.push("", ...docEntryToMarkdown(entry, stateLanes).map((l) => l === "" ? l : ` ${l}`));
|
|
1021
1194
|
}
|
|
1022
1195
|
return lines;
|
|
1023
1196
|
}
|
|
@@ -1026,9 +1199,10 @@ function scenarioToMarkdown(scenario, options = {}) {
|
|
|
1026
1199
|
const full = variant === "full";
|
|
1027
1200
|
const lines = full ? [`# ${scenario.title}`, ""] : [`## ${scenario.title} _(${scenario.status})_`, ""];
|
|
1028
1201
|
if (full && meta.length > 0) lines.push(...meta);
|
|
1202
|
+
const stateLanes = /* @__PURE__ */ new Map();
|
|
1029
1203
|
if (scenario.steps.length > 0) {
|
|
1030
1204
|
if (full) lines.push("", "## Steps", "");
|
|
1031
|
-
scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full)));
|
|
1205
|
+
scenario.steps.forEach((step, i) => lines.push(...stepLines(step, i + 1, full, stateLanes)));
|
|
1032
1206
|
}
|
|
1033
1207
|
if (scenario.errorMessage) {
|
|
1034
1208
|
if (full) lines.push("", "## Failure", "");
|
|
@@ -1037,7 +1211,7 @@ function scenarioToMarkdown(scenario, options = {}) {
|
|
|
1037
1211
|
}
|
|
1038
1212
|
if (full && scenario.docEntries.length > 0) {
|
|
1039
1213
|
lines.push("", "## Docs", "");
|
|
1040
|
-
for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry), "");
|
|
1214
|
+
for (const entry of scenario.docEntries) lines.push(...docEntryToMarkdown(entry, stateLanes), "");
|
|
1041
1215
|
}
|
|
1042
1216
|
return lines.join("\n").replaceAll(/\n{3,}/g, "\n\n").trimEnd() + (full ? "\n" : "");
|
|
1043
1217
|
}
|
|
@@ -1077,9 +1251,9 @@ function scenarioPermalink(scenario) {
|
|
|
1077
1251
|
|
|
1078
1252
|
// src/components/ui/card.tsx
|
|
1079
1253
|
import "react";
|
|
1080
|
-
import { jsx as
|
|
1254
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1081
1255
|
function Card({ className, ...props }) {
|
|
1082
|
-
return /* @__PURE__ */
|
|
1256
|
+
return /* @__PURE__ */ jsx23(
|
|
1083
1257
|
"div",
|
|
1084
1258
|
{
|
|
1085
1259
|
"data-slot": "card",
|
|
@@ -1092,7 +1266,7 @@ function Card({ className, ...props }) {
|
|
|
1092
1266
|
);
|
|
1093
1267
|
}
|
|
1094
1268
|
function CardHeader({ className, ...props }) {
|
|
1095
|
-
return /* @__PURE__ */
|
|
1269
|
+
return /* @__PURE__ */ jsx23(
|
|
1096
1270
|
"div",
|
|
1097
1271
|
{
|
|
1098
1272
|
"data-slot": "card-header",
|
|
@@ -1105,7 +1279,7 @@ function CardHeader({ className, ...props }) {
|
|
|
1105
1279
|
);
|
|
1106
1280
|
}
|
|
1107
1281
|
function CardContent({ className, ...props }) {
|
|
1108
|
-
return /* @__PURE__ */
|
|
1282
|
+
return /* @__PURE__ */ jsx23(
|
|
1109
1283
|
"div",
|
|
1110
1284
|
{
|
|
1111
1285
|
"data-slot": "card-content",
|
|
@@ -1119,13 +1293,13 @@ function CardContent({ className, ...props }) {
|
|
|
1119
1293
|
import "react";
|
|
1120
1294
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
1121
1295
|
import { CheckIcon } from "lucide-react";
|
|
1122
|
-
import { jsx as
|
|
1296
|
+
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1123
1297
|
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";
|
|
1124
1298
|
function DropdownMenu(props) {
|
|
1125
|
-
return /* @__PURE__ */
|
|
1299
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
1126
1300
|
}
|
|
1127
1301
|
function DropdownMenuTrigger(props) {
|
|
1128
|
-
return /* @__PURE__ */
|
|
1302
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
1129
1303
|
}
|
|
1130
1304
|
function DropdownMenuContent({
|
|
1131
1305
|
className,
|
|
@@ -1133,14 +1307,14 @@ function DropdownMenuContent({
|
|
|
1133
1307
|
sideOffset = 4,
|
|
1134
1308
|
...props
|
|
1135
1309
|
}) {
|
|
1136
|
-
return /* @__PURE__ */
|
|
1310
|
+
return /* @__PURE__ */ jsx24(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx24(
|
|
1137
1311
|
MenuPrimitive.Positioner,
|
|
1138
1312
|
{
|
|
1139
1313
|
"data-slot": "dropdown-menu-positioner",
|
|
1140
1314
|
className: "z-50",
|
|
1141
1315
|
align,
|
|
1142
1316
|
sideOffset,
|
|
1143
|
-
children: /* @__PURE__ */
|
|
1317
|
+
children: /* @__PURE__ */ jsx24(
|
|
1144
1318
|
MenuPrimitive.Popup,
|
|
1145
1319
|
{
|
|
1146
1320
|
"data-slot": "dropdown-menu-content",
|
|
@@ -1158,7 +1332,7 @@ function DropdownMenuItem({
|
|
|
1158
1332
|
className,
|
|
1159
1333
|
...props
|
|
1160
1334
|
}) {
|
|
1161
|
-
return /* @__PURE__ */
|
|
1335
|
+
return /* @__PURE__ */ jsx24(
|
|
1162
1336
|
MenuPrimitive.Item,
|
|
1163
1337
|
{
|
|
1164
1338
|
"data-slot": "dropdown-menu-item",
|
|
@@ -1170,7 +1344,7 @@ function DropdownMenuItem({
|
|
|
1170
1344
|
|
|
1171
1345
|
// src/components/ReportScenario.tsx
|
|
1172
1346
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
1173
|
-
import { jsx as
|
|
1347
|
+
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1174
1348
|
var STATUS_META = {
|
|
1175
1349
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
1176
1350
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1197,7 +1371,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1197
1371
|
/* @__PURE__ */ jsxs16(CardHeader, { className: "px-4 py-3", children: [
|
|
1198
1372
|
/* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
1199
1373
|
hideTitle ? null : /* @__PURE__ */ jsxs16("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1200
|
-
collapsible ? /* @__PURE__ */
|
|
1374
|
+
collapsible ? /* @__PURE__ */ jsx25(
|
|
1201
1375
|
"button",
|
|
1202
1376
|
{
|
|
1203
1377
|
type: "button",
|
|
@@ -1206,36 +1380,36 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1206
1380
|
"aria-controls": bodyId,
|
|
1207
1381
|
"aria-label": `Toggle ${scenario.title}`,
|
|
1208
1382
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
1209
|
-
children: /* @__PURE__ */
|
|
1383
|
+
children: /* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
1210
1384
|
}
|
|
1211
1385
|
) : null,
|
|
1212
|
-
/* @__PURE__ */
|
|
1213
|
-
/* @__PURE__ */
|
|
1386
|
+
/* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1387
|
+
/* @__PURE__ */ jsx25("span", { children: scenario.title })
|
|
1214
1388
|
] }),
|
|
1215
1389
|
/* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1216
|
-
/* @__PURE__ */
|
|
1217
|
-
scenario.durationMs > 0 ? /* @__PURE__ */
|
|
1218
|
-
meta.showPill ? /* @__PURE__ */
|
|
1390
|
+
/* @__PURE__ */ jsx25(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1391
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ jsx25("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
1392
|
+
meta.showPill ? /* @__PURE__ */ jsx25(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx25("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1219
1393
|
actions ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1220
|
-
/* @__PURE__ */
|
|
1394
|
+
/* @__PURE__ */ jsx25(
|
|
1221
1395
|
DropdownMenuTrigger,
|
|
1222
1396
|
{
|
|
1223
1397
|
"aria-label": `Actions for ${scenario.title}`,
|
|
1224
1398
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1225
|
-
children: /* @__PURE__ */
|
|
1399
|
+
children: /* @__PURE__ */ jsx25(MoreHorizontalIcon, { "aria-hidden": true })
|
|
1226
1400
|
}
|
|
1227
1401
|
),
|
|
1228
1402
|
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
|
|
1229
1403
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1230
|
-
/* @__PURE__ */
|
|
1404
|
+
/* @__PURE__ */ jsx25(LinkIcon, {}),
|
|
1231
1405
|
" Copy link"
|
|
1232
1406
|
] }),
|
|
1233
1407
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1234
|
-
/* @__PURE__ */
|
|
1408
|
+
/* @__PURE__ */ jsx25(FileTextIcon, {}),
|
|
1235
1409
|
" Copy as Markdown"
|
|
1236
1410
|
] }),
|
|
1237
1411
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1238
|
-
/* @__PURE__ */
|
|
1412
|
+
/* @__PURE__ */ jsx25(SparklesIcon, {}),
|
|
1239
1413
|
" Explain with AI"
|
|
1240
1414
|
] })
|
|
1241
1415
|
] })
|
|
@@ -1243,12 +1417,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1243
1417
|
] })
|
|
1244
1418
|
] }),
|
|
1245
1419
|
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: [
|
|
1246
|
-
scenario.tags.map((t) => /* @__PURE__ */
|
|
1247
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */
|
|
1420
|
+
scenario.tags.map((t) => /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsx25(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1421
|
+
(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}`))
|
|
1248
1422
|
] }) : null
|
|
1249
1423
|
] }),
|
|
1250
1424
|
/* @__PURE__ */ jsxs16(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1251
|
-
scenario.errorMessage ? /* @__PURE__ */
|
|
1425
|
+
scenario.errorMessage ? /* @__PURE__ */ jsx25(
|
|
1252
1426
|
"pre",
|
|
1253
1427
|
{
|
|
1254
1428
|
role: "alert",
|
|
@@ -1256,11 +1430,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1256
1430
|
children: scenario.errorMessage
|
|
1257
1431
|
}
|
|
1258
1432
|
) : null,
|
|
1259
|
-
/* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1261
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
/* @__PURE__ */
|
|
1433
|
+
/* @__PURE__ */ jsx25(ReportStoryboard, { scenario }),
|
|
1434
|
+
/* @__PURE__ */ jsx25(ReportSteps, { scenario }),
|
|
1435
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx25("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx25(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1436
|
+
/* @__PURE__ */ jsx25(ReportAttachments, { attachments: scenario.attachments }),
|
|
1437
|
+
/* @__PURE__ */ jsx25(ReportTrace, { spans: scenario.otelSpans })
|
|
1264
1438
|
] })
|
|
1265
1439
|
]
|
|
1266
1440
|
}
|
|
@@ -1268,13 +1442,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1268
1442
|
}
|
|
1269
1443
|
|
|
1270
1444
|
// src/components/ReportScenarioList.tsx
|
|
1271
|
-
import { Fragment as Fragment8, jsx as
|
|
1445
|
+
import { Fragment as Fragment8, jsx as jsx26 } from "react/jsx-runtime";
|
|
1272
1446
|
function ReportScenarioList({ feature }) {
|
|
1273
|
-
return /* @__PURE__ */
|
|
1447
|
+
return /* @__PURE__ */ jsx26(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx26(ReportScenario, { scenario }, scenario.id)) });
|
|
1274
1448
|
}
|
|
1275
1449
|
|
|
1276
1450
|
// src/components/ReportFeature.tsx
|
|
1277
|
-
import { Fragment as Fragment9, jsx as
|
|
1451
|
+
import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1278
1452
|
function ReportFeature({ feature }) {
|
|
1279
1453
|
const titleId = `${feature.id}-title`;
|
|
1280
1454
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1295,7 +1469,7 @@ function ReportFeature({ feature }) {
|
|
|
1295
1469
|
children: [
|
|
1296
1470
|
/* @__PURE__ */ jsxs17("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1297
1471
|
/* @__PURE__ */ jsxs17("div", { className: "min-w-0", children: [
|
|
1298
|
-
/* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsx27("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs17(
|
|
1299
1473
|
"button",
|
|
1300
1474
|
{
|
|
1301
1475
|
type: "button",
|
|
@@ -1304,12 +1478,12 @@ function ReportFeature({ feature }) {
|
|
|
1304
1478
|
"aria-controls": bodyId,
|
|
1305
1479
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1306
1480
|
children: [
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1481
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1482
|
+
/* @__PURE__ */ jsx27("span", { className: "truncate", children: feature.title })
|
|
1309
1483
|
]
|
|
1310
1484
|
}
|
|
1311
1485
|
) : feature.title }),
|
|
1312
|
-
/* @__PURE__ */
|
|
1486
|
+
/* @__PURE__ */ jsx27("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1313
1487
|
] }),
|
|
1314
1488
|
/* @__PURE__ */ jsxs17(
|
|
1315
1489
|
"p",
|
|
@@ -1321,13 +1495,13 @@ function ReportFeature({ feature }) {
|
|
|
1321
1495
|
s.passed,
|
|
1322
1496
|
" passed"
|
|
1323
1497
|
] }),
|
|
1324
|
-
/* @__PURE__ */
|
|
1498
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1325
1499
|
/* @__PURE__ */ jsxs17("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1326
1500
|
s.failed,
|
|
1327
1501
|
" failed"
|
|
1328
1502
|
] }),
|
|
1329
1503
|
skipped > 0 ? /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
1330
|
-
/* @__PURE__ */
|
|
1504
|
+
/* @__PURE__ */ jsx27("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1331
1505
|
/* @__PURE__ */ jsxs17("span", { children: [
|
|
1332
1506
|
skipped,
|
|
1333
1507
|
" skipped"
|
|
@@ -1337,7 +1511,7 @@ function ReportFeature({ feature }) {
|
|
|
1337
1511
|
}
|
|
1338
1512
|
)
|
|
1339
1513
|
] }),
|
|
1340
|
-
/* @__PURE__ */
|
|
1514
|
+
/* @__PURE__ */ jsx27("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx27(ReportScenarioList, { feature }) })
|
|
1341
1515
|
]
|
|
1342
1516
|
}
|
|
1343
1517
|
)
|
|
@@ -1345,17 +1519,17 @@ function ReportFeature({ feature }) {
|
|
|
1345
1519
|
}
|
|
1346
1520
|
|
|
1347
1521
|
// src/components/ReportFeatureList.tsx
|
|
1348
|
-
import { jsx as
|
|
1522
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1349
1523
|
function ReportFeatureList() {
|
|
1350
1524
|
const report = useReport();
|
|
1351
|
-
return /* @__PURE__ */
|
|
1525
|
+
return /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx28(ReportFeature, { feature }, feature.id)) });
|
|
1352
1526
|
}
|
|
1353
1527
|
|
|
1354
1528
|
// src/components/ui/empty.tsx
|
|
1355
1529
|
import { cva as cva2 } from "class-variance-authority";
|
|
1356
|
-
import { jsx as
|
|
1530
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1357
1531
|
function Empty({ className, ...props }) {
|
|
1358
|
-
return /* @__PURE__ */
|
|
1532
|
+
return /* @__PURE__ */ jsx29(
|
|
1359
1533
|
"div",
|
|
1360
1534
|
{
|
|
1361
1535
|
"data-slot": "empty",
|
|
@@ -1368,7 +1542,7 @@ function Empty({ className, ...props }) {
|
|
|
1368
1542
|
);
|
|
1369
1543
|
}
|
|
1370
1544
|
function EmptyHeader({ className, ...props }) {
|
|
1371
|
-
return /* @__PURE__ */
|
|
1545
|
+
return /* @__PURE__ */ jsx29(
|
|
1372
1546
|
"div",
|
|
1373
1547
|
{
|
|
1374
1548
|
"data-slot": "empty-header",
|
|
@@ -1395,7 +1569,7 @@ var emptyMediaVariants = cva2(
|
|
|
1395
1569
|
}
|
|
1396
1570
|
);
|
|
1397
1571
|
function EmptyTitle({ className, ...props }) {
|
|
1398
|
-
return /* @__PURE__ */
|
|
1572
|
+
return /* @__PURE__ */ jsx29(
|
|
1399
1573
|
"div",
|
|
1400
1574
|
{
|
|
1401
1575
|
"data-slot": "empty-title",
|
|
@@ -1406,16 +1580,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1406
1580
|
}
|
|
1407
1581
|
|
|
1408
1582
|
// src/components/ReportEmpty.tsx
|
|
1409
|
-
import { jsx as
|
|
1583
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1410
1584
|
function ReportEmpty({ message }) {
|
|
1411
|
-
return /* @__PURE__ */
|
|
1585
|
+
return /* @__PURE__ */ jsx30(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx30(EmptyHeader, { children: /* @__PURE__ */ jsx30(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1412
1586
|
}
|
|
1413
1587
|
|
|
1414
1588
|
// src/components/ReportSummary.tsx
|
|
1415
|
-
import { jsx as
|
|
1589
|
+
import { jsx as jsx31, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1416
1590
|
function ReportSummary({ className }) {
|
|
1417
1591
|
const report = useReport();
|
|
1418
|
-
return /* @__PURE__ */
|
|
1592
|
+
return /* @__PURE__ */ jsx31(
|
|
1419
1593
|
ReportSummaryView,
|
|
1420
1594
|
{
|
|
1421
1595
|
summary: report.summary,
|
|
@@ -1441,7 +1615,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1441
1615
|
if (summary.pending > 0) {
|
|
1442
1616
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1443
1617
|
}
|
|
1444
|
-
return /* @__PURE__ */
|
|
1618
|
+
return /* @__PURE__ */ jsx31(
|
|
1445
1619
|
"dl",
|
|
1446
1620
|
{
|
|
1447
1621
|
className: cn(
|
|
@@ -1461,10 +1635,10 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1461
1635
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1462
1636
|
children: [
|
|
1463
1637
|
/* @__PURE__ */ jsxs18("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1464
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsx31("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1465
1639
|
c.label
|
|
1466
1640
|
] }),
|
|
1467
|
-
/* @__PURE__ */
|
|
1641
|
+
/* @__PURE__ */ jsx31("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1468
1642
|
]
|
|
1469
1643
|
},
|
|
1470
1644
|
c.status
|
|
@@ -1524,7 +1698,7 @@ function prUrl(ci) {
|
|
|
1524
1698
|
}
|
|
1525
1699
|
|
|
1526
1700
|
// src/components/ReportMeta.tsx
|
|
1527
|
-
import { jsx as
|
|
1701
|
+
import { jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1528
1702
|
function ReportMeta() {
|
|
1529
1703
|
const report = useReport();
|
|
1530
1704
|
const items = [];
|
|
@@ -1547,7 +1721,7 @@ function ReportMeta() {
|
|
|
1547
1721
|
const short = sha.slice(0, 8);
|
|
1548
1722
|
items.push({
|
|
1549
1723
|
label: "Commit",
|
|
1550
|
-
value: url ? /* @__PURE__ */
|
|
1724
|
+
value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1551
1725
|
});
|
|
1552
1726
|
}
|
|
1553
1727
|
if (report.ci) {
|
|
@@ -1564,7 +1738,7 @@ function ReportMeta() {
|
|
|
1564
1738
|
const label = `#${report.ci.prNumber}`;
|
|
1565
1739
|
items.push({
|
|
1566
1740
|
label: "PR",
|
|
1567
|
-
value: url ? /* @__PURE__ */
|
|
1741
|
+
value: url ? /* @__PURE__ */ jsx32("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1568
1742
|
});
|
|
1569
1743
|
}
|
|
1570
1744
|
if (items.length === 0) return null;
|
|
@@ -1574,26 +1748,26 @@ function ReportMeta() {
|
|
|
1574
1748
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1575
1749
|
/* @__PURE__ */ jsxs19("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1576
1750
|
/* @__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: [
|
|
1577
|
-
/* @__PURE__ */
|
|
1751
|
+
/* @__PURE__ */ jsx32("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1578
1752
|
"Run details"
|
|
1579
1753
|
] }),
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
1754
|
+
/* @__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: [
|
|
1755
|
+
/* @__PURE__ */ jsx32("dt", { className: "font-medium", children: item.label }),
|
|
1756
|
+
/* @__PURE__ */ jsx32("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1583
1757
|
] }, item.label)) })
|
|
1584
1758
|
] })
|
|
1585
1759
|
);
|
|
1586
1760
|
}
|
|
1587
1761
|
|
|
1588
1762
|
// src/components/ReportSchemaError.tsx
|
|
1589
|
-
import { jsx as
|
|
1763
|
+
import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1590
1764
|
function ReportSchemaError({ error }) {
|
|
1591
1765
|
return /* @__PURE__ */ jsxs20("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1592
|
-
/* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1766
|
+
/* @__PURE__ */ jsx33("p", { children: /* @__PURE__ */ jsx33("strong", { children: "Report could not be displayed." }) }),
|
|
1767
|
+
/* @__PURE__ */ jsx33("p", { children: error.message }),
|
|
1594
1768
|
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs20("p", { children: [
|
|
1595
1769
|
"The report bundle is newer than this version of ",
|
|
1596
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ jsx33("code", { children: "executable-stories-react" }),
|
|
1597
1771
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1598
1772
|
] }) : null,
|
|
1599
1773
|
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs20("details", { children: [
|
|
@@ -1602,20 +1776,20 @@ function ReportSchemaError({ error }) {
|
|
|
1602
1776
|
" validation issue",
|
|
1603
1777
|
error.issues.length === 1 ? "" : "s"
|
|
1604
1778
|
] }),
|
|
1605
|
-
/* @__PURE__ */
|
|
1779
|
+
/* @__PURE__ */ jsx33("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1606
1780
|
] }) : null
|
|
1607
1781
|
] });
|
|
1608
1782
|
}
|
|
1609
1783
|
|
|
1610
1784
|
// src/components/ReportShell.tsx
|
|
1611
|
-
import { Fragment as Fragment10, jsx as
|
|
1785
|
+
import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1612
1786
|
function ReportErrorShell({
|
|
1613
1787
|
error,
|
|
1614
1788
|
className,
|
|
1615
1789
|
title,
|
|
1616
1790
|
dataTheme
|
|
1617
1791
|
}) {
|
|
1618
|
-
return /* @__PURE__ */
|
|
1792
|
+
return /* @__PURE__ */ jsx34("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx34(ReportSchemaError, { error }) });
|
|
1619
1793
|
}
|
|
1620
1794
|
|
|
1621
1795
|
// src/interactive/ReportInteractive.tsx
|
|
@@ -1624,12 +1798,12 @@ import { Monitor, Moon, Sun } from "lucide-react";
|
|
|
1624
1798
|
// src/components/ui/switch.tsx
|
|
1625
1799
|
import "react";
|
|
1626
1800
|
import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
|
|
1627
|
-
import { jsx as
|
|
1801
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1628
1802
|
function Switch({
|
|
1629
1803
|
className,
|
|
1630
1804
|
...props
|
|
1631
1805
|
}) {
|
|
1632
|
-
return /* @__PURE__ */
|
|
1806
|
+
return /* @__PURE__ */ jsx35(
|
|
1633
1807
|
SwitchPrimitive.Root,
|
|
1634
1808
|
{
|
|
1635
1809
|
"data-slot": "switch",
|
|
@@ -1638,7 +1812,7 @@ function Switch({
|
|
|
1638
1812
|
className
|
|
1639
1813
|
),
|
|
1640
1814
|
...props,
|
|
1641
|
-
children: /* @__PURE__ */
|
|
1815
|
+
children: /* @__PURE__ */ jsx35(
|
|
1642
1816
|
SwitchPrimitive.Thumb,
|
|
1643
1817
|
{
|
|
1644
1818
|
"data-slot": "switch-thumb",
|
|
@@ -1654,7 +1828,7 @@ import * as React5 from "react";
|
|
|
1654
1828
|
import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
|
|
1655
1829
|
import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
|
|
1656
1830
|
import { cva as cva3 } from "class-variance-authority";
|
|
1657
|
-
import { jsx as
|
|
1831
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
1658
1832
|
var toggleItemVariants = cva3(
|
|
1659
1833
|
"inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap text-muted-foreground transition-[color,background-color,box-shadow] outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-background data-[pressed]:text-foreground data-[pressed]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1660
1834
|
{
|
|
@@ -1676,13 +1850,13 @@ function ToggleGroup({
|
|
|
1676
1850
|
children,
|
|
1677
1851
|
...props
|
|
1678
1852
|
}) {
|
|
1679
|
-
return /* @__PURE__ */
|
|
1853
|
+
return /* @__PURE__ */ jsx36(
|
|
1680
1854
|
ToggleGroupPrimitive,
|
|
1681
1855
|
{
|
|
1682
1856
|
"data-slot": "toggle-group",
|
|
1683
1857
|
className: cn("flex w-fit items-center gap-0.5 rounded-lg bg-muted p-0.5", className),
|
|
1684
1858
|
...props,
|
|
1685
|
-
children: /* @__PURE__ */
|
|
1859
|
+
children: /* @__PURE__ */ jsx36(ToggleGroupContext.Provider, { value: { size }, children })
|
|
1686
1860
|
}
|
|
1687
1861
|
);
|
|
1688
1862
|
}
|
|
@@ -1693,7 +1867,7 @@ function ToggleGroupItem({
|
|
|
1693
1867
|
...props
|
|
1694
1868
|
}) {
|
|
1695
1869
|
const context = React5.useContext(ToggleGroupContext);
|
|
1696
|
-
return /* @__PURE__ */
|
|
1870
|
+
return /* @__PURE__ */ jsx36(
|
|
1697
1871
|
TogglePrimitive,
|
|
1698
1872
|
{
|
|
1699
1873
|
"data-slot": "toggle-group-item",
|
|
@@ -1713,9 +1887,9 @@ import { Search } from "lucide-react";
|
|
|
1713
1887
|
|
|
1714
1888
|
// src/components/ui/input.tsx
|
|
1715
1889
|
import "react";
|
|
1716
|
-
import { jsx as
|
|
1890
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1717
1891
|
function Input({ className, type, ...props }) {
|
|
1718
|
-
return /* @__PURE__ */
|
|
1892
|
+
return /* @__PURE__ */ jsx37(
|
|
1719
1893
|
"input",
|
|
1720
1894
|
{
|
|
1721
1895
|
type,
|
|
@@ -1732,7 +1906,7 @@ function Input({ className, type, ...props }) {
|
|
|
1732
1906
|
}
|
|
1733
1907
|
|
|
1734
1908
|
// src/interactive/ReportSearch.tsx
|
|
1735
|
-
import { jsx as
|
|
1909
|
+
import { jsx as jsx38, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1736
1910
|
var ReportSearch = forwardRef(
|
|
1737
1911
|
function ReportSearch2(props, ref) {
|
|
1738
1912
|
const {
|
|
@@ -1755,16 +1929,16 @@ var ReportSearch = forwardRef(
|
|
|
1755
1929
|
}
|
|
1756
1930
|
}
|
|
1757
1931
|
return /* @__PURE__ */ jsxs22("div", { className: cn("es-search flex flex-col gap-1", className), children: [
|
|
1758
|
-
/* @__PURE__ */
|
|
1932
|
+
/* @__PURE__ */ jsx38("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
|
|
1759
1933
|
/* @__PURE__ */ jsxs22("div", { className: "relative w-full sm:w-72", children: [
|
|
1760
|
-
/* @__PURE__ */
|
|
1934
|
+
/* @__PURE__ */ jsx38(
|
|
1761
1935
|
Search,
|
|
1762
1936
|
{
|
|
1763
1937
|
"aria-hidden": true,
|
|
1764
1938
|
className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
|
|
1765
1939
|
}
|
|
1766
1940
|
),
|
|
1767
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsx38(
|
|
1768
1942
|
Input,
|
|
1769
1943
|
{
|
|
1770
1944
|
ref,
|
|
@@ -1822,7 +1996,7 @@ function scrollToScenarioId(scenarioId, options = {}) {
|
|
|
1822
1996
|
}
|
|
1823
1997
|
|
|
1824
1998
|
// src/interactive/ReportFailureBanner.tsx
|
|
1825
|
-
import { jsx as
|
|
1999
|
+
import { jsx as jsx39, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1826
2000
|
function ReportFailureBanner({ failures }) {
|
|
1827
2001
|
const first = failures[0];
|
|
1828
2002
|
const jumpToFirst = useCallback2(() => {
|
|
@@ -1839,12 +2013,12 @@ function ReportFailureBanner({ failures }) {
|
|
|
1839
2013
|
"aria-label": "Failure summary",
|
|
1840
2014
|
children: [
|
|
1841
2015
|
/* @__PURE__ */ jsxs23("span", { className: "es-failure-banner-text", children: [
|
|
1842
|
-
/* @__PURE__ */
|
|
2016
|
+
/* @__PURE__ */ jsx39("strong", { children: failures.length }),
|
|
1843
2017
|
" ",
|
|
1844
2018
|
"failure",
|
|
1845
2019
|
failures.length === 1 ? "" : "s"
|
|
1846
2020
|
] }),
|
|
1847
|
-
/* @__PURE__ */
|
|
2021
|
+
/* @__PURE__ */ jsx39(
|
|
1848
2022
|
"button",
|
|
1849
2023
|
{
|
|
1850
2024
|
type: "button",
|
|
@@ -1861,7 +2035,7 @@ function ReportFailureBanner({ failures }) {
|
|
|
1861
2035
|
|
|
1862
2036
|
// src/interactive/ReportFreshness.tsx
|
|
1863
2037
|
import { useEffect, useState as useState2 } from "react";
|
|
1864
|
-
import { Fragment as Fragment11, jsx as
|
|
2038
|
+
import { Fragment as Fragment11, jsx as jsx40, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1865
2039
|
function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
1866
2040
|
const [now, setNow] = useState2(nowMs);
|
|
1867
2041
|
useEffect(() => {
|
|
@@ -1869,7 +2043,7 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1869
2043
|
}, [nowMs]);
|
|
1870
2044
|
if (lastRunMs === void 0 || now === void 0) return null;
|
|
1871
2045
|
const age = formatRelativeAge(lastRunMs, now);
|
|
1872
|
-
const runLink = ciUrl ? /* @__PURE__ */
|
|
2046
|
+
const runLink = ciUrl ? /* @__PURE__ */ jsx40(
|
|
1873
2047
|
"a",
|
|
1874
2048
|
{
|
|
1875
2049
|
href: ciUrl,
|
|
@@ -1903,13 +2077,13 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
|
|
|
1903
2077
|
}
|
|
1904
2078
|
|
|
1905
2079
|
// src/interactive/ReportLastRunDelta.tsx
|
|
1906
|
-
import { Fragment as Fragment12, jsx as
|
|
2080
|
+
import { Fragment as Fragment12, jsx as jsx41, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1907
2081
|
var MAX_LINKS = 5;
|
|
1908
2082
|
function ScenarioLinks({ scenarios, tone }) {
|
|
1909
2083
|
return /* @__PURE__ */ jsxs25(Fragment12, { children: [
|
|
1910
2084
|
scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ jsxs25("span", { children: [
|
|
1911
2085
|
i > 0 ? ", " : "",
|
|
1912
|
-
/* @__PURE__ */
|
|
2086
|
+
/* @__PURE__ */ jsx41("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
|
|
1913
2087
|
] }, s.id)),
|
|
1914
2088
|
scenarios.length > MAX_LINKS ? /* @__PURE__ */ jsxs25("span", { children: [
|
|
1915
2089
|
" and ",
|
|
@@ -1928,20 +2102,20 @@ function ReportLastRunDelta({
|
|
|
1928
2102
|
if (!delta) return null;
|
|
1929
2103
|
const { newlyFailing, newlyPassing, added } = delta;
|
|
1930
2104
|
if (newlyFailing.length === 0 && newlyPassing.length === 0 && added.length === 0) {
|
|
1931
|
-
return /* @__PURE__ */
|
|
2105
|
+
return /* @__PURE__ */ jsx41("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
|
|
1932
2106
|
}
|
|
1933
2107
|
return /* @__PURE__ */ jsxs25("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
|
|
1934
|
-
/* @__PURE__ */
|
|
2108
|
+
/* @__PURE__ */ jsx41("span", { className: "font-medium text-foreground", children: "Since last run:" }),
|
|
1935
2109
|
newlyFailing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-fail", children: [
|
|
1936
2110
|
newlyFailing.length,
|
|
1937
2111
|
" newly failing (",
|
|
1938
|
-
/* @__PURE__ */
|
|
2112
|
+
/* @__PURE__ */ jsx41(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
|
|
1939
2113
|
")"
|
|
1940
2114
|
] }) : null,
|
|
1941
2115
|
newlyPassing.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2 text-pass", children: [
|
|
1942
2116
|
newlyPassing.length,
|
|
1943
2117
|
" fixed (",
|
|
1944
|
-
/* @__PURE__ */
|
|
2118
|
+
/* @__PURE__ */ jsx41(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
|
|
1945
2119
|
")"
|
|
1946
2120
|
] }) : null,
|
|
1947
2121
|
added.length > 0 ? /* @__PURE__ */ jsxs25("span", { className: "ml-2", children: [
|
|
@@ -2008,7 +2182,7 @@ function Button({
|
|
|
2008
2182
|
}
|
|
2009
2183
|
|
|
2010
2184
|
// src/interactive/ReportShortcutsHelp.tsx
|
|
2011
|
-
import { jsx as
|
|
2185
|
+
import { jsx as jsx42, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2012
2186
|
var SHORTCUTS = [
|
|
2013
2187
|
{ keys: "/", description: "Focus search" },
|
|
2014
2188
|
{ keys: "f", description: "Jump to next failure" },
|
|
@@ -2020,9 +2194,9 @@ var SHORTCUTS = [
|
|
|
2020
2194
|
];
|
|
2021
2195
|
function Keys({ keys }) {
|
|
2022
2196
|
const parts = keys.split(" ");
|
|
2023
|
-
return /* @__PURE__ */
|
|
2024
|
-
i > 0 ? /* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2197
|
+
return /* @__PURE__ */ jsx42("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1", children: [
|
|
2198
|
+
i > 0 ? /* @__PURE__ */ jsx42("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
|
|
2199
|
+
/* @__PURE__ */ jsx42("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
|
|
2026
2200
|
] }, k)) });
|
|
2027
2201
|
}
|
|
2028
2202
|
function ReportShortcutsHelp({ open, onClose }) {
|
|
@@ -2041,12 +2215,12 @@ function ReportShortcutsHelp({ open, onClose }) {
|
|
|
2041
2215
|
"aria-label": "Keyboard shortcuts",
|
|
2042
2216
|
onClose,
|
|
2043
2217
|
children: [
|
|
2044
|
-
/* @__PURE__ */
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
/* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2218
|
+
/* @__PURE__ */ jsx42("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
|
|
2219
|
+
/* @__PURE__ */ jsx42("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs26("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
|
|
2220
|
+
/* @__PURE__ */ jsx42("dt", { className: "justify-self-start", children: /* @__PURE__ */ jsx42(Keys, { keys: s.keys }) }),
|
|
2221
|
+
/* @__PURE__ */ jsx42("dd", { className: "text-sm text-muted-foreground", children: s.description })
|
|
2048
2222
|
] }, s.keys)) }),
|
|
2049
|
-
/* @__PURE__ */
|
|
2223
|
+
/* @__PURE__ */ jsx42("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ jsx42(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
|
|
2050
2224
|
]
|
|
2051
2225
|
}
|
|
2052
2226
|
);
|
|
@@ -2247,7 +2421,7 @@ function failuresFirst(report) {
|
|
|
2247
2421
|
|
|
2248
2422
|
// src/interactive/ReportFilters.tsx
|
|
2249
2423
|
import { useState as useState3 } from "react";
|
|
2250
|
-
import { jsx as
|
|
2424
|
+
import { jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2251
2425
|
var TAG_LIMIT = 12;
|
|
2252
2426
|
function ReportFilters({
|
|
2253
2427
|
statuses,
|
|
@@ -2262,7 +2436,7 @@ function ReportFilters({
|
|
|
2262
2436
|
const tagsCollapsed = tags.length > TAG_LIMIT && !showAllTags;
|
|
2263
2437
|
const visibleTags = tagsCollapsed ? tags.slice(0, TAG_LIMIT) : tags;
|
|
2264
2438
|
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-2", children: [
|
|
2265
|
-
statuses.length > 0 ? /* @__PURE__ */
|
|
2439
|
+
statuses.length > 0 ? /* @__PURE__ */ jsx43("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
|
|
2266
2440
|
const active = status === opt.key;
|
|
2267
2441
|
return /* @__PURE__ */ jsxs27(
|
|
2268
2442
|
"button",
|
|
@@ -2276,7 +2450,7 @@ function ReportFilters({
|
|
|
2276
2450
|
),
|
|
2277
2451
|
children: [
|
|
2278
2452
|
opt.label,
|
|
2279
|
-
/* @__PURE__ */
|
|
2453
|
+
/* @__PURE__ */ jsx43("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
|
|
2280
2454
|
]
|
|
2281
2455
|
},
|
|
2282
2456
|
opt.key
|
|
@@ -2285,14 +2459,14 @@ function ReportFilters({
|
|
|
2285
2459
|
tags.length > 0 ? /* @__PURE__ */ jsxs27("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
|
|
2286
2460
|
visibleTags.map((tag) => {
|
|
2287
2461
|
const active = activeTags.includes(tag);
|
|
2288
|
-
return /* @__PURE__ */
|
|
2462
|
+
return /* @__PURE__ */ jsx43("li", { children: /* @__PURE__ */ jsx43(
|
|
2289
2463
|
"button",
|
|
2290
2464
|
{
|
|
2291
2465
|
type: "button",
|
|
2292
2466
|
"aria-pressed": active,
|
|
2293
2467
|
onClick: () => onToggleTag(tag),
|
|
2294
2468
|
className: "cursor-pointer",
|
|
2295
|
-
children: /* @__PURE__ */
|
|
2469
|
+
children: /* @__PURE__ */ jsx43(
|
|
2296
2470
|
Badge,
|
|
2297
2471
|
{
|
|
2298
2472
|
variant: "tag",
|
|
@@ -2305,7 +2479,7 @@ function ReportFilters({
|
|
|
2305
2479
|
}
|
|
2306
2480
|
) }, tag);
|
|
2307
2481
|
}),
|
|
2308
|
-
tags.length > TAG_LIMIT ? /* @__PURE__ */
|
|
2482
|
+
tags.length > TAG_LIMIT ? /* @__PURE__ */ jsx43("li", { children: /* @__PURE__ */ jsx43(
|
|
2309
2483
|
"button",
|
|
2310
2484
|
{
|
|
2311
2485
|
type: "button",
|
|
@@ -2321,7 +2495,7 @@ function ReportFilters({
|
|
|
2321
2495
|
|
|
2322
2496
|
// src/interactive/ReportToc.tsx
|
|
2323
2497
|
import { useEffect as useEffect5, useMemo as useMemo2, useState as useState4 } from "react";
|
|
2324
|
-
import { jsx as
|
|
2498
|
+
import { jsx as jsx44, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2325
2499
|
var DOT = {
|
|
2326
2500
|
passed: "bg-pass",
|
|
2327
2501
|
failed: "bg-fail",
|
|
@@ -2350,11 +2524,11 @@ function TocContent({ onNavigate }) {
|
|
|
2350
2524
|
return () => observer.disconnect();
|
|
2351
2525
|
}, [scenarioIds]);
|
|
2352
2526
|
if (report.features.length === 0) return null;
|
|
2353
|
-
return /* @__PURE__ */
|
|
2354
|
-
/* @__PURE__ */
|
|
2355
|
-
/* @__PURE__ */
|
|
2527
|
+
return /* @__PURE__ */ jsx44("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ jsxs28("li", { children: [
|
|
2528
|
+
/* @__PURE__ */ jsx44("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
|
|
2529
|
+
/* @__PURE__ */ jsx44("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
|
|
2356
2530
|
const active = activeId === scenario.id;
|
|
2357
|
-
return /* @__PURE__ */
|
|
2531
|
+
return /* @__PURE__ */ jsx44("li", { children: /* @__PURE__ */ jsxs28(
|
|
2358
2532
|
"a",
|
|
2359
2533
|
{
|
|
2360
2534
|
href: `#${scenario.id}`,
|
|
@@ -2369,14 +2543,14 @@ function TocContent({ onNavigate }) {
|
|
|
2369
2543
|
active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
|
|
2370
2544
|
),
|
|
2371
2545
|
children: [
|
|
2372
|
-
/* @__PURE__ */
|
|
2546
|
+
/* @__PURE__ */ jsx44(
|
|
2373
2547
|
"span",
|
|
2374
2548
|
{
|
|
2375
2549
|
"aria-hidden": true,
|
|
2376
2550
|
className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
|
|
2377
2551
|
}
|
|
2378
2552
|
),
|
|
2379
|
-
/* @__PURE__ */
|
|
2553
|
+
/* @__PURE__ */ jsx44("span", { className: "break-words", children: scenario.title })
|
|
2380
2554
|
]
|
|
2381
2555
|
}
|
|
2382
2556
|
) }, scenario.id);
|
|
@@ -2392,8 +2566,8 @@ function ReportToc() {
|
|
|
2392
2566
|
"aria-label": "Table of contents",
|
|
2393
2567
|
className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
|
|
2394
2568
|
children: [
|
|
2395
|
-
/* @__PURE__ */
|
|
2396
|
-
/* @__PURE__ */
|
|
2569
|
+
/* @__PURE__ */ jsx44("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
|
|
2570
|
+
/* @__PURE__ */ jsx44(TocContent, {})
|
|
2397
2571
|
]
|
|
2398
2572
|
}
|
|
2399
2573
|
);
|
|
@@ -2403,31 +2577,31 @@ function ReportToc() {
|
|
|
2403
2577
|
import { useState as useState5 } from "react";
|
|
2404
2578
|
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
|
2405
2579
|
import { ListIcon, XIcon } from "lucide-react";
|
|
2406
|
-
import { jsx as
|
|
2580
|
+
import { jsx as jsx45, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2407
2581
|
function ReportTocDrawer() {
|
|
2408
2582
|
const report = useReport();
|
|
2409
2583
|
const [open, setOpen] = useState5(false);
|
|
2410
2584
|
if (report.features.length === 0) return null;
|
|
2411
2585
|
return /* @__PURE__ */ jsxs29(DialogPrimitive.Root, { open, onOpenChange: setOpen, children: [
|
|
2412
2586
|
/* @__PURE__ */ jsxs29(DialogPrimitive.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
|
|
2413
|
-
/* @__PURE__ */
|
|
2587
|
+
/* @__PURE__ */ jsx45(ListIcon, { "aria-hidden": true }),
|
|
2414
2588
|
" Contents"
|
|
2415
2589
|
] }),
|
|
2416
2590
|
/* @__PURE__ */ jsxs29(DialogPrimitive.Portal, { children: [
|
|
2417
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ jsx45(DialogPrimitive.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
|
|
2418
2592
|
/* @__PURE__ */ jsxs29(DialogPrimitive.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
|
|
2419
2593
|
/* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between", children: [
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2594
|
+
/* @__PURE__ */ jsx45(DialogPrimitive.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
|
|
2595
|
+
/* @__PURE__ */ jsx45(
|
|
2422
2596
|
DialogPrimitive.Close,
|
|
2423
2597
|
{
|
|
2424
2598
|
"aria-label": "Close contents",
|
|
2425
2599
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
2426
|
-
children: /* @__PURE__ */
|
|
2600
|
+
children: /* @__PURE__ */ jsx45(XIcon, { "aria-hidden": true })
|
|
2427
2601
|
}
|
|
2428
2602
|
)
|
|
2429
2603
|
] }),
|
|
2430
|
-
/* @__PURE__ */
|
|
2604
|
+
/* @__PURE__ */ jsx45(TocContent, { onNavigate: () => setOpen(false) })
|
|
2431
2605
|
] })
|
|
2432
2606
|
] })
|
|
2433
2607
|
] });
|
|
@@ -2482,14 +2656,14 @@ function useTheme() {
|
|
|
2482
2656
|
}
|
|
2483
2657
|
|
|
2484
2658
|
// src/interactive/ReportInteractive.tsx
|
|
2485
|
-
import { Fragment as Fragment13, jsx as
|
|
2659
|
+
import { Fragment as Fragment13, jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2486
2660
|
function ReportInteractive(props) {
|
|
2487
2661
|
const { report, className, title, dataTheme } = props;
|
|
2488
2662
|
const result = unwrapReport(report);
|
|
2489
2663
|
if (!result.ok) {
|
|
2490
|
-
return /* @__PURE__ */
|
|
2664
|
+
return /* @__PURE__ */ jsx46(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
2491
2665
|
}
|
|
2492
|
-
return /* @__PURE__ */
|
|
2666
|
+
return /* @__PURE__ */ jsx46(ReportInteractiveView, { ...props, report: result.data });
|
|
2493
2667
|
}
|
|
2494
2668
|
var THEME_OPTIONS = [
|
|
2495
2669
|
{ value: "light", label: "Light", Icon: Sun },
|
|
@@ -2497,7 +2671,7 @@ var THEME_OPTIONS = [
|
|
|
2497
2671
|
{ value: "dark", label: "Dark", Icon: Moon }
|
|
2498
2672
|
];
|
|
2499
2673
|
function ThemeSegment({ pref, onPref }) {
|
|
2500
|
-
return /* @__PURE__ */
|
|
2674
|
+
return /* @__PURE__ */ jsx46(
|
|
2501
2675
|
ToggleGroup,
|
|
2502
2676
|
{
|
|
2503
2677
|
size: "sm",
|
|
@@ -2507,7 +2681,7 @@ function ThemeSegment({ pref, onPref }) {
|
|
|
2507
2681
|
if (next) onPref(next);
|
|
2508
2682
|
},
|
|
2509
2683
|
"aria-label": "Color theme",
|
|
2510
|
-
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */
|
|
2684
|
+
children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ jsx46(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ jsx46(Icon, {}) }, value))
|
|
2511
2685
|
}
|
|
2512
2686
|
);
|
|
2513
2687
|
}
|
|
@@ -2629,7 +2803,7 @@ function ReportInteractiveView({
|
|
|
2629
2803
|
const totalScenarios = report.summary.total;
|
|
2630
2804
|
const matchedScenarios = filtered.summary.total;
|
|
2631
2805
|
const showToc = !hideToc && totalScenarios > 3;
|
|
2632
|
-
return /* @__PURE__ */
|
|
2806
|
+
return /* @__PURE__ */ jsx46(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ jsx46(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ jsx46(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ jsx46(
|
|
2633
2807
|
ReportRoot,
|
|
2634
2808
|
{
|
|
2635
2809
|
report: filtered,
|
|
@@ -2654,9 +2828,9 @@ function ReportInteractiveView({
|
|
|
2654
2828
|
hideHeader ? "justify-end" : "justify-between"
|
|
2655
2829
|
),
|
|
2656
2830
|
children: [
|
|
2657
|
-
hideHeader ? null : /* @__PURE__ */
|
|
2831
|
+
hideHeader ? null : /* @__PURE__ */ jsx46("h1", { className: "min-w-0", children: title ?? "Story Report" }),
|
|
2658
2832
|
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2659
|
-
/* @__PURE__ */
|
|
2833
|
+
/* @__PURE__ */ jsx46(
|
|
2660
2834
|
ReportSearch,
|
|
2661
2835
|
{
|
|
2662
2836
|
ref: searchRef,
|
|
@@ -2666,16 +2840,16 @@ function ReportInteractiveView({
|
|
|
2666
2840
|
totalCount: totalScenarios
|
|
2667
2841
|
}
|
|
2668
2842
|
),
|
|
2669
|
-
/* @__PURE__ */
|
|
2843
|
+
/* @__PURE__ */ jsx46(ThemeSegment, { pref: themePref, onPref: setThemePref })
|
|
2670
2844
|
] })
|
|
2671
2845
|
]
|
|
2672
2846
|
}
|
|
2673
2847
|
),
|
|
2674
2848
|
hideHeader ? null : /* @__PURE__ */ jsxs30(Fragment13, { children: [
|
|
2675
|
-
/* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2849
|
+
/* @__PURE__ */ jsx46(ReportSummary, {}),
|
|
2850
|
+
/* @__PURE__ */ jsx46(ReportMeta, {})
|
|
2677
2851
|
] }),
|
|
2678
|
-
/* @__PURE__ */
|
|
2852
|
+
/* @__PURE__ */ jsx46(
|
|
2679
2853
|
ReportFreshness,
|
|
2680
2854
|
{
|
|
2681
2855
|
lastRunMs: reportLastRunMs(report),
|
|
@@ -2683,8 +2857,8 @@ function ReportInteractiveView({
|
|
|
2683
2857
|
staleAfterDays
|
|
2684
2858
|
}
|
|
2685
2859
|
),
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2860
|
+
/* @__PURE__ */ jsx46(ReportLastRunDelta, { history: scenarioHistory, report }),
|
|
2861
|
+
/* @__PURE__ */ jsx46(
|
|
2688
2862
|
ReportFilters,
|
|
2689
2863
|
{
|
|
2690
2864
|
statuses: statusOptions,
|
|
@@ -2696,13 +2870,13 @@ function ReportInteractiveView({
|
|
|
2696
2870
|
}
|
|
2697
2871
|
),
|
|
2698
2872
|
/* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
|
|
2699
|
-
showToc ? /* @__PURE__ */
|
|
2873
|
+
showToc ? /* @__PURE__ */ jsx46(ReportTocDrawer, {}) : null,
|
|
2700
2874
|
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2701
|
-
/* @__PURE__ */
|
|
2702
|
-
/* @__PURE__ */
|
|
2875
|
+
/* @__PURE__ */ jsx46(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
|
|
2876
|
+
/* @__PURE__ */ jsx46("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
|
|
2703
2877
|
] }),
|
|
2704
2878
|
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
2705
|
-
/* @__PURE__ */
|
|
2879
|
+
/* @__PURE__ */ jsx46(
|
|
2706
2880
|
Switch,
|
|
2707
2881
|
{
|
|
2708
2882
|
id: docsId,
|
|
@@ -2710,16 +2884,16 @@ function ReportInteractiveView({
|
|
|
2710
2884
|
onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
|
|
2711
2885
|
}
|
|
2712
2886
|
),
|
|
2713
|
-
/* @__PURE__ */
|
|
2887
|
+
/* @__PURE__ */ jsx46("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
|
|
2714
2888
|
] })
|
|
2715
2889
|
] })
|
|
2716
2890
|
] }),
|
|
2717
|
-
/* @__PURE__ */
|
|
2891
|
+
/* @__PURE__ */ jsx46(ReportFailureBanner, { failures }),
|
|
2718
2892
|
hasContent ? showToc ? /* @__PURE__ */ jsxs30("div", { className: "flex gap-6", children: [
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
] }) : /* @__PURE__ */
|
|
2722
|
-
/* @__PURE__ */
|
|
2893
|
+
/* @__PURE__ */ jsx46(ReportToc, {}),
|
|
2894
|
+
/* @__PURE__ */ jsx46("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ jsx46(ReportFeatureList, {}) })
|
|
2895
|
+
] }) : /* @__PURE__ */ jsx46("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsx46(ReportFeatureList, {}) }) : /* @__PURE__ */ jsx46(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
|
|
2896
|
+
/* @__PURE__ */ jsx46(
|
|
2723
2897
|
"button",
|
|
2724
2898
|
{
|
|
2725
2899
|
type: "button",
|
|
@@ -2730,8 +2904,8 @@ function ReportInteractiveView({
|
|
|
2730
2904
|
children: "?"
|
|
2731
2905
|
}
|
|
2732
2906
|
),
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
toast ? /* @__PURE__ */
|
|
2907
|
+
/* @__PURE__ */ jsx46(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
|
|
2908
|
+
toast ? /* @__PURE__ */ jsx46(
|
|
2735
2909
|
"div",
|
|
2736
2910
|
{
|
|
2737
2911
|
role: "status",
|
|
@@ -2755,7 +2929,7 @@ import { createElement, useEffect as useEffect8, useState as useState9 } from "r
|
|
|
2755
2929
|
|
|
2756
2930
|
// src/components/doc/MermaidView.tsx
|
|
2757
2931
|
import { useEffect as useEffect7, useRef as useRef4, useState as useState8 } from "react";
|
|
2758
|
-
import { jsx as
|
|
2932
|
+
import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2759
2933
|
function prefersDark(el) {
|
|
2760
2934
|
const themed = el?.closest("[data-theme]");
|
|
2761
2935
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -2793,8 +2967,8 @@ function MermaidView({ entry, load }) {
|
|
|
2793
2967
|
}, [entry.code, load]);
|
|
2794
2968
|
if (svg) {
|
|
2795
2969
|
return /* @__PURE__ */ jsxs31("figure", { ref, className: "my-3", children: [
|
|
2796
|
-
entry.title ? /* @__PURE__ */
|
|
2797
|
-
/* @__PURE__ */
|
|
2970
|
+
entry.title ? /* @__PURE__ */ jsx47("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
2971
|
+
/* @__PURE__ */ jsx47(
|
|
2798
2972
|
"div",
|
|
2799
2973
|
{
|
|
2800
2974
|
role: "img",
|
|
@@ -2805,11 +2979,11 @@ function MermaidView({ entry, load }) {
|
|
|
2805
2979
|
)
|
|
2806
2980
|
] });
|
|
2807
2981
|
}
|
|
2808
|
-
return /* @__PURE__ */
|
|
2982
|
+
return /* @__PURE__ */ jsx47(MermaidSource, { entry, ref });
|
|
2809
2983
|
}
|
|
2810
2984
|
|
|
2811
2985
|
// src/interactive/island-renderers.tsx
|
|
2812
|
-
import { jsx as
|
|
2986
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2813
2987
|
var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
|
|
2814
2988
|
var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
|
|
2815
2989
|
function cachedCdnModule(url) {
|
|
@@ -2843,13 +3017,13 @@ function CdnHighlightedCode({ entry }) {
|
|
|
2843
3017
|
cancelled = true;
|
|
2844
3018
|
};
|
|
2845
3019
|
}, [entry.content, entry.lang]);
|
|
2846
|
-
return /* @__PURE__ */
|
|
3020
|
+
return /* @__PURE__ */ jsx48(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ jsx48(
|
|
2847
3021
|
"code",
|
|
2848
3022
|
{
|
|
2849
3023
|
className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
|
|
2850
3024
|
dangerouslySetInnerHTML: { __html: html }
|
|
2851
3025
|
}
|
|
2852
|
-
) : /* @__PURE__ */
|
|
3026
|
+
) : /* @__PURE__ */ jsx48("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
2853
3027
|
}
|
|
2854
3028
|
function buildIslandRenderers(opts) {
|
|
2855
3029
|
const renderers = {};
|
|
@@ -2863,7 +3037,7 @@ function buildIslandRenderers(opts) {
|
|
|
2863
3037
|
}
|
|
2864
3038
|
|
|
2865
3039
|
// src/interactive/ReportInteractiveIsland.tsx
|
|
2866
|
-
import { jsx as
|
|
3040
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
2867
3041
|
function ReportInteractiveIsland({
|
|
2868
3042
|
report,
|
|
2869
3043
|
title,
|
|
@@ -2877,7 +3051,7 @@ function ReportInteractiveIsland({
|
|
|
2877
3051
|
() => buildIslandRenderers({ syntaxHighlighting, mermaid }),
|
|
2878
3052
|
[syntaxHighlighting, mermaid]
|
|
2879
3053
|
);
|
|
2880
|
-
return /* @__PURE__ */
|
|
3054
|
+
return /* @__PURE__ */ jsx49(
|
|
2881
3055
|
ReportInteractive,
|
|
2882
3056
|
{
|
|
2883
3057
|
report,
|