executable-stories-react 0.11.0 → 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 +414 -464
- 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 +313 -361
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +1440 -1298
- 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 +1394 -1249
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +34 -147
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.js +34 -147
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +29 -29
- package/dist/ssr.cjs +330 -259
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +249 -175
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -289,23 +289,48 @@ function useReport() {
|
|
|
289
289
|
// src/components/ReportScenario.tsx
|
|
290
290
|
import { formatDuration as formatDuration3 } from "executable-stories-core/utils/duration";
|
|
291
291
|
|
|
292
|
+
// src/lib/step-params.tsx
|
|
293
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
294
|
+
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
295
|
+
function highlightStepParams(text) {
|
|
296
|
+
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
297
|
+
if (matches.length === 0) return text;
|
|
298
|
+
const nodes = [];
|
|
299
|
+
let lastIndex = 0;
|
|
300
|
+
matches.forEach((match, i) => {
|
|
301
|
+
const start = match.index;
|
|
302
|
+
const end = start + match[0].length;
|
|
303
|
+
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
304
|
+
nodes.push(
|
|
305
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
306
|
+
);
|
|
307
|
+
lastIndex = end;
|
|
308
|
+
});
|
|
309
|
+
if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
|
|
310
|
+
return nodes;
|
|
311
|
+
}
|
|
312
|
+
|
|
292
313
|
// src/components/ReportSteps.tsx
|
|
314
|
+
import {
|
|
315
|
+
assertionState,
|
|
316
|
+
assertiveSteps
|
|
317
|
+
} from "executable-stories-core/utils/assertive-steps";
|
|
293
318
|
import { formatDuration } from "executable-stories-core/utils/duration";
|
|
294
319
|
|
|
295
320
|
// src/components/doc/DocNote.tsx
|
|
296
|
-
import { jsx as
|
|
321
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
297
322
|
function DocNote({ entry }) {
|
|
298
|
-
return /* @__PURE__ */
|
|
323
|
+
return /* @__PURE__ */ jsx4("p", { className: "my-2 text-sm text-muted-foreground", children: entry.text });
|
|
299
324
|
}
|
|
300
325
|
|
|
301
326
|
// src/components/doc/DocTag.tsx
|
|
302
|
-
import { jsx as
|
|
327
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
303
328
|
function DocTag({ entry }) {
|
|
304
|
-
return /* @__PURE__ */
|
|
329
|
+
return /* @__PURE__ */ jsx5("ul", { className: "my-2 flex flex-wrap gap-1.5", "aria-label": "Tags", children: entry.names.map((n) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(Badge, { variant: "tag", children: n }) }, n)) });
|
|
305
330
|
}
|
|
306
331
|
|
|
307
332
|
// src/components/doc/DocKv.tsx
|
|
308
|
-
import { jsx as
|
|
333
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
309
334
|
function formatValue(value) {
|
|
310
335
|
if (value === null) return "null";
|
|
311
336
|
if (typeof value === "string") return value;
|
|
@@ -318,8 +343,8 @@ function formatValue(value) {
|
|
|
318
343
|
}
|
|
319
344
|
function DocKv({ entry }) {
|
|
320
345
|
return /* @__PURE__ */ jsxs2("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
346
|
+
/* @__PURE__ */ jsx6("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
|
|
347
|
+
/* @__PURE__ */ jsx6("dd", { className: "font-mono text-foreground", children: formatValue(entry.value) })
|
|
323
348
|
] });
|
|
324
349
|
}
|
|
325
350
|
|
|
@@ -337,37 +362,37 @@ function useBuiltinRenderers() {
|
|
|
337
362
|
}
|
|
338
363
|
|
|
339
364
|
// src/components/doc/DocCode.tsx
|
|
340
|
-
import { Fragment, jsx as
|
|
365
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
341
366
|
function CodeFigure({ label, children }) {
|
|
342
367
|
return /* @__PURE__ */ jsxs3("figure", { className: "my-3", children: [
|
|
343
|
-
label ? /* @__PURE__ */
|
|
344
|
-
/* @__PURE__ */
|
|
368
|
+
label ? /* @__PURE__ */ jsx7("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: label }) : null,
|
|
369
|
+
/* @__PURE__ */ jsx7("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3", children })
|
|
345
370
|
] });
|
|
346
371
|
}
|
|
347
372
|
function DocCode({ entry }) {
|
|
348
373
|
const renderers = useBuiltinRenderers();
|
|
349
374
|
if (renderers.code) {
|
|
350
|
-
return /* @__PURE__ */
|
|
375
|
+
return /* @__PURE__ */ jsx7(Fragment, { children: renderers.code(entry) });
|
|
351
376
|
}
|
|
352
|
-
return /* @__PURE__ */
|
|
377
|
+
return /* @__PURE__ */ jsx7(CodeFigure, { label: entry.label, children: /* @__PURE__ */ jsx7("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
|
|
353
378
|
}
|
|
354
379
|
|
|
355
380
|
// src/components/doc/DocTable.tsx
|
|
356
|
-
import { jsx as
|
|
381
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
357
382
|
function DocTable({ entry }) {
|
|
358
383
|
return /* @__PURE__ */ jsxs4("figure", { className: "my-3", children: [
|
|
359
|
-
entry.label ? /* @__PURE__ */
|
|
360
|
-
/* @__PURE__ */
|
|
361
|
-
/* @__PURE__ */
|
|
362
|
-
/* @__PURE__ */
|
|
384
|
+
entry.label ? /* @__PURE__ */ jsx8("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.label }) : null,
|
|
385
|
+
/* @__PURE__ */ jsx8("div", { tabIndex: 0, className: "overflow-x-auto rounded-md border border-border", children: /* @__PURE__ */ jsxs4("table", { className: "w-full border-collapse text-sm", children: [
|
|
386
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { className: "bg-muted/50", children: entry.columns.map((c) => /* @__PURE__ */ jsx8("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-semibold", children: c }, c)) }) }),
|
|
387
|
+
/* @__PURE__ */ jsx8("tbody", { children: entry.rows.map((row, i) => /* @__PURE__ */ jsx8("tr", { children: row.map((cell, j) => /* @__PURE__ */ jsx8("td", { className: "border-b border-border px-3 py-2 text-foreground", children: cell }, j)) }, i)) })
|
|
363
388
|
] }) })
|
|
364
389
|
] });
|
|
365
390
|
}
|
|
366
391
|
|
|
367
392
|
// src/components/doc/DocLink.tsx
|
|
368
|
-
import { jsx as
|
|
393
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
369
394
|
function DocLink({ entry }) {
|
|
370
|
-
return /* @__PURE__ */
|
|
395
|
+
return /* @__PURE__ */ jsx9(
|
|
371
396
|
"a",
|
|
372
397
|
{
|
|
373
398
|
className: "text-sm font-medium text-primary underline underline-offset-2 hover:no-underline",
|
|
@@ -401,16 +426,16 @@ function neutralizeUrl(value) {
|
|
|
401
426
|
}
|
|
402
427
|
|
|
403
428
|
// src/components/doc/DocSection.tsx
|
|
404
|
-
import { Fragment as Fragment2, jsx as
|
|
429
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
405
430
|
function DocSection({ entry }) {
|
|
406
431
|
const renderers = useBuiltinRenderers();
|
|
407
432
|
if (renderers.section) {
|
|
408
|
-
return /* @__PURE__ */
|
|
433
|
+
return /* @__PURE__ */ jsx10(Fragment2, { children: renderers.section(entry) });
|
|
409
434
|
}
|
|
410
435
|
const html = safeMarkdownHtml(entry.markdown);
|
|
411
436
|
return /* @__PURE__ */ jsxs5("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
|
|
412
|
-
entry.title ? /* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
437
|
+
entry.title ? /* @__PURE__ */ jsx10("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
|
|
438
|
+
/* @__PURE__ */ jsx10(
|
|
414
439
|
"div",
|
|
415
440
|
{
|
|
416
441
|
className: "es-doc-prose prose prose-sm max-w-none",
|
|
@@ -421,11 +446,11 @@ function DocSection({ entry }) {
|
|
|
421
446
|
}
|
|
422
447
|
|
|
423
448
|
// src/components/doc/DocMermaid.tsx
|
|
424
|
-
import { Fragment as Fragment3, jsx as
|
|
449
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
425
450
|
function MermaidSource({ entry, ref }) {
|
|
426
451
|
return /* @__PURE__ */ jsxs6("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
|
|
427
|
-
entry.title ? /* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
452
|
+
entry.title ? /* @__PURE__ */ jsx11("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
453
|
+
/* @__PURE__ */ jsx11(
|
|
429
454
|
"pre",
|
|
430
455
|
{
|
|
431
456
|
"data-mermaid": true,
|
|
@@ -439,24 +464,24 @@ function MermaidSource({ entry, ref }) {
|
|
|
439
464
|
function DocMermaid({ entry }) {
|
|
440
465
|
const renderers = useBuiltinRenderers();
|
|
441
466
|
if (renderers.mermaid) {
|
|
442
|
-
return /* @__PURE__ */
|
|
467
|
+
return /* @__PURE__ */ jsx11(Fragment3, { children: renderers.mermaid(entry) });
|
|
443
468
|
}
|
|
444
|
-
return /* @__PURE__ */
|
|
469
|
+
return /* @__PURE__ */ jsx11(MermaidSource, { entry });
|
|
445
470
|
}
|
|
446
471
|
|
|
447
472
|
// src/components/doc/DocScreenshot.tsx
|
|
448
|
-
import { jsx as
|
|
473
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
449
474
|
function DocScreenshot({ entry }) {
|
|
450
475
|
const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
|
|
451
476
|
if (!src) {
|
|
452
477
|
return /* @__PURE__ */ jsxs7("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
/* @__PURE__ */
|
|
455
|
-
entry.alt ? /* @__PURE__ */
|
|
478
|
+
/* @__PURE__ */ jsx12("div", { className: "font-medium", children: "Screenshot unavailable" }),
|
|
479
|
+
/* @__PURE__ */ jsx12("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
480
|
+
entry.alt ? /* @__PURE__ */ jsx12("figcaption", { className: "mt-1.5 text-xs", children: entry.alt }) : null
|
|
456
481
|
] });
|
|
457
482
|
}
|
|
458
483
|
return /* @__PURE__ */ jsxs7("figure", { className: "my-3", children: [
|
|
459
|
-
/* @__PURE__ */
|
|
484
|
+
/* @__PURE__ */ jsx12(
|
|
460
485
|
"img",
|
|
461
486
|
{
|
|
462
487
|
src,
|
|
@@ -465,24 +490,24 @@ function DocScreenshot({ entry }) {
|
|
|
465
490
|
className: "max-w-full rounded-md border border-border"
|
|
466
491
|
}
|
|
467
492
|
),
|
|
468
|
-
entry.alt ? /* @__PURE__ */
|
|
493
|
+
entry.alt ? /* @__PURE__ */ jsx12("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
|
|
469
494
|
] });
|
|
470
495
|
}
|
|
471
496
|
|
|
472
497
|
// src/components/doc/DocVideo.tsx
|
|
473
|
-
import { jsx as
|
|
498
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
474
499
|
function DocVideo({ entry }) {
|
|
475
500
|
if (isLocalFsPath(entry.path)) {
|
|
476
501
|
return /* @__PURE__ */ jsxs8("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
477
|
-
/* @__PURE__ */
|
|
478
|
-
/* @__PURE__ */
|
|
479
|
-
entry.caption ? /* @__PURE__ */
|
|
502
|
+
/* @__PURE__ */ jsx13("div", { className: "font-medium", children: "Video unavailable" }),
|
|
503
|
+
/* @__PURE__ */ jsx13("div", { className: "mt-1 break-all font-mono text-xs", children: entry.path }),
|
|
504
|
+
entry.caption ? /* @__PURE__ */ jsx13("figcaption", { className: "mt-1.5 text-xs", children: entry.caption }) : null
|
|
480
505
|
] });
|
|
481
506
|
}
|
|
482
507
|
const src = safeUrl(entry.path);
|
|
483
508
|
const poster = safeUrl(entry.poster);
|
|
484
509
|
return /* @__PURE__ */ jsxs8("figure", { className: "my-3", children: [
|
|
485
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ jsx13(
|
|
486
511
|
"video",
|
|
487
512
|
{
|
|
488
513
|
controls: true,
|
|
@@ -492,12 +517,12 @@ function DocVideo({ entry }) {
|
|
|
492
517
|
className: "max-w-full rounded-md border border-border"
|
|
493
518
|
}
|
|
494
519
|
),
|
|
495
|
-
entry.caption ? /* @__PURE__ */
|
|
520
|
+
entry.caption ? /* @__PURE__ */ jsx13("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
|
|
496
521
|
] });
|
|
497
522
|
}
|
|
498
523
|
|
|
499
524
|
// src/components/doc/DocHtml.tsx
|
|
500
|
-
import { jsx as
|
|
525
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
501
526
|
function DocHtml({ entry }) {
|
|
502
527
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
503
528
|
const title = entry.title ?? "Embedded HTML";
|
|
@@ -505,8 +530,8 @@ function DocHtml({ entry }) {
|
|
|
505
530
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
506
531
|
return /* @__PURE__ */ jsxs9("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
507
532
|
/* @__PURE__ */ jsxs9("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: [
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
safeHref ? /* @__PURE__ */
|
|
533
|
+
/* @__PURE__ */ jsx14("span", { children: entry.title ?? "HTML" }),
|
|
534
|
+
safeHref ? /* @__PURE__ */ jsx14(
|
|
510
535
|
"a",
|
|
511
536
|
{
|
|
512
537
|
href: safeHref,
|
|
@@ -519,7 +544,7 @@ function DocHtml({ entry }) {
|
|
|
519
544
|
}
|
|
520
545
|
) : null
|
|
521
546
|
] }),
|
|
522
|
-
/* @__PURE__ */
|
|
547
|
+
/* @__PURE__ */ jsx14(
|
|
523
548
|
"iframe",
|
|
524
549
|
{
|
|
525
550
|
...frameProps,
|
|
@@ -534,7 +559,7 @@ function DocHtml({ entry }) {
|
|
|
534
559
|
}
|
|
535
560
|
|
|
536
561
|
// src/components/doc/DocState.tsx
|
|
537
|
-
import { jsx as
|
|
562
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
538
563
|
function DocState({ entry }) {
|
|
539
564
|
let json;
|
|
540
565
|
try {
|
|
@@ -542,20 +567,20 @@ function DocState({ entry }) {
|
|
|
542
567
|
} catch {
|
|
543
568
|
json = String(entry.value);
|
|
544
569
|
}
|
|
545
|
-
return /* @__PURE__ */
|
|
570
|
+
return /* @__PURE__ */ jsx15(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx15("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
546
571
|
}
|
|
547
572
|
|
|
548
573
|
// src/components/doc/DocCustom.tsx
|
|
549
|
-
import { Fragment as Fragment4, jsx as
|
|
574
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
550
575
|
function DocCustom({ entry }) {
|
|
551
576
|
const renderers = useCustomRenderers();
|
|
552
577
|
const renderer = renderers[entry.type];
|
|
553
578
|
if (renderer) {
|
|
554
|
-
return /* @__PURE__ */
|
|
579
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: renderer(entry) });
|
|
555
580
|
}
|
|
556
581
|
return /* @__PURE__ */ jsxs10("div", { className: "my-2", "data-type": entry.type, children: [
|
|
557
|
-
/* @__PURE__ */
|
|
558
|
-
/* @__PURE__ */
|
|
582
|
+
/* @__PURE__ */ jsx16("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: entry.type }),
|
|
583
|
+
/* @__PURE__ */ jsx16("pre", { tabIndex: 0, className: "overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs text-foreground", children: safeStringify2(entry.data) })
|
|
559
584
|
] });
|
|
560
585
|
}
|
|
561
586
|
function safeStringify2(value) {
|
|
@@ -567,64 +592,43 @@ function safeStringify2(value) {
|
|
|
567
592
|
}
|
|
568
593
|
|
|
569
594
|
// src/components/doc/DocEntry.tsx
|
|
570
|
-
import { jsx as
|
|
595
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
571
596
|
function DocEntry({ entry }) {
|
|
572
597
|
switch (entry.kind) {
|
|
573
598
|
case "note":
|
|
574
|
-
return /* @__PURE__ */
|
|
599
|
+
return /* @__PURE__ */ jsx17(DocNote, { entry });
|
|
575
600
|
case "tag":
|
|
576
|
-
return /* @__PURE__ */
|
|
601
|
+
return /* @__PURE__ */ jsx17(DocTag, { entry });
|
|
577
602
|
case "kv":
|
|
578
|
-
return /* @__PURE__ */
|
|
603
|
+
return /* @__PURE__ */ jsx17(DocKv, { entry });
|
|
579
604
|
case "code":
|
|
580
|
-
return /* @__PURE__ */
|
|
605
|
+
return /* @__PURE__ */ jsx17(DocCode, { entry });
|
|
581
606
|
case "table":
|
|
582
|
-
return /* @__PURE__ */
|
|
607
|
+
return /* @__PURE__ */ jsx17(DocTable, { entry });
|
|
583
608
|
case "link":
|
|
584
|
-
return /* @__PURE__ */
|
|
609
|
+
return /* @__PURE__ */ jsx17(DocLink, { entry });
|
|
585
610
|
case "section":
|
|
586
|
-
return /* @__PURE__ */
|
|
611
|
+
return /* @__PURE__ */ jsx17(DocSection, { entry });
|
|
587
612
|
case "mermaid":
|
|
588
|
-
return /* @__PURE__ */
|
|
613
|
+
return /* @__PURE__ */ jsx17(DocMermaid, { entry });
|
|
589
614
|
case "screenshot":
|
|
590
|
-
return /* @__PURE__ */
|
|
615
|
+
return /* @__PURE__ */ jsx17(DocScreenshot, { entry });
|
|
591
616
|
case "video":
|
|
592
|
-
return /* @__PURE__ */
|
|
617
|
+
return /* @__PURE__ */ jsx17(DocVideo, { entry });
|
|
593
618
|
case "html":
|
|
594
|
-
return /* @__PURE__ */
|
|
619
|
+
return /* @__PURE__ */ jsx17(DocHtml, { entry });
|
|
595
620
|
case "state":
|
|
596
|
-
return /* @__PURE__ */
|
|
621
|
+
return /* @__PURE__ */ jsx17(DocState, { entry });
|
|
597
622
|
case "custom":
|
|
598
|
-
return /* @__PURE__ */
|
|
623
|
+
return /* @__PURE__ */ jsx17(DocCustom, { entry });
|
|
599
624
|
}
|
|
600
625
|
}
|
|
601
626
|
|
|
602
627
|
// src/components/ReportDocEntries.tsx
|
|
603
|
-
import { Fragment as Fragment5, jsx as
|
|
628
|
+
import { Fragment as Fragment5, jsx as jsx18 } from "react/jsx-runtime";
|
|
604
629
|
function ReportDocEntries({ entries }) {
|
|
605
630
|
if (entries.length === 0) return null;
|
|
606
|
-
return /* @__PURE__ */
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
// src/lib/step-params.tsx
|
|
610
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
611
|
-
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
612
|
-
function highlightStepParams(text) {
|
|
613
|
-
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
614
|
-
if (matches.length === 0) return text;
|
|
615
|
-
const nodes = [];
|
|
616
|
-
let lastIndex = 0;
|
|
617
|
-
matches.forEach((match, i) => {
|
|
618
|
-
const start = match.index;
|
|
619
|
-
const end = start + match[0].length;
|
|
620
|
-
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
621
|
-
nodes.push(
|
|
622
|
-
/* @__PURE__ */ jsx18("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
623
|
-
);
|
|
624
|
-
lastIndex = end;
|
|
625
|
-
});
|
|
626
|
-
if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
|
|
627
|
-
return nodes;
|
|
631
|
+
return /* @__PURE__ */ jsx18(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx18(DocEntry, { entry }, i)) });
|
|
628
632
|
}
|
|
629
633
|
|
|
630
634
|
// src/components/ReportSteps.tsx
|
|
@@ -643,9 +647,22 @@ var STEP_GLYPH_COLOR = {
|
|
|
643
647
|
};
|
|
644
648
|
function ReportSteps({ scenario }) {
|
|
645
649
|
if (scenario.steps.length === 0) return null;
|
|
646
|
-
|
|
650
|
+
const unasserted = new Set(
|
|
651
|
+
assertionState(scenario.steps) === "unasserted" ? assertiveSteps(scenario.steps).map((step) => step.id) : []
|
|
652
|
+
);
|
|
653
|
+
return /* @__PURE__ */ jsx19("ol", { "data-slot": "steps", className: "flex flex-col", children: scenario.steps.map((step) => /* @__PURE__ */ jsx19(
|
|
654
|
+
ReportStepItem,
|
|
655
|
+
{
|
|
656
|
+
step,
|
|
657
|
+
unasserted: unasserted.has(step.id)
|
|
658
|
+
},
|
|
659
|
+
step.id
|
|
660
|
+
)) });
|
|
647
661
|
}
|
|
648
|
-
function ReportStepItem({
|
|
662
|
+
function ReportStepItem({
|
|
663
|
+
step,
|
|
664
|
+
unasserted = false
|
|
665
|
+
}) {
|
|
649
666
|
const kw = step.keyword.toLowerCase();
|
|
650
667
|
const continuation = kw === "and" || kw === "but";
|
|
651
668
|
return /* @__PURE__ */ jsxs11(
|
|
@@ -653,10 +670,23 @@ function ReportStepItem({ step }) {
|
|
|
653
670
|
{
|
|
654
671
|
id: step.id,
|
|
655
672
|
"data-status": step.status,
|
|
656
|
-
className: cn(
|
|
673
|
+
className: cn(
|
|
674
|
+
"py-1.5 text-[0.8125rem] leading-normal",
|
|
675
|
+
continuation && "pl-5"
|
|
676
|
+
),
|
|
657
677
|
children: [
|
|
658
678
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-baseline gap-2", children: [
|
|
659
|
-
/* @__PURE__ */ jsx19(
|
|
679
|
+
/* @__PURE__ */ jsx19(
|
|
680
|
+
"span",
|
|
681
|
+
{
|
|
682
|
+
"aria-hidden": true,
|
|
683
|
+
className: cn(
|
|
684
|
+
"w-4 shrink-0 text-center text-xs",
|
|
685
|
+
STEP_GLYPH_COLOR[step.status]
|
|
686
|
+
),
|
|
687
|
+
children: STEP_GLYPH[step.status] ?? "\u25CB"
|
|
688
|
+
}
|
|
689
|
+
),
|
|
660
690
|
/* @__PURE__ */ jsx19(
|
|
661
691
|
"span",
|
|
662
692
|
{
|
|
@@ -668,6 +698,7 @@ function ReportStepItem({ step }) {
|
|
|
668
698
|
}
|
|
669
699
|
),
|
|
670
700
|
/* @__PURE__ */ jsx19("span", { className: "flex-1 text-foreground", children: highlightStepParams(step.text) }),
|
|
701
|
+
unasserted ? /* @__PURE__ */ jsx19("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,
|
|
671
702
|
step.durationMs > 0 ? /* @__PURE__ */ jsx19("span", { className: "shrink-0 whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(step.durationMs) }) : null
|
|
672
703
|
] }),
|
|
673
704
|
step.errorMessage ? /* @__PURE__ */ jsx19(
|
|
@@ -1063,21 +1094,104 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1063
1094
|
] });
|
|
1064
1095
|
}
|
|
1065
1096
|
|
|
1097
|
+
// src/components/ScenarioStaleness.tsx
|
|
1098
|
+
import { useEffect, useState } from "react";
|
|
1099
|
+
|
|
1100
|
+
// src/lib/provenance.ts
|
|
1101
|
+
function reportLastRunMs(report) {
|
|
1102
|
+
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
1103
|
+
if (report.startedAtMs && report.startedAtMs > 0) return report.startedAtMs;
|
|
1104
|
+
return void 0;
|
|
1105
|
+
}
|
|
1106
|
+
function scenarioLastRunMs(scenario, report) {
|
|
1107
|
+
if (scenario.lastRunAtMs && scenario.lastRunAtMs > 0) return scenario.lastRunAtMs;
|
|
1108
|
+
return reportLastRunMs(report);
|
|
1109
|
+
}
|
|
1110
|
+
function formatRelativeAge(thenMs, nowMs) {
|
|
1111
|
+
const deltaMs = Math.max(0, nowMs - thenMs);
|
|
1112
|
+
const minutes = Math.floor(deltaMs / 6e4);
|
|
1113
|
+
if (minutes < 1) return "just now";
|
|
1114
|
+
if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
1115
|
+
const hours = Math.floor(minutes / 60);
|
|
1116
|
+
if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
1117
|
+
const days = Math.floor(hours / 24);
|
|
1118
|
+
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
1119
|
+
}
|
|
1120
|
+
function isReportStale(lastRunMs, staleAfterDays, nowMs) {
|
|
1121
|
+
if (lastRunMs === void 0 || staleAfterDays <= 0) return false;
|
|
1122
|
+
return nowMs - lastRunMs >= staleAfterDays * 864e5;
|
|
1123
|
+
}
|
|
1124
|
+
var CI_DISPLAY_NAMES = {
|
|
1125
|
+
github: "GitHub Actions",
|
|
1126
|
+
gitlab: "GitLab CI",
|
|
1127
|
+
circleci: "CircleCI",
|
|
1128
|
+
jenkins: "Jenkins",
|
|
1129
|
+
azure: "Azure DevOps",
|
|
1130
|
+
buildkite: "Buildkite",
|
|
1131
|
+
travis: "Travis CI",
|
|
1132
|
+
ci: "CI"
|
|
1133
|
+
};
|
|
1134
|
+
function ciDisplayName(name) {
|
|
1135
|
+
return CI_DISPLAY_NAMES[name] ?? name;
|
|
1136
|
+
}
|
|
1137
|
+
function commitUrl(ci, sha) {
|
|
1138
|
+
const commitSha = ci?.commitSha ?? sha;
|
|
1139
|
+
if (!ci?.url || !commitSha) return void 0;
|
|
1140
|
+
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1141
|
+
if (github) return `${github[1]}/commit/${commitSha}`;
|
|
1142
|
+
const gitlab = ci.url.match(/^(https?:\/\/.+)\/-\/pipelines\//);
|
|
1143
|
+
if (gitlab) return `${gitlab[1]}/-/commit/${commitSha}`;
|
|
1144
|
+
return void 0;
|
|
1145
|
+
}
|
|
1146
|
+
function prUrl(ci) {
|
|
1147
|
+
if (!ci?.url || !ci.prNumber) return void 0;
|
|
1148
|
+
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1149
|
+
if (github) return `${github[1]}/pull/${ci.prNumber}`;
|
|
1150
|
+
return void 0;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// src/interactive/scenario-freshness-context.tsx
|
|
1154
|
+
import { createContext as createContext3, useContext as useContext4 } from "react";
|
|
1155
|
+
var ScenarioFreshnessContext = createContext3(null);
|
|
1156
|
+
var ScenarioFreshnessProvider = ScenarioFreshnessContext.Provider;
|
|
1157
|
+
function useScenarioFreshness() {
|
|
1158
|
+
return useContext4(ScenarioFreshnessContext);
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
// src/components/ScenarioStaleness.tsx
|
|
1162
|
+
import { jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1163
|
+
function ScenarioStaleness({ scenario }) {
|
|
1164
|
+
const freshness = useScenarioFreshness();
|
|
1165
|
+
const fixedNow = freshness?.nowMs;
|
|
1166
|
+
const [now, setNow] = useState(fixedNow);
|
|
1167
|
+
useEffect(() => {
|
|
1168
|
+
if (fixedNow === void 0) setNow(Date.now());
|
|
1169
|
+
}, [fixedNow]);
|
|
1170
|
+
if (!freshness || now === void 0) return null;
|
|
1171
|
+
const lastRunAtMs = scenario.lastRunAtMs;
|
|
1172
|
+
if (!lastRunAtMs || lastRunAtMs <= 0) return null;
|
|
1173
|
+
if (!isReportStale(lastRunAtMs, freshness.staleAfterDays, now)) return null;
|
|
1174
|
+
return /* @__PURE__ */ jsxs16(Badge, { variant: "outline", "aria-label": "Scenario freshness", children: [
|
|
1175
|
+
"Last ran ",
|
|
1176
|
+
formatRelativeAge(lastRunAtMs, now)
|
|
1177
|
+
] });
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1066
1180
|
// src/interactive/collapse-context.ts
|
|
1067
|
-
import { createContext as
|
|
1068
|
-
var CollapseContext =
|
|
1181
|
+
import { createContext as createContext4, useCallback, useContext as useContext5, useState as useState2 } from "react";
|
|
1182
|
+
var CollapseContext = createContext4(null);
|
|
1069
1183
|
var CollapseProvider = CollapseContext.Provider;
|
|
1070
1184
|
function useCollapse() {
|
|
1071
|
-
return
|
|
1185
|
+
return useContext5(CollapseContext);
|
|
1072
1186
|
}
|
|
1073
1187
|
|
|
1074
1188
|
// src/interactive/scenario-actions.tsx
|
|
1075
|
-
import { createContext as
|
|
1189
|
+
import { createContext as createContext5, useContext as useContext6 } from "react";
|
|
1076
1190
|
import { scenarioToMarkdown as coreScenarioToMarkdown } from "executable-stories-core/utils/scenario-markdown";
|
|
1077
|
-
var ScenarioActionsContext =
|
|
1191
|
+
var ScenarioActionsContext = createContext5(null);
|
|
1078
1192
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1079
1193
|
function useScenarioActions() {
|
|
1080
|
-
return
|
|
1194
|
+
return useContext6(ScenarioActionsContext);
|
|
1081
1195
|
}
|
|
1082
1196
|
|
|
1083
1197
|
// src/components/ui/card.tsx
|
|
@@ -1124,7 +1238,7 @@ function CardContent({ className, ...props }) {
|
|
|
1124
1238
|
import "react";
|
|
1125
1239
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
1126
1240
|
import { CheckIcon } from "lucide-react";
|
|
1127
|
-
import { jsx as jsx25, jsxs as
|
|
1241
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1128
1242
|
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";
|
|
1129
1243
|
function DropdownMenu(props) {
|
|
1130
1244
|
return /* @__PURE__ */ jsx25(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
@@ -1175,7 +1289,7 @@ function DropdownMenuItem({
|
|
|
1175
1289
|
|
|
1176
1290
|
// src/components/ReportScenario.tsx
|
|
1177
1291
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
1178
|
-
import { jsx as jsx26, jsxs as
|
|
1292
|
+
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1179
1293
|
var STATUS_META = {
|
|
1180
1294
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
1181
1295
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1191,7 +1305,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1191
1305
|
const collapsible = collapse !== null && !hideTitle;
|
|
1192
1306
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
1193
1307
|
const actions = useScenarioActions();
|
|
1194
|
-
return /* @__PURE__ */
|
|
1308
|
+
return /* @__PURE__ */ jsxs18(
|
|
1195
1309
|
Card,
|
|
1196
1310
|
{
|
|
1197
1311
|
id: scenario.id,
|
|
@@ -1199,9 +1313,9 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1199
1313
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
1200
1314
|
className: "gap-0 py-0",
|
|
1201
1315
|
children: [
|
|
1202
|
-
/* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */
|
|
1204
|
-
hideTitle ? null : /* @__PURE__ */
|
|
1316
|
+
/* @__PURE__ */ jsxs18(CardHeader, { className: "px-4 py-3", children: [
|
|
1317
|
+
/* @__PURE__ */ jsxs18("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
1318
|
+
hideTitle ? null : /* @__PURE__ */ jsxs18("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1205
1319
|
collapsible ? /* @__PURE__ */ jsx26(
|
|
1206
1320
|
"button",
|
|
1207
1321
|
{
|
|
@@ -1217,11 +1331,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1217
1331
|
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1218
1332
|
/* @__PURE__ */ jsx26("span", { children: scenario.title })
|
|
1219
1333
|
] }),
|
|
1220
|
-
/* @__PURE__ */
|
|
1334
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1221
1335
|
/* @__PURE__ */ jsx26(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1336
|
+
/* @__PURE__ */ jsx26(ScenarioStaleness, { scenario }),
|
|
1222
1337
|
scenario.durationMs > 0 ? /* @__PURE__ */ jsx26("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration3(scenario.durationMs) }) : null,
|
|
1223
1338
|
meta.showPill ? /* @__PURE__ */ jsx26(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx26("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1224
|
-
actions ? /* @__PURE__ */
|
|
1339
|
+
actions ? /* @__PURE__ */ jsxs18(DropdownMenu, { children: [
|
|
1225
1340
|
/* @__PURE__ */ jsx26(
|
|
1226
1341
|
DropdownMenuTrigger,
|
|
1227
1342
|
{
|
|
@@ -1230,16 +1345,16 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1230
1345
|
children: /* @__PURE__ */ jsx26(MoreHorizontalIcon, { "aria-hidden": true })
|
|
1231
1346
|
}
|
|
1232
1347
|
),
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1348
|
+
/* @__PURE__ */ jsxs18(DropdownMenuContent, { align: "end", children: [
|
|
1349
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1235
1350
|
/* @__PURE__ */ jsx26(LinkIcon, {}),
|
|
1236
1351
|
" Copy link"
|
|
1237
1352
|
] }),
|
|
1238
|
-
/* @__PURE__ */
|
|
1353
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1239
1354
|
/* @__PURE__ */ jsx26(FileTextIcon, {}),
|
|
1240
1355
|
" Copy as Markdown"
|
|
1241
1356
|
] }),
|
|
1242
|
-
/* @__PURE__ */
|
|
1357
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1243
1358
|
/* @__PURE__ */ jsx26(SparklesIcon, {}),
|
|
1244
1359
|
" Explain with AI"
|
|
1245
1360
|
] })
|
|
@@ -1247,12 +1362,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1247
1362
|
] }) : null
|
|
1248
1363
|
] })
|
|
1249
1364
|
] }),
|
|
1250
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
1365
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs18("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
1251
1366
|
scenario.tags.map((t) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1252
1367
|
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx26("li", { children: ticket.url ? /* @__PURE__ */ jsx26("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx26(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx26(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
1253
1368
|
] }) : null
|
|
1254
1369
|
] }),
|
|
1255
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsxs18(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1256
1371
|
scenario.errorMessage ? /* @__PURE__ */ jsx26(
|
|
1257
1372
|
"pre",
|
|
1258
1373
|
{
|
|
@@ -1279,12 +1394,12 @@ function ReportScenarioList({ feature }) {
|
|
|
1279
1394
|
}
|
|
1280
1395
|
|
|
1281
1396
|
// src/components/ReportFeatureIntro.tsx
|
|
1282
|
-
import { jsx as jsx28, jsxs as
|
|
1397
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1283
1398
|
function ReportFeatureIntro({ feature }) {
|
|
1284
1399
|
const hasNarrative = Boolean(feature.narrative?.trim());
|
|
1285
1400
|
const hasGlossary = Boolean(feature.glossary?.length);
|
|
1286
1401
|
if (!hasNarrative && !hasGlossary) return null;
|
|
1287
|
-
return /* @__PURE__ */
|
|
1402
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
|
|
1288
1403
|
hasNarrative ? /* @__PURE__ */ jsx28(
|
|
1289
1404
|
"div",
|
|
1290
1405
|
{
|
|
@@ -1292,7 +1407,7 @@ function ReportFeatureIntro({ feature }) {
|
|
|
1292
1407
|
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1293
1408
|
}
|
|
1294
1409
|
) : null,
|
|
1295
|
-
hasGlossary ? /* @__PURE__ */ jsx28("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */
|
|
1410
|
+
hasGlossary ? /* @__PURE__ */ jsx28("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ jsxs19("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
|
|
1296
1411
|
/* @__PURE__ */ jsx28("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1297
1412
|
/* @__PURE__ */ jsx28("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
|
|
1298
1413
|
] }, entry.term)) }) : null
|
|
@@ -1306,7 +1421,7 @@ function featureKindLabel(kind) {
|
|
|
1306
1421
|
}
|
|
1307
1422
|
|
|
1308
1423
|
// src/components/ReportFeature.tsx
|
|
1309
|
-
import { Fragment as Fragment9, jsx as jsx29, jsxs as
|
|
1424
|
+
import { Fragment as Fragment9, jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1310
1425
|
function ReportFeature({ feature }) {
|
|
1311
1426
|
const titleId = `${feature.id}-title`;
|
|
1312
1427
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1318,7 +1433,7 @@ function ReportFeature({ feature }) {
|
|
|
1318
1433
|
return (
|
|
1319
1434
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1320
1435
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1321
|
-
/* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsxs20(
|
|
1322
1437
|
"section",
|
|
1323
1438
|
{
|
|
1324
1439
|
id: feature.id,
|
|
@@ -1326,9 +1441,9 @@ function ReportFeature({ feature }) {
|
|
|
1326
1441
|
"aria-labelledby": titleId,
|
|
1327
1442
|
className: "flex flex-col gap-3",
|
|
1328
1443
|
children: [
|
|
1329
|
-
/* @__PURE__ */
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */ jsx29("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */
|
|
1444
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1445
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
1446
|
+
/* @__PURE__ */ jsx29("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs20(
|
|
1332
1447
|
"button",
|
|
1333
1448
|
{
|
|
1334
1449
|
type: "button",
|
|
@@ -1342,29 +1457,29 @@ function ReportFeature({ feature }) {
|
|
|
1342
1457
|
]
|
|
1343
1458
|
}
|
|
1344
1459
|
) : feature.title }),
|
|
1345
|
-
/* @__PURE__ */
|
|
1460
|
+
/* @__PURE__ */ jsxs20("p", { className: cn("mt-0.5 flex items-center gap-2 text-xs text-muted-foreground", collapse && "pl-5"), children: [
|
|
1346
1461
|
kindLabel ? /* @__PURE__ */ jsx29("span", { className: "shrink-0 rounded-sm bg-muted px-1.5 py-0.5 font-medium text-foreground", children: kindLabel }) : null,
|
|
1347
1462
|
/* @__PURE__ */ jsx29("span", { className: "truncate font-mono", children: feature.sourceFile })
|
|
1348
1463
|
] })
|
|
1349
1464
|
] }),
|
|
1350
|
-
/* @__PURE__ */
|
|
1465
|
+
/* @__PURE__ */ jsxs20(
|
|
1351
1466
|
"p",
|
|
1352
1467
|
{
|
|
1353
1468
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1354
1469
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1355
1470
|
children: [
|
|
1356
|
-
/* @__PURE__ */
|
|
1471
|
+
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1357
1472
|
s.passed,
|
|
1358
1473
|
" passed"
|
|
1359
1474
|
] }),
|
|
1360
1475
|
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1361
|
-
/* @__PURE__ */
|
|
1476
|
+
/* @__PURE__ */ jsxs20("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1362
1477
|
s.failed,
|
|
1363
1478
|
" failed"
|
|
1364
1479
|
] }),
|
|
1365
|
-
skipped > 0 ? /* @__PURE__ */
|
|
1480
|
+
skipped > 0 ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
1366
1481
|
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1367
|
-
/* @__PURE__ */
|
|
1482
|
+
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1368
1483
|
skipped,
|
|
1369
1484
|
" skipped"
|
|
1370
1485
|
] })
|
|
@@ -1373,7 +1488,7 @@ function ReportFeature({ feature }) {
|
|
|
1373
1488
|
}
|
|
1374
1489
|
)
|
|
1375
1490
|
] }),
|
|
1376
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsxs20("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
|
|
1377
1492
|
/* @__PURE__ */ jsx29(ReportFeatureIntro, { feature }),
|
|
1378
1493
|
/* @__PURE__ */ jsx29(ReportScenarioList, { feature })
|
|
1379
1494
|
] })
|
|
@@ -1451,7 +1566,7 @@ function ReportEmpty({ message }) {
|
|
|
1451
1566
|
}
|
|
1452
1567
|
|
|
1453
1568
|
// src/components/ReportSummary.tsx
|
|
1454
|
-
import { jsx as jsx33, jsxs as
|
|
1569
|
+
import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1455
1570
|
function ReportSummary({ className }) {
|
|
1456
1571
|
const report = useReport();
|
|
1457
1572
|
return /* @__PURE__ */ jsx33(
|
|
@@ -1493,13 +1608,13 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1493
1608
|
"aria-label": ariaLabel,
|
|
1494
1609
|
children: cards.map((c) => {
|
|
1495
1610
|
const tone = TONE[c.status];
|
|
1496
|
-
return /* @__PURE__ */
|
|
1611
|
+
return /* @__PURE__ */ jsxs21(
|
|
1497
1612
|
"div",
|
|
1498
1613
|
{
|
|
1499
1614
|
"data-status": c.status,
|
|
1500
1615
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1501
1616
|
children: [
|
|
1502
|
-
/* @__PURE__ */
|
|
1617
|
+
/* @__PURE__ */ jsxs21("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1503
1618
|
/* @__PURE__ */ jsx33("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1504
1619
|
c.label
|
|
1505
1620
|
] }),
|
|
@@ -1515,58 +1630,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1515
1630
|
|
|
1516
1631
|
// src/components/ReportMeta.tsx
|
|
1517
1632
|
import { formatDuration as formatDuration4 } from "executable-stories-core/utils/duration";
|
|
1518
|
-
|
|
1519
|
-
// src/lib/provenance.ts
|
|
1520
|
-
function reportLastRunMs(report) {
|
|
1521
|
-
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
1522
|
-
if (report.startedAtMs && report.startedAtMs > 0) return report.startedAtMs;
|
|
1523
|
-
return void 0;
|
|
1524
|
-
}
|
|
1525
|
-
function formatRelativeAge(thenMs, nowMs) {
|
|
1526
|
-
const deltaMs = Math.max(0, nowMs - thenMs);
|
|
1527
|
-
const minutes = Math.floor(deltaMs / 6e4);
|
|
1528
|
-
if (minutes < 1) return "just now";
|
|
1529
|
-
if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
1530
|
-
const hours = Math.floor(minutes / 60);
|
|
1531
|
-
if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
1532
|
-
const days = Math.floor(hours / 24);
|
|
1533
|
-
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
1534
|
-
}
|
|
1535
|
-
function isReportStale(lastRunMs, staleAfterDays, nowMs) {
|
|
1536
|
-
if (lastRunMs === void 0 || staleAfterDays <= 0) return false;
|
|
1537
|
-
return nowMs - lastRunMs >= staleAfterDays * 864e5;
|
|
1538
|
-
}
|
|
1539
|
-
var CI_DISPLAY_NAMES = {
|
|
1540
|
-
github: "GitHub Actions",
|
|
1541
|
-
gitlab: "GitLab CI",
|
|
1542
|
-
circleci: "CircleCI",
|
|
1543
|
-
jenkins: "Jenkins",
|
|
1544
|
-
azure: "Azure DevOps",
|
|
1545
|
-
buildkite: "Buildkite",
|
|
1546
|
-
travis: "Travis CI",
|
|
1547
|
-
ci: "CI"
|
|
1548
|
-
};
|
|
1549
|
-
function ciDisplayName(name) {
|
|
1550
|
-
return CI_DISPLAY_NAMES[name] ?? name;
|
|
1551
|
-
}
|
|
1552
|
-
function commitUrl(ci, sha) {
|
|
1553
|
-
const commitSha = ci?.commitSha ?? sha;
|
|
1554
|
-
if (!ci?.url || !commitSha) return void 0;
|
|
1555
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1556
|
-
if (github) return `${github[1]}/commit/${commitSha}`;
|
|
1557
|
-
const gitlab = ci.url.match(/^(https?:\/\/.+)\/-\/pipelines\//);
|
|
1558
|
-
if (gitlab) return `${gitlab[1]}/-/commit/${commitSha}`;
|
|
1559
|
-
return void 0;
|
|
1560
|
-
}
|
|
1561
|
-
function prUrl(ci) {
|
|
1562
|
-
if (!ci?.url || !ci.prNumber) return void 0;
|
|
1563
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1564
|
-
if (github) return `${github[1]}/pull/${ci.prNumber}`;
|
|
1565
|
-
return void 0;
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// src/components/ReportMeta.tsx
|
|
1569
|
-
import { jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1633
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1570
1634
|
function ReportMeta() {
|
|
1571
1635
|
const report = useReport();
|
|
1572
1636
|
const items = [];
|
|
@@ -1595,7 +1659,7 @@ function ReportMeta() {
|
|
|
1595
1659
|
if (report.ci) {
|
|
1596
1660
|
items.push({
|
|
1597
1661
|
label: "CI",
|
|
1598
|
-
value: report.ci.url ? /* @__PURE__ */
|
|
1662
|
+
value: report.ci.url ? /* @__PURE__ */ jsxs22("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1599
1663
|
ciDisplayName(report.ci.name),
|
|
1600
1664
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1601
1665
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1614,12 +1678,12 @@ function ReportMeta() {
|
|
|
1614
1678
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1615
1679
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1616
1680
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1681
|
+
/* @__PURE__ */ jsxs22("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1682
|
+
/* @__PURE__ */ jsxs22("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: [
|
|
1619
1683
|
/* @__PURE__ */ jsx34("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1620
1684
|
"Run details"
|
|
1621
1685
|
] }),
|
|
1622
|
-
/* @__PURE__ */ jsx34("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__ */
|
|
1686
|
+
/* @__PURE__ */ jsx34("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__ */ jsxs22("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1623
1687
|
/* @__PURE__ */ jsx34("dt", { className: "font-medium", children: item.label }),
|
|
1624
1688
|
/* @__PURE__ */ jsx34("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1625
1689
|
] }, item.label)) })
|
|
@@ -1628,18 +1692,18 @@ function ReportMeta() {
|
|
|
1628
1692
|
}
|
|
1629
1693
|
|
|
1630
1694
|
// src/components/ReportSchemaError.tsx
|
|
1631
|
-
import { jsx as jsx35, jsxs as
|
|
1695
|
+
import { jsx as jsx35, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1632
1696
|
function ReportSchemaError({ error }) {
|
|
1633
|
-
return /* @__PURE__ */
|
|
1697
|
+
return /* @__PURE__ */ jsxs23("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1634
1698
|
/* @__PURE__ */ jsx35("p", { children: /* @__PURE__ */ jsx35("strong", { children: "Report could not be displayed." }) }),
|
|
1635
1699
|
/* @__PURE__ */ jsx35("p", { children: error.message }),
|
|
1636
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */
|
|
1700
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs23("p", { children: [
|
|
1637
1701
|
"The report bundle is newer than this version of ",
|
|
1638
1702
|
/* @__PURE__ */ jsx35("code", { children: "executable-stories-react" }),
|
|
1639
1703
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1640
1704
|
] }) : null,
|
|
1641
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */
|
|
1642
|
-
/* @__PURE__ */
|
|
1705
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs23("details", { children: [
|
|
1706
|
+
/* @__PURE__ */ jsxs23("summary", { children: [
|
|
1643
1707
|
error.issues.length,
|
|
1644
1708
|
" validation issue",
|
|
1645
1709
|
error.issues.length === 1 ? "" : "s"
|
|
@@ -1650,9 +1714,9 @@ function ReportSchemaError({ error }) {
|
|
|
1650
1714
|
}
|
|
1651
1715
|
|
|
1652
1716
|
// src/components/ReportShell.tsx
|
|
1653
|
-
import { Fragment as Fragment10, jsx as jsx36, jsxs as
|
|
1717
|
+
import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1654
1718
|
function ReportTitleBlock({ title }) {
|
|
1655
|
-
return /* @__PURE__ */
|
|
1719
|
+
return /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
1656
1720
|
/* @__PURE__ */ jsx36("h1", { children: title ?? "Story Report" }),
|
|
1657
1721
|
/* @__PURE__ */ jsx36(ReportSummary, {}),
|
|
1658
1722
|
/* @__PURE__ */ jsx36(ReportMeta, {})
|
|
@@ -1668,7 +1732,7 @@ function ReportErrorShell({
|
|
|
1668
1732
|
}
|
|
1669
1733
|
|
|
1670
1734
|
// src/components/Report.tsx
|
|
1671
|
-
import { jsx as jsx37, jsxs as
|
|
1735
|
+
import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1672
1736
|
function Report(props) {
|
|
1673
1737
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1674
1738
|
const result = unwrapReport(report);
|
|
@@ -1677,15 +1741,15 @@ function Report(props) {
|
|
|
1677
1741
|
}
|
|
1678
1742
|
const data = result.data;
|
|
1679
1743
|
const hasContent = data.features.length > 0;
|
|
1680
|
-
return /* @__PURE__ */ jsx37(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */
|
|
1744
|
+
return /* @__PURE__ */ jsx37(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs25("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1681
1745
|
/* @__PURE__ */ jsx37("header", { className: "es-report-header", children: /* @__PURE__ */ jsx37(ReportTitleBlock, { title }) }),
|
|
1682
1746
|
hasContent ? /* @__PURE__ */ jsx37(ReportFeatureList, {}) : /* @__PURE__ */ jsx37(ReportEmpty, {})
|
|
1683
1747
|
] }) });
|
|
1684
1748
|
}
|
|
1685
1749
|
|
|
1686
1750
|
// src/components/doc/MermaidView.tsx
|
|
1687
|
-
import { useEffect, useRef, useState as
|
|
1688
|
-
import { Fragment as Fragment11, jsx as jsx38, jsxs as
|
|
1751
|
+
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
1752
|
+
import { Fragment as Fragment11, jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1689
1753
|
function prefersDark(el) {
|
|
1690
1754
|
const themed = el?.closest("[data-theme]");
|
|
1691
1755
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1694,9 +1758,9 @@ function prefersDark(el) {
|
|
|
1694
1758
|
}
|
|
1695
1759
|
function MermaidView({ entry, load }) {
|
|
1696
1760
|
const ref = useRef(null);
|
|
1697
|
-
const [svg, setSvg] =
|
|
1698
|
-
const [error, setError] =
|
|
1699
|
-
|
|
1761
|
+
const [svg, setSvg] = useState3(null);
|
|
1762
|
+
const [error, setError] = useState3(null);
|
|
1763
|
+
useEffect2(() => {
|
|
1700
1764
|
let cancelled = false;
|
|
1701
1765
|
const draw = async () => {
|
|
1702
1766
|
let mermaid;
|
|
@@ -1739,7 +1803,7 @@ function MermaidView({ entry, load }) {
|
|
|
1739
1803
|
};
|
|
1740
1804
|
}, [entry.code, load]);
|
|
1741
1805
|
if (svg) {
|
|
1742
|
-
return /* @__PURE__ */
|
|
1806
|
+
return /* @__PURE__ */ jsxs26("figure", { ref, className: "my-3", children: [
|
|
1743
1807
|
entry.title ? /* @__PURE__ */ jsx38("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1744
1808
|
/* @__PURE__ */ jsx38(
|
|
1745
1809
|
"div",
|
|
@@ -1752,8 +1816,8 @@ function MermaidView({ entry, load }) {
|
|
|
1752
1816
|
)
|
|
1753
1817
|
] });
|
|
1754
1818
|
}
|
|
1755
|
-
return /* @__PURE__ */
|
|
1756
|
-
error ? /* @__PURE__ */
|
|
1819
|
+
return /* @__PURE__ */ jsxs26(Fragment11, { children: [
|
|
1820
|
+
error ? /* @__PURE__ */ jsxs26(
|
|
1757
1821
|
"p",
|
|
1758
1822
|
{
|
|
1759
1823
|
role: "alert",
|
|
@@ -1781,13 +1845,13 @@ function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
|
1781
1845
|
}
|
|
1782
1846
|
|
|
1783
1847
|
// src/components/ScenarioExplorer.tsx
|
|
1784
|
-
import { useState as
|
|
1848
|
+
import { useState as useState4 } from "react";
|
|
1785
1849
|
|
|
1786
1850
|
// src/components/ui/command.tsx
|
|
1787
1851
|
import "react";
|
|
1788
1852
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1789
1853
|
import { SearchIcon } from "lucide-react";
|
|
1790
|
-
import { jsx as jsx40, jsxs as
|
|
1854
|
+
import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1791
1855
|
function Command({
|
|
1792
1856
|
className,
|
|
1793
1857
|
...props
|
|
@@ -1808,7 +1872,7 @@ function CommandInput({
|
|
|
1808
1872
|
className,
|
|
1809
1873
|
...props
|
|
1810
1874
|
}) {
|
|
1811
|
-
return /* @__PURE__ */
|
|
1875
|
+
return /* @__PURE__ */ jsxs27(
|
|
1812
1876
|
"div",
|
|
1813
1877
|
{
|
|
1814
1878
|
"data-slot": "command-input-wrapper",
|
|
@@ -1892,7 +1956,7 @@ function CommandItem({
|
|
|
1892
1956
|
}
|
|
1893
1957
|
|
|
1894
1958
|
// src/components/ScenarioExplorer.tsx
|
|
1895
|
-
import { jsx as jsx41, jsxs as
|
|
1959
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1896
1960
|
var STATUS_FILTERS = [
|
|
1897
1961
|
{ value: "all", label: "All" },
|
|
1898
1962
|
{ value: "passed", label: "Passed" },
|
|
@@ -1901,19 +1965,19 @@ var STATUS_FILTERS = [
|
|
|
1901
1965
|
{ value: "pending", label: "Pending" }
|
|
1902
1966
|
];
|
|
1903
1967
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1904
|
-
const [status, setStatus] =
|
|
1968
|
+
const [status, setStatus] = useState4("all");
|
|
1905
1969
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1906
|
-
return /* @__PURE__ */
|
|
1907
|
-
summary ? /* @__PURE__ */
|
|
1970
|
+
return /* @__PURE__ */ jsxs28("div", { className: "font-sans text-foreground", children: [
|
|
1971
|
+
summary ? /* @__PURE__ */ jsxs28("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1908
1972
|
summary.total,
|
|
1909
1973
|
" scenarios \xB7 ",
|
|
1910
|
-
/* @__PURE__ */
|
|
1974
|
+
/* @__PURE__ */ jsxs28("span", { className: "text-pass", children: [
|
|
1911
1975
|
summary.passed,
|
|
1912
1976
|
" passed"
|
|
1913
1977
|
] }),
|
|
1914
1978
|
" \xB7",
|
|
1915
1979
|
" ",
|
|
1916
|
-
/* @__PURE__ */
|
|
1980
|
+
/* @__PURE__ */ jsxs28("span", { className: "text-fail", children: [
|
|
1917
1981
|
summary.failed,
|
|
1918
1982
|
" failed"
|
|
1919
1983
|
] })
|
|
@@ -1933,14 +1997,14 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1933
1997
|
},
|
|
1934
1998
|
f.value
|
|
1935
1999
|
)) }),
|
|
1936
|
-
/* @__PURE__ */
|
|
2000
|
+
/* @__PURE__ */ jsxs28(
|
|
1937
2001
|
Command,
|
|
1938
2002
|
{
|
|
1939
2003
|
className: "rounded-lg border border-border bg-card",
|
|
1940
2004
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1941
2005
|
children: [
|
|
1942
2006
|
/* @__PURE__ */ jsx41(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
1943
|
-
/* @__PURE__ */
|
|
2007
|
+
/* @__PURE__ */ jsxs28(CommandList, { className: "max-h-none", children: [
|
|
1944
2008
|
/* @__PURE__ */ jsx41(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
1945
2009
|
/* @__PURE__ */ jsx41(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx41(
|
|
1946
2010
|
CommandItem,
|
|
@@ -1948,7 +2012,7 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1948
2012
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1949
2013
|
asChild: true,
|
|
1950
2014
|
className: "cursor-pointer",
|
|
1951
|
-
children: /* @__PURE__ */
|
|
2015
|
+
children: /* @__PURE__ */ jsxs28("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
1952
2016
|
/* @__PURE__ */ jsx41(Badge, { variant: s.status, children: s.status }),
|
|
1953
2017
|
/* @__PURE__ */ jsx41("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
1954
2018
|
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx41(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
@@ -2118,11 +2182,7 @@ var story_report_v1_default = {
|
|
|
2118
2182
|
},
|
|
2119
2183
|
kind: {
|
|
2120
2184
|
type: "string",
|
|
2121
|
-
enum: [
|
|
2122
|
-
"feature",
|
|
2123
|
-
"ability",
|
|
2124
|
-
"business-need"
|
|
2125
|
-
],
|
|
2185
|
+
enum: ["feature", "ability", "business-need"],
|
|
2126
2186
|
description: "How the feature was declared. Absent when the title was derived rather than declared."
|
|
2127
2187
|
},
|
|
2128
2188
|
narrative: {
|
|
@@ -2137,13 +2197,7 @@ var story_report_v1_default = {
|
|
|
2137
2197
|
description: "Terms this feature defines, linked wherever they appear in scenario text."
|
|
2138
2198
|
}
|
|
2139
2199
|
},
|
|
2140
|
-
required: [
|
|
2141
|
-
"id",
|
|
2142
|
-
"title",
|
|
2143
|
-
"sourceFile",
|
|
2144
|
-
"summary",
|
|
2145
|
-
"scenarios"
|
|
2146
|
-
],
|
|
2200
|
+
required: ["id", "title", "sourceFile", "summary", "scenarios"],
|
|
2147
2201
|
additionalProperties: false
|
|
2148
2202
|
},
|
|
2149
2203
|
Scenario: {
|
|
@@ -2273,6 +2327,11 @@ var story_report_v1_default = {
|
|
|
2273
2327
|
type: "number",
|
|
2274
2328
|
minimum: 0
|
|
2275
2329
|
},
|
|
2330
|
+
assertions: {
|
|
2331
|
+
type: "integer",
|
|
2332
|
+
minimum: 0,
|
|
2333
|
+
description: "Assertions observed or declared for this step. Omit when the adapter cannot observe assertions; zero means observed none."
|
|
2334
|
+
},
|
|
2276
2335
|
errorMessage: {
|
|
2277
2336
|
type: "string"
|
|
2278
2337
|
},
|
|
@@ -2300,33 +2359,15 @@ var story_report_v1_default = {
|
|
|
2300
2359
|
},
|
|
2301
2360
|
StepKeyword: {
|
|
2302
2361
|
type: "string",
|
|
2303
|
-
enum: [
|
|
2304
|
-
"Given",
|
|
2305
|
-
"When",
|
|
2306
|
-
"Then",
|
|
2307
|
-
"And",
|
|
2308
|
-
"But"
|
|
2309
|
-
]
|
|
2362
|
+
enum: ["Given", "When", "Then", "And", "But"]
|
|
2310
2363
|
},
|
|
2311
2364
|
StepMode: {
|
|
2312
2365
|
type: "string",
|
|
2313
|
-
enum: [
|
|
2314
|
-
"normal",
|
|
2315
|
-
"skip",
|
|
2316
|
-
"only",
|
|
2317
|
-
"todo",
|
|
2318
|
-
"fails",
|
|
2319
|
-
"concurrent"
|
|
2320
|
-
]
|
|
2366
|
+
enum: ["normal", "skip", "only", "todo", "fails", "concurrent"]
|
|
2321
2367
|
},
|
|
2322
2368
|
TestStatus: {
|
|
2323
2369
|
type: "string",
|
|
2324
|
-
enum: [
|
|
2325
|
-
"passed",
|
|
2326
|
-
"failed",
|
|
2327
|
-
"skipped",
|
|
2328
|
-
"pending"
|
|
2329
|
-
]
|
|
2370
|
+
enum: ["passed", "failed", "skipped", "pending"]
|
|
2330
2371
|
},
|
|
2331
2372
|
Ticket: {
|
|
2332
2373
|
type: "object",
|
|
@@ -2339,9 +2380,7 @@ var story_report_v1_default = {
|
|
|
2339
2380
|
type: "string"
|
|
2340
2381
|
}
|
|
2341
2382
|
},
|
|
2342
|
-
required: [
|
|
2343
|
-
"id"
|
|
2344
|
-
],
|
|
2383
|
+
required: ["id"],
|
|
2345
2384
|
additionalProperties: false
|
|
2346
2385
|
},
|
|
2347
2386
|
Attachment: {
|
|
@@ -2359,18 +2398,10 @@ var story_report_v1_default = {
|
|
|
2359
2398
|
},
|
|
2360
2399
|
contentEncoding: {
|
|
2361
2400
|
type: "string",
|
|
2362
|
-
enum: [
|
|
2363
|
-
"BASE64",
|
|
2364
|
-
"IDENTITY"
|
|
2365
|
-
]
|
|
2401
|
+
enum: ["BASE64", "IDENTITY"]
|
|
2366
2402
|
}
|
|
2367
2403
|
},
|
|
2368
|
-
required: [
|
|
2369
|
-
"name",
|
|
2370
|
-
"mediaType",
|
|
2371
|
-
"body",
|
|
2372
|
-
"contentEncoding"
|
|
2373
|
-
],
|
|
2404
|
+
required: ["name", "mediaType", "body", "contentEncoding"],
|
|
2374
2405
|
additionalProperties: false
|
|
2375
2406
|
},
|
|
2376
2407
|
CIInfo: {
|
|
@@ -2395,9 +2426,7 @@ var story_report_v1_default = {
|
|
|
2395
2426
|
type: "string"
|
|
2396
2427
|
}
|
|
2397
2428
|
},
|
|
2398
|
-
required: [
|
|
2399
|
-
"name"
|
|
2400
|
-
],
|
|
2429
|
+
required: ["name"],
|
|
2401
2430
|
additionalProperties: false
|
|
2402
2431
|
},
|
|
2403
2432
|
CoverageSummary: {
|
|
@@ -2428,10 +2457,7 @@ var story_report_v1_default = {
|
|
|
2428
2457
|
},
|
|
2429
2458
|
DocPhase: {
|
|
2430
2459
|
type: "string",
|
|
2431
|
-
enum: [
|
|
2432
|
-
"static",
|
|
2433
|
-
"runtime"
|
|
2434
|
-
]
|
|
2460
|
+
enum: ["static", "runtime"]
|
|
2435
2461
|
},
|
|
2436
2462
|
DocEntry: {
|
|
2437
2463
|
oneOf: [
|
|
@@ -2495,11 +2521,7 @@ var story_report_v1_default = {
|
|
|
2495
2521
|
}
|
|
2496
2522
|
}
|
|
2497
2523
|
},
|
|
2498
|
-
required: [
|
|
2499
|
-
"kind",
|
|
2500
|
-
"text",
|
|
2501
|
-
"phase"
|
|
2502
|
-
],
|
|
2524
|
+
required: ["kind", "text", "phase"],
|
|
2503
2525
|
additionalProperties: false
|
|
2504
2526
|
},
|
|
2505
2527
|
DocTag: {
|
|
@@ -2524,11 +2546,7 @@ var story_report_v1_default = {
|
|
|
2524
2546
|
}
|
|
2525
2547
|
}
|
|
2526
2548
|
},
|
|
2527
|
-
required: [
|
|
2528
|
-
"kind",
|
|
2529
|
-
"names",
|
|
2530
|
-
"phase"
|
|
2531
|
-
],
|
|
2549
|
+
required: ["kind", "names", "phase"],
|
|
2532
2550
|
additionalProperties: false
|
|
2533
2551
|
},
|
|
2534
2552
|
DocKv: {
|
|
@@ -2551,12 +2569,7 @@ var story_report_v1_default = {
|
|
|
2551
2569
|
}
|
|
2552
2570
|
}
|
|
2553
2571
|
},
|
|
2554
|
-
required: [
|
|
2555
|
-
"kind",
|
|
2556
|
-
"label",
|
|
2557
|
-
"value",
|
|
2558
|
-
"phase"
|
|
2559
|
-
],
|
|
2572
|
+
required: ["kind", "label", "value", "phase"],
|
|
2560
2573
|
additionalProperties: false
|
|
2561
2574
|
},
|
|
2562
2575
|
DocCode: {
|
|
@@ -2584,12 +2597,7 @@ var story_report_v1_default = {
|
|
|
2584
2597
|
}
|
|
2585
2598
|
}
|
|
2586
2599
|
},
|
|
2587
|
-
required: [
|
|
2588
|
-
"kind",
|
|
2589
|
-
"label",
|
|
2590
|
-
"content",
|
|
2591
|
-
"phase"
|
|
2592
|
-
],
|
|
2600
|
+
required: ["kind", "label", "content", "phase"],
|
|
2593
2601
|
additionalProperties: false
|
|
2594
2602
|
},
|
|
2595
2603
|
DocTable: {
|
|
@@ -2626,13 +2634,7 @@ var story_report_v1_default = {
|
|
|
2626
2634
|
}
|
|
2627
2635
|
}
|
|
2628
2636
|
},
|
|
2629
|
-
required: [
|
|
2630
|
-
"kind",
|
|
2631
|
-
"label",
|
|
2632
|
-
"columns",
|
|
2633
|
-
"rows",
|
|
2634
|
-
"phase"
|
|
2635
|
-
],
|
|
2637
|
+
required: ["kind", "label", "columns", "rows", "phase"],
|
|
2636
2638
|
additionalProperties: false
|
|
2637
2639
|
},
|
|
2638
2640
|
DocLink: {
|
|
@@ -2657,12 +2659,7 @@ var story_report_v1_default = {
|
|
|
2657
2659
|
}
|
|
2658
2660
|
}
|
|
2659
2661
|
},
|
|
2660
|
-
required: [
|
|
2661
|
-
"kind",
|
|
2662
|
-
"label",
|
|
2663
|
-
"url",
|
|
2664
|
-
"phase"
|
|
2665
|
-
],
|
|
2662
|
+
required: ["kind", "label", "url", "phase"],
|
|
2666
2663
|
additionalProperties: false
|
|
2667
2664
|
},
|
|
2668
2665
|
DocSection: {
|
|
@@ -2687,12 +2684,7 @@ var story_report_v1_default = {
|
|
|
2687
2684
|
}
|
|
2688
2685
|
}
|
|
2689
2686
|
},
|
|
2690
|
-
required: [
|
|
2691
|
-
"kind",
|
|
2692
|
-
"title",
|
|
2693
|
-
"markdown",
|
|
2694
|
-
"phase"
|
|
2695
|
-
],
|
|
2687
|
+
required: ["kind", "title", "markdown", "phase"],
|
|
2696
2688
|
additionalProperties: false
|
|
2697
2689
|
},
|
|
2698
2690
|
DocMermaid: {
|
|
@@ -2717,11 +2709,7 @@ var story_report_v1_default = {
|
|
|
2717
2709
|
}
|
|
2718
2710
|
}
|
|
2719
2711
|
},
|
|
2720
|
-
required: [
|
|
2721
|
-
"kind",
|
|
2722
|
-
"code",
|
|
2723
|
-
"phase"
|
|
2724
|
-
],
|
|
2712
|
+
required: ["kind", "code", "phase"],
|
|
2725
2713
|
additionalProperties: false
|
|
2726
2714
|
},
|
|
2727
2715
|
DocScreenshot: {
|
|
@@ -2746,11 +2734,7 @@ var story_report_v1_default = {
|
|
|
2746
2734
|
}
|
|
2747
2735
|
}
|
|
2748
2736
|
},
|
|
2749
|
-
required: [
|
|
2750
|
-
"kind",
|
|
2751
|
-
"path",
|
|
2752
|
-
"phase"
|
|
2753
|
-
],
|
|
2737
|
+
required: ["kind", "path", "phase"],
|
|
2754
2738
|
additionalProperties: false
|
|
2755
2739
|
},
|
|
2756
2740
|
DocVideo: {
|
|
@@ -2778,11 +2762,7 @@ var story_report_v1_default = {
|
|
|
2778
2762
|
}
|
|
2779
2763
|
}
|
|
2780
2764
|
},
|
|
2781
|
-
required: [
|
|
2782
|
-
"kind",
|
|
2783
|
-
"path",
|
|
2784
|
-
"phase"
|
|
2785
|
-
],
|
|
2765
|
+
required: ["kind", "path", "phase"],
|
|
2786
2766
|
additionalProperties: false
|
|
2787
2767
|
},
|
|
2788
2768
|
DocHtml: {
|
|
@@ -2823,26 +2803,17 @@ var story_report_v1_default = {
|
|
|
2823
2803
|
}
|
|
2824
2804
|
}
|
|
2825
2805
|
},
|
|
2826
|
-
required: [
|
|
2827
|
-
"kind",
|
|
2828
|
-
"phase"
|
|
2829
|
-
],
|
|
2806
|
+
required: ["kind", "phase"],
|
|
2830
2807
|
additionalProperties: false,
|
|
2831
2808
|
oneOf: [
|
|
2832
2809
|
{
|
|
2833
|
-
required: [
|
|
2834
|
-
"path"
|
|
2835
|
-
]
|
|
2810
|
+
required: ["path"]
|
|
2836
2811
|
},
|
|
2837
2812
|
{
|
|
2838
|
-
required: [
|
|
2839
|
-
"url"
|
|
2840
|
-
]
|
|
2813
|
+
required: ["url"]
|
|
2841
2814
|
},
|
|
2842
2815
|
{
|
|
2843
|
-
required: [
|
|
2844
|
-
"content"
|
|
2845
|
-
]
|
|
2816
|
+
required: ["content"]
|
|
2846
2817
|
}
|
|
2847
2818
|
]
|
|
2848
2819
|
},
|
|
@@ -2866,11 +2837,7 @@ var story_report_v1_default = {
|
|
|
2866
2837
|
}
|
|
2867
2838
|
}
|
|
2868
2839
|
},
|
|
2869
|
-
required: [
|
|
2870
|
-
"kind",
|
|
2871
|
-
"value",
|
|
2872
|
-
"phase"
|
|
2873
|
-
],
|
|
2840
|
+
required: ["kind", "value", "phase"],
|
|
2874
2841
|
additionalProperties: false
|
|
2875
2842
|
},
|
|
2876
2843
|
DocCustom: {
|
|
@@ -2894,21 +2861,12 @@ var story_report_v1_default = {
|
|
|
2894
2861
|
}
|
|
2895
2862
|
}
|
|
2896
2863
|
},
|
|
2897
|
-
required: [
|
|
2898
|
-
"kind",
|
|
2899
|
-
"type",
|
|
2900
|
-
"data",
|
|
2901
|
-
"phase"
|
|
2902
|
-
],
|
|
2864
|
+
required: ["kind", "type", "data", "phase"],
|
|
2903
2865
|
additionalProperties: false
|
|
2904
2866
|
},
|
|
2905
2867
|
OtelSpan: {
|
|
2906
2868
|
type: "object",
|
|
2907
|
-
required: [
|
|
2908
|
-
"spanId",
|
|
2909
|
-
"name",
|
|
2910
|
-
"status"
|
|
2911
|
-
],
|
|
2869
|
+
required: ["spanId", "name", "status"],
|
|
2912
2870
|
properties: {
|
|
2913
2871
|
spanId: {
|
|
2914
2872
|
type: "string"
|
|
@@ -2932,11 +2890,7 @@ var story_report_v1_default = {
|
|
|
2932
2890
|
type: "number"
|
|
2933
2891
|
},
|
|
2934
2892
|
status: {
|
|
2935
|
-
enum: [
|
|
2936
|
-
"ok",
|
|
2937
|
-
"error",
|
|
2938
|
-
"unset"
|
|
2939
|
-
]
|
|
2893
|
+
enum: ["ok", "error", "unset"]
|
|
2940
2894
|
},
|
|
2941
2895
|
statusMessage: {
|
|
2942
2896
|
type: "string"
|
|
@@ -2960,10 +2914,7 @@ var story_report_v1_default = {
|
|
|
2960
2914
|
minLength: 1
|
|
2961
2915
|
}
|
|
2962
2916
|
},
|
|
2963
|
-
required: [
|
|
2964
|
-
"term",
|
|
2965
|
-
"definition"
|
|
2966
|
-
],
|
|
2917
|
+
required: ["term", "definition"],
|
|
2967
2918
|
additionalProperties: false
|
|
2968
2919
|
}
|
|
2969
2920
|
}
|
|
@@ -3066,6 +3017,7 @@ export {
|
|
|
3066
3017
|
parseStoryReport,
|
|
3067
3018
|
prUrl,
|
|
3068
3019
|
reportLastRunMs,
|
|
3020
|
+
scenarioLastRunMs,
|
|
3069
3021
|
storyReportSchema,
|
|
3070
3022
|
useBuiltinRenderers,
|
|
3071
3023
|
useCustomRenderers,
|