executable-stories-formatters 0.7.12 → 0.7.13
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/adapters.cjs +9 -2
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- package/dist/adapters.js +9 -2
- package/dist/adapters.js.map +1 -1
- package/dist/cli.js +134 -11
- package/dist/cli.js.map +1 -1
- package/dist/{index-C0OOaaiK.d.cts → index-fqrm5-Xr.d.cts} +34 -24
- package/dist/{index-C0OOaaiK.d.ts → index-fqrm5-Xr.d.ts} +34 -24
- package/dist/index.cjs +143 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -9
- package/dist/index.d.ts +7 -9
- package/dist/index.js +143 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import { S as StoryMeta, C as CIInfo$1, a as StoryStep, D as DocEntry, N as NormalizedTicket, O as OtelSpan, b as CIProvider,
|
|
2
|
-
export { i as DocPhase, J as JestAdapterOptions, j as JestAggregatedResult, k as JestFileResult, l as JestTestResult, m as OtelAttributeValue, P as PlaywrightAdapterOptions, n as PlaywrightAnnotation, o as PlaywrightAttachment, p as PlaywrightError, q as PlaywrightLocation, r as PlaywrightStatus, s as PlaywrightTestCase, t as PlaywrightTestResult, u as RawStepEvent, v as RawTestCase, w as STORY_META_KEY, x as StepKeyword, y as StepMode, z as StoryFileReport, V as VitestAdapterOptions, A as VitestSerializedError, B as VitestState, E as VitestTestCase, F as VitestTestModule, G as VitestTestResult, H as toCIInfo, I as toRawCIInfo } from './index-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Canonical types for Layer 2: Anti-Corruption Layer output.
|
|
6
|
-
*
|
|
7
|
-
* These types are strict and have all required fields populated.
|
|
8
|
-
* Formatters (Layer 3) accept only these canonical types.
|
|
9
|
-
*/
|
|
1
|
+
import { S as StoryMeta, R as RawStatus, C as CIInfo$1, a as StoryStep, D as DocEntry, N as NormalizedTicket, O as OtelSpan, b as CIProvider, c as RawAttachment, d as RawRun, e as RawCIInfo, f as adaptJestRun, g as adaptPlaywrightRun, h as adaptVitestRun } from './index-fqrm5-Xr.cjs';
|
|
2
|
+
export { i as DocPhase, J as JestAdapterOptions, j as JestAggregatedResult, k as JestFileResult, l as JestTestResult, m as OtelAttributeValue, P as PlaywrightAdapterOptions, n as PlaywrightAnnotation, o as PlaywrightAttachment, p as PlaywrightError, q as PlaywrightLocation, r as PlaywrightStatus, s as PlaywrightTestCase, t as PlaywrightTestResult, u as RawStepEvent, v as RawTestCase, w as STORY_META_KEY, x as StepKeyword, y as StepMode, z as StoryFileReport, V as VitestAdapterOptions, A as VitestSerializedError, B as VitestState, E as VitestTestCase, F as VitestTestModule, G as VitestTestResult, H as toCIInfo, I as toRawCIInfo } from './index-fqrm5-Xr.cjs';
|
|
10
3
|
|
|
11
4
|
/** Canonical test status (Cucumber-compatible) */
|
|
12
5
|
type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
@@ -14,6 +7,8 @@ type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
|
14
7
|
interface StepResult {
|
|
15
8
|
/** Step index (0-based) */
|
|
16
9
|
index: number;
|
|
10
|
+
/** Stable step ID when available */
|
|
11
|
+
stepId?: string;
|
|
17
12
|
/** Step status */
|
|
18
13
|
status: TestStatus;
|
|
19
14
|
/** Duration in milliseconds (default 0) */
|
|
@@ -57,6 +52,8 @@ interface TestCaseResult {
|
|
|
57
52
|
sourceLine: number;
|
|
58
53
|
/** Test status (required) */
|
|
59
54
|
status: TestStatus;
|
|
55
|
+
/** Original adapter/framework status (preserved for diagnostics). */
|
|
56
|
+
rawStatus?: RawStatus;
|
|
60
57
|
/** Duration in milliseconds (required, default 0) */
|
|
61
58
|
durationMs: number;
|
|
62
59
|
/** Error message if failed */
|
|
@@ -1094,6 +1091,7 @@ declare function deriveStepResults(steps: StoryStep[], scenarioStatus: TestStatu
|
|
|
1094
1091
|
*/
|
|
1095
1092
|
declare function mergeStepResults(derived: StepResult[], events?: Array<{
|
|
1096
1093
|
index?: number;
|
|
1094
|
+
stepId?: string;
|
|
1097
1095
|
status?: string;
|
|
1098
1096
|
durationMs?: number;
|
|
1099
1097
|
errorMessage?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import { S as StoryMeta, C as CIInfo$1, a as StoryStep, D as DocEntry, N as NormalizedTicket, O as OtelSpan, b as CIProvider,
|
|
2
|
-
export { i as DocPhase, J as JestAdapterOptions, j as JestAggregatedResult, k as JestFileResult, l as JestTestResult, m as OtelAttributeValue, P as PlaywrightAdapterOptions, n as PlaywrightAnnotation, o as PlaywrightAttachment, p as PlaywrightError, q as PlaywrightLocation, r as PlaywrightStatus, s as PlaywrightTestCase, t as PlaywrightTestResult, u as RawStepEvent, v as RawTestCase, w as STORY_META_KEY, x as StepKeyword, y as StepMode, z as StoryFileReport, V as VitestAdapterOptions, A as VitestSerializedError, B as VitestState, E as VitestTestCase, F as VitestTestModule, G as VitestTestResult, H as toCIInfo, I as toRawCIInfo } from './index-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Canonical types for Layer 2: Anti-Corruption Layer output.
|
|
6
|
-
*
|
|
7
|
-
* These types are strict and have all required fields populated.
|
|
8
|
-
* Formatters (Layer 3) accept only these canonical types.
|
|
9
|
-
*/
|
|
1
|
+
import { S as StoryMeta, R as RawStatus, C as CIInfo$1, a as StoryStep, D as DocEntry, N as NormalizedTicket, O as OtelSpan, b as CIProvider, c as RawAttachment, d as RawRun, e as RawCIInfo, f as adaptJestRun, g as adaptPlaywrightRun, h as adaptVitestRun } from './index-fqrm5-Xr.js';
|
|
2
|
+
export { i as DocPhase, J as JestAdapterOptions, j as JestAggregatedResult, k as JestFileResult, l as JestTestResult, m as OtelAttributeValue, P as PlaywrightAdapterOptions, n as PlaywrightAnnotation, o as PlaywrightAttachment, p as PlaywrightError, q as PlaywrightLocation, r as PlaywrightStatus, s as PlaywrightTestCase, t as PlaywrightTestResult, u as RawStepEvent, v as RawTestCase, w as STORY_META_KEY, x as StepKeyword, y as StepMode, z as StoryFileReport, V as VitestAdapterOptions, A as VitestSerializedError, B as VitestState, E as VitestTestCase, F as VitestTestModule, G as VitestTestResult, H as toCIInfo, I as toRawCIInfo } from './index-fqrm5-Xr.js';
|
|
10
3
|
|
|
11
4
|
/** Canonical test status (Cucumber-compatible) */
|
|
12
5
|
type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
@@ -14,6 +7,8 @@ type TestStatus = "passed" | "failed" | "skipped" | "pending";
|
|
|
14
7
|
interface StepResult {
|
|
15
8
|
/** Step index (0-based) */
|
|
16
9
|
index: number;
|
|
10
|
+
/** Stable step ID when available */
|
|
11
|
+
stepId?: string;
|
|
17
12
|
/** Step status */
|
|
18
13
|
status: TestStatus;
|
|
19
14
|
/** Duration in milliseconds (default 0) */
|
|
@@ -57,6 +52,8 @@ interface TestCaseResult {
|
|
|
57
52
|
sourceLine: number;
|
|
58
53
|
/** Test status (required) */
|
|
59
54
|
status: TestStatus;
|
|
55
|
+
/** Original adapter/framework status (preserved for diagnostics). */
|
|
56
|
+
rawStatus?: RawStatus;
|
|
60
57
|
/** Duration in milliseconds (required, default 0) */
|
|
61
58
|
durationMs: number;
|
|
62
59
|
/** Error message if failed */
|
|
@@ -1094,6 +1091,7 @@ declare function deriveStepResults(steps: StoryStep[], scenarioStatus: TestStatu
|
|
|
1094
1091
|
*/
|
|
1095
1092
|
declare function mergeStepResults(derived: StepResult[], events?: Array<{
|
|
1096
1093
|
index?: number;
|
|
1094
|
+
stepId?: string;
|
|
1097
1095
|
status?: string;
|
|
1098
1096
|
durationMs?: number;
|
|
1099
1097
|
errorMessage?: string;
|
package/dist/index.js
CHANGED
|
@@ -51,6 +51,7 @@ function deriveStepResults(steps, scenarioStatus, error) {
|
|
|
51
51
|
if (scenarioStatus === "passed") {
|
|
52
52
|
return steps.map((_, index) => ({
|
|
53
53
|
index,
|
|
54
|
+
stepId: steps[index].id,
|
|
54
55
|
status: "passed",
|
|
55
56
|
durationMs: 0
|
|
56
57
|
}));
|
|
@@ -58,6 +59,7 @@ function deriveStepResults(steps, scenarioStatus, error) {
|
|
|
58
59
|
if (scenarioStatus === "skipped" || scenarioStatus === "pending") {
|
|
59
60
|
return steps.map((_, index) => ({
|
|
60
61
|
index,
|
|
62
|
+
stepId: steps[index].id,
|
|
61
63
|
status: scenarioStatus,
|
|
62
64
|
durationMs: 0
|
|
63
65
|
}));
|
|
@@ -65,16 +67,17 @@ function deriveStepResults(steps, scenarioStatus, error) {
|
|
|
65
67
|
const failingIndex = findFailingStepIndex(steps, error);
|
|
66
68
|
return steps.map((_, index) => {
|
|
67
69
|
if (index < failingIndex) {
|
|
68
|
-
return { index, status: "passed", durationMs: 0 };
|
|
70
|
+
return { index, stepId: steps[index].id, status: "passed", durationMs: 0 };
|
|
69
71
|
} else if (index === failingIndex) {
|
|
70
72
|
return {
|
|
71
73
|
index,
|
|
74
|
+
stepId: steps[index].id,
|
|
72
75
|
status: "failed",
|
|
73
76
|
durationMs: 0,
|
|
74
77
|
errorMessage: error?.message
|
|
75
78
|
};
|
|
76
79
|
} else {
|
|
77
|
-
return { index, status: "skipped", durationMs: 0 };
|
|
80
|
+
return { index, stepId: steps[index].id, status: "skipped", durationMs: 0 };
|
|
78
81
|
}
|
|
79
82
|
});
|
|
80
83
|
}
|
|
@@ -96,18 +99,23 @@ function mergeStepResults(derived, events) {
|
|
|
96
99
|
return derived;
|
|
97
100
|
}
|
|
98
101
|
const actualByIndex = /* @__PURE__ */ new Map();
|
|
102
|
+
const actualByStepId = /* @__PURE__ */ new Map();
|
|
99
103
|
for (const event of events) {
|
|
100
104
|
if (event.index !== void 0) {
|
|
101
105
|
actualByIndex.set(event.index, event);
|
|
102
106
|
}
|
|
107
|
+
if (event.stepId) {
|
|
108
|
+
actualByStepId.set(event.stepId, event);
|
|
109
|
+
}
|
|
103
110
|
}
|
|
104
111
|
return derived.map((step) => {
|
|
105
|
-
const actual = actualByIndex.get(step.index);
|
|
112
|
+
const actual = (step.stepId ? actualByStepId.get(step.stepId) : void 0) ?? actualByIndex.get(step.index);
|
|
106
113
|
if (!actual) {
|
|
107
114
|
return step;
|
|
108
115
|
}
|
|
109
116
|
return {
|
|
110
117
|
index: step.index,
|
|
118
|
+
stepId: step.stepId ?? actual.stepId,
|
|
111
119
|
status: normalizeStepStatus(actual.status) ?? step.status,
|
|
112
120
|
durationMs: actual.durationMs ?? step.durationMs,
|
|
113
121
|
errorMessage: actual.errorMessage ?? step.errorMessage
|
|
@@ -241,6 +249,7 @@ function canonicalizeTestCase(raw, options, projectRoot) {
|
|
|
241
249
|
derivedSteps,
|
|
242
250
|
raw.stepEvents?.map((e) => ({
|
|
243
251
|
index: e.index,
|
|
252
|
+
stepId: e.stepId,
|
|
244
253
|
status: e.status,
|
|
245
254
|
durationMs: e.durationMs,
|
|
246
255
|
errorMessage: e.errorMessage
|
|
@@ -262,6 +271,7 @@ function canonicalizeTestCase(raw, options, projectRoot) {
|
|
|
262
271
|
sourceFile,
|
|
263
272
|
sourceLine: raw.sourceLine ?? 1,
|
|
264
273
|
status,
|
|
274
|
+
rawStatus: raw.status,
|
|
265
275
|
durationMs: raw.durationMs ?? 0,
|
|
266
276
|
errorMessage: raw.error?.message,
|
|
267
277
|
errorStack: raw.error?.stack,
|
|
@@ -629,19 +639,34 @@ ${doc.markdown}`,
|
|
|
629
639
|
}
|
|
630
640
|
};
|
|
631
641
|
}
|
|
632
|
-
case "
|
|
642
|
+
case "custom":
|
|
643
|
+
if (doc.type === "visual" && doc.data && typeof doc.data === "object") {
|
|
644
|
+
const data = doc.data;
|
|
645
|
+
const status = typeof data.status === "string" ? data.status : "unknown";
|
|
646
|
+
const lines = [`Visual Check (${status})`];
|
|
647
|
+
if (typeof data.baseline === "string") lines.push(`Baseline: ${data.baseline}`);
|
|
648
|
+
if (typeof data.actual === "string") lines.push(`Actual: ${data.actual}`);
|
|
649
|
+
if (typeof data.diff === "string") lines.push(`Diff: ${data.diff}`);
|
|
650
|
+
return {
|
|
651
|
+
doc_string: {
|
|
652
|
+
content: lines.join("\n"),
|
|
653
|
+
content_type: "text/plain",
|
|
654
|
+
line: 0
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
}
|
|
633
658
|
return {
|
|
634
659
|
doc_string: {
|
|
635
|
-
content: doc.
|
|
636
|
-
content_type: "
|
|
660
|
+
content: JSON.stringify(doc.data, null, 2),
|
|
661
|
+
content_type: "application/json",
|
|
637
662
|
line: 0
|
|
638
663
|
}
|
|
639
664
|
};
|
|
640
|
-
case "
|
|
665
|
+
case "tag":
|
|
641
666
|
return {
|
|
642
667
|
doc_string: {
|
|
643
|
-
content:
|
|
644
|
-
content_type: "
|
|
668
|
+
content: doc.names.map((n) => `@${n}`).join(" "),
|
|
669
|
+
content_type: "text/plain",
|
|
645
670
|
line: 0
|
|
646
671
|
}
|
|
647
672
|
};
|
|
@@ -2159,6 +2184,14 @@ body {
|
|
|
2159
2184
|
font-family: var(--font-mono);
|
|
2160
2185
|
}
|
|
2161
2186
|
|
|
2187
|
+
.outcome-tag {
|
|
2188
|
+
background: var(--status-fail-bg, color-mix(in srgb, var(--destructive, #ef4444) 12%, transparent));
|
|
2189
|
+
color: var(--destructive, #b91c1c);
|
|
2190
|
+
border-color: color-mix(in srgb, var(--destructive, #ef4444) 35%, transparent);
|
|
2191
|
+
text-transform: uppercase;
|
|
2192
|
+
letter-spacing: 0.04em;
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2162
2195
|
.scenario-duration {
|
|
2163
2196
|
font-size: 0.75rem;
|
|
2164
2197
|
color: var(--muted-foreground);
|
|
@@ -2922,6 +2955,63 @@ body {
|
|
|
2922
2955
|
opacity: 0.8;
|
|
2923
2956
|
}
|
|
2924
2957
|
|
|
2958
|
+
/* ============================================================================
|
|
2959
|
+
Documentation Entries - Visual Check
|
|
2960
|
+
============================================================================ */
|
|
2961
|
+
.doc-visual {
|
|
2962
|
+
margin-bottom: 0.5rem;
|
|
2963
|
+
padding: 0.75rem;
|
|
2964
|
+
border: 1px solid var(--border);
|
|
2965
|
+
border-radius: calc(var(--radius) - 2px);
|
|
2966
|
+
background: var(--muted, transparent);
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
.doc-visual:last-child {
|
|
2970
|
+
margin-bottom: 0;
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
.doc-visual-header {
|
|
2974
|
+
font-size: 0.8125rem;
|
|
2975
|
+
font-weight: 600;
|
|
2976
|
+
margin-bottom: 0.5rem;
|
|
2977
|
+
display: flex;
|
|
2978
|
+
align-items: center;
|
|
2979
|
+
gap: 0.5rem;
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
.doc-visual-status {
|
|
2983
|
+
font-size: 0.6875rem;
|
|
2984
|
+
font-family: var(--font-mono);
|
|
2985
|
+
font-weight: 500;
|
|
2986
|
+
padding: 0.125rem 0.5rem;
|
|
2987
|
+
border-radius: 9999px;
|
|
2988
|
+
background: var(--tag-bg);
|
|
2989
|
+
color: var(--tag-color);
|
|
2990
|
+
border: 1px solid var(--tag-border);
|
|
2991
|
+
text-transform: uppercase;
|
|
2992
|
+
letter-spacing: 0.04em;
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
.doc-visual-grid {
|
|
2996
|
+
display: grid;
|
|
2997
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
2998
|
+
gap: 0.5rem;
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
.doc-visual-item {
|
|
3002
|
+
display: flex;
|
|
3003
|
+
flex-direction: column;
|
|
3004
|
+
gap: 0.25rem;
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
.doc-visual-label {
|
|
3008
|
+
font-size: 0.6875rem;
|
|
3009
|
+
font-weight: 600;
|
|
3010
|
+
color: var(--muted-foreground);
|
|
3011
|
+
text-transform: uppercase;
|
|
3012
|
+
letter-spacing: 0.04em;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2925
3015
|
/* ============================================================================
|
|
2926
3016
|
Documentation Entries - Custom
|
|
2927
3017
|
============================================================================ */
|
|
@@ -13044,6 +13134,22 @@ function renderDocScreenshot(entry, deps) {
|
|
|
13044
13134
|
</div>`;
|
|
13045
13135
|
}
|
|
13046
13136
|
function renderDocCustom(entry, deps) {
|
|
13137
|
+
if (entry.type === "visual" && entry.data && typeof entry.data === "object") {
|
|
13138
|
+
const data = entry.data;
|
|
13139
|
+
const status = typeof data.status === "string" ? data.status : "unknown";
|
|
13140
|
+
const baseline = typeof data.baseline === "string" ? data.baseline : void 0;
|
|
13141
|
+
const actual = typeof data.actual === "string" ? data.actual : void 0;
|
|
13142
|
+
const diff = typeof data.diff === "string" ? data.diff : void 0;
|
|
13143
|
+
const maybeImg = (src, label) => src ? `<div class="doc-visual-item"><div class="doc-visual-label">${deps.escapeHtml(label ?? "")}</div><img src="${deps.escapeHtml(src)}" alt="${deps.escapeHtml(label ?? "visual image")}" class="doc-screenshot-img" /></div>` : "";
|
|
13144
|
+
return `<div class="doc-visual">
|
|
13145
|
+
<div class="doc-visual-header">Visual Check <span class="doc-visual-status">${deps.escapeHtml(status)}</span></div>
|
|
13146
|
+
<div class="doc-visual-grid">
|
|
13147
|
+
${maybeImg(baseline, "Baseline")}
|
|
13148
|
+
${maybeImg(actual, "Actual")}
|
|
13149
|
+
${maybeImg(diff, "Diff")}
|
|
13150
|
+
</div>
|
|
13151
|
+
</div>`;
|
|
13152
|
+
}
|
|
13047
13153
|
const dataStr = JSON.stringify(entry.data, null, 2);
|
|
13048
13154
|
return `<div class="doc-custom">
|
|
13049
13155
|
<div class="doc-custom-type">${deps.escapeHtml(entry.type)}</div>
|
|
@@ -13112,8 +13218,11 @@ function renderStep(step, stepResult, index, deps) {
|
|
|
13112
13218
|
</div>${stepDocs}`;
|
|
13113
13219
|
}
|
|
13114
13220
|
function renderSteps(args, deps) {
|
|
13221
|
+
const byStepId = new Map(
|
|
13222
|
+
args.stepResults.filter((sr) => typeof sr.stepId === "string" && sr.stepId.length > 0).map((sr) => [sr.stepId, sr])
|
|
13223
|
+
);
|
|
13115
13224
|
const stepsHtml = args.steps.map((step, index) => {
|
|
13116
|
-
const stepResult = args.stepResults.find((sr) => sr.index === index);
|
|
13225
|
+
const stepResult = (step.id ? byStepId.get(step.id) : void 0) ?? args.stepResults.find((sr) => sr.index === index);
|
|
13117
13226
|
return renderStep(step, stepResult, index, deps);
|
|
13118
13227
|
}).join("");
|
|
13119
13228
|
return `<div class="steps">${stepsHtml}</div>`;
|
|
@@ -13166,6 +13275,7 @@ function renderScenario(args, deps) {
|
|
|
13166
13275
|
const duration = tc.durationMs > 0 ? `${(tc.durationMs / 1e3).toFixed(2)}s` : "";
|
|
13167
13276
|
const tags = tc.tags.map((t) => `<span class="tag">${deps.escapeHtml(t)}</span>`).join("");
|
|
13168
13277
|
const tickets = (tc.story.tickets ?? []).map((t) => renderTicket(t, deps.ticketUrlTemplate, deps.escapeHtml)).join("");
|
|
13278
|
+
const outcomeBadge = tc.rawStatus === "timeout" || tc.rawStatus === "interrupted" ? `<span class="tag outcome-tag">${deps.escapeHtml(tc.rawStatus)}</span>` : "";
|
|
13169
13279
|
const otelMeta = tc.story.meta?.otel;
|
|
13170
13280
|
let traceBadge = "";
|
|
13171
13281
|
if (otelMeta?.traceId) {
|
|
@@ -13233,7 +13343,7 @@ function renderScenario(args, deps) {
|
|
|
13233
13343
|
<span class="status-icon ${statusClass}">${statusIcon2}</span>
|
|
13234
13344
|
<span class="scenario-name">${deps.escapeHtml(tc.story.scenario)}</span>
|
|
13235
13345
|
</div>
|
|
13236
|
-
<div class="scenario-meta">${tags}${tickets}${sourceLink}${traceBadge}${metricBadges}</div>
|
|
13346
|
+
<div class="scenario-meta">${tags}${tickets}${outcomeBadge}${sourceLink}${traceBadge}${metricBadges}</div>
|
|
13237
13347
|
</div>
|
|
13238
13348
|
<div class="scenario-actions">
|
|
13239
13349
|
<button class="copy-scenario-btn" onclick="copyScenarioAsMarkdown('scenario-${tc.id}')" aria-label="Copy scenario as markdown" title="Copy as Markdown"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
|
|
@@ -14237,6 +14347,9 @@ var MarkdownFormatter = class {
|
|
|
14237
14347
|
});
|
|
14238
14348
|
meta.push(`Tickets: ${ticketLinks.join(", ")}`);
|
|
14239
14349
|
}
|
|
14350
|
+
if (tc.rawStatus === "timeout" || tc.rawStatus === "interrupted") {
|
|
14351
|
+
meta.push(`Outcome: \`${tc.rawStatus}\``);
|
|
14352
|
+
}
|
|
14240
14353
|
const otelMeta = tc.story.meta?.otel;
|
|
14241
14354
|
if (otelMeta?.traceId) {
|
|
14242
14355
|
const traceTemplate = this.options.traceUrlTemplate;
|
|
@@ -14399,6 +14512,16 @@ var MarkdownFormatter = class {
|
|
|
14399
14512
|
lines.push(`${indent}`);
|
|
14400
14513
|
break;
|
|
14401
14514
|
case "custom":
|
|
14515
|
+
if (entry.type === "visual" && entry.data && typeof entry.data === "object") {
|
|
14516
|
+
const data = entry.data;
|
|
14517
|
+
const status = typeof data.status === "string" ? data.status : "unknown";
|
|
14518
|
+
lines.push(`${indent}**Visual Check** (${status})`);
|
|
14519
|
+
if (typeof data.baseline === "string") lines.push(`${indent}- Baseline: ${data.baseline}`);
|
|
14520
|
+
if (typeof data.actual === "string") lines.push(`${indent}- Actual: ${data.actual}`);
|
|
14521
|
+
if (typeof data.diff === "string") lines.push(`${indent}- Diff: ${data.diff}`);
|
|
14522
|
+
lines.push(`${indent}`);
|
|
14523
|
+
break;
|
|
14524
|
+
}
|
|
14402
14525
|
lines.push(`${indent}**[${entry.type}]**`);
|
|
14403
14526
|
lines.push(`${indent}`);
|
|
14404
14527
|
lines.push(`${indent}\`\`\`json`);
|
|
@@ -17050,6 +17173,14 @@ function adaptPlaywrightRun(testResults, options = {}) {
|
|
|
17050
17173
|
message: result.errors[0].message,
|
|
17051
17174
|
stack: result.errors[0].stack
|
|
17052
17175
|
} : void 0;
|
|
17176
|
+
const stepEvents = result.stepEvents?.length ? result.stepEvents : story.steps.map(
|
|
17177
|
+
(step, index) => step.durationMs !== void 0 ? {
|
|
17178
|
+
index,
|
|
17179
|
+
stepId: step.id,
|
|
17180
|
+
title: step.text,
|
|
17181
|
+
durationMs: step.durationMs
|
|
17182
|
+
} : void 0
|
|
17183
|
+
).filter((e) => e !== void 0);
|
|
17053
17184
|
testCases.push({
|
|
17054
17185
|
externalId: test.titlePath().join(" > "),
|
|
17055
17186
|
title: story.scenario,
|
|
@@ -17060,8 +17191,7 @@ function adaptPlaywrightRun(testResults, options = {}) {
|
|
|
17060
17191
|
status: mapPlaywrightStatus(result.status),
|
|
17061
17192
|
durationMs: result.duration,
|
|
17062
17193
|
error,
|
|
17063
|
-
stepEvents: void 0,
|
|
17064
|
-
// Playwright could provide step info, but we don't capture it yet
|
|
17194
|
+
stepEvents: stepEvents.length > 0 ? stepEvents : void 0,
|
|
17065
17195
|
attachments,
|
|
17066
17196
|
meta: {
|
|
17067
17197
|
playwrightStatus: result.status,
|