executable-stories-react 0.10.1 → 0.12.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 +482 -451
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +440 -407
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +1430 -1246
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +32 -32
- package/dist/interactive.d.ts +32 -32
- package/dist/interactive.js +1473 -1286
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +65 -139
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.js +65 -139
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +30 -28
- package/dist/ssr.cjs +367 -254
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +325 -209
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -84,6 +84,7 @@ __export(src_exports, {
|
|
|
84
84
|
parseStoryReport: () => parseStoryReport,
|
|
85
85
|
prUrl: () => prUrl,
|
|
86
86
|
reportLastRunMs: () => reportLastRunMs,
|
|
87
|
+
scenarioLastRunMs: () => scenarioLastRunMs,
|
|
87
88
|
storyReportSchema: () => storyReportSchema,
|
|
88
89
|
useBuiltinRenderers: () => useBuiltinRenderers,
|
|
89
90
|
useCustomRenderers: () => useCustomRenderers,
|
|
@@ -380,23 +381,45 @@ function useReport() {
|
|
|
380
381
|
// src/components/ReportScenario.tsx
|
|
381
382
|
var import_duration3 = require("executable-stories-core/utils/duration");
|
|
382
383
|
|
|
384
|
+
// src/lib/step-params.tsx
|
|
385
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
386
|
+
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
387
|
+
function highlightStepParams(text) {
|
|
388
|
+
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
389
|
+
if (matches.length === 0) return text;
|
|
390
|
+
const nodes = [];
|
|
391
|
+
let lastIndex = 0;
|
|
392
|
+
matches.forEach((match, i) => {
|
|
393
|
+
const start = match.index;
|
|
394
|
+
const end = start + match[0].length;
|
|
395
|
+
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
396
|
+
nodes.push(
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
398
|
+
);
|
|
399
|
+
lastIndex = end;
|
|
400
|
+
});
|
|
401
|
+
if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
|
|
402
|
+
return nodes;
|
|
403
|
+
}
|
|
404
|
+
|
|
383
405
|
// src/components/ReportSteps.tsx
|
|
406
|
+
var import_assertive_steps = require("executable-stories-core/utils/assertive-steps");
|
|
384
407
|
var import_duration = require("executable-stories-core/utils/duration");
|
|
385
408
|
|
|
386
409
|
// src/components/doc/DocNote.tsx
|
|
387
|
-
var
|
|
410
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
388
411
|
function DocNote({ entry }) {
|
|
389
|
-
return /* @__PURE__ */ (0,
|
|
412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
|
|
390
413
|
}
|
|
391
414
|
|
|
392
415
|
// src/components/doc/DocTag.tsx
|
|
393
|
-
var
|
|
416
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
394
417
|
function DocTag({ entry }) {
|
|
395
|
-
return /* @__PURE__ */ (0,
|
|
418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "my-2 flex flex-wrap gap-1.5", "aria-label": "Tags", children: entry.names.map((n) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Badge, { variant: "tag", children: n }) }, n)) });
|
|
396
419
|
}
|
|
397
420
|
|
|
398
421
|
// src/components/doc/DocKv.tsx
|
|
399
|
-
var
|
|
422
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
400
423
|
function formatValue(value) {
|
|
401
424
|
if (value === null) return "null";
|
|
402
425
|
if (typeof value === "string") return value;
|
|
@@ -408,9 +431,9 @@ function formatValue(value) {
|
|
|
408
431
|
}
|
|
409
432
|
}
|
|
410
433
|
function DocKv({ entry }) {
|
|
411
|
-
return /* @__PURE__ */ (0,
|
|
412
|
-
/* @__PURE__ */ (0,
|
|
413
|
-
/* @__PURE__ */ (0,
|
|
434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
|
|
436
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { className: "font-mono text-foreground", children: formatValue(entry.value) })
|
|
414
437
|
] });
|
|
415
438
|
}
|
|
416
439
|
|
|
@@ -428,37 +451,37 @@ function useBuiltinRenderers() {
|
|
|
428
451
|
}
|
|
429
452
|
|
|
430
453
|
// src/components/doc/DocCode.tsx
|
|
431
|
-
var
|
|
454
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
432
455
|
function CodeFigure({ label, children }) {
|
|
433
|
-
return /* @__PURE__ */ (0,
|
|
434
|
-
label ? /* @__PURE__ */ (0,
|
|
435
|
-
/* @__PURE__ */ (0,
|
|
456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("figure", { className: "my-3", children: [
|
|
457
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: label }) : null,
|
|
458
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3", children })
|
|
436
459
|
] });
|
|
437
460
|
}
|
|
438
461
|
function DocCode({ entry }) {
|
|
439
462
|
const renderers = useBuiltinRenderers();
|
|
440
463
|
if (renderers.code) {
|
|
441
|
-
return /* @__PURE__ */ (0,
|
|
464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: renderers.code(entry) });
|
|
442
465
|
}
|
|
443
|
-
return /* @__PURE__ */ (0,
|
|
466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CodeFigure, { label: entry.label, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
444
467
|
}
|
|
445
468
|
|
|
446
469
|
// src/components/doc/DocTable.tsx
|
|
447
|
-
var
|
|
470
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
448
471
|
function DocTable({ entry }) {
|
|
449
|
-
return /* @__PURE__ */ (0,
|
|
450
|
-
entry.label ? /* @__PURE__ */ (0,
|
|
451
|
-
/* @__PURE__ */ (0,
|
|
452
|
-
/* @__PURE__ */ (0,
|
|
453
|
-
/* @__PURE__ */ (0,
|
|
472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("figure", { className: "my-3", children: [
|
|
473
|
+
entry.label ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("table", { className: "w-full border-collapse text-sm", children: [
|
|
475
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { children: row.map((cell, j) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
|
|
454
477
|
] }) })
|
|
455
478
|
] });
|
|
456
479
|
}
|
|
457
480
|
|
|
458
481
|
// src/components/doc/DocLink.tsx
|
|
459
|
-
var
|
|
482
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
460
483
|
function DocLink({ entry }) {
|
|
461
|
-
return /* @__PURE__ */ (0,
|
|
484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
462
485
|
"a",
|
|
463
486
|
{
|
|
464
487
|
className: "text-sm font-medium text-primary underline underline-offset-2 hover:no-underline",
|
|
@@ -470,30 +493,38 @@ function DocLink({ entry }) {
|
|
|
470
493
|
);
|
|
471
494
|
}
|
|
472
495
|
|
|
473
|
-
// src/
|
|
496
|
+
// src/lib/markdown.ts
|
|
474
497
|
var import_marked = require("marked");
|
|
475
498
|
|
|
476
499
|
// src/lib/url.ts
|
|
477
500
|
var import_url = require("executable-stories-core/utils/url");
|
|
478
501
|
|
|
479
|
-
// src/
|
|
480
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
481
|
-
function neutralizeUrl(value) {
|
|
482
|
-
return (0, import_url.safeUrl)(value) ?? "#";
|
|
483
|
-
}
|
|
502
|
+
// src/lib/markdown.ts
|
|
484
503
|
function safeMarkdownHtml(markdown) {
|
|
485
504
|
const raw = import_marked.marked.parse(markdown, { async: false });
|
|
486
505
|
return raw.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<\/?(?:iframe|object|embed|form|base)\b[^>]*>/gi, "").replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, "").replace(/\son[a-z]+\s*=\s*'[^']*'/gi, "").replace(/\son[a-z]+\s*=\s*[^\s>]+/gi, "").replace(/(href|src)\s*=\s*"([^"]*)"/gi, (_m, attr, val) => `${attr}="${neutralizeUrl(val)}"`).replace(/(href|src)\s*=\s*'([^']*)'/gi, (_m, attr, val) => `${attr}='${neutralizeUrl(val)}'`);
|
|
487
506
|
}
|
|
507
|
+
function dedent(text) {
|
|
508
|
+
const lines = text.replace(/\t/g, " ").split("\n");
|
|
509
|
+
const indents = lines.filter((line) => line.trim().length > 0).map((line) => line.length - line.trimStart().length);
|
|
510
|
+
const shortest = indents.length > 0 ? Math.min(...indents) : 0;
|
|
511
|
+
return lines.map((line) => line.slice(shortest)).join("\n").trim();
|
|
512
|
+
}
|
|
513
|
+
function neutralizeUrl(value) {
|
|
514
|
+
return (0, import_url.safeUrl)(value) ?? "#";
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// src/components/doc/DocSection.tsx
|
|
518
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
488
519
|
function DocSection({ entry }) {
|
|
489
520
|
const renderers = useBuiltinRenderers();
|
|
490
521
|
if (renderers.section) {
|
|
491
|
-
return /* @__PURE__ */ (0,
|
|
522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: renderers.section(entry) });
|
|
492
523
|
}
|
|
493
524
|
const html = safeMarkdownHtml(entry.markdown);
|
|
494
|
-
return /* @__PURE__ */ (0,
|
|
495
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
496
|
-
/* @__PURE__ */ (0,
|
|
525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
|
|
526
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
|
|
527
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
497
528
|
"div",
|
|
498
529
|
{
|
|
499
530
|
className: "es-doc-prose prose prose-sm max-w-none",
|
|
@@ -504,11 +535,11 @@ function DocSection({ entry }) {
|
|
|
504
535
|
}
|
|
505
536
|
|
|
506
537
|
// src/components/doc/DocMermaid.tsx
|
|
507
|
-
var
|
|
538
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
508
539
|
function MermaidSource({ entry, ref }) {
|
|
509
|
-
return /* @__PURE__ */ (0,
|
|
510
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
511
|
-
/* @__PURE__ */ (0,
|
|
540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
|
|
541
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
512
543
|
"pre",
|
|
513
544
|
{
|
|
514
545
|
"data-mermaid": true,
|
|
@@ -522,24 +553,24 @@ function MermaidSource({ entry, ref }) {
|
|
|
522
553
|
function DocMermaid({ entry }) {
|
|
523
554
|
const renderers = useBuiltinRenderers();
|
|
524
555
|
if (renderers.mermaid) {
|
|
525
|
-
return /* @__PURE__ */ (0,
|
|
556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: renderers.mermaid(entry) });
|
|
526
557
|
}
|
|
527
|
-
return /* @__PURE__ */ (0,
|
|
558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MermaidSource, { entry });
|
|
528
559
|
}
|
|
529
560
|
|
|
530
561
|
// src/components/doc/DocScreenshot.tsx
|
|
531
|
-
var
|
|
562
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
532
563
|
function DocScreenshot({ entry }) {
|
|
533
564
|
const src = (0, import_url.isLocalFsPath)(entry.path) ? void 0 : (0, import_url.safeImageUrl)(entry.path);
|
|
534
565
|
if (!src) {
|
|
535
|
-
return /* @__PURE__ */ (0,
|
|
536
|
-
/* @__PURE__ */ (0,
|
|
537
|
-
/* @__PURE__ */ (0,
|
|
538
|
-
entry.alt ? /* @__PURE__ */ (0,
|
|
566
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
567
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "font-medium", children: "Screenshot unavailable" }),
|
|
568
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
569
|
+
entry.alt ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.alt }) : null
|
|
539
570
|
] });
|
|
540
571
|
}
|
|
541
|
-
return /* @__PURE__ */ (0,
|
|
542
|
-
/* @__PURE__ */ (0,
|
|
572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "my-3", children: [
|
|
573
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
543
574
|
"img",
|
|
544
575
|
{
|
|
545
576
|
src,
|
|
@@ -548,24 +579,24 @@ function DocScreenshot({ entry }) {
|
|
|
548
579
|
className: "max-w-full rounded-md border border-border"
|
|
549
580
|
}
|
|
550
581
|
),
|
|
551
|
-
entry.alt ? /* @__PURE__ */ (0,
|
|
582
|
+
entry.alt ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
|
|
552
583
|
] });
|
|
553
584
|
}
|
|
554
585
|
|
|
555
586
|
// src/components/doc/DocVideo.tsx
|
|
556
|
-
var
|
|
587
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
557
588
|
function DocVideo({ entry }) {
|
|
558
589
|
if ((0, import_url.isLocalFsPath)(entry.path)) {
|
|
559
|
-
return /* @__PURE__ */ (0,
|
|
560
|
-
/* @__PURE__ */ (0,
|
|
561
|
-
/* @__PURE__ */ (0,
|
|
562
|
-
entry.caption ? /* @__PURE__ */ (0,
|
|
590
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "font-medium", children: "Video unavailable" }),
|
|
592
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
593
|
+
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
|
|
563
594
|
] });
|
|
564
595
|
}
|
|
565
596
|
const src = (0, import_url.safeUrl)(entry.path);
|
|
566
597
|
const poster = (0, import_url.safeUrl)(entry.poster);
|
|
567
|
-
return /* @__PURE__ */ (0,
|
|
568
|
-
/* @__PURE__ */ (0,
|
|
598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "my-3", children: [
|
|
599
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
569
600
|
"video",
|
|
570
601
|
{
|
|
571
602
|
controls: true,
|
|
@@ -575,21 +606,21 @@ function DocVideo({ entry }) {
|
|
|
575
606
|
className: "max-w-full rounded-md border border-border"
|
|
576
607
|
}
|
|
577
608
|
),
|
|
578
|
-
entry.caption ? /* @__PURE__ */ (0,
|
|
609
|
+
entry.caption ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
|
|
579
610
|
] });
|
|
580
611
|
}
|
|
581
612
|
|
|
582
613
|
// src/components/doc/DocHtml.tsx
|
|
583
|
-
var
|
|
614
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
584
615
|
function DocHtml({ entry }) {
|
|
585
616
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
586
617
|
const title = entry.title ?? "Embedded HTML";
|
|
587
618
|
const safeHref = (0, import_url.safeUrl)(entry.url ?? entry.path);
|
|
588
619
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
589
|
-
return /* @__PURE__ */ (0,
|
|
590
|
-
/* @__PURE__ */ (0,
|
|
591
|
-
/* @__PURE__ */ (0,
|
|
592
|
-
safeHref ? /* @__PURE__ */ (0,
|
|
620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("figcaption", { className: "flex items-center justify-between border-b border-border bg-muted/40 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
622
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: entry.title ?? "HTML" }),
|
|
623
|
+
safeHref ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
593
624
|
"a",
|
|
594
625
|
{
|
|
595
626
|
href: safeHref,
|
|
@@ -602,7 +633,7 @@ function DocHtml({ entry }) {
|
|
|
602
633
|
}
|
|
603
634
|
) : null
|
|
604
635
|
] }),
|
|
605
|
-
/* @__PURE__ */ (0,
|
|
636
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
606
637
|
"iframe",
|
|
607
638
|
{
|
|
608
639
|
...frameProps,
|
|
@@ -617,7 +648,7 @@ function DocHtml({ entry }) {
|
|
|
617
648
|
}
|
|
618
649
|
|
|
619
650
|
// src/components/doc/DocState.tsx
|
|
620
|
-
var
|
|
651
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
621
652
|
function DocState({ entry }) {
|
|
622
653
|
let json;
|
|
623
654
|
try {
|
|
@@ -625,20 +656,20 @@ function DocState({ entry }) {
|
|
|
625
656
|
} catch {
|
|
626
657
|
json = String(entry.value);
|
|
627
658
|
}
|
|
628
|
-
return /* @__PURE__ */ (0,
|
|
659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
629
660
|
}
|
|
630
661
|
|
|
631
662
|
// src/components/doc/DocCustom.tsx
|
|
632
|
-
var
|
|
663
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
633
664
|
function DocCustom({ entry }) {
|
|
634
665
|
const renderers = useCustomRenderers();
|
|
635
666
|
const renderer = renderers[entry.type];
|
|
636
667
|
if (renderer) {
|
|
637
|
-
return /* @__PURE__ */ (0,
|
|
668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: renderer(entry) });
|
|
638
669
|
}
|
|
639
|
-
return /* @__PURE__ */ (0,
|
|
640
|
-
/* @__PURE__ */ (0,
|
|
641
|
-
/* @__PURE__ */ (0,
|
|
670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "my-2", "data-type": entry.type, children: [
|
|
671
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
|
|
672
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify2(entry.data) })
|
|
642
673
|
] });
|
|
643
674
|
}
|
|
644
675
|
function safeStringify2(value) {
|
|
@@ -650,64 +681,43 @@ function safeStringify2(value) {
|
|
|
650
681
|
}
|
|
651
682
|
|
|
652
683
|
// src/components/doc/DocEntry.tsx
|
|
653
|
-
var
|
|
684
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
654
685
|
function DocEntry({ entry }) {
|
|
655
686
|
switch (entry.kind) {
|
|
656
687
|
case "note":
|
|
657
|
-
return /* @__PURE__ */ (0,
|
|
688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocNote, { entry });
|
|
658
689
|
case "tag":
|
|
659
|
-
return /* @__PURE__ */ (0,
|
|
690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocTag, { entry });
|
|
660
691
|
case "kv":
|
|
661
|
-
return /* @__PURE__ */ (0,
|
|
692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocKv, { entry });
|
|
662
693
|
case "code":
|
|
663
|
-
return /* @__PURE__ */ (0,
|
|
694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocCode, { entry });
|
|
664
695
|
case "table":
|
|
665
|
-
return /* @__PURE__ */ (0,
|
|
696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocTable, { entry });
|
|
666
697
|
case "link":
|
|
667
|
-
return /* @__PURE__ */ (0,
|
|
698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocLink, { entry });
|
|
668
699
|
case "section":
|
|
669
|
-
return /* @__PURE__ */ (0,
|
|
700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocSection, { entry });
|
|
670
701
|
case "mermaid":
|
|
671
|
-
return /* @__PURE__ */ (0,
|
|
702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocMermaid, { entry });
|
|
672
703
|
case "screenshot":
|
|
673
|
-
return /* @__PURE__ */ (0,
|
|
704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocScreenshot, { entry });
|
|
674
705
|
case "video":
|
|
675
|
-
return /* @__PURE__ */ (0,
|
|
706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocVideo, { entry });
|
|
676
707
|
case "html":
|
|
677
|
-
return /* @__PURE__ */ (0,
|
|
708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocHtml, { entry });
|
|
678
709
|
case "state":
|
|
679
|
-
return /* @__PURE__ */ (0,
|
|
710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocState, { entry });
|
|
680
711
|
case "custom":
|
|
681
|
-
return /* @__PURE__ */ (0,
|
|
712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocCustom, { entry });
|
|
682
713
|
}
|
|
683
714
|
}
|
|
684
715
|
|
|
685
716
|
// src/components/ReportDocEntries.tsx
|
|
686
|
-
var
|
|
717
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
687
718
|
function ReportDocEntries({ entries }) {
|
|
688
719
|
if (entries.length === 0) return null;
|
|
689
|
-
return /* @__PURE__ */ (0,
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// src/lib/step-params.tsx
|
|
693
|
-
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
694
|
-
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
695
|
-
function highlightStepParams(text) {
|
|
696
|
-
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
697
|
-
if (matches.length === 0) return text;
|
|
698
|
-
const nodes = [];
|
|
699
|
-
let lastIndex = 0;
|
|
700
|
-
matches.forEach((match, i) => {
|
|
701
|
-
const start = match.index;
|
|
702
|
-
const end = start + match[0].length;
|
|
703
|
-
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
704
|
-
nodes.push(
|
|
705
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
706
|
-
);
|
|
707
|
-
lastIndex = end;
|
|
708
|
-
});
|
|
709
|
-
if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
|
|
710
|
-
return nodes;
|
|
720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DocEntry, { entry }, i)) });
|
|
711
721
|
}
|
|
712
722
|
|
|
713
723
|
// src/components/ReportSteps.tsx
|
|
@@ -726,9 +736,22 @@ var STEP_GLYPH_COLOR = {
|
|
|
726
736
|
};
|
|
727
737
|
function ReportSteps({ scenario }) {
|
|
728
738
|
if (scenario.steps.length === 0) return null;
|
|
729
|
-
|
|
739
|
+
const unasserted = new Set(
|
|
740
|
+
(0, import_assertive_steps.assertionState)(scenario.steps) === "unasserted" ? (0, import_assertive_steps.assertiveSteps)(scenario.steps).map((step) => step.id) : []
|
|
741
|
+
);
|
|
742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
743
|
+
ReportStepItem,
|
|
744
|
+
{
|
|
745
|
+
step,
|
|
746
|
+
unasserted: unasserted.has(step.id)
|
|
747
|
+
},
|
|
748
|
+
step.id
|
|
749
|
+
)) });
|
|
730
750
|
}
|
|
731
|
-
function ReportStepItem({
|
|
751
|
+
function ReportStepItem({
|
|
752
|
+
step,
|
|
753
|
+
unasserted = false
|
|
754
|
+
}) {
|
|
732
755
|
const kw = step.keyword.toLowerCase();
|
|
733
756
|
const continuation = kw === "and" || kw === "but";
|
|
734
757
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
@@ -736,10 +759,23 @@ function ReportStepItem({ step }) {
|
|
|
736
759
|
{
|
|
737
760
|
id: step.id,
|
|
738
761
|
"data-status": step.status,
|
|
739
|
-
className: cn(
|
|
762
|
+
className: cn(
|
|
763
|
+
"py-1.5 text-[0.8125rem] leading-normal",
|
|
764
|
+
continuation && "pl-5"
|
|
765
|
+
),
|
|
740
766
|
children: [
|
|
741
767
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-baseline gap-2", children: [
|
|
742
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
769
|
+
"span",
|
|
770
|
+
{
|
|
771
|
+
"aria-hidden": true,
|
|
772
|
+
className: cn(
|
|
773
|
+
"w-4 shrink-0 text-center text-xs",
|
|
774
|
+
STEP_GLYPH_COLOR[step.status]
|
|
775
|
+
),
|
|
776
|
+
children: STEP_GLYPH[step.status] ?? "\u25CB"
|
|
777
|
+
}
|
|
778
|
+
),
|
|
743
779
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
744
780
|
"span",
|
|
745
781
|
{
|
|
@@ -751,6 +787,7 @@ function ReportStepItem({ step }) {
|
|
|
751
787
|
}
|
|
752
788
|
),
|
|
753
789
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
790
|
+
unasserted ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 rounded-full border border-pend-border bg-pend-bg px-2 py-0.5 text-[0.6875rem] font-medium text-pend", children: "No assertion" }) : null,
|
|
754
791
|
step.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: (0, import_duration.formatDuration)(step.durationMs) }) : null
|
|
755
792
|
] }),
|
|
756
793
|
step.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -1146,28 +1183,111 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1146
1183
|
] });
|
|
1147
1184
|
}
|
|
1148
1185
|
|
|
1149
|
-
// src/
|
|
1186
|
+
// src/components/ScenarioStaleness.tsx
|
|
1187
|
+
var import_react7 = require("react");
|
|
1188
|
+
|
|
1189
|
+
// src/lib/provenance.ts
|
|
1190
|
+
function reportLastRunMs(report) {
|
|
1191
|
+
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
1192
|
+
if (report.startedAtMs && report.startedAtMs > 0) return report.startedAtMs;
|
|
1193
|
+
return void 0;
|
|
1194
|
+
}
|
|
1195
|
+
function scenarioLastRunMs(scenario, report) {
|
|
1196
|
+
if (scenario.lastRunAtMs && scenario.lastRunAtMs > 0) return scenario.lastRunAtMs;
|
|
1197
|
+
return reportLastRunMs(report);
|
|
1198
|
+
}
|
|
1199
|
+
function formatRelativeAge(thenMs, nowMs) {
|
|
1200
|
+
const deltaMs = Math.max(0, nowMs - thenMs);
|
|
1201
|
+
const minutes = Math.floor(deltaMs / 6e4);
|
|
1202
|
+
if (minutes < 1) return "just now";
|
|
1203
|
+
if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
1204
|
+
const hours = Math.floor(minutes / 60);
|
|
1205
|
+
if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
1206
|
+
const days = Math.floor(hours / 24);
|
|
1207
|
+
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
1208
|
+
}
|
|
1209
|
+
function isReportStale(lastRunMs, staleAfterDays, nowMs) {
|
|
1210
|
+
if (lastRunMs === void 0 || staleAfterDays <= 0) return false;
|
|
1211
|
+
return nowMs - lastRunMs >= staleAfterDays * 864e5;
|
|
1212
|
+
}
|
|
1213
|
+
var CI_DISPLAY_NAMES = {
|
|
1214
|
+
github: "GitHub Actions",
|
|
1215
|
+
gitlab: "GitLab CI",
|
|
1216
|
+
circleci: "CircleCI",
|
|
1217
|
+
jenkins: "Jenkins",
|
|
1218
|
+
azure: "Azure DevOps",
|
|
1219
|
+
buildkite: "Buildkite",
|
|
1220
|
+
travis: "Travis CI",
|
|
1221
|
+
ci: "CI"
|
|
1222
|
+
};
|
|
1223
|
+
function ciDisplayName(name) {
|
|
1224
|
+
return CI_DISPLAY_NAMES[name] ?? name;
|
|
1225
|
+
}
|
|
1226
|
+
function commitUrl(ci, sha) {
|
|
1227
|
+
const commitSha = ci?.commitSha ?? sha;
|
|
1228
|
+
if (!ci?.url || !commitSha) return void 0;
|
|
1229
|
+
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1230
|
+
if (github) return `${github[1]}/commit/${commitSha}`;
|
|
1231
|
+
const gitlab = ci.url.match(/^(https?:\/\/.+)\/-\/pipelines\//);
|
|
1232
|
+
if (gitlab) return `${gitlab[1]}/-/commit/${commitSha}`;
|
|
1233
|
+
return void 0;
|
|
1234
|
+
}
|
|
1235
|
+
function prUrl(ci) {
|
|
1236
|
+
if (!ci?.url || !ci.prNumber) return void 0;
|
|
1237
|
+
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1238
|
+
if (github) return `${github[1]}/pull/${ci.prNumber}`;
|
|
1239
|
+
return void 0;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
// src/interactive/scenario-freshness-context.tsx
|
|
1150
1243
|
var import_react6 = require("react");
|
|
1151
|
-
var
|
|
1244
|
+
var ScenarioFreshnessContext = (0, import_react6.createContext)(null);
|
|
1245
|
+
var ScenarioFreshnessProvider = ScenarioFreshnessContext.Provider;
|
|
1246
|
+
function useScenarioFreshness() {
|
|
1247
|
+
return (0, import_react6.useContext)(ScenarioFreshnessContext);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// src/components/ScenarioStaleness.tsx
|
|
1251
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1252
|
+
function ScenarioStaleness({ scenario }) {
|
|
1253
|
+
const freshness = useScenarioFreshness();
|
|
1254
|
+
const fixedNow = freshness?.nowMs;
|
|
1255
|
+
const [now, setNow] = (0, import_react7.useState)(fixedNow);
|
|
1256
|
+
(0, import_react7.useEffect)(() => {
|
|
1257
|
+
if (fixedNow === void 0) setNow(Date.now());
|
|
1258
|
+
}, [fixedNow]);
|
|
1259
|
+
if (!freshness || now === void 0) return null;
|
|
1260
|
+
const lastRunAtMs = scenario.lastRunAtMs;
|
|
1261
|
+
if (!lastRunAtMs || lastRunAtMs <= 0) return null;
|
|
1262
|
+
if (!isReportStale(lastRunAtMs, freshness.staleAfterDays, now)) return null;
|
|
1263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Badge, { variant: "outline", "aria-label": "Scenario freshness", children: [
|
|
1264
|
+
"Last ran ",
|
|
1265
|
+
formatRelativeAge(lastRunAtMs, now)
|
|
1266
|
+
] });
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
// src/interactive/collapse-context.ts
|
|
1270
|
+
var import_react8 = require("react");
|
|
1271
|
+
var CollapseContext = (0, import_react8.createContext)(null);
|
|
1152
1272
|
var CollapseProvider = CollapseContext.Provider;
|
|
1153
1273
|
function useCollapse() {
|
|
1154
|
-
return (0,
|
|
1274
|
+
return (0, import_react8.useContext)(CollapseContext);
|
|
1155
1275
|
}
|
|
1156
1276
|
|
|
1157
1277
|
// src/interactive/scenario-actions.tsx
|
|
1158
|
-
var
|
|
1278
|
+
var import_react9 = require("react");
|
|
1159
1279
|
var import_scenario_markdown = require("executable-stories-core/utils/scenario-markdown");
|
|
1160
|
-
var ScenarioActionsContext = (0,
|
|
1280
|
+
var ScenarioActionsContext = (0, import_react9.createContext)(null);
|
|
1161
1281
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1162
1282
|
function useScenarioActions() {
|
|
1163
|
-
return (0,
|
|
1283
|
+
return (0, import_react9.useContext)(ScenarioActionsContext);
|
|
1164
1284
|
}
|
|
1165
1285
|
|
|
1166
1286
|
// src/components/ui/card.tsx
|
|
1167
1287
|
var React2 = require("react");
|
|
1168
|
-
var
|
|
1288
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1169
1289
|
function Card({ className, ...props }) {
|
|
1170
|
-
return /* @__PURE__ */ (0,
|
|
1290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1171
1291
|
"div",
|
|
1172
1292
|
{
|
|
1173
1293
|
"data-slot": "card",
|
|
@@ -1180,7 +1300,7 @@ function Card({ className, ...props }) {
|
|
|
1180
1300
|
);
|
|
1181
1301
|
}
|
|
1182
1302
|
function CardHeader({ className, ...props }) {
|
|
1183
|
-
return /* @__PURE__ */ (0,
|
|
1303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1184
1304
|
"div",
|
|
1185
1305
|
{
|
|
1186
1306
|
"data-slot": "card-header",
|
|
@@ -1193,7 +1313,7 @@ function CardHeader({ className, ...props }) {
|
|
|
1193
1313
|
);
|
|
1194
1314
|
}
|
|
1195
1315
|
function CardContent({ className, ...props }) {
|
|
1196
|
-
return /* @__PURE__ */ (0,
|
|
1316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1197
1317
|
"div",
|
|
1198
1318
|
{
|
|
1199
1319
|
"data-slot": "card-content",
|
|
@@ -1207,13 +1327,13 @@ function CardContent({ className, ...props }) {
|
|
|
1207
1327
|
var React3 = require("react");
|
|
1208
1328
|
var import_menu = require("@base-ui/react/menu");
|
|
1209
1329
|
var import_lucide_react = require("lucide-react");
|
|
1210
|
-
var
|
|
1330
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1211
1331
|
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";
|
|
1212
1332
|
function DropdownMenu(props) {
|
|
1213
|
-
return /* @__PURE__ */ (0,
|
|
1333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
1214
1334
|
}
|
|
1215
1335
|
function DropdownMenuTrigger(props) {
|
|
1216
|
-
return /* @__PURE__ */ (0,
|
|
1336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
1217
1337
|
}
|
|
1218
1338
|
function DropdownMenuContent({
|
|
1219
1339
|
className,
|
|
@@ -1221,14 +1341,14 @@ function DropdownMenuContent({
|
|
|
1221
1341
|
sideOffset = 4,
|
|
1222
1342
|
...props
|
|
1223
1343
|
}) {
|
|
1224
|
-
return /* @__PURE__ */ (0,
|
|
1344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_menu.Menu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1225
1345
|
import_menu.Menu.Positioner,
|
|
1226
1346
|
{
|
|
1227
1347
|
"data-slot": "dropdown-menu-positioner",
|
|
1228
1348
|
className: "z-50",
|
|
1229
1349
|
align,
|
|
1230
1350
|
sideOffset,
|
|
1231
|
-
children: /* @__PURE__ */ (0,
|
|
1351
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1232
1352
|
import_menu.Menu.Popup,
|
|
1233
1353
|
{
|
|
1234
1354
|
"data-slot": "dropdown-menu-content",
|
|
@@ -1246,7 +1366,7 @@ function DropdownMenuItem({
|
|
|
1246
1366
|
className,
|
|
1247
1367
|
...props
|
|
1248
1368
|
}) {
|
|
1249
|
-
return /* @__PURE__ */ (0,
|
|
1369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1250
1370
|
import_menu.Menu.Item,
|
|
1251
1371
|
{
|
|
1252
1372
|
"data-slot": "dropdown-menu-item",
|
|
@@ -1258,7 +1378,7 @@ function DropdownMenuItem({
|
|
|
1258
1378
|
|
|
1259
1379
|
// src/components/ReportScenario.tsx
|
|
1260
1380
|
var import_lucide_react2 = require("lucide-react");
|
|
1261
|
-
var
|
|
1381
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1262
1382
|
var STATUS_META = {
|
|
1263
1383
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
1264
1384
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1274,7 +1394,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1274
1394
|
const collapsible = collapse !== null && !hideTitle;
|
|
1275
1395
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
1276
1396
|
const actions = useScenarioActions();
|
|
1277
|
-
return /* @__PURE__ */ (0,
|
|
1397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
1278
1398
|
Card,
|
|
1279
1399
|
{
|
|
1280
1400
|
id: scenario.id,
|
|
@@ -1282,10 +1402,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1282
1402
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
1283
1403
|
className: "gap-0 py-0",
|
|
1284
1404
|
children: [
|
|
1285
|
-
/* @__PURE__ */ (0,
|
|
1286
|
-
/* @__PURE__ */ (0,
|
|
1287
|
-
hideTitle ? null : /* @__PURE__ */ (0,
|
|
1288
|
-
collapsible ? /* @__PURE__ */ (0,
|
|
1405
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CardHeader, { className: "px-4 py-3", children: [
|
|
1406
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
1407
|
+
hideTitle ? null : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1408
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1289
1409
|
"button",
|
|
1290
1410
|
{
|
|
1291
1411
|
type: "button",
|
|
@@ -1294,49 +1414,50 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1294
1414
|
"aria-controls": bodyId,
|
|
1295
1415
|
"aria-label": `Toggle ${scenario.title}`,
|
|
1296
1416
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
1297
|
-
children: /* @__PURE__ */ (0,
|
|
1417
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
1298
1418
|
}
|
|
1299
1419
|
) : null,
|
|
1300
|
-
/* @__PURE__ */ (0,
|
|
1301
|
-
/* @__PURE__ */ (0,
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: scenario.title })
|
|
1302
1422
|
] }),
|
|
1303
|
-
/* @__PURE__ */ (0,
|
|
1304
|
-
/* @__PURE__ */ (0,
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ScenarioStaleness, { scenario }),
|
|
1426
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: (0, import_duration3.formatDuration)(scenario.durationMs) }) : null,
|
|
1427
|
+
meta.showPill ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1428
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenu, { children: [
|
|
1429
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1309
1430
|
DropdownMenuTrigger,
|
|
1310
1431
|
{
|
|
1311
1432
|
"aria-label": `Actions for ${scenario.title}`,
|
|
1312
1433
|
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
1313
|
-
children: /* @__PURE__ */ (0,
|
|
1434
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react2.MoreHorizontalIcon, { "aria-hidden": true })
|
|
1314
1435
|
}
|
|
1315
1436
|
),
|
|
1316
|
-
/* @__PURE__ */ (0,
|
|
1317
|
-
/* @__PURE__ */ (0,
|
|
1318
|
-
/* @__PURE__ */ (0,
|
|
1437
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react2.LinkIcon, {}),
|
|
1319
1440
|
" Copy link"
|
|
1320
1441
|
] }),
|
|
1321
|
-
/* @__PURE__ */ (0,
|
|
1322
|
-
/* @__PURE__ */ (0,
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1443
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react2.FileTextIcon, {}),
|
|
1323
1444
|
" Copy as Markdown"
|
|
1324
1445
|
] }),
|
|
1325
|
-
/* @__PURE__ */ (0,
|
|
1326
|
-
/* @__PURE__ */ (0,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react2.SparklesIcon, {}),
|
|
1327
1448
|
" Explain with AI"
|
|
1328
1449
|
] })
|
|
1329
1450
|
] })
|
|
1330
1451
|
] }) : null
|
|
1331
1452
|
] })
|
|
1332
1453
|
] }),
|
|
1333
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0,
|
|
1334
|
-
scenario.tags.map((t) => /* @__PURE__ */ (0,
|
|
1335
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0,
|
|
1454
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1455
|
+
scenario.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1456
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("li", { children: ticket.url ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1336
1457
|
] }) : null
|
|
1337
1458
|
] }),
|
|
1338
|
-
/* @__PURE__ */ (0,
|
|
1339
|
-
scenario.errorMessage ? /* @__PURE__ */ (0,
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1460
|
+
scenario.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1340
1461
|
"pre",
|
|
1341
1462
|
{
|
|
1342
1463
|
role: "alert",
|
|
@@ -1344,11 +1465,11 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1344
1465
|
children: scenario.errorMessage
|
|
1345
1466
|
}
|
|
1346
1467
|
) : null,
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1348
|
-
/* @__PURE__ */ (0,
|
|
1349
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0,
|
|
1350
|
-
/* @__PURE__ */ (0,
|
|
1351
|
-
/* @__PURE__ */ (0,
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportStoryboard, { scenario }),
|
|
1469
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportSteps, { scenario }),
|
|
1470
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
1471
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportAttachments, { attachments: scenario.attachments }),
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportTrace, { spans: scenario.otelSpans })
|
|
1352
1473
|
] })
|
|
1353
1474
|
]
|
|
1354
1475
|
}
|
|
@@ -1356,13 +1477,40 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1356
1477
|
}
|
|
1357
1478
|
|
|
1358
1479
|
// src/components/ReportScenarioList.tsx
|
|
1359
|
-
var
|
|
1480
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1360
1481
|
function ReportScenarioList({ feature }) {
|
|
1361
|
-
return /* @__PURE__ */ (0,
|
|
1482
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ReportScenario, { scenario }, scenario.id)) });
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
// src/components/ReportFeatureIntro.tsx
|
|
1486
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1487
|
+
function ReportFeatureIntro({ feature }) {
|
|
1488
|
+
const hasNarrative = Boolean(feature.narrative?.trim());
|
|
1489
|
+
const hasGlossary = Boolean(feature.glossary?.length);
|
|
1490
|
+
if (!hasNarrative && !hasGlossary) return null;
|
|
1491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
|
|
1492
|
+
hasNarrative ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1493
|
+
"div",
|
|
1494
|
+
{
|
|
1495
|
+
className: "es-doc-prose prose prose-sm max-w-none text-muted-foreground",
|
|
1496
|
+
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1497
|
+
}
|
|
1498
|
+
) : null,
|
|
1499
|
+
hasGlossary ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
|
|
1502
|
+
] }, entry.term)) }) : null
|
|
1503
|
+
] });
|
|
1504
|
+
}
|
|
1505
|
+
function featureKindLabel(kind) {
|
|
1506
|
+
if (kind === "ability") return "Ability";
|
|
1507
|
+
if (kind === "business-need") return "Business need";
|
|
1508
|
+
if (kind === "feature") return "Feature";
|
|
1509
|
+
return null;
|
|
1362
1510
|
}
|
|
1363
1511
|
|
|
1364
1512
|
// src/components/ReportFeature.tsx
|
|
1365
|
-
var
|
|
1513
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1366
1514
|
function ReportFeature({ feature }) {
|
|
1367
1515
|
const titleId = `${feature.id}-title`;
|
|
1368
1516
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1370,10 +1518,11 @@ function ReportFeature({ feature }) {
|
|
|
1370
1518
|
const skipped = s.skipped + s.pending;
|
|
1371
1519
|
const collapse = useCollapse();
|
|
1372
1520
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1521
|
+
const kindLabel = featureKindLabel(feature.kind);
|
|
1373
1522
|
return (
|
|
1374
1523
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1375
1524
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1377
1526
|
"section",
|
|
1378
1527
|
{
|
|
1379
1528
|
id: feature.id,
|
|
@@ -1381,9 +1530,9 @@ function ReportFeature({ feature }) {
|
|
|
1381
1530
|
"aria-labelledby": titleId,
|
|
1382
1531
|
className: "flex flex-col gap-3",
|
|
1383
1532
|
children: [
|
|
1384
|
-
/* @__PURE__ */ (0,
|
|
1385
|
-
/* @__PURE__ */ (0,
|
|
1386
|
-
/* @__PURE__ */ (0,
|
|
1533
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1534
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "min-w-0", children: [
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1387
1536
|
"button",
|
|
1388
1537
|
{
|
|
1389
1538
|
type: "button",
|
|
@@ -1392,31 +1541,34 @@ function ReportFeature({ feature }) {
|
|
|
1392
1541
|
"aria-controls": bodyId,
|
|
1393
1542
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1394
1543
|
children: [
|
|
1395
|
-
/* @__PURE__ */ (0,
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1545
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "truncate", children: feature.title })
|
|
1397
1546
|
]
|
|
1398
1547
|
}
|
|
1399
1548
|
) : feature.title }),
|
|
1400
|
-
/* @__PURE__ */ (0,
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("p", { className: cn("mt-0.5 flex items-center gap-2 text-xs text-muted-foreground", collapse && "pl-5"), children: [
|
|
1550
|
+
kindLabel ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "shrink-0 rounded-sm bg-muted px-1.5 py-0.5 font-medium text-foreground", children: kindLabel }) : null,
|
|
1551
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "truncate font-mono", children: feature.sourceFile })
|
|
1552
|
+
] })
|
|
1401
1553
|
] }),
|
|
1402
|
-
/* @__PURE__ */ (0,
|
|
1554
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1403
1555
|
"p",
|
|
1404
1556
|
{
|
|
1405
1557
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1406
1558
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1407
1559
|
children: [
|
|
1408
|
-
/* @__PURE__ */ (0,
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
|
|
1409
1561
|
s.passed,
|
|
1410
1562
|
" passed"
|
|
1411
1563
|
] }),
|
|
1412
|
-
/* @__PURE__ */ (0,
|
|
1413
|
-
/* @__PURE__ */ (0,
|
|
1564
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1565
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1414
1566
|
s.failed,
|
|
1415
1567
|
" failed"
|
|
1416
1568
|
] }),
|
|
1417
|
-
skipped > 0 ? /* @__PURE__ */ (0,
|
|
1418
|
-
/* @__PURE__ */ (0,
|
|
1419
|
-
/* @__PURE__ */ (0,
|
|
1569
|
+
skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
|
|
1420
1572
|
skipped,
|
|
1421
1573
|
" skipped"
|
|
1422
1574
|
] })
|
|
@@ -1425,7 +1577,10 @@ function ReportFeature({ feature }) {
|
|
|
1425
1577
|
}
|
|
1426
1578
|
)
|
|
1427
1579
|
] }),
|
|
1428
|
-
/* @__PURE__ */ (0,
|
|
1580
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReportFeatureIntro, { feature }),
|
|
1582
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReportScenarioList, { feature })
|
|
1583
|
+
] })
|
|
1429
1584
|
]
|
|
1430
1585
|
}
|
|
1431
1586
|
)
|
|
@@ -1433,17 +1588,17 @@ function ReportFeature({ feature }) {
|
|
|
1433
1588
|
}
|
|
1434
1589
|
|
|
1435
1590
|
// src/components/ReportFeatureList.tsx
|
|
1436
|
-
var
|
|
1591
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1437
1592
|
function ReportFeatureList() {
|
|
1438
1593
|
const report = useReport();
|
|
1439
|
-
return /* @__PURE__ */ (0,
|
|
1594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ReportFeature, { feature }, feature.id)) });
|
|
1440
1595
|
}
|
|
1441
1596
|
|
|
1442
1597
|
// src/components/ui/empty.tsx
|
|
1443
1598
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
1444
|
-
var
|
|
1599
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1445
1600
|
function Empty({ className, ...props }) {
|
|
1446
|
-
return /* @__PURE__ */ (0,
|
|
1601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1447
1602
|
"div",
|
|
1448
1603
|
{
|
|
1449
1604
|
"data-slot": "empty",
|
|
@@ -1456,7 +1611,7 @@ function Empty({ className, ...props }) {
|
|
|
1456
1611
|
);
|
|
1457
1612
|
}
|
|
1458
1613
|
function EmptyHeader({ className, ...props }) {
|
|
1459
|
-
return /* @__PURE__ */ (0,
|
|
1614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1460
1615
|
"div",
|
|
1461
1616
|
{
|
|
1462
1617
|
"data-slot": "empty-header",
|
|
@@ -1483,7 +1638,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
|
|
|
1483
1638
|
}
|
|
1484
1639
|
);
|
|
1485
1640
|
function EmptyTitle({ className, ...props }) {
|
|
1486
|
-
return /* @__PURE__ */ (0,
|
|
1641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1487
1642
|
"div",
|
|
1488
1643
|
{
|
|
1489
1644
|
"data-slot": "empty-title",
|
|
@@ -1494,16 +1649,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1494
1649
|
}
|
|
1495
1650
|
|
|
1496
1651
|
// src/components/ReportEmpty.tsx
|
|
1497
|
-
var
|
|
1652
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1498
1653
|
function ReportEmpty({ message }) {
|
|
1499
|
-
return /* @__PURE__ */ (0,
|
|
1654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1500
1655
|
}
|
|
1501
1656
|
|
|
1502
1657
|
// src/components/ReportSummary.tsx
|
|
1503
|
-
var
|
|
1658
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1504
1659
|
function ReportSummary({ className }) {
|
|
1505
1660
|
const report = useReport();
|
|
1506
|
-
return /* @__PURE__ */ (0,
|
|
1661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1507
1662
|
ReportSummaryView,
|
|
1508
1663
|
{
|
|
1509
1664
|
summary: report.summary,
|
|
@@ -1529,7 +1684,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1529
1684
|
if (summary.pending > 0) {
|
|
1530
1685
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1531
1686
|
}
|
|
1532
|
-
return /* @__PURE__ */ (0,
|
|
1687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1533
1688
|
"dl",
|
|
1534
1689
|
{
|
|
1535
1690
|
className: cn(
|
|
@@ -1542,17 +1697,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1542
1697
|
"aria-label": ariaLabel,
|
|
1543
1698
|
children: cards.map((c) => {
|
|
1544
1699
|
const tone = TONE[c.status];
|
|
1545
|
-
return /* @__PURE__ */ (0,
|
|
1700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
1546
1701
|
"div",
|
|
1547
1702
|
{
|
|
1548
1703
|
"data-status": c.status,
|
|
1549
1704
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1550
1705
|
children: [
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
1552
|
-
/* @__PURE__ */ (0,
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1707
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1553
1708
|
c.label
|
|
1554
1709
|
] }),
|
|
1555
|
-
/* @__PURE__ */ (0,
|
|
1710
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1556
1711
|
]
|
|
1557
1712
|
},
|
|
1558
1713
|
c.status
|
|
@@ -1564,58 +1719,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1564
1719
|
|
|
1565
1720
|
// src/components/ReportMeta.tsx
|
|
1566
1721
|
var import_duration4 = require("executable-stories-core/utils/duration");
|
|
1567
|
-
|
|
1568
|
-
// src/lib/provenance.ts
|
|
1569
|
-
function reportLastRunMs(report) {
|
|
1570
|
-
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
1571
|
-
if (report.startedAtMs && report.startedAtMs > 0) return report.startedAtMs;
|
|
1572
|
-
return void 0;
|
|
1573
|
-
}
|
|
1574
|
-
function formatRelativeAge(thenMs, nowMs) {
|
|
1575
|
-
const deltaMs = Math.max(0, nowMs - thenMs);
|
|
1576
|
-
const minutes = Math.floor(deltaMs / 6e4);
|
|
1577
|
-
if (minutes < 1) return "just now";
|
|
1578
|
-
if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
1579
|
-
const hours = Math.floor(minutes / 60);
|
|
1580
|
-
if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
1581
|
-
const days = Math.floor(hours / 24);
|
|
1582
|
-
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
1583
|
-
}
|
|
1584
|
-
function isReportStale(lastRunMs, staleAfterDays, nowMs) {
|
|
1585
|
-
if (lastRunMs === void 0 || staleAfterDays <= 0) return false;
|
|
1586
|
-
return nowMs - lastRunMs >= staleAfterDays * 864e5;
|
|
1587
|
-
}
|
|
1588
|
-
var CI_DISPLAY_NAMES = {
|
|
1589
|
-
github: "GitHub Actions",
|
|
1590
|
-
gitlab: "GitLab CI",
|
|
1591
|
-
circleci: "CircleCI",
|
|
1592
|
-
jenkins: "Jenkins",
|
|
1593
|
-
azure: "Azure DevOps",
|
|
1594
|
-
buildkite: "Buildkite",
|
|
1595
|
-
travis: "Travis CI",
|
|
1596
|
-
ci: "CI"
|
|
1597
|
-
};
|
|
1598
|
-
function ciDisplayName(name) {
|
|
1599
|
-
return CI_DISPLAY_NAMES[name] ?? name;
|
|
1600
|
-
}
|
|
1601
|
-
function commitUrl(ci, sha) {
|
|
1602
|
-
const commitSha = ci?.commitSha ?? sha;
|
|
1603
|
-
if (!ci?.url || !commitSha) return void 0;
|
|
1604
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1605
|
-
if (github) return `${github[1]}/commit/${commitSha}`;
|
|
1606
|
-
const gitlab = ci.url.match(/^(https?:\/\/.+)\/-\/pipelines\//);
|
|
1607
|
-
if (gitlab) return `${gitlab[1]}/-/commit/${commitSha}`;
|
|
1608
|
-
return void 0;
|
|
1609
|
-
}
|
|
1610
|
-
function prUrl(ci) {
|
|
1611
|
-
if (!ci?.url || !ci.prNumber) return void 0;
|
|
1612
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1613
|
-
if (github) return `${github[1]}/pull/${ci.prNumber}`;
|
|
1614
|
-
return void 0;
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
// src/components/ReportMeta.tsx
|
|
1618
|
-
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1722
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1619
1723
|
function ReportMeta() {
|
|
1620
1724
|
const report = useReport();
|
|
1621
1725
|
const items = [];
|
|
@@ -1638,13 +1742,13 @@ function ReportMeta() {
|
|
|
1638
1742
|
const short = sha.slice(0, 8);
|
|
1639
1743
|
items.push({
|
|
1640
1744
|
label: "Commit",
|
|
1641
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1745
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1642
1746
|
});
|
|
1643
1747
|
}
|
|
1644
1748
|
if (report.ci) {
|
|
1645
1749
|
items.push({
|
|
1646
1750
|
label: "CI",
|
|
1647
|
-
value: report.ci.url ? /* @__PURE__ */ (0,
|
|
1751
|
+
value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1648
1752
|
ciDisplayName(report.ci.name),
|
|
1649
1753
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1650
1754
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1655,7 +1759,7 @@ function ReportMeta() {
|
|
|
1655
1759
|
const label = `#${report.ci.prNumber}`;
|
|
1656
1760
|
items.push({
|
|
1657
1761
|
label: "PR",
|
|
1658
|
-
value: url ? /* @__PURE__ */ (0,
|
|
1762
|
+
value: url ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1659
1763
|
});
|
|
1660
1764
|
}
|
|
1661
1765
|
if (items.length === 0) return null;
|
|
@@ -1663,48 +1767,48 @@ function ReportMeta() {
|
|
|
1663
1767
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1664
1768
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1665
1769
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1666
|
-
/* @__PURE__ */ (0,
|
|
1667
|
-
/* @__PURE__ */ (0,
|
|
1668
|
-
/* @__PURE__ */ (0,
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1669
1773
|
"Run details"
|
|
1670
1774
|
] }),
|
|
1671
|
-
/* @__PURE__ */ (0,
|
|
1672
|
-
/* @__PURE__ */ (0,
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("dt", { className: "font-medium", children: item.label }),
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1674
1778
|
] }, item.label)) })
|
|
1675
1779
|
] })
|
|
1676
1780
|
);
|
|
1677
1781
|
}
|
|
1678
1782
|
|
|
1679
1783
|
// src/components/ReportSchemaError.tsx
|
|
1680
|
-
var
|
|
1784
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1681
1785
|
function ReportSchemaError({ error }) {
|
|
1682
|
-
return /* @__PURE__ */ (0,
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
1684
|
-
/* @__PURE__ */ (0,
|
|
1685
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0,
|
|
1786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1787
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("strong", { children: "Report could not be displayed." }) }),
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { children: error.message }),
|
|
1789
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { children: [
|
|
1686
1790
|
"The report bundle is newer than this version of ",
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1791
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { children: "executable-stories-react" }),
|
|
1688
1792
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1689
1793
|
] }) : null,
|
|
1690
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0,
|
|
1691
|
-
/* @__PURE__ */ (0,
|
|
1794
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("details", { children: [
|
|
1795
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("summary", { children: [
|
|
1692
1796
|
error.issues.length,
|
|
1693
1797
|
" validation issue",
|
|
1694
1798
|
error.issues.length === 1 ? "" : "s"
|
|
1695
1799
|
] }),
|
|
1696
|
-
/* @__PURE__ */ (0,
|
|
1800
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1697
1801
|
] }) : null
|
|
1698
1802
|
] });
|
|
1699
1803
|
}
|
|
1700
1804
|
|
|
1701
1805
|
// src/components/ReportShell.tsx
|
|
1702
|
-
var
|
|
1806
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1703
1807
|
function ReportTitleBlock({ title }) {
|
|
1704
|
-
return /* @__PURE__ */ (0,
|
|
1705
|
-
/* @__PURE__ */ (0,
|
|
1706
|
-
/* @__PURE__ */ (0,
|
|
1707
|
-
/* @__PURE__ */ (0,
|
|
1808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
1809
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("h1", { children: title ?? "Story Report" }),
|
|
1810
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportSummary, {}),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportMeta, {})
|
|
1708
1812
|
] });
|
|
1709
1813
|
}
|
|
1710
1814
|
function ReportErrorShell({
|
|
@@ -1713,28 +1817,28 @@ function ReportErrorShell({
|
|
|
1713
1817
|
title,
|
|
1714
1818
|
dataTheme
|
|
1715
1819
|
}) {
|
|
1716
|
-
return /* @__PURE__ */ (0,
|
|
1820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportSchemaError, { error }) });
|
|
1717
1821
|
}
|
|
1718
1822
|
|
|
1719
1823
|
// src/components/Report.tsx
|
|
1720
|
-
var
|
|
1824
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1721
1825
|
function Report(props) {
|
|
1722
1826
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1723
1827
|
const result = unwrapReport(report);
|
|
1724
1828
|
if (!result.ok) {
|
|
1725
|
-
return /* @__PURE__ */ (0,
|
|
1829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1726
1830
|
}
|
|
1727
1831
|
const data = result.data;
|
|
1728
1832
|
const hasContent = data.features.length > 0;
|
|
1729
|
-
return /* @__PURE__ */ (0,
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
1731
|
-
hasContent ? /* @__PURE__ */ (0,
|
|
1833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1834
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("header", { className: "es-report-header", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReportTitleBlock, { title }) }),
|
|
1835
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReportFeatureList, {}) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ReportEmpty, {})
|
|
1732
1836
|
] }) });
|
|
1733
1837
|
}
|
|
1734
1838
|
|
|
1735
1839
|
// src/components/doc/MermaidView.tsx
|
|
1736
|
-
var
|
|
1737
|
-
var
|
|
1840
|
+
var import_react10 = require("react");
|
|
1841
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1738
1842
|
function prefersDark(el) {
|
|
1739
1843
|
const themed = el?.closest("[data-theme]");
|
|
1740
1844
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1742,10 +1846,10 @@ function prefersDark(el) {
|
|
|
1742
1846
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
1743
1847
|
}
|
|
1744
1848
|
function MermaidView({ entry, load }) {
|
|
1745
|
-
const ref = (0,
|
|
1746
|
-
const [svg, setSvg] = (0,
|
|
1747
|
-
const [error, setError] = (0,
|
|
1748
|
-
(0,
|
|
1849
|
+
const ref = (0, import_react10.useRef)(null);
|
|
1850
|
+
const [svg, setSvg] = (0, import_react10.useState)(null);
|
|
1851
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
1852
|
+
(0, import_react10.useEffect)(() => {
|
|
1749
1853
|
let cancelled = false;
|
|
1750
1854
|
const draw = async () => {
|
|
1751
1855
|
let mermaid;
|
|
@@ -1788,9 +1892,9 @@ function MermaidView({ entry, load }) {
|
|
|
1788
1892
|
};
|
|
1789
1893
|
}, [entry.code, load]);
|
|
1790
1894
|
if (svg) {
|
|
1791
|
-
return /* @__PURE__ */ (0,
|
|
1792
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
1793
|
-
/* @__PURE__ */ (0,
|
|
1895
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("figure", { ref, className: "my-3", children: [
|
|
1896
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1794
1898
|
"div",
|
|
1795
1899
|
{
|
|
1796
1900
|
role: "img",
|
|
@@ -1801,8 +1905,8 @@ function MermaidView({ entry, load }) {
|
|
|
1801
1905
|
)
|
|
1802
1906
|
] });
|
|
1803
1907
|
}
|
|
1804
|
-
return /* @__PURE__ */ (0,
|
|
1805
|
-
error ? /* @__PURE__ */ (0,
|
|
1908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
|
|
1909
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
1806
1910
|
"p",
|
|
1807
1911
|
{
|
|
1808
1912
|
role: "alert",
|
|
@@ -1814,34 +1918,34 @@ function MermaidView({ entry, load }) {
|
|
|
1814
1918
|
]
|
|
1815
1919
|
}
|
|
1816
1920
|
) : null,
|
|
1817
|
-
/* @__PURE__ */ (0,
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(MermaidSource, { entry, ref })
|
|
1818
1922
|
] });
|
|
1819
1923
|
}
|
|
1820
1924
|
|
|
1821
1925
|
// src/components/doc/MermaidDiagram.tsx
|
|
1822
|
-
var
|
|
1926
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
1823
1927
|
var mermaidLoader;
|
|
1824
1928
|
function loadMermaid() {
|
|
1825
1929
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1826
1930
|
return mermaidLoader;
|
|
1827
1931
|
}
|
|
1828
1932
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1829
|
-
return /* @__PURE__ */ (0,
|
|
1933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MermaidView, { entry, load });
|
|
1830
1934
|
}
|
|
1831
1935
|
|
|
1832
1936
|
// src/components/ScenarioExplorer.tsx
|
|
1833
|
-
var
|
|
1937
|
+
var import_react11 = require("react");
|
|
1834
1938
|
|
|
1835
1939
|
// src/components/ui/command.tsx
|
|
1836
1940
|
var React4 = require("react");
|
|
1837
1941
|
var import_cmdk = require("cmdk");
|
|
1838
1942
|
var import_lucide_react3 = require("lucide-react");
|
|
1839
|
-
var
|
|
1943
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1840
1944
|
function Command({
|
|
1841
1945
|
className,
|
|
1842
1946
|
...props
|
|
1843
1947
|
}) {
|
|
1844
|
-
return /* @__PURE__ */ (0,
|
|
1948
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1845
1949
|
import_cmdk.Command,
|
|
1846
1950
|
{
|
|
1847
1951
|
"data-slot": "command",
|
|
@@ -1857,14 +1961,14 @@ function CommandInput({
|
|
|
1857
1961
|
className,
|
|
1858
1962
|
...props
|
|
1859
1963
|
}) {
|
|
1860
|
-
return /* @__PURE__ */ (0,
|
|
1964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
1861
1965
|
"div",
|
|
1862
1966
|
{
|
|
1863
1967
|
"data-slot": "command-input-wrapper",
|
|
1864
1968
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1865
1969
|
children: [
|
|
1866
|
-
/* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react3.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1868
1972
|
import_cmdk.Command.Input,
|
|
1869
1973
|
{
|
|
1870
1974
|
"data-slot": "command-input",
|
|
@@ -1883,7 +1987,7 @@ function CommandList({
|
|
|
1883
1987
|
className,
|
|
1884
1988
|
...props
|
|
1885
1989
|
}) {
|
|
1886
|
-
return /* @__PURE__ */ (0,
|
|
1990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1887
1991
|
import_cmdk.Command.List,
|
|
1888
1992
|
{
|
|
1889
1993
|
"data-slot": "command-list",
|
|
@@ -1898,7 +2002,7 @@ function CommandList({
|
|
|
1898
2002
|
function CommandEmpty({
|
|
1899
2003
|
...props
|
|
1900
2004
|
}) {
|
|
1901
|
-
return /* @__PURE__ */ (0,
|
|
2005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1902
2006
|
import_cmdk.Command.Empty,
|
|
1903
2007
|
{
|
|
1904
2008
|
"data-slot": "command-empty",
|
|
@@ -1911,7 +2015,7 @@ function CommandGroup({
|
|
|
1911
2015
|
className,
|
|
1912
2016
|
...props
|
|
1913
2017
|
}) {
|
|
1914
|
-
return /* @__PURE__ */ (0,
|
|
2018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1915
2019
|
import_cmdk.Command.Group,
|
|
1916
2020
|
{
|
|
1917
2021
|
"data-slot": "command-group",
|
|
@@ -1927,7 +2031,7 @@ function CommandItem({
|
|
|
1927
2031
|
className,
|
|
1928
2032
|
...props
|
|
1929
2033
|
}) {
|
|
1930
|
-
return /* @__PURE__ */ (0,
|
|
2034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1931
2035
|
import_cmdk.Command.Item,
|
|
1932
2036
|
{
|
|
1933
2037
|
"data-slot": "command-item",
|
|
@@ -1941,7 +2045,7 @@ function CommandItem({
|
|
|
1941
2045
|
}
|
|
1942
2046
|
|
|
1943
2047
|
// src/components/ScenarioExplorer.tsx
|
|
1944
|
-
var
|
|
2048
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
1945
2049
|
var STATUS_FILTERS = [
|
|
1946
2050
|
{ value: "all", label: "All" },
|
|
1947
2051
|
{ value: "passed", label: "Passed" },
|
|
@@ -1950,24 +2054,24 @@ var STATUS_FILTERS = [
|
|
|
1950
2054
|
{ value: "pending", label: "Pending" }
|
|
1951
2055
|
];
|
|
1952
2056
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1953
|
-
const [status, setStatus] = (0,
|
|
2057
|
+
const [status, setStatus] = (0, import_react11.useState)("all");
|
|
1954
2058
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1955
|
-
return /* @__PURE__ */ (0,
|
|
1956
|
-
summary ? /* @__PURE__ */ (0,
|
|
2059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "font-sans text-foreground", children: [
|
|
2060
|
+
summary ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1957
2061
|
summary.total,
|
|
1958
2062
|
" scenarios \xB7 ",
|
|
1959
|
-
/* @__PURE__ */ (0,
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-pass", children: [
|
|
1960
2064
|
summary.passed,
|
|
1961
2065
|
" passed"
|
|
1962
2066
|
] }),
|
|
1963
2067
|
" \xB7",
|
|
1964
2068
|
" ",
|
|
1965
|
-
/* @__PURE__ */ (0,
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-fail", children: [
|
|
1966
2070
|
summary.failed,
|
|
1967
2071
|
" failed"
|
|
1968
2072
|
] })
|
|
1969
2073
|
] }) : null,
|
|
1970
|
-
/* @__PURE__ */ (0,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1971
2075
|
"button",
|
|
1972
2076
|
{
|
|
1973
2077
|
type: "button",
|
|
@@ -1982,26 +2086,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1982
2086
|
},
|
|
1983
2087
|
f.value
|
|
1984
2088
|
)) }),
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
2089
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
1986
2090
|
Command,
|
|
1987
2091
|
{
|
|
1988
2092
|
className: "rounded-lg border border-border bg-card",
|
|
1989
2093
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1990
2094
|
children: [
|
|
1991
|
-
/* @__PURE__ */ (0,
|
|
1992
|
-
/* @__PURE__ */ (0,
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(CommandList, { className: "max-h-none", children: [
|
|
2097
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1995
2099
|
CommandItem,
|
|
1996
2100
|
{
|
|
1997
2101
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1998
2102
|
asChild: true,
|
|
1999
2103
|
className: "cursor-pointer",
|
|
2000
|
-
children: /* @__PURE__ */ (0,
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2002
|
-
/* @__PURE__ */ (0,
|
|
2003
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0,
|
|
2004
|
-
/* @__PURE__ */ (0,
|
|
2104
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
2105
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Badge, { variant: s.status, children: s.status }),
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
2107
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
2005
2109
|
] })
|
|
2006
2110
|
},
|
|
2007
2111
|
s.id
|
|
@@ -2148,7 +2252,7 @@ var story_report_v1_default = {
|
|
|
2148
2252
|
title: {
|
|
2149
2253
|
type: "string",
|
|
2150
2254
|
minLength: 1,
|
|
2151
|
-
description: "Display title.
|
|
2255
|
+
description: "Display title. Comes from story.feature(...) when declared, otherwise the describe block or file basename."
|
|
2152
2256
|
},
|
|
2153
2257
|
sourceFile: {
|
|
2154
2258
|
type: "string",
|
|
@@ -2164,15 +2268,25 @@ var story_report_v1_default = {
|
|
|
2164
2268
|
$ref: "#/$defs/Scenario"
|
|
2165
2269
|
},
|
|
2166
2270
|
description: "Scenarios in this feature, in declaration order."
|
|
2271
|
+
},
|
|
2272
|
+
kind: {
|
|
2273
|
+
type: "string",
|
|
2274
|
+
enum: ["feature", "ability", "business-need"],
|
|
2275
|
+
description: "How the feature was declared. Absent when the title was derived rather than declared."
|
|
2276
|
+
},
|
|
2277
|
+
narrative: {
|
|
2278
|
+
type: "string",
|
|
2279
|
+
description: "Markdown explaining why the feature exists and who it serves."
|
|
2280
|
+
},
|
|
2281
|
+
glossary: {
|
|
2282
|
+
type: "array",
|
|
2283
|
+
items: {
|
|
2284
|
+
$ref: "#/$defs/GlossaryTerm"
|
|
2285
|
+
},
|
|
2286
|
+
description: "Terms this feature defines, linked wherever they appear in scenario text."
|
|
2167
2287
|
}
|
|
2168
2288
|
},
|
|
2169
|
-
required: [
|
|
2170
|
-
"id",
|
|
2171
|
-
"title",
|
|
2172
|
-
"sourceFile",
|
|
2173
|
-
"summary",
|
|
2174
|
-
"scenarios"
|
|
2175
|
-
],
|
|
2289
|
+
required: ["id", "title", "sourceFile", "summary", "scenarios"],
|
|
2176
2290
|
additionalProperties: false
|
|
2177
2291
|
},
|
|
2178
2292
|
Scenario: {
|
|
@@ -2302,6 +2416,11 @@ var story_report_v1_default = {
|
|
|
2302
2416
|
type: "number",
|
|
2303
2417
|
minimum: 0
|
|
2304
2418
|
},
|
|
2419
|
+
assertions: {
|
|
2420
|
+
type: "integer",
|
|
2421
|
+
minimum: 0,
|
|
2422
|
+
description: "Assertions observed or declared for this step. Omit when the adapter cannot observe assertions; zero means observed none."
|
|
2423
|
+
},
|
|
2305
2424
|
errorMessage: {
|
|
2306
2425
|
type: "string"
|
|
2307
2426
|
},
|
|
@@ -2329,33 +2448,15 @@ var story_report_v1_default = {
|
|
|
2329
2448
|
},
|
|
2330
2449
|
StepKeyword: {
|
|
2331
2450
|
type: "string",
|
|
2332
|
-
enum: [
|
|
2333
|
-
"Given",
|
|
2334
|
-
"When",
|
|
2335
|
-
"Then",
|
|
2336
|
-
"And",
|
|
2337
|
-
"But"
|
|
2338
|
-
]
|
|
2451
|
+
enum: ["Given", "When", "Then", "And", "But"]
|
|
2339
2452
|
},
|
|
2340
2453
|
StepMode: {
|
|
2341
2454
|
type: "string",
|
|
2342
|
-
enum: [
|
|
2343
|
-
"normal",
|
|
2344
|
-
"skip",
|
|
2345
|
-
"only",
|
|
2346
|
-
"todo",
|
|
2347
|
-
"fails",
|
|
2348
|
-
"concurrent"
|
|
2349
|
-
]
|
|
2455
|
+
enum: ["normal", "skip", "only", "todo", "fails", "concurrent"]
|
|
2350
2456
|
},
|
|
2351
2457
|
TestStatus: {
|
|
2352
2458
|
type: "string",
|
|
2353
|
-
enum: [
|
|
2354
|
-
"passed",
|
|
2355
|
-
"failed",
|
|
2356
|
-
"skipped",
|
|
2357
|
-
"pending"
|
|
2358
|
-
]
|
|
2459
|
+
enum: ["passed", "failed", "skipped", "pending"]
|
|
2359
2460
|
},
|
|
2360
2461
|
Ticket: {
|
|
2361
2462
|
type: "object",
|
|
@@ -2368,9 +2469,7 @@ var story_report_v1_default = {
|
|
|
2368
2469
|
type: "string"
|
|
2369
2470
|
}
|
|
2370
2471
|
},
|
|
2371
|
-
required: [
|
|
2372
|
-
"id"
|
|
2373
|
-
],
|
|
2472
|
+
required: ["id"],
|
|
2374
2473
|
additionalProperties: false
|
|
2375
2474
|
},
|
|
2376
2475
|
Attachment: {
|
|
@@ -2388,18 +2487,10 @@ var story_report_v1_default = {
|
|
|
2388
2487
|
},
|
|
2389
2488
|
contentEncoding: {
|
|
2390
2489
|
type: "string",
|
|
2391
|
-
enum: [
|
|
2392
|
-
"BASE64",
|
|
2393
|
-
"IDENTITY"
|
|
2394
|
-
]
|
|
2490
|
+
enum: ["BASE64", "IDENTITY"]
|
|
2395
2491
|
}
|
|
2396
2492
|
},
|
|
2397
|
-
required: [
|
|
2398
|
-
"name",
|
|
2399
|
-
"mediaType",
|
|
2400
|
-
"body",
|
|
2401
|
-
"contentEncoding"
|
|
2402
|
-
],
|
|
2493
|
+
required: ["name", "mediaType", "body", "contentEncoding"],
|
|
2403
2494
|
additionalProperties: false
|
|
2404
2495
|
},
|
|
2405
2496
|
CIInfo: {
|
|
@@ -2424,9 +2515,7 @@ var story_report_v1_default = {
|
|
|
2424
2515
|
type: "string"
|
|
2425
2516
|
}
|
|
2426
2517
|
},
|
|
2427
|
-
required: [
|
|
2428
|
-
"name"
|
|
2429
|
-
],
|
|
2518
|
+
required: ["name"],
|
|
2430
2519
|
additionalProperties: false
|
|
2431
2520
|
},
|
|
2432
2521
|
CoverageSummary: {
|
|
@@ -2457,10 +2546,7 @@ var story_report_v1_default = {
|
|
|
2457
2546
|
},
|
|
2458
2547
|
DocPhase: {
|
|
2459
2548
|
type: "string",
|
|
2460
|
-
enum: [
|
|
2461
|
-
"static",
|
|
2462
|
-
"runtime"
|
|
2463
|
-
]
|
|
2549
|
+
enum: ["static", "runtime"]
|
|
2464
2550
|
},
|
|
2465
2551
|
DocEntry: {
|
|
2466
2552
|
oneOf: [
|
|
@@ -2524,11 +2610,7 @@ var story_report_v1_default = {
|
|
|
2524
2610
|
}
|
|
2525
2611
|
}
|
|
2526
2612
|
},
|
|
2527
|
-
required: [
|
|
2528
|
-
"kind",
|
|
2529
|
-
"text",
|
|
2530
|
-
"phase"
|
|
2531
|
-
],
|
|
2613
|
+
required: ["kind", "text", "phase"],
|
|
2532
2614
|
additionalProperties: false
|
|
2533
2615
|
},
|
|
2534
2616
|
DocTag: {
|
|
@@ -2553,11 +2635,7 @@ var story_report_v1_default = {
|
|
|
2553
2635
|
}
|
|
2554
2636
|
}
|
|
2555
2637
|
},
|
|
2556
|
-
required: [
|
|
2557
|
-
"kind",
|
|
2558
|
-
"names",
|
|
2559
|
-
"phase"
|
|
2560
|
-
],
|
|
2638
|
+
required: ["kind", "names", "phase"],
|
|
2561
2639
|
additionalProperties: false
|
|
2562
2640
|
},
|
|
2563
2641
|
DocKv: {
|
|
@@ -2580,12 +2658,7 @@ var story_report_v1_default = {
|
|
|
2580
2658
|
}
|
|
2581
2659
|
}
|
|
2582
2660
|
},
|
|
2583
|
-
required: [
|
|
2584
|
-
"kind",
|
|
2585
|
-
"label",
|
|
2586
|
-
"value",
|
|
2587
|
-
"phase"
|
|
2588
|
-
],
|
|
2661
|
+
required: ["kind", "label", "value", "phase"],
|
|
2589
2662
|
additionalProperties: false
|
|
2590
2663
|
},
|
|
2591
2664
|
DocCode: {
|
|
@@ -2613,12 +2686,7 @@ var story_report_v1_default = {
|
|
|
2613
2686
|
}
|
|
2614
2687
|
}
|
|
2615
2688
|
},
|
|
2616
|
-
required: [
|
|
2617
|
-
"kind",
|
|
2618
|
-
"label",
|
|
2619
|
-
"content",
|
|
2620
|
-
"phase"
|
|
2621
|
-
],
|
|
2689
|
+
required: ["kind", "label", "content", "phase"],
|
|
2622
2690
|
additionalProperties: false
|
|
2623
2691
|
},
|
|
2624
2692
|
DocTable: {
|
|
@@ -2655,13 +2723,7 @@ var story_report_v1_default = {
|
|
|
2655
2723
|
}
|
|
2656
2724
|
}
|
|
2657
2725
|
},
|
|
2658
|
-
required: [
|
|
2659
|
-
"kind",
|
|
2660
|
-
"label",
|
|
2661
|
-
"columns",
|
|
2662
|
-
"rows",
|
|
2663
|
-
"phase"
|
|
2664
|
-
],
|
|
2726
|
+
required: ["kind", "label", "columns", "rows", "phase"],
|
|
2665
2727
|
additionalProperties: false
|
|
2666
2728
|
},
|
|
2667
2729
|
DocLink: {
|
|
@@ -2686,12 +2748,7 @@ var story_report_v1_default = {
|
|
|
2686
2748
|
}
|
|
2687
2749
|
}
|
|
2688
2750
|
},
|
|
2689
|
-
required: [
|
|
2690
|
-
"kind",
|
|
2691
|
-
"label",
|
|
2692
|
-
"url",
|
|
2693
|
-
"phase"
|
|
2694
|
-
],
|
|
2751
|
+
required: ["kind", "label", "url", "phase"],
|
|
2695
2752
|
additionalProperties: false
|
|
2696
2753
|
},
|
|
2697
2754
|
DocSection: {
|
|
@@ -2716,12 +2773,7 @@ var story_report_v1_default = {
|
|
|
2716
2773
|
}
|
|
2717
2774
|
}
|
|
2718
2775
|
},
|
|
2719
|
-
required: [
|
|
2720
|
-
"kind",
|
|
2721
|
-
"title",
|
|
2722
|
-
"markdown",
|
|
2723
|
-
"phase"
|
|
2724
|
-
],
|
|
2776
|
+
required: ["kind", "title", "markdown", "phase"],
|
|
2725
2777
|
additionalProperties: false
|
|
2726
2778
|
},
|
|
2727
2779
|
DocMermaid: {
|
|
@@ -2746,11 +2798,7 @@ var story_report_v1_default = {
|
|
|
2746
2798
|
}
|
|
2747
2799
|
}
|
|
2748
2800
|
},
|
|
2749
|
-
required: [
|
|
2750
|
-
"kind",
|
|
2751
|
-
"code",
|
|
2752
|
-
"phase"
|
|
2753
|
-
],
|
|
2801
|
+
required: ["kind", "code", "phase"],
|
|
2754
2802
|
additionalProperties: false
|
|
2755
2803
|
},
|
|
2756
2804
|
DocScreenshot: {
|
|
@@ -2775,11 +2823,7 @@ var story_report_v1_default = {
|
|
|
2775
2823
|
}
|
|
2776
2824
|
}
|
|
2777
2825
|
},
|
|
2778
|
-
required: [
|
|
2779
|
-
"kind",
|
|
2780
|
-
"path",
|
|
2781
|
-
"phase"
|
|
2782
|
-
],
|
|
2826
|
+
required: ["kind", "path", "phase"],
|
|
2783
2827
|
additionalProperties: false
|
|
2784
2828
|
},
|
|
2785
2829
|
DocVideo: {
|
|
@@ -2807,11 +2851,7 @@ var story_report_v1_default = {
|
|
|
2807
2851
|
}
|
|
2808
2852
|
}
|
|
2809
2853
|
},
|
|
2810
|
-
required: [
|
|
2811
|
-
"kind",
|
|
2812
|
-
"path",
|
|
2813
|
-
"phase"
|
|
2814
|
-
],
|
|
2854
|
+
required: ["kind", "path", "phase"],
|
|
2815
2855
|
additionalProperties: false
|
|
2816
2856
|
},
|
|
2817
2857
|
DocHtml: {
|
|
@@ -2852,26 +2892,17 @@ var story_report_v1_default = {
|
|
|
2852
2892
|
}
|
|
2853
2893
|
}
|
|
2854
2894
|
},
|
|
2855
|
-
required: [
|
|
2856
|
-
"kind",
|
|
2857
|
-
"phase"
|
|
2858
|
-
],
|
|
2895
|
+
required: ["kind", "phase"],
|
|
2859
2896
|
additionalProperties: false,
|
|
2860
2897
|
oneOf: [
|
|
2861
2898
|
{
|
|
2862
|
-
required: [
|
|
2863
|
-
"path"
|
|
2864
|
-
]
|
|
2899
|
+
required: ["path"]
|
|
2865
2900
|
},
|
|
2866
2901
|
{
|
|
2867
|
-
required: [
|
|
2868
|
-
"url"
|
|
2869
|
-
]
|
|
2902
|
+
required: ["url"]
|
|
2870
2903
|
},
|
|
2871
2904
|
{
|
|
2872
|
-
required: [
|
|
2873
|
-
"content"
|
|
2874
|
-
]
|
|
2905
|
+
required: ["content"]
|
|
2875
2906
|
}
|
|
2876
2907
|
]
|
|
2877
2908
|
},
|
|
@@ -2895,11 +2926,7 @@ var story_report_v1_default = {
|
|
|
2895
2926
|
}
|
|
2896
2927
|
}
|
|
2897
2928
|
},
|
|
2898
|
-
required: [
|
|
2899
|
-
"kind",
|
|
2900
|
-
"value",
|
|
2901
|
-
"phase"
|
|
2902
|
-
],
|
|
2929
|
+
required: ["kind", "value", "phase"],
|
|
2903
2930
|
additionalProperties: false
|
|
2904
2931
|
},
|
|
2905
2932
|
DocCustom: {
|
|
@@ -2923,21 +2950,12 @@ var story_report_v1_default = {
|
|
|
2923
2950
|
}
|
|
2924
2951
|
}
|
|
2925
2952
|
},
|
|
2926
|
-
required: [
|
|
2927
|
-
"kind",
|
|
2928
|
-
"type",
|
|
2929
|
-
"data",
|
|
2930
|
-
"phase"
|
|
2931
|
-
],
|
|
2953
|
+
required: ["kind", "type", "data", "phase"],
|
|
2932
2954
|
additionalProperties: false
|
|
2933
2955
|
},
|
|
2934
2956
|
OtelSpan: {
|
|
2935
2957
|
type: "object",
|
|
2936
|
-
required: [
|
|
2937
|
-
"spanId",
|
|
2938
|
-
"name",
|
|
2939
|
-
"status"
|
|
2940
|
-
],
|
|
2958
|
+
required: ["spanId", "name", "status"],
|
|
2941
2959
|
properties: {
|
|
2942
2960
|
spanId: {
|
|
2943
2961
|
type: "string"
|
|
@@ -2961,11 +2979,7 @@ var story_report_v1_default = {
|
|
|
2961
2979
|
type: "number"
|
|
2962
2980
|
},
|
|
2963
2981
|
status: {
|
|
2964
|
-
enum: [
|
|
2965
|
-
"ok",
|
|
2966
|
-
"error",
|
|
2967
|
-
"unset"
|
|
2968
|
-
]
|
|
2982
|
+
enum: ["ok", "error", "unset"]
|
|
2969
2983
|
},
|
|
2970
2984
|
statusMessage: {
|
|
2971
2985
|
type: "string"
|
|
@@ -2975,6 +2989,22 @@ var story_report_v1_default = {
|
|
|
2975
2989
|
}
|
|
2976
2990
|
},
|
|
2977
2991
|
additionalProperties: false
|
|
2992
|
+
},
|
|
2993
|
+
GlossaryTerm: {
|
|
2994
|
+
type: "object",
|
|
2995
|
+
description: "One glossary entry: a term the scenarios use and what it means.",
|
|
2996
|
+
properties: {
|
|
2997
|
+
term: {
|
|
2998
|
+
type: "string",
|
|
2999
|
+
minLength: 1
|
|
3000
|
+
},
|
|
3001
|
+
definition: {
|
|
3002
|
+
type: "string",
|
|
3003
|
+
minLength: 1
|
|
3004
|
+
}
|
|
3005
|
+
},
|
|
3006
|
+
required: ["term", "definition"],
|
|
3007
|
+
additionalProperties: false
|
|
2978
3008
|
}
|
|
2979
3009
|
}
|
|
2980
3010
|
};
|
|
@@ -3077,6 +3107,7 @@ function parseStoryReport(input) {
|
|
|
3077
3107
|
parseStoryReport,
|
|
3078
3108
|
prUrl,
|
|
3079
3109
|
reportLastRunMs,
|
|
3110
|
+
scenarioLastRunMs,
|
|
3080
3111
|
storyReportSchema,
|
|
3081
3112
|
useBuiltinRenderers,
|
|
3082
3113
|
useCustomRenderers,
|