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.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",
|
|
@@ -379,30 +404,38 @@ function DocLink({ entry }) {
|
|
|
379
404
|
);
|
|
380
405
|
}
|
|
381
406
|
|
|
382
|
-
// src/
|
|
407
|
+
// src/lib/markdown.ts
|
|
383
408
|
import { marked } from "marked";
|
|
384
409
|
|
|
385
410
|
// src/lib/url.ts
|
|
386
411
|
import { safeUrl, safeImageUrl, isLocalFsPath } from "executable-stories-core/utils/url";
|
|
387
412
|
|
|
388
|
-
// src/
|
|
389
|
-
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
390
|
-
function neutralizeUrl(value) {
|
|
391
|
-
return safeUrl(value) ?? "#";
|
|
392
|
-
}
|
|
413
|
+
// src/lib/markdown.ts
|
|
393
414
|
function safeMarkdownHtml(markdown) {
|
|
394
415
|
const raw = marked.parse(markdown, { async: false });
|
|
395
416
|
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)}'`);
|
|
396
417
|
}
|
|
418
|
+
function dedent(text) {
|
|
419
|
+
const lines = text.replace(/\t/g, " ").split("\n");
|
|
420
|
+
const indents = lines.filter((line) => line.trim().length > 0).map((line) => line.length - line.trimStart().length);
|
|
421
|
+
const shortest = indents.length > 0 ? Math.min(...indents) : 0;
|
|
422
|
+
return lines.map((line) => line.slice(shortest)).join("\n").trim();
|
|
423
|
+
}
|
|
424
|
+
function neutralizeUrl(value) {
|
|
425
|
+
return safeUrl(value) ?? "#";
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/components/doc/DocSection.tsx
|
|
429
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
397
430
|
function DocSection({ entry }) {
|
|
398
431
|
const renderers = useBuiltinRenderers();
|
|
399
432
|
if (renderers.section) {
|
|
400
|
-
return /* @__PURE__ */
|
|
433
|
+
return /* @__PURE__ */ jsx10(Fragment2, { children: renderers.section(entry) });
|
|
401
434
|
}
|
|
402
435
|
const html = safeMarkdownHtml(entry.markdown);
|
|
403
436
|
return /* @__PURE__ */ jsxs5("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
|
|
404
|
-
entry.title ? /* @__PURE__ */
|
|
405
|
-
/* @__PURE__ */
|
|
437
|
+
entry.title ? /* @__PURE__ */ jsx10("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
|
|
438
|
+
/* @__PURE__ */ jsx10(
|
|
406
439
|
"div",
|
|
407
440
|
{
|
|
408
441
|
className: "es-doc-prose prose prose-sm max-w-none",
|
|
@@ -413,11 +446,11 @@ function DocSection({ entry }) {
|
|
|
413
446
|
}
|
|
414
447
|
|
|
415
448
|
// src/components/doc/DocMermaid.tsx
|
|
416
|
-
import { Fragment as Fragment3, jsx as
|
|
449
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
417
450
|
function MermaidSource({ entry, ref }) {
|
|
418
451
|
return /* @__PURE__ */ jsxs6("figure", { ref, className: "my-3", "aria-label": entry.title ?? "Diagram", children: [
|
|
419
|
-
entry.title ? /* @__PURE__ */
|
|
420
|
-
/* @__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(
|
|
421
454
|
"pre",
|
|
422
455
|
{
|
|
423
456
|
"data-mermaid": true,
|
|
@@ -431,24 +464,24 @@ function MermaidSource({ entry, ref }) {
|
|
|
431
464
|
function DocMermaid({ entry }) {
|
|
432
465
|
const renderers = useBuiltinRenderers();
|
|
433
466
|
if (renderers.mermaid) {
|
|
434
|
-
return /* @__PURE__ */
|
|
467
|
+
return /* @__PURE__ */ jsx11(Fragment3, { children: renderers.mermaid(entry) });
|
|
435
468
|
}
|
|
436
|
-
return /* @__PURE__ */
|
|
469
|
+
return /* @__PURE__ */ jsx11(MermaidSource, { entry });
|
|
437
470
|
}
|
|
438
471
|
|
|
439
472
|
// src/components/doc/DocScreenshot.tsx
|
|
440
|
-
import { jsx as
|
|
473
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
441
474
|
function DocScreenshot({ entry }) {
|
|
442
475
|
const src = isLocalFsPath(entry.path) ? void 0 : safeImageUrl(entry.path);
|
|
443
476
|
if (!src) {
|
|
444
477
|
return /* @__PURE__ */ jsxs7("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
445
|
-
/* @__PURE__ */
|
|
446
|
-
/* @__PURE__ */
|
|
447
|
-
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
|
|
448
481
|
] });
|
|
449
482
|
}
|
|
450
483
|
return /* @__PURE__ */ jsxs7("figure", { className: "my-3", children: [
|
|
451
|
-
/* @__PURE__ */
|
|
484
|
+
/* @__PURE__ */ jsx12(
|
|
452
485
|
"img",
|
|
453
486
|
{
|
|
454
487
|
src,
|
|
@@ -457,24 +490,24 @@ function DocScreenshot({ entry }) {
|
|
|
457
490
|
className: "max-w-full rounded-md border border-border"
|
|
458
491
|
}
|
|
459
492
|
),
|
|
460
|
-
entry.alt ? /* @__PURE__ */
|
|
493
|
+
entry.alt ? /* @__PURE__ */ jsx12("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: entry.alt }) : null
|
|
461
494
|
] });
|
|
462
495
|
}
|
|
463
496
|
|
|
464
497
|
// src/components/doc/DocVideo.tsx
|
|
465
|
-
import { jsx as
|
|
498
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
466
499
|
function DocVideo({ entry }) {
|
|
467
500
|
if (isLocalFsPath(entry.path)) {
|
|
468
501
|
return /* @__PURE__ */ jsxs8("figure", { className: "my-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [
|
|
469
|
-
/* @__PURE__ */
|
|
470
|
-
/* @__PURE__ */
|
|
471
|
-
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
|
|
472
505
|
] });
|
|
473
506
|
}
|
|
474
507
|
const src = safeUrl(entry.path);
|
|
475
508
|
const poster = safeUrl(entry.poster);
|
|
476
509
|
return /* @__PURE__ */ jsxs8("figure", { className: "my-3", children: [
|
|
477
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ jsx13(
|
|
478
511
|
"video",
|
|
479
512
|
{
|
|
480
513
|
controls: true,
|
|
@@ -484,12 +517,12 @@ function DocVideo({ entry }) {
|
|
|
484
517
|
className: "max-w-full rounded-md border border-border"
|
|
485
518
|
}
|
|
486
519
|
),
|
|
487
|
-
entry.caption ? /* @__PURE__ */
|
|
520
|
+
entry.caption ? /* @__PURE__ */ jsx13("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: entry.caption }) : null
|
|
488
521
|
] });
|
|
489
522
|
}
|
|
490
523
|
|
|
491
524
|
// src/components/doc/DocHtml.tsx
|
|
492
|
-
import { jsx as
|
|
525
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
493
526
|
function DocHtml({ entry }) {
|
|
494
527
|
const height = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
495
528
|
const title = entry.title ?? "Embedded HTML";
|
|
@@ -497,8 +530,8 @@ function DocHtml({ entry }) {
|
|
|
497
530
|
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content } : { src: safeHref ?? "" };
|
|
498
531
|
return /* @__PURE__ */ jsxs9("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
499
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: [
|
|
500
|
-
/* @__PURE__ */
|
|
501
|
-
safeHref ? /* @__PURE__ */
|
|
533
|
+
/* @__PURE__ */ jsx14("span", { children: entry.title ?? "HTML" }),
|
|
534
|
+
safeHref ? /* @__PURE__ */ jsx14(
|
|
502
535
|
"a",
|
|
503
536
|
{
|
|
504
537
|
href: safeHref,
|
|
@@ -511,7 +544,7 @@ function DocHtml({ entry }) {
|
|
|
511
544
|
}
|
|
512
545
|
) : null
|
|
513
546
|
] }),
|
|
514
|
-
/* @__PURE__ */
|
|
547
|
+
/* @__PURE__ */ jsx14(
|
|
515
548
|
"iframe",
|
|
516
549
|
{
|
|
517
550
|
...frameProps,
|
|
@@ -526,7 +559,7 @@ function DocHtml({ entry }) {
|
|
|
526
559
|
}
|
|
527
560
|
|
|
528
561
|
// src/components/doc/DocState.tsx
|
|
529
|
-
import { jsx as
|
|
562
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
530
563
|
function DocState({ entry }) {
|
|
531
564
|
let json;
|
|
532
565
|
try {
|
|
@@ -534,20 +567,20 @@ function DocState({ entry }) {
|
|
|
534
567
|
} catch {
|
|
535
568
|
json = String(entry.value);
|
|
536
569
|
}
|
|
537
|
-
return /* @__PURE__ */
|
|
570
|
+
return /* @__PURE__ */ jsx15(CodeFigure, { label: entry.label ?? "State", children: /* @__PURE__ */ jsx15("code", { className: "font-mono text-xs language-json", children: json }) });
|
|
538
571
|
}
|
|
539
572
|
|
|
540
573
|
// src/components/doc/DocCustom.tsx
|
|
541
|
-
import { Fragment as Fragment4, jsx as
|
|
574
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
542
575
|
function DocCustom({ entry }) {
|
|
543
576
|
const renderers = useCustomRenderers();
|
|
544
577
|
const renderer = renderers[entry.type];
|
|
545
578
|
if (renderer) {
|
|
546
|
-
return /* @__PURE__ */
|
|
579
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: renderer(entry) });
|
|
547
580
|
}
|
|
548
581
|
return /* @__PURE__ */ jsxs10("div", { className: "my-2", "data-type": entry.type, children: [
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
/* @__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) })
|
|
551
584
|
] });
|
|
552
585
|
}
|
|
553
586
|
function safeStringify2(value) {
|
|
@@ -559,64 +592,43 @@ function safeStringify2(value) {
|
|
|
559
592
|
}
|
|
560
593
|
|
|
561
594
|
// src/components/doc/DocEntry.tsx
|
|
562
|
-
import { jsx as
|
|
595
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
563
596
|
function DocEntry({ entry }) {
|
|
564
597
|
switch (entry.kind) {
|
|
565
598
|
case "note":
|
|
566
|
-
return /* @__PURE__ */
|
|
599
|
+
return /* @__PURE__ */ jsx17(DocNote, { entry });
|
|
567
600
|
case "tag":
|
|
568
|
-
return /* @__PURE__ */
|
|
601
|
+
return /* @__PURE__ */ jsx17(DocTag, { entry });
|
|
569
602
|
case "kv":
|
|
570
|
-
return /* @__PURE__ */
|
|
603
|
+
return /* @__PURE__ */ jsx17(DocKv, { entry });
|
|
571
604
|
case "code":
|
|
572
|
-
return /* @__PURE__ */
|
|
605
|
+
return /* @__PURE__ */ jsx17(DocCode, { entry });
|
|
573
606
|
case "table":
|
|
574
|
-
return /* @__PURE__ */
|
|
607
|
+
return /* @__PURE__ */ jsx17(DocTable, { entry });
|
|
575
608
|
case "link":
|
|
576
|
-
return /* @__PURE__ */
|
|
609
|
+
return /* @__PURE__ */ jsx17(DocLink, { entry });
|
|
577
610
|
case "section":
|
|
578
|
-
return /* @__PURE__ */
|
|
611
|
+
return /* @__PURE__ */ jsx17(DocSection, { entry });
|
|
579
612
|
case "mermaid":
|
|
580
|
-
return /* @__PURE__ */
|
|
613
|
+
return /* @__PURE__ */ jsx17(DocMermaid, { entry });
|
|
581
614
|
case "screenshot":
|
|
582
|
-
return /* @__PURE__ */
|
|
615
|
+
return /* @__PURE__ */ jsx17(DocScreenshot, { entry });
|
|
583
616
|
case "video":
|
|
584
|
-
return /* @__PURE__ */
|
|
617
|
+
return /* @__PURE__ */ jsx17(DocVideo, { entry });
|
|
585
618
|
case "html":
|
|
586
|
-
return /* @__PURE__ */
|
|
619
|
+
return /* @__PURE__ */ jsx17(DocHtml, { entry });
|
|
587
620
|
case "state":
|
|
588
|
-
return /* @__PURE__ */
|
|
621
|
+
return /* @__PURE__ */ jsx17(DocState, { entry });
|
|
589
622
|
case "custom":
|
|
590
|
-
return /* @__PURE__ */
|
|
623
|
+
return /* @__PURE__ */ jsx17(DocCustom, { entry });
|
|
591
624
|
}
|
|
592
625
|
}
|
|
593
626
|
|
|
594
627
|
// src/components/ReportDocEntries.tsx
|
|
595
|
-
import { Fragment as Fragment5, jsx as
|
|
628
|
+
import { Fragment as Fragment5, jsx as jsx18 } from "react/jsx-runtime";
|
|
596
629
|
function ReportDocEntries({ entries }) {
|
|
597
630
|
if (entries.length === 0) return null;
|
|
598
|
-
return /* @__PURE__ */
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// src/lib/step-params.tsx
|
|
602
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
603
|
-
var STEP_PARAM_PATTERN = /"[^"]*"|(?<![\w.-])\d+(?:\.\d+)?(?![\w.-])/g;
|
|
604
|
-
function highlightStepParams(text) {
|
|
605
|
-
const matches = Array.from(text.matchAll(STEP_PARAM_PATTERN));
|
|
606
|
-
if (matches.length === 0) return text;
|
|
607
|
-
const nodes = [];
|
|
608
|
-
let lastIndex = 0;
|
|
609
|
-
matches.forEach((match, i) => {
|
|
610
|
-
const start = match.index;
|
|
611
|
-
const end = start + match[0].length;
|
|
612
|
-
if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
|
|
613
|
-
nodes.push(
|
|
614
|
-
/* @__PURE__ */ jsx18("span", { className: "font-medium text-step-param italic", children: match[0] }, i)
|
|
615
|
-
);
|
|
616
|
-
lastIndex = end;
|
|
617
|
-
});
|
|
618
|
-
if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
|
|
619
|
-
return nodes;
|
|
631
|
+
return /* @__PURE__ */ jsx18(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx18(DocEntry, { entry }, i)) });
|
|
620
632
|
}
|
|
621
633
|
|
|
622
634
|
// src/components/ReportSteps.tsx
|
|
@@ -635,9 +647,22 @@ var STEP_GLYPH_COLOR = {
|
|
|
635
647
|
};
|
|
636
648
|
function ReportSteps({ scenario }) {
|
|
637
649
|
if (scenario.steps.length === 0) return null;
|
|
638
|
-
|
|
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
|
+
)) });
|
|
639
661
|
}
|
|
640
|
-
function ReportStepItem({
|
|
662
|
+
function ReportStepItem({
|
|
663
|
+
step,
|
|
664
|
+
unasserted = false
|
|
665
|
+
}) {
|
|
641
666
|
const kw = step.keyword.toLowerCase();
|
|
642
667
|
const continuation = kw === "and" || kw === "but";
|
|
643
668
|
return /* @__PURE__ */ jsxs11(
|
|
@@ -645,10 +670,23 @@ function ReportStepItem({ step }) {
|
|
|
645
670
|
{
|
|
646
671
|
id: step.id,
|
|
647
672
|
"data-status": step.status,
|
|
648
|
-
className: cn(
|
|
673
|
+
className: cn(
|
|
674
|
+
"py-1.5 text-[0.8125rem] leading-normal",
|
|
675
|
+
continuation && "pl-5"
|
|
676
|
+
),
|
|
649
677
|
children: [
|
|
650
678
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-baseline gap-2", children: [
|
|
651
|
-
/* @__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
|
+
),
|
|
652
690
|
/* @__PURE__ */ jsx19(
|
|
653
691
|
"span",
|
|
654
692
|
{
|
|
@@ -660,6 +698,7 @@ function ReportStepItem({ step }) {
|
|
|
660
698
|
}
|
|
661
699
|
),
|
|
662
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,
|
|
663
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
|
|
664
703
|
] }),
|
|
665
704
|
step.errorMessage ? /* @__PURE__ */ jsx19(
|
|
@@ -1055,21 +1094,104 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1055
1094
|
] });
|
|
1056
1095
|
}
|
|
1057
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
|
+
|
|
1058
1180
|
// src/interactive/collapse-context.ts
|
|
1059
|
-
import { createContext as
|
|
1060
|
-
var CollapseContext =
|
|
1181
|
+
import { createContext as createContext4, useCallback, useContext as useContext5, useState as useState2 } from "react";
|
|
1182
|
+
var CollapseContext = createContext4(null);
|
|
1061
1183
|
var CollapseProvider = CollapseContext.Provider;
|
|
1062
1184
|
function useCollapse() {
|
|
1063
|
-
return
|
|
1185
|
+
return useContext5(CollapseContext);
|
|
1064
1186
|
}
|
|
1065
1187
|
|
|
1066
1188
|
// src/interactive/scenario-actions.tsx
|
|
1067
|
-
import { createContext as
|
|
1189
|
+
import { createContext as createContext5, useContext as useContext6 } from "react";
|
|
1068
1190
|
import { scenarioToMarkdown as coreScenarioToMarkdown } from "executable-stories-core/utils/scenario-markdown";
|
|
1069
|
-
var ScenarioActionsContext =
|
|
1191
|
+
var ScenarioActionsContext = createContext5(null);
|
|
1070
1192
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1071
1193
|
function useScenarioActions() {
|
|
1072
|
-
return
|
|
1194
|
+
return useContext6(ScenarioActionsContext);
|
|
1073
1195
|
}
|
|
1074
1196
|
|
|
1075
1197
|
// src/components/ui/card.tsx
|
|
@@ -1116,7 +1238,7 @@ function CardContent({ className, ...props }) {
|
|
|
1116
1238
|
import "react";
|
|
1117
1239
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
1118
1240
|
import { CheckIcon } from "lucide-react";
|
|
1119
|
-
import { jsx as jsx25, jsxs as
|
|
1241
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1120
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";
|
|
1121
1243
|
function DropdownMenu(props) {
|
|
1122
1244
|
return /* @__PURE__ */ jsx25(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
@@ -1167,7 +1289,7 @@ function DropdownMenuItem({
|
|
|
1167
1289
|
|
|
1168
1290
|
// src/components/ReportScenario.tsx
|
|
1169
1291
|
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
1170
|
-
import { jsx as jsx26, jsxs as
|
|
1292
|
+
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1171
1293
|
var STATUS_META = {
|
|
1172
1294
|
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
1173
1295
|
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
@@ -1183,7 +1305,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1183
1305
|
const collapsible = collapse !== null && !hideTitle;
|
|
1184
1306
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
1185
1307
|
const actions = useScenarioActions();
|
|
1186
|
-
return /* @__PURE__ */
|
|
1308
|
+
return /* @__PURE__ */ jsxs18(
|
|
1187
1309
|
Card,
|
|
1188
1310
|
{
|
|
1189
1311
|
id: scenario.id,
|
|
@@ -1191,9 +1313,9 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1191
1313
|
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
1192
1314
|
className: "gap-0 py-0",
|
|
1193
1315
|
children: [
|
|
1194
|
-
/* @__PURE__ */
|
|
1195
|
-
/* @__PURE__ */
|
|
1196
|
-
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: [
|
|
1197
1319
|
collapsible ? /* @__PURE__ */ jsx26(
|
|
1198
1320
|
"button",
|
|
1199
1321
|
{
|
|
@@ -1209,11 +1331,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1209
1331
|
/* @__PURE__ */ jsx26("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
1210
1332
|
/* @__PURE__ */ jsx26("span", { children: scenario.title })
|
|
1211
1333
|
] }),
|
|
1212
|
-
/* @__PURE__ */
|
|
1334
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1213
1335
|
/* @__PURE__ */ jsx26(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
1336
|
+
/* @__PURE__ */ jsx26(ScenarioStaleness, { scenario }),
|
|
1214
1337
|
scenario.durationMs > 0 ? /* @__PURE__ */ jsx26("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration3(scenario.durationMs) }) : null,
|
|
1215
1338
|
meta.showPill ? /* @__PURE__ */ jsx26(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx26("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
1216
|
-
actions ? /* @__PURE__ */
|
|
1339
|
+
actions ? /* @__PURE__ */ jsxs18(DropdownMenu, { children: [
|
|
1217
1340
|
/* @__PURE__ */ jsx26(
|
|
1218
1341
|
DropdownMenuTrigger,
|
|
1219
1342
|
{
|
|
@@ -1222,16 +1345,16 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1222
1345
|
children: /* @__PURE__ */ jsx26(MoreHorizontalIcon, { "aria-hidden": true })
|
|
1223
1346
|
}
|
|
1224
1347
|
),
|
|
1225
|
-
/* @__PURE__ */
|
|
1226
|
-
/* @__PURE__ */
|
|
1348
|
+
/* @__PURE__ */ jsxs18(DropdownMenuContent, { align: "end", children: [
|
|
1349
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
1227
1350
|
/* @__PURE__ */ jsx26(LinkIcon, {}),
|
|
1228
1351
|
" Copy link"
|
|
1229
1352
|
] }),
|
|
1230
|
-
/* @__PURE__ */
|
|
1353
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
1231
1354
|
/* @__PURE__ */ jsx26(FileTextIcon, {}),
|
|
1232
1355
|
" Copy as Markdown"
|
|
1233
1356
|
] }),
|
|
1234
|
-
/* @__PURE__ */
|
|
1357
|
+
/* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
1235
1358
|
/* @__PURE__ */ jsx26(SparklesIcon, {}),
|
|
1236
1359
|
" Explain with AI"
|
|
1237
1360
|
] })
|
|
@@ -1239,12 +1362,12 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
1239
1362
|
] }) : null
|
|
1240
1363
|
] })
|
|
1241
1364
|
] }),
|
|
1242
|
-
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: [
|
|
1243
1366
|
scenario.tags.map((t) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
1244
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}`))
|
|
1245
1368
|
] }) : null
|
|
1246
1369
|
] }),
|
|
1247
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsxs18(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
1248
1371
|
scenario.errorMessage ? /* @__PURE__ */ jsx26(
|
|
1249
1372
|
"pre",
|
|
1250
1373
|
{
|
|
@@ -1270,8 +1393,35 @@ function ReportScenarioList({ feature }) {
|
|
|
1270
1393
|
return /* @__PURE__ */ jsx27(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx27(ReportScenario, { scenario }, scenario.id)) });
|
|
1271
1394
|
}
|
|
1272
1395
|
|
|
1396
|
+
// src/components/ReportFeatureIntro.tsx
|
|
1397
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1398
|
+
function ReportFeatureIntro({ feature }) {
|
|
1399
|
+
const hasNarrative = Boolean(feature.narrative?.trim());
|
|
1400
|
+
const hasGlossary = Boolean(feature.glossary?.length);
|
|
1401
|
+
if (!hasNarrative && !hasGlossary) return null;
|
|
1402
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
|
|
1403
|
+
hasNarrative ? /* @__PURE__ */ jsx28(
|
|
1404
|
+
"div",
|
|
1405
|
+
{
|
|
1406
|
+
className: "es-doc-prose prose prose-sm max-w-none text-muted-foreground",
|
|
1407
|
+
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1408
|
+
}
|
|
1409
|
+
) : null,
|
|
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: [
|
|
1411
|
+
/* @__PURE__ */ jsx28("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1412
|
+
/* @__PURE__ */ jsx28("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
|
|
1413
|
+
] }, entry.term)) }) : null
|
|
1414
|
+
] });
|
|
1415
|
+
}
|
|
1416
|
+
function featureKindLabel(kind) {
|
|
1417
|
+
if (kind === "ability") return "Ability";
|
|
1418
|
+
if (kind === "business-need") return "Business need";
|
|
1419
|
+
if (kind === "feature") return "Feature";
|
|
1420
|
+
return null;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1273
1423
|
// src/components/ReportFeature.tsx
|
|
1274
|
-
import { Fragment as Fragment9, jsx as
|
|
1424
|
+
import { Fragment as Fragment9, jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1275
1425
|
function ReportFeature({ feature }) {
|
|
1276
1426
|
const titleId = `${feature.id}-title`;
|
|
1277
1427
|
const bodyId = `${feature.id}-body`;
|
|
@@ -1279,10 +1429,11 @@ function ReportFeature({ feature }) {
|
|
|
1279
1429
|
const skipped = s.skipped + s.pending;
|
|
1280
1430
|
const collapse = useCollapse();
|
|
1281
1431
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1432
|
+
const kindLabel = featureKindLabel(feature.kind);
|
|
1282
1433
|
return (
|
|
1283
1434
|
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
1284
1435
|
// layer of nesting so the scenario cards below read as the primary unit.
|
|
1285
|
-
/* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsxs20(
|
|
1286
1437
|
"section",
|
|
1287
1438
|
{
|
|
1288
1439
|
id: feature.id,
|
|
@@ -1290,9 +1441,9 @@ function ReportFeature({ feature }) {
|
|
|
1290
1441
|
"aria-labelledby": titleId,
|
|
1291
1442
|
className: "flex flex-col gap-3",
|
|
1292
1443
|
children: [
|
|
1293
|
-
/* @__PURE__ */
|
|
1294
|
-
/* @__PURE__ */
|
|
1295
|
-
/* @__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(
|
|
1296
1447
|
"button",
|
|
1297
1448
|
{
|
|
1298
1449
|
type: "button",
|
|
@@ -1301,31 +1452,34 @@ function ReportFeature({ feature }) {
|
|
|
1301
1452
|
"aria-controls": bodyId,
|
|
1302
1453
|
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1303
1454
|
children: [
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
/* @__PURE__ */
|
|
1455
|
+
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1456
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate", children: feature.title })
|
|
1306
1457
|
]
|
|
1307
1458
|
}
|
|
1308
1459
|
) : feature.title }),
|
|
1309
|
-
/* @__PURE__ */
|
|
1460
|
+
/* @__PURE__ */ jsxs20("p", { className: cn("mt-0.5 flex items-center gap-2 text-xs text-muted-foreground", collapse && "pl-5"), children: [
|
|
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,
|
|
1462
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate font-mono", children: feature.sourceFile })
|
|
1463
|
+
] })
|
|
1310
1464
|
] }),
|
|
1311
|
-
/* @__PURE__ */
|
|
1465
|
+
/* @__PURE__ */ jsxs20(
|
|
1312
1466
|
"p",
|
|
1313
1467
|
{
|
|
1314
1468
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1315
1469
|
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1316
1470
|
children: [
|
|
1317
|
-
/* @__PURE__ */
|
|
1471
|
+
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1318
1472
|
s.passed,
|
|
1319
1473
|
" passed"
|
|
1320
1474
|
] }),
|
|
1321
|
-
/* @__PURE__ */
|
|
1322
|
-
/* @__PURE__ */
|
|
1475
|
+
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1476
|
+
/* @__PURE__ */ jsxs20("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1323
1477
|
s.failed,
|
|
1324
1478
|
" failed"
|
|
1325
1479
|
] }),
|
|
1326
|
-
skipped > 0 ? /* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
/* @__PURE__ */
|
|
1480
|
+
skipped > 0 ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
1481
|
+
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1482
|
+
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1329
1483
|
skipped,
|
|
1330
1484
|
" skipped"
|
|
1331
1485
|
] })
|
|
@@ -1334,7 +1488,10 @@ function ReportFeature({ feature }) {
|
|
|
1334
1488
|
}
|
|
1335
1489
|
)
|
|
1336
1490
|
] }),
|
|
1337
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsxs20("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
|
|
1492
|
+
/* @__PURE__ */ jsx29(ReportFeatureIntro, { feature }),
|
|
1493
|
+
/* @__PURE__ */ jsx29(ReportScenarioList, { feature })
|
|
1494
|
+
] })
|
|
1338
1495
|
]
|
|
1339
1496
|
}
|
|
1340
1497
|
)
|
|
@@ -1342,17 +1499,17 @@ function ReportFeature({ feature }) {
|
|
|
1342
1499
|
}
|
|
1343
1500
|
|
|
1344
1501
|
// src/components/ReportFeatureList.tsx
|
|
1345
|
-
import { jsx as
|
|
1502
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1346
1503
|
function ReportFeatureList() {
|
|
1347
1504
|
const report = useReport();
|
|
1348
|
-
return /* @__PURE__ */
|
|
1505
|
+
return /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx30(ReportFeature, { feature }, feature.id)) });
|
|
1349
1506
|
}
|
|
1350
1507
|
|
|
1351
1508
|
// src/components/ui/empty.tsx
|
|
1352
1509
|
import { cva as cva2 } from "class-variance-authority";
|
|
1353
|
-
import { jsx as
|
|
1510
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
1354
1511
|
function Empty({ className, ...props }) {
|
|
1355
|
-
return /* @__PURE__ */
|
|
1512
|
+
return /* @__PURE__ */ jsx31(
|
|
1356
1513
|
"div",
|
|
1357
1514
|
{
|
|
1358
1515
|
"data-slot": "empty",
|
|
@@ -1365,7 +1522,7 @@ function Empty({ className, ...props }) {
|
|
|
1365
1522
|
);
|
|
1366
1523
|
}
|
|
1367
1524
|
function EmptyHeader({ className, ...props }) {
|
|
1368
|
-
return /* @__PURE__ */
|
|
1525
|
+
return /* @__PURE__ */ jsx31(
|
|
1369
1526
|
"div",
|
|
1370
1527
|
{
|
|
1371
1528
|
"data-slot": "empty-header",
|
|
@@ -1392,7 +1549,7 @@ var emptyMediaVariants = cva2(
|
|
|
1392
1549
|
}
|
|
1393
1550
|
);
|
|
1394
1551
|
function EmptyTitle({ className, ...props }) {
|
|
1395
|
-
return /* @__PURE__ */
|
|
1552
|
+
return /* @__PURE__ */ jsx31(
|
|
1396
1553
|
"div",
|
|
1397
1554
|
{
|
|
1398
1555
|
"data-slot": "empty-title",
|
|
@@ -1403,16 +1560,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1403
1560
|
}
|
|
1404
1561
|
|
|
1405
1562
|
// src/components/ReportEmpty.tsx
|
|
1406
|
-
import { jsx as
|
|
1563
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
1407
1564
|
function ReportEmpty({ message }) {
|
|
1408
|
-
return /* @__PURE__ */
|
|
1565
|
+
return /* @__PURE__ */ jsx32(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx32(EmptyHeader, { children: /* @__PURE__ */ jsx32(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1409
1566
|
}
|
|
1410
1567
|
|
|
1411
1568
|
// src/components/ReportSummary.tsx
|
|
1412
|
-
import { jsx as
|
|
1569
|
+
import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1413
1570
|
function ReportSummary({ className }) {
|
|
1414
1571
|
const report = useReport();
|
|
1415
|
-
return /* @__PURE__ */
|
|
1572
|
+
return /* @__PURE__ */ jsx33(
|
|
1416
1573
|
ReportSummaryView,
|
|
1417
1574
|
{
|
|
1418
1575
|
summary: report.summary,
|
|
@@ -1438,7 +1595,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1438
1595
|
if (summary.pending > 0) {
|
|
1439
1596
|
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1440
1597
|
}
|
|
1441
|
-
return /* @__PURE__ */
|
|
1598
|
+
return /* @__PURE__ */ jsx33(
|
|
1442
1599
|
"dl",
|
|
1443
1600
|
{
|
|
1444
1601
|
className: cn(
|
|
@@ -1451,17 +1608,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1451
1608
|
"aria-label": ariaLabel,
|
|
1452
1609
|
children: cards.map((c) => {
|
|
1453
1610
|
const tone = TONE[c.status];
|
|
1454
|
-
return /* @__PURE__ */
|
|
1611
|
+
return /* @__PURE__ */ jsxs21(
|
|
1455
1612
|
"div",
|
|
1456
1613
|
{
|
|
1457
1614
|
"data-status": c.status,
|
|
1458
1615
|
className: "rounded-lg border bg-card px-4 py-3",
|
|
1459
1616
|
children: [
|
|
1460
|
-
/* @__PURE__ */
|
|
1461
|
-
/* @__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: [
|
|
1618
|
+
/* @__PURE__ */ jsx33("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1462
1619
|
c.label
|
|
1463
1620
|
] }),
|
|
1464
|
-
/* @__PURE__ */
|
|
1621
|
+
/* @__PURE__ */ jsx33("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1465
1622
|
]
|
|
1466
1623
|
},
|
|
1467
1624
|
c.status
|
|
@@ -1473,58 +1630,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
|
1473
1630
|
|
|
1474
1631
|
// src/components/ReportMeta.tsx
|
|
1475
1632
|
import { formatDuration as formatDuration4 } from "executable-stories-core/utils/duration";
|
|
1476
|
-
|
|
1477
|
-
// src/lib/provenance.ts
|
|
1478
|
-
function reportLastRunMs(report) {
|
|
1479
|
-
if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
|
|
1480
|
-
if (report.startedAtMs && report.startedAtMs > 0) return report.startedAtMs;
|
|
1481
|
-
return void 0;
|
|
1482
|
-
}
|
|
1483
|
-
function formatRelativeAge(thenMs, nowMs) {
|
|
1484
|
-
const deltaMs = Math.max(0, nowMs - thenMs);
|
|
1485
|
-
const minutes = Math.floor(deltaMs / 6e4);
|
|
1486
|
-
if (minutes < 1) return "just now";
|
|
1487
|
-
if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
1488
|
-
const hours = Math.floor(minutes / 60);
|
|
1489
|
-
if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
1490
|
-
const days = Math.floor(hours / 24);
|
|
1491
|
-
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
1492
|
-
}
|
|
1493
|
-
function isReportStale(lastRunMs, staleAfterDays, nowMs) {
|
|
1494
|
-
if (lastRunMs === void 0 || staleAfterDays <= 0) return false;
|
|
1495
|
-
return nowMs - lastRunMs >= staleAfterDays * 864e5;
|
|
1496
|
-
}
|
|
1497
|
-
var CI_DISPLAY_NAMES = {
|
|
1498
|
-
github: "GitHub Actions",
|
|
1499
|
-
gitlab: "GitLab CI",
|
|
1500
|
-
circleci: "CircleCI",
|
|
1501
|
-
jenkins: "Jenkins",
|
|
1502
|
-
azure: "Azure DevOps",
|
|
1503
|
-
buildkite: "Buildkite",
|
|
1504
|
-
travis: "Travis CI",
|
|
1505
|
-
ci: "CI"
|
|
1506
|
-
};
|
|
1507
|
-
function ciDisplayName(name) {
|
|
1508
|
-
return CI_DISPLAY_NAMES[name] ?? name;
|
|
1509
|
-
}
|
|
1510
|
-
function commitUrl(ci, sha) {
|
|
1511
|
-
const commitSha = ci?.commitSha ?? sha;
|
|
1512
|
-
if (!ci?.url || !commitSha) return void 0;
|
|
1513
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1514
|
-
if (github) return `${github[1]}/commit/${commitSha}`;
|
|
1515
|
-
const gitlab = ci.url.match(/^(https?:\/\/.+)\/-\/pipelines\//);
|
|
1516
|
-
if (gitlab) return `${gitlab[1]}/-/commit/${commitSha}`;
|
|
1517
|
-
return void 0;
|
|
1518
|
-
}
|
|
1519
|
-
function prUrl(ci) {
|
|
1520
|
-
if (!ci?.url || !ci.prNumber) return void 0;
|
|
1521
|
-
const github = ci.url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/actions\/runs\//);
|
|
1522
|
-
if (github) return `${github[1]}/pull/${ci.prNumber}`;
|
|
1523
|
-
return void 0;
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
// src/components/ReportMeta.tsx
|
|
1527
|
-
import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1633
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1528
1634
|
function ReportMeta() {
|
|
1529
1635
|
const report = useReport();
|
|
1530
1636
|
const items = [];
|
|
@@ -1547,13 +1653,13 @@ function ReportMeta() {
|
|
|
1547
1653
|
const short = sha.slice(0, 8);
|
|
1548
1654
|
items.push({
|
|
1549
1655
|
label: "Commit",
|
|
1550
|
-
value: url ? /* @__PURE__ */
|
|
1656
|
+
value: url ? /* @__PURE__ */ jsx34("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1551
1657
|
});
|
|
1552
1658
|
}
|
|
1553
1659
|
if (report.ci) {
|
|
1554
1660
|
items.push({
|
|
1555
1661
|
label: "CI",
|
|
1556
|
-
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: [
|
|
1557
1663
|
ciDisplayName(report.ci.name),
|
|
1558
1664
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1559
1665
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1564,7 +1670,7 @@ function ReportMeta() {
|
|
|
1564
1670
|
const label = `#${report.ci.prNumber}`;
|
|
1565
1671
|
items.push({
|
|
1566
1672
|
label: "PR",
|
|
1567
|
-
value: url ? /* @__PURE__ */
|
|
1673
|
+
value: url ? /* @__PURE__ */ jsx34("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1568
1674
|
});
|
|
1569
1675
|
}
|
|
1570
1676
|
if (items.length === 0) return null;
|
|
@@ -1572,48 +1678,48 @@ function ReportMeta() {
|
|
|
1572
1678
|
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1573
1679
|
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1574
1680
|
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1575
|
-
/* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1577
|
-
/* @__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: [
|
|
1683
|
+
/* @__PURE__ */ jsx34("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1578
1684
|
"Run details"
|
|
1579
1685
|
] }),
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__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: [
|
|
1687
|
+
/* @__PURE__ */ jsx34("dt", { className: "font-medium", children: item.label }),
|
|
1688
|
+
/* @__PURE__ */ jsx34("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1583
1689
|
] }, item.label)) })
|
|
1584
1690
|
] })
|
|
1585
1691
|
);
|
|
1586
1692
|
}
|
|
1587
1693
|
|
|
1588
1694
|
// src/components/ReportSchemaError.tsx
|
|
1589
|
-
import { jsx as
|
|
1695
|
+
import { jsx as jsx35, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1590
1696
|
function ReportSchemaError({ error }) {
|
|
1591
|
-
return /* @__PURE__ */
|
|
1592
|
-
/* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1594
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */
|
|
1697
|
+
return /* @__PURE__ */ jsxs23("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1698
|
+
/* @__PURE__ */ jsx35("p", { children: /* @__PURE__ */ jsx35("strong", { children: "Report could not be displayed." }) }),
|
|
1699
|
+
/* @__PURE__ */ jsx35("p", { children: error.message }),
|
|
1700
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs23("p", { children: [
|
|
1595
1701
|
"The report bundle is newer than this version of ",
|
|
1596
|
-
/* @__PURE__ */
|
|
1702
|
+
/* @__PURE__ */ jsx35("code", { children: "executable-stories-react" }),
|
|
1597
1703
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1598
1704
|
] }) : null,
|
|
1599
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1705
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs23("details", { children: [
|
|
1706
|
+
/* @__PURE__ */ jsxs23("summary", { children: [
|
|
1601
1707
|
error.issues.length,
|
|
1602
1708
|
" validation issue",
|
|
1603
1709
|
error.issues.length === 1 ? "" : "s"
|
|
1604
1710
|
] }),
|
|
1605
|
-
/* @__PURE__ */
|
|
1711
|
+
/* @__PURE__ */ jsx35("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1606
1712
|
] }) : null
|
|
1607
1713
|
] });
|
|
1608
1714
|
}
|
|
1609
1715
|
|
|
1610
1716
|
// src/components/ReportShell.tsx
|
|
1611
|
-
import { Fragment as Fragment10, jsx as
|
|
1717
|
+
import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1612
1718
|
function ReportTitleBlock({ title }) {
|
|
1613
|
-
return /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1616
|
-
/* @__PURE__ */
|
|
1719
|
+
return /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
1720
|
+
/* @__PURE__ */ jsx36("h1", { children: title ?? "Story Report" }),
|
|
1721
|
+
/* @__PURE__ */ jsx36(ReportSummary, {}),
|
|
1722
|
+
/* @__PURE__ */ jsx36(ReportMeta, {})
|
|
1617
1723
|
] });
|
|
1618
1724
|
}
|
|
1619
1725
|
function ReportErrorShell({
|
|
@@ -1622,28 +1728,28 @@ function ReportErrorShell({
|
|
|
1622
1728
|
title,
|
|
1623
1729
|
dataTheme
|
|
1624
1730
|
}) {
|
|
1625
|
-
return /* @__PURE__ */
|
|
1731
|
+
return /* @__PURE__ */ jsx36("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx36(ReportSchemaError, { error }) });
|
|
1626
1732
|
}
|
|
1627
1733
|
|
|
1628
1734
|
// src/components/Report.tsx
|
|
1629
|
-
import { jsx as
|
|
1735
|
+
import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1630
1736
|
function Report(props) {
|
|
1631
1737
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1632
1738
|
const result = unwrapReport(report);
|
|
1633
1739
|
if (!result.ok) {
|
|
1634
|
-
return /* @__PURE__ */
|
|
1740
|
+
return /* @__PURE__ */ jsx37(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1635
1741
|
}
|
|
1636
1742
|
const data = result.data;
|
|
1637
1743
|
const hasContent = data.features.length > 0;
|
|
1638
|
-
return /* @__PURE__ */
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
hasContent ? /* @__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: [
|
|
1745
|
+
/* @__PURE__ */ jsx37("header", { className: "es-report-header", children: /* @__PURE__ */ jsx37(ReportTitleBlock, { title }) }),
|
|
1746
|
+
hasContent ? /* @__PURE__ */ jsx37(ReportFeatureList, {}) : /* @__PURE__ */ jsx37(ReportEmpty, {})
|
|
1641
1747
|
] }) });
|
|
1642
1748
|
}
|
|
1643
1749
|
|
|
1644
1750
|
// src/components/doc/MermaidView.tsx
|
|
1645
|
-
import { useEffect, useRef, useState as
|
|
1646
|
-
import { Fragment as Fragment11, jsx 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";
|
|
1647
1753
|
function prefersDark(el) {
|
|
1648
1754
|
const themed = el?.closest("[data-theme]");
|
|
1649
1755
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1652,9 +1758,9 @@ function prefersDark(el) {
|
|
|
1652
1758
|
}
|
|
1653
1759
|
function MermaidView({ entry, load }) {
|
|
1654
1760
|
const ref = useRef(null);
|
|
1655
|
-
const [svg, setSvg] =
|
|
1656
|
-
const [error, setError] =
|
|
1657
|
-
|
|
1761
|
+
const [svg, setSvg] = useState3(null);
|
|
1762
|
+
const [error, setError] = useState3(null);
|
|
1763
|
+
useEffect2(() => {
|
|
1658
1764
|
let cancelled = false;
|
|
1659
1765
|
const draw = async () => {
|
|
1660
1766
|
let mermaid;
|
|
@@ -1697,9 +1803,9 @@ function MermaidView({ entry, load }) {
|
|
|
1697
1803
|
};
|
|
1698
1804
|
}, [entry.code, load]);
|
|
1699
1805
|
if (svg) {
|
|
1700
|
-
return /* @__PURE__ */
|
|
1701
|
-
entry.title ? /* @__PURE__ */
|
|
1702
|
-
/* @__PURE__ */
|
|
1806
|
+
return /* @__PURE__ */ jsxs26("figure", { ref, className: "my-3", children: [
|
|
1807
|
+
entry.title ? /* @__PURE__ */ jsx38("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1808
|
+
/* @__PURE__ */ jsx38(
|
|
1703
1809
|
"div",
|
|
1704
1810
|
{
|
|
1705
1811
|
role: "img",
|
|
@@ -1710,8 +1816,8 @@ function MermaidView({ entry, load }) {
|
|
|
1710
1816
|
)
|
|
1711
1817
|
] });
|
|
1712
1818
|
}
|
|
1713
|
-
return /* @__PURE__ */
|
|
1714
|
-
error ? /* @__PURE__ */
|
|
1819
|
+
return /* @__PURE__ */ jsxs26(Fragment11, { children: [
|
|
1820
|
+
error ? /* @__PURE__ */ jsxs26(
|
|
1715
1821
|
"p",
|
|
1716
1822
|
{
|
|
1717
1823
|
role: "alert",
|
|
@@ -1723,34 +1829,34 @@ function MermaidView({ entry, load }) {
|
|
|
1723
1829
|
]
|
|
1724
1830
|
}
|
|
1725
1831
|
) : null,
|
|
1726
|
-
/* @__PURE__ */
|
|
1832
|
+
/* @__PURE__ */ jsx38(MermaidSource, { entry, ref })
|
|
1727
1833
|
] });
|
|
1728
1834
|
}
|
|
1729
1835
|
|
|
1730
1836
|
// src/components/doc/MermaidDiagram.tsx
|
|
1731
|
-
import { jsx as
|
|
1837
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
1732
1838
|
var mermaidLoader;
|
|
1733
1839
|
function loadMermaid() {
|
|
1734
1840
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1735
1841
|
return mermaidLoader;
|
|
1736
1842
|
}
|
|
1737
1843
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1738
|
-
return /* @__PURE__ */
|
|
1844
|
+
return /* @__PURE__ */ jsx39(MermaidView, { entry, load });
|
|
1739
1845
|
}
|
|
1740
1846
|
|
|
1741
1847
|
// src/components/ScenarioExplorer.tsx
|
|
1742
|
-
import { useState as
|
|
1848
|
+
import { useState as useState4 } from "react";
|
|
1743
1849
|
|
|
1744
1850
|
// src/components/ui/command.tsx
|
|
1745
1851
|
import "react";
|
|
1746
1852
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1747
1853
|
import { SearchIcon } from "lucide-react";
|
|
1748
|
-
import { jsx as
|
|
1854
|
+
import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1749
1855
|
function Command({
|
|
1750
1856
|
className,
|
|
1751
1857
|
...props
|
|
1752
1858
|
}) {
|
|
1753
|
-
return /* @__PURE__ */
|
|
1859
|
+
return /* @__PURE__ */ jsx40(
|
|
1754
1860
|
CommandPrimitive,
|
|
1755
1861
|
{
|
|
1756
1862
|
"data-slot": "command",
|
|
@@ -1766,14 +1872,14 @@ function CommandInput({
|
|
|
1766
1872
|
className,
|
|
1767
1873
|
...props
|
|
1768
1874
|
}) {
|
|
1769
|
-
return /* @__PURE__ */
|
|
1875
|
+
return /* @__PURE__ */ jsxs27(
|
|
1770
1876
|
"div",
|
|
1771
1877
|
{
|
|
1772
1878
|
"data-slot": "command-input-wrapper",
|
|
1773
1879
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1774
1880
|
children: [
|
|
1775
|
-
/* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
1881
|
+
/* @__PURE__ */ jsx40(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1882
|
+
/* @__PURE__ */ jsx40(
|
|
1777
1883
|
CommandPrimitive.Input,
|
|
1778
1884
|
{
|
|
1779
1885
|
"data-slot": "command-input",
|
|
@@ -1792,7 +1898,7 @@ function CommandList({
|
|
|
1792
1898
|
className,
|
|
1793
1899
|
...props
|
|
1794
1900
|
}) {
|
|
1795
|
-
return /* @__PURE__ */
|
|
1901
|
+
return /* @__PURE__ */ jsx40(
|
|
1796
1902
|
CommandPrimitive.List,
|
|
1797
1903
|
{
|
|
1798
1904
|
"data-slot": "command-list",
|
|
@@ -1807,7 +1913,7 @@ function CommandList({
|
|
|
1807
1913
|
function CommandEmpty({
|
|
1808
1914
|
...props
|
|
1809
1915
|
}) {
|
|
1810
|
-
return /* @__PURE__ */
|
|
1916
|
+
return /* @__PURE__ */ jsx40(
|
|
1811
1917
|
CommandPrimitive.Empty,
|
|
1812
1918
|
{
|
|
1813
1919
|
"data-slot": "command-empty",
|
|
@@ -1820,7 +1926,7 @@ function CommandGroup({
|
|
|
1820
1926
|
className,
|
|
1821
1927
|
...props
|
|
1822
1928
|
}) {
|
|
1823
|
-
return /* @__PURE__ */
|
|
1929
|
+
return /* @__PURE__ */ jsx40(
|
|
1824
1930
|
CommandPrimitive.Group,
|
|
1825
1931
|
{
|
|
1826
1932
|
"data-slot": "command-group",
|
|
@@ -1836,7 +1942,7 @@ function CommandItem({
|
|
|
1836
1942
|
className,
|
|
1837
1943
|
...props
|
|
1838
1944
|
}) {
|
|
1839
|
-
return /* @__PURE__ */
|
|
1945
|
+
return /* @__PURE__ */ jsx40(
|
|
1840
1946
|
CommandPrimitive.Item,
|
|
1841
1947
|
{
|
|
1842
1948
|
"data-slot": "command-item",
|
|
@@ -1850,7 +1956,7 @@ function CommandItem({
|
|
|
1850
1956
|
}
|
|
1851
1957
|
|
|
1852
1958
|
// src/components/ScenarioExplorer.tsx
|
|
1853
|
-
import { jsx as
|
|
1959
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1854
1960
|
var STATUS_FILTERS = [
|
|
1855
1961
|
{ value: "all", label: "All" },
|
|
1856
1962
|
{ value: "passed", label: "Passed" },
|
|
@@ -1859,24 +1965,24 @@ var STATUS_FILTERS = [
|
|
|
1859
1965
|
{ value: "pending", label: "Pending" }
|
|
1860
1966
|
];
|
|
1861
1967
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1862
|
-
const [status, setStatus] =
|
|
1968
|
+
const [status, setStatus] = useState4("all");
|
|
1863
1969
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1864
|
-
return /* @__PURE__ */
|
|
1865
|
-
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: [
|
|
1866
1972
|
summary.total,
|
|
1867
1973
|
" scenarios \xB7 ",
|
|
1868
|
-
/* @__PURE__ */
|
|
1974
|
+
/* @__PURE__ */ jsxs28("span", { className: "text-pass", children: [
|
|
1869
1975
|
summary.passed,
|
|
1870
1976
|
" passed"
|
|
1871
1977
|
] }),
|
|
1872
1978
|
" \xB7",
|
|
1873
1979
|
" ",
|
|
1874
|
-
/* @__PURE__ */
|
|
1980
|
+
/* @__PURE__ */ jsxs28("span", { className: "text-fail", children: [
|
|
1875
1981
|
summary.failed,
|
|
1876
1982
|
" failed"
|
|
1877
1983
|
] })
|
|
1878
1984
|
] }) : null,
|
|
1879
|
-
/* @__PURE__ */
|
|
1985
|
+
/* @__PURE__ */ jsx41("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx41(
|
|
1880
1986
|
"button",
|
|
1881
1987
|
{
|
|
1882
1988
|
type: "button",
|
|
@@ -1891,26 +1997,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1891
1997
|
},
|
|
1892
1998
|
f.value
|
|
1893
1999
|
)) }),
|
|
1894
|
-
/* @__PURE__ */
|
|
2000
|
+
/* @__PURE__ */ jsxs28(
|
|
1895
2001
|
Command,
|
|
1896
2002
|
{
|
|
1897
2003
|
className: "rounded-lg border border-border bg-card",
|
|
1898
2004
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1899
2005
|
children: [
|
|
1900
|
-
/* @__PURE__ */
|
|
1901
|
-
/* @__PURE__ */
|
|
1902
|
-
/* @__PURE__ */
|
|
1903
|
-
/* @__PURE__ */
|
|
2006
|
+
/* @__PURE__ */ jsx41(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
2007
|
+
/* @__PURE__ */ jsxs28(CommandList, { className: "max-h-none", children: [
|
|
2008
|
+
/* @__PURE__ */ jsx41(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
2009
|
+
/* @__PURE__ */ jsx41(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx41(
|
|
1904
2010
|
CommandItem,
|
|
1905
2011
|
{
|
|
1906
2012
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1907
2013
|
asChild: true,
|
|
1908
2014
|
className: "cursor-pointer",
|
|
1909
|
-
children: /* @__PURE__ */
|
|
1910
|
-
/* @__PURE__ */
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
2015
|
+
children: /* @__PURE__ */ jsxs28("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
2016
|
+
/* @__PURE__ */ jsx41(Badge, { variant: s.status, children: s.status }),
|
|
2017
|
+
/* @__PURE__ */ jsx41("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
2018
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx41(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
2019
|
+
/* @__PURE__ */ jsx41("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
1914
2020
|
] })
|
|
1915
2021
|
},
|
|
1916
2022
|
s.id
|
|
@@ -2057,7 +2163,7 @@ var story_report_v1_default = {
|
|
|
2057
2163
|
title: {
|
|
2058
2164
|
type: "string",
|
|
2059
2165
|
minLength: 1,
|
|
2060
|
-
description: "Display title.
|
|
2166
|
+
description: "Display title. Comes from story.feature(...) when declared, otherwise the describe block or file basename."
|
|
2061
2167
|
},
|
|
2062
2168
|
sourceFile: {
|
|
2063
2169
|
type: "string",
|
|
@@ -2073,15 +2179,25 @@ var story_report_v1_default = {
|
|
|
2073
2179
|
$ref: "#/$defs/Scenario"
|
|
2074
2180
|
},
|
|
2075
2181
|
description: "Scenarios in this feature, in declaration order."
|
|
2182
|
+
},
|
|
2183
|
+
kind: {
|
|
2184
|
+
type: "string",
|
|
2185
|
+
enum: ["feature", "ability", "business-need"],
|
|
2186
|
+
description: "How the feature was declared. Absent when the title was derived rather than declared."
|
|
2187
|
+
},
|
|
2188
|
+
narrative: {
|
|
2189
|
+
type: "string",
|
|
2190
|
+
description: "Markdown explaining why the feature exists and who it serves."
|
|
2191
|
+
},
|
|
2192
|
+
glossary: {
|
|
2193
|
+
type: "array",
|
|
2194
|
+
items: {
|
|
2195
|
+
$ref: "#/$defs/GlossaryTerm"
|
|
2196
|
+
},
|
|
2197
|
+
description: "Terms this feature defines, linked wherever they appear in scenario text."
|
|
2076
2198
|
}
|
|
2077
2199
|
},
|
|
2078
|
-
required: [
|
|
2079
|
-
"id",
|
|
2080
|
-
"title",
|
|
2081
|
-
"sourceFile",
|
|
2082
|
-
"summary",
|
|
2083
|
-
"scenarios"
|
|
2084
|
-
],
|
|
2200
|
+
required: ["id", "title", "sourceFile", "summary", "scenarios"],
|
|
2085
2201
|
additionalProperties: false
|
|
2086
2202
|
},
|
|
2087
2203
|
Scenario: {
|
|
@@ -2211,6 +2327,11 @@ var story_report_v1_default = {
|
|
|
2211
2327
|
type: "number",
|
|
2212
2328
|
minimum: 0
|
|
2213
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
|
+
},
|
|
2214
2335
|
errorMessage: {
|
|
2215
2336
|
type: "string"
|
|
2216
2337
|
},
|
|
@@ -2238,33 +2359,15 @@ var story_report_v1_default = {
|
|
|
2238
2359
|
},
|
|
2239
2360
|
StepKeyword: {
|
|
2240
2361
|
type: "string",
|
|
2241
|
-
enum: [
|
|
2242
|
-
"Given",
|
|
2243
|
-
"When",
|
|
2244
|
-
"Then",
|
|
2245
|
-
"And",
|
|
2246
|
-
"But"
|
|
2247
|
-
]
|
|
2362
|
+
enum: ["Given", "When", "Then", "And", "But"]
|
|
2248
2363
|
},
|
|
2249
2364
|
StepMode: {
|
|
2250
2365
|
type: "string",
|
|
2251
|
-
enum: [
|
|
2252
|
-
"normal",
|
|
2253
|
-
"skip",
|
|
2254
|
-
"only",
|
|
2255
|
-
"todo",
|
|
2256
|
-
"fails",
|
|
2257
|
-
"concurrent"
|
|
2258
|
-
]
|
|
2366
|
+
enum: ["normal", "skip", "only", "todo", "fails", "concurrent"]
|
|
2259
2367
|
},
|
|
2260
2368
|
TestStatus: {
|
|
2261
2369
|
type: "string",
|
|
2262
|
-
enum: [
|
|
2263
|
-
"passed",
|
|
2264
|
-
"failed",
|
|
2265
|
-
"skipped",
|
|
2266
|
-
"pending"
|
|
2267
|
-
]
|
|
2370
|
+
enum: ["passed", "failed", "skipped", "pending"]
|
|
2268
2371
|
},
|
|
2269
2372
|
Ticket: {
|
|
2270
2373
|
type: "object",
|
|
@@ -2277,9 +2380,7 @@ var story_report_v1_default = {
|
|
|
2277
2380
|
type: "string"
|
|
2278
2381
|
}
|
|
2279
2382
|
},
|
|
2280
|
-
required: [
|
|
2281
|
-
"id"
|
|
2282
|
-
],
|
|
2383
|
+
required: ["id"],
|
|
2283
2384
|
additionalProperties: false
|
|
2284
2385
|
},
|
|
2285
2386
|
Attachment: {
|
|
@@ -2297,18 +2398,10 @@ var story_report_v1_default = {
|
|
|
2297
2398
|
},
|
|
2298
2399
|
contentEncoding: {
|
|
2299
2400
|
type: "string",
|
|
2300
|
-
enum: [
|
|
2301
|
-
"BASE64",
|
|
2302
|
-
"IDENTITY"
|
|
2303
|
-
]
|
|
2401
|
+
enum: ["BASE64", "IDENTITY"]
|
|
2304
2402
|
}
|
|
2305
2403
|
},
|
|
2306
|
-
required: [
|
|
2307
|
-
"name",
|
|
2308
|
-
"mediaType",
|
|
2309
|
-
"body",
|
|
2310
|
-
"contentEncoding"
|
|
2311
|
-
],
|
|
2404
|
+
required: ["name", "mediaType", "body", "contentEncoding"],
|
|
2312
2405
|
additionalProperties: false
|
|
2313
2406
|
},
|
|
2314
2407
|
CIInfo: {
|
|
@@ -2333,9 +2426,7 @@ var story_report_v1_default = {
|
|
|
2333
2426
|
type: "string"
|
|
2334
2427
|
}
|
|
2335
2428
|
},
|
|
2336
|
-
required: [
|
|
2337
|
-
"name"
|
|
2338
|
-
],
|
|
2429
|
+
required: ["name"],
|
|
2339
2430
|
additionalProperties: false
|
|
2340
2431
|
},
|
|
2341
2432
|
CoverageSummary: {
|
|
@@ -2366,10 +2457,7 @@ var story_report_v1_default = {
|
|
|
2366
2457
|
},
|
|
2367
2458
|
DocPhase: {
|
|
2368
2459
|
type: "string",
|
|
2369
|
-
enum: [
|
|
2370
|
-
"static",
|
|
2371
|
-
"runtime"
|
|
2372
|
-
]
|
|
2460
|
+
enum: ["static", "runtime"]
|
|
2373
2461
|
},
|
|
2374
2462
|
DocEntry: {
|
|
2375
2463
|
oneOf: [
|
|
@@ -2433,11 +2521,7 @@ var story_report_v1_default = {
|
|
|
2433
2521
|
}
|
|
2434
2522
|
}
|
|
2435
2523
|
},
|
|
2436
|
-
required: [
|
|
2437
|
-
"kind",
|
|
2438
|
-
"text",
|
|
2439
|
-
"phase"
|
|
2440
|
-
],
|
|
2524
|
+
required: ["kind", "text", "phase"],
|
|
2441
2525
|
additionalProperties: false
|
|
2442
2526
|
},
|
|
2443
2527
|
DocTag: {
|
|
@@ -2462,11 +2546,7 @@ var story_report_v1_default = {
|
|
|
2462
2546
|
}
|
|
2463
2547
|
}
|
|
2464
2548
|
},
|
|
2465
|
-
required: [
|
|
2466
|
-
"kind",
|
|
2467
|
-
"names",
|
|
2468
|
-
"phase"
|
|
2469
|
-
],
|
|
2549
|
+
required: ["kind", "names", "phase"],
|
|
2470
2550
|
additionalProperties: false
|
|
2471
2551
|
},
|
|
2472
2552
|
DocKv: {
|
|
@@ -2489,12 +2569,7 @@ var story_report_v1_default = {
|
|
|
2489
2569
|
}
|
|
2490
2570
|
}
|
|
2491
2571
|
},
|
|
2492
|
-
required: [
|
|
2493
|
-
"kind",
|
|
2494
|
-
"label",
|
|
2495
|
-
"value",
|
|
2496
|
-
"phase"
|
|
2497
|
-
],
|
|
2572
|
+
required: ["kind", "label", "value", "phase"],
|
|
2498
2573
|
additionalProperties: false
|
|
2499
2574
|
},
|
|
2500
2575
|
DocCode: {
|
|
@@ -2522,12 +2597,7 @@ var story_report_v1_default = {
|
|
|
2522
2597
|
}
|
|
2523
2598
|
}
|
|
2524
2599
|
},
|
|
2525
|
-
required: [
|
|
2526
|
-
"kind",
|
|
2527
|
-
"label",
|
|
2528
|
-
"content",
|
|
2529
|
-
"phase"
|
|
2530
|
-
],
|
|
2600
|
+
required: ["kind", "label", "content", "phase"],
|
|
2531
2601
|
additionalProperties: false
|
|
2532
2602
|
},
|
|
2533
2603
|
DocTable: {
|
|
@@ -2564,13 +2634,7 @@ var story_report_v1_default = {
|
|
|
2564
2634
|
}
|
|
2565
2635
|
}
|
|
2566
2636
|
},
|
|
2567
|
-
required: [
|
|
2568
|
-
"kind",
|
|
2569
|
-
"label",
|
|
2570
|
-
"columns",
|
|
2571
|
-
"rows",
|
|
2572
|
-
"phase"
|
|
2573
|
-
],
|
|
2637
|
+
required: ["kind", "label", "columns", "rows", "phase"],
|
|
2574
2638
|
additionalProperties: false
|
|
2575
2639
|
},
|
|
2576
2640
|
DocLink: {
|
|
@@ -2595,12 +2659,7 @@ var story_report_v1_default = {
|
|
|
2595
2659
|
}
|
|
2596
2660
|
}
|
|
2597
2661
|
},
|
|
2598
|
-
required: [
|
|
2599
|
-
"kind",
|
|
2600
|
-
"label",
|
|
2601
|
-
"url",
|
|
2602
|
-
"phase"
|
|
2603
|
-
],
|
|
2662
|
+
required: ["kind", "label", "url", "phase"],
|
|
2604
2663
|
additionalProperties: false
|
|
2605
2664
|
},
|
|
2606
2665
|
DocSection: {
|
|
@@ -2625,12 +2684,7 @@ var story_report_v1_default = {
|
|
|
2625
2684
|
}
|
|
2626
2685
|
}
|
|
2627
2686
|
},
|
|
2628
|
-
required: [
|
|
2629
|
-
"kind",
|
|
2630
|
-
"title",
|
|
2631
|
-
"markdown",
|
|
2632
|
-
"phase"
|
|
2633
|
-
],
|
|
2687
|
+
required: ["kind", "title", "markdown", "phase"],
|
|
2634
2688
|
additionalProperties: false
|
|
2635
2689
|
},
|
|
2636
2690
|
DocMermaid: {
|
|
@@ -2655,11 +2709,7 @@ var story_report_v1_default = {
|
|
|
2655
2709
|
}
|
|
2656
2710
|
}
|
|
2657
2711
|
},
|
|
2658
|
-
required: [
|
|
2659
|
-
"kind",
|
|
2660
|
-
"code",
|
|
2661
|
-
"phase"
|
|
2662
|
-
],
|
|
2712
|
+
required: ["kind", "code", "phase"],
|
|
2663
2713
|
additionalProperties: false
|
|
2664
2714
|
},
|
|
2665
2715
|
DocScreenshot: {
|
|
@@ -2684,11 +2734,7 @@ var story_report_v1_default = {
|
|
|
2684
2734
|
}
|
|
2685
2735
|
}
|
|
2686
2736
|
},
|
|
2687
|
-
required: [
|
|
2688
|
-
"kind",
|
|
2689
|
-
"path",
|
|
2690
|
-
"phase"
|
|
2691
|
-
],
|
|
2737
|
+
required: ["kind", "path", "phase"],
|
|
2692
2738
|
additionalProperties: false
|
|
2693
2739
|
},
|
|
2694
2740
|
DocVideo: {
|
|
@@ -2716,11 +2762,7 @@ var story_report_v1_default = {
|
|
|
2716
2762
|
}
|
|
2717
2763
|
}
|
|
2718
2764
|
},
|
|
2719
|
-
required: [
|
|
2720
|
-
"kind",
|
|
2721
|
-
"path",
|
|
2722
|
-
"phase"
|
|
2723
|
-
],
|
|
2765
|
+
required: ["kind", "path", "phase"],
|
|
2724
2766
|
additionalProperties: false
|
|
2725
2767
|
},
|
|
2726
2768
|
DocHtml: {
|
|
@@ -2761,26 +2803,17 @@ var story_report_v1_default = {
|
|
|
2761
2803
|
}
|
|
2762
2804
|
}
|
|
2763
2805
|
},
|
|
2764
|
-
required: [
|
|
2765
|
-
"kind",
|
|
2766
|
-
"phase"
|
|
2767
|
-
],
|
|
2806
|
+
required: ["kind", "phase"],
|
|
2768
2807
|
additionalProperties: false,
|
|
2769
2808
|
oneOf: [
|
|
2770
2809
|
{
|
|
2771
|
-
required: [
|
|
2772
|
-
"path"
|
|
2773
|
-
]
|
|
2810
|
+
required: ["path"]
|
|
2774
2811
|
},
|
|
2775
2812
|
{
|
|
2776
|
-
required: [
|
|
2777
|
-
"url"
|
|
2778
|
-
]
|
|
2813
|
+
required: ["url"]
|
|
2779
2814
|
},
|
|
2780
2815
|
{
|
|
2781
|
-
required: [
|
|
2782
|
-
"content"
|
|
2783
|
-
]
|
|
2816
|
+
required: ["content"]
|
|
2784
2817
|
}
|
|
2785
2818
|
]
|
|
2786
2819
|
},
|
|
@@ -2804,11 +2837,7 @@ var story_report_v1_default = {
|
|
|
2804
2837
|
}
|
|
2805
2838
|
}
|
|
2806
2839
|
},
|
|
2807
|
-
required: [
|
|
2808
|
-
"kind",
|
|
2809
|
-
"value",
|
|
2810
|
-
"phase"
|
|
2811
|
-
],
|
|
2840
|
+
required: ["kind", "value", "phase"],
|
|
2812
2841
|
additionalProperties: false
|
|
2813
2842
|
},
|
|
2814
2843
|
DocCustom: {
|
|
@@ -2832,21 +2861,12 @@ var story_report_v1_default = {
|
|
|
2832
2861
|
}
|
|
2833
2862
|
}
|
|
2834
2863
|
},
|
|
2835
|
-
required: [
|
|
2836
|
-
"kind",
|
|
2837
|
-
"type",
|
|
2838
|
-
"data",
|
|
2839
|
-
"phase"
|
|
2840
|
-
],
|
|
2864
|
+
required: ["kind", "type", "data", "phase"],
|
|
2841
2865
|
additionalProperties: false
|
|
2842
2866
|
},
|
|
2843
2867
|
OtelSpan: {
|
|
2844
2868
|
type: "object",
|
|
2845
|
-
required: [
|
|
2846
|
-
"spanId",
|
|
2847
|
-
"name",
|
|
2848
|
-
"status"
|
|
2849
|
-
],
|
|
2869
|
+
required: ["spanId", "name", "status"],
|
|
2850
2870
|
properties: {
|
|
2851
2871
|
spanId: {
|
|
2852
2872
|
type: "string"
|
|
@@ -2870,11 +2890,7 @@ var story_report_v1_default = {
|
|
|
2870
2890
|
type: "number"
|
|
2871
2891
|
},
|
|
2872
2892
|
status: {
|
|
2873
|
-
enum: [
|
|
2874
|
-
"ok",
|
|
2875
|
-
"error",
|
|
2876
|
-
"unset"
|
|
2877
|
-
]
|
|
2893
|
+
enum: ["ok", "error", "unset"]
|
|
2878
2894
|
},
|
|
2879
2895
|
statusMessage: {
|
|
2880
2896
|
type: "string"
|
|
@@ -2884,6 +2900,22 @@ var story_report_v1_default = {
|
|
|
2884
2900
|
}
|
|
2885
2901
|
},
|
|
2886
2902
|
additionalProperties: false
|
|
2903
|
+
},
|
|
2904
|
+
GlossaryTerm: {
|
|
2905
|
+
type: "object",
|
|
2906
|
+
description: "One glossary entry: a term the scenarios use and what it means.",
|
|
2907
|
+
properties: {
|
|
2908
|
+
term: {
|
|
2909
|
+
type: "string",
|
|
2910
|
+
minLength: 1
|
|
2911
|
+
},
|
|
2912
|
+
definition: {
|
|
2913
|
+
type: "string",
|
|
2914
|
+
minLength: 1
|
|
2915
|
+
}
|
|
2916
|
+
},
|
|
2917
|
+
required: ["term", "definition"],
|
|
2918
|
+
additionalProperties: false
|
|
2887
2919
|
}
|
|
2888
2920
|
}
|
|
2889
2921
|
};
|
|
@@ -2985,6 +3017,7 @@ export {
|
|
|
2985
3017
|
parseStoryReport,
|
|
2986
3018
|
prUrl,
|
|
2987
3019
|
reportLastRunMs,
|
|
3020
|
+
scenarioLastRunMs,
|
|
2988
3021
|
storyReportSchema,
|
|
2989
3022
|
useBuiltinRenderers,
|
|
2990
3023
|
useCustomRenderers,
|