executable-stories-formatters 0.7.5 → 0.7.7
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/cli.js +351 -63
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +272 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -3
- package/dist/index.d.ts +81 -3
- package/dist/index.js +268 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
AstroFormatter: () => AstroFormatter,
|
|
33
34
|
CucumberHtmlFormatter: () => CucumberHtmlFormatter,
|
|
34
35
|
CucumberJsonFormatter: () => CucumberJsonFormatter,
|
|
35
36
|
CucumberMessagesFormatter: () => CucumberMessagesFormatter,
|
|
@@ -53,6 +54,7 @@ __export(src_exports, {
|
|
|
53
54
|
canonicalizeRun: () => canonicalizeRun,
|
|
54
55
|
clearVersionCache: () => clearVersionCache,
|
|
55
56
|
computeTestMetrics: () => computeTestMetrics,
|
|
57
|
+
copyMarkdownAssets: () => copyMarkdownAssets,
|
|
56
58
|
createPrCommentSummary: () => createPrCommentSummary,
|
|
57
59
|
createReportGenerator: () => createReportGenerator,
|
|
58
60
|
deriveStepResults: () => deriveStepResults,
|
|
@@ -85,6 +87,7 @@ __export(src_exports, {
|
|
|
85
87
|
resolveAttachments: () => resolveAttachments,
|
|
86
88
|
resolveTheme: () => resolveTheme,
|
|
87
89
|
resolveTraceUrl: () => resolveTraceUrl,
|
|
90
|
+
rewriteAssetPaths: () => rewriteAssetPaths,
|
|
88
91
|
saveHistory: () => saveHistory,
|
|
89
92
|
sendNotifications: () => sendNotifications,
|
|
90
93
|
sendSlackNotification: () => sendSlackNotification,
|
|
@@ -100,8 +103,8 @@ __export(src_exports, {
|
|
|
100
103
|
validateCanonicalRun: () => validateCanonicalRun
|
|
101
104
|
});
|
|
102
105
|
module.exports = __toCommonJS(src_exports);
|
|
103
|
-
var
|
|
104
|
-
var
|
|
106
|
+
var fs7 = require("fs");
|
|
107
|
+
var path7 = __toESM(require("path"), 1);
|
|
105
108
|
var fsPromises = __toESM(require("fs/promises"), 1);
|
|
106
109
|
|
|
107
110
|
// src/converters/acl/status.ts
|
|
@@ -3452,6 +3455,12 @@ body {
|
|
|
3452
3455
|
font-weight: 600;
|
|
3453
3456
|
font-size: 0.875rem;
|
|
3454
3457
|
color: var(--foreground);
|
|
3458
|
+
text-decoration: none;
|
|
3459
|
+
cursor: pointer;
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
a.toc-title:hover {
|
|
3463
|
+
color: var(--primary);
|
|
3455
3464
|
}
|
|
3456
3465
|
|
|
3457
3466
|
.toc-feature {
|
|
@@ -3629,7 +3638,7 @@ function corporateBuildBody(args, deps) {
|
|
|
3629
3638
|
const sidebar = `
|
|
3630
3639
|
<nav class="toc">
|
|
3631
3640
|
<div class="toc-header">
|
|
3632
|
-
<
|
|
3641
|
+
<a href="#" class="toc-title" onclick="window.scrollTo({top:0,behavior:'smooth'});return false;">Test Report</a>
|
|
3633
3642
|
<div class="toc-stats">
|
|
3634
3643
|
<div class="toc-stat-row">
|
|
3635
3644
|
<span class="toc-stat-label">Total</span>
|
|
@@ -13257,7 +13266,7 @@ function renderScenario(args, deps) {
|
|
|
13257
13266
|
<div class="scenario-meta">${tags}${tickets}${sourceLink}${traceBadge}${metricBadges}</div>
|
|
13258
13267
|
</div>
|
|
13259
13268
|
<div class="scenario-actions">
|
|
13260
|
-
<button class="copy-scenario-btn" onclick="copyScenarioAsMarkdown('scenario-${tc.id}')" aria-label="Copy scenario as markdown" title="Copy as Markdown"
|
|
13269
|
+
<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>
|
|
13261
13270
|
<button class="permalink-anchor" onclick="copyPermalink('scenario-${tc.id}')" aria-label="Copy link to scenario" title="Copy link">#</button>
|
|
13262
13271
|
<span class="scenario-duration">${duration}</span>
|
|
13263
13272
|
</div>
|
|
@@ -13636,7 +13645,7 @@ function renderToc(args, deps) {
|
|
|
13636
13645
|
}
|
|
13637
13646
|
return `<nav class="toc-sidebar" aria-label="Table of contents">
|
|
13638
13647
|
<div class="toc-header">
|
|
13639
|
-
<
|
|
13648
|
+
<a href="#" class="toc-title" onclick="window.scrollTo({top:0,behavior:'smooth'});return false;">Contents</a>
|
|
13640
13649
|
</div>
|
|
13641
13650
|
<div class="toc-body">
|
|
13642
13651
|
${features.join("\n")}
|
|
@@ -15097,8 +15106,8 @@ function extractDocAttachments(step) {
|
|
|
15097
15106
|
}
|
|
15098
15107
|
return attachments;
|
|
15099
15108
|
}
|
|
15100
|
-
function guessMediaType(
|
|
15101
|
-
const lower =
|
|
15109
|
+
function guessMediaType(path8) {
|
|
15110
|
+
const lower = path8.toLowerCase();
|
|
15102
15111
|
if (lower.endsWith(".png")) return "image/png";
|
|
15103
15112
|
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
15104
15113
|
if (lower.endsWith(".gif")) return "image/gif";
|
|
@@ -15239,11 +15248,11 @@ var CucumberHtmlFormatter = class {
|
|
|
15239
15248
|
for (const envelope of envelopes) {
|
|
15240
15249
|
const accepted = htmlStream.write(envelope);
|
|
15241
15250
|
if (!accepted) {
|
|
15242
|
-
await new Promise((
|
|
15251
|
+
await new Promise((resolve7) => htmlStream.once("drain", resolve7));
|
|
15243
15252
|
}
|
|
15244
15253
|
}
|
|
15245
|
-
await new Promise((
|
|
15246
|
-
collector.on("finish",
|
|
15254
|
+
await new Promise((resolve7, reject) => {
|
|
15255
|
+
collector.on("finish", resolve7);
|
|
15247
15256
|
collector.on("error", reject);
|
|
15248
15257
|
htmlStream.end();
|
|
15249
15258
|
});
|
|
@@ -16245,6 +16254,177 @@ function replaceAssetRef(html, original, replacement) {
|
|
|
16245
16254
|
return html;
|
|
16246
16255
|
}
|
|
16247
16256
|
|
|
16257
|
+
// src/formatters/astro.ts
|
|
16258
|
+
var AstroFormatter = class _AstroFormatter {
|
|
16259
|
+
markdownFormatter;
|
|
16260
|
+
title;
|
|
16261
|
+
constructor(options = {}) {
|
|
16262
|
+
this.title = options.markdown?.title ?? "User Stories";
|
|
16263
|
+
this.markdownFormatter = new MarkdownFormatter({
|
|
16264
|
+
...options.markdown,
|
|
16265
|
+
title: this.title,
|
|
16266
|
+
stepStyle: "gherkin",
|
|
16267
|
+
includeFrontMatter: false,
|
|
16268
|
+
includeSummaryTable: false,
|
|
16269
|
+
includeMetadata: false
|
|
16270
|
+
});
|
|
16271
|
+
}
|
|
16272
|
+
format(run) {
|
|
16273
|
+
const markdown = this.markdownFormatter.format(run);
|
|
16274
|
+
const body = markdown.replace(/^# .+\n\n?/, "");
|
|
16275
|
+
const frontmatter = this.buildFrontmatter(run);
|
|
16276
|
+
return `${frontmatter}
|
|
16277
|
+
${body}`;
|
|
16278
|
+
}
|
|
16279
|
+
buildFrontmatter(run) {
|
|
16280
|
+
const badge = _AstroFormatter.computeBadge(run.testCases);
|
|
16281
|
+
const count = run.testCases.length;
|
|
16282
|
+
const description = `${count} scenario${count !== 1 ? "s" : ""} \u2014 ${badge.text.toLowerCase()}`;
|
|
16283
|
+
const lines = [
|
|
16284
|
+
"---",
|
|
16285
|
+
`title: ${this.title}`,
|
|
16286
|
+
`description: ${description}`,
|
|
16287
|
+
"sidebar:",
|
|
16288
|
+
" badge:",
|
|
16289
|
+
` text: ${badge.text}`,
|
|
16290
|
+
` variant: ${badge.variant}`,
|
|
16291
|
+
"---"
|
|
16292
|
+
];
|
|
16293
|
+
return lines.join("\n");
|
|
16294
|
+
}
|
|
16295
|
+
static computeBadge(testCases) {
|
|
16296
|
+
const statuses = new Set(testCases.map((tc) => tc.status));
|
|
16297
|
+
if (statuses.has("failed")) return { text: "Failed", variant: "danger" };
|
|
16298
|
+
if (statuses.has("pending")) return { text: "Pending", variant: "caution" };
|
|
16299
|
+
if (statuses.has("skipped") && !statuses.has("passed")) return { text: "Skipped", variant: "caution" };
|
|
16300
|
+
return { text: "Passed", variant: "success" };
|
|
16301
|
+
}
|
|
16302
|
+
};
|
|
16303
|
+
|
|
16304
|
+
// src/formatters/astro-assets.ts
|
|
16305
|
+
var fs4 = __toESM(require("fs"), 1);
|
|
16306
|
+
var path4 = __toESM(require("path"), 1);
|
|
16307
|
+
var SKIP_PREFIXES = ["http://", "https://", "data:", "#"];
|
|
16308
|
+
function isLocalPath(src) {
|
|
16309
|
+
const trimmed = src.trim();
|
|
16310
|
+
if (SKIP_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
|
|
16311
|
+
return false;
|
|
16312
|
+
}
|
|
16313
|
+
return !path4.posix.isAbsolute(trimmed) && !path4.win32.isAbsolute(trimmed);
|
|
16314
|
+
}
|
|
16315
|
+
function stripCodeContent(markdown) {
|
|
16316
|
+
let result = markdown.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$/gm, "");
|
|
16317
|
+
result = result.replace(/(`+)(?:(?!\1).)+\1/g, "");
|
|
16318
|
+
result = result.replace(/<pre\b[^>]*>[\s\S]*?<\/pre>/gi, "");
|
|
16319
|
+
result = result.replace(/<code\b[^>]*>[\s\S]*?<\/code>/gi, "");
|
|
16320
|
+
return result;
|
|
16321
|
+
}
|
|
16322
|
+
function scanMarkdownAssets(markdown) {
|
|
16323
|
+
const found = /* @__PURE__ */ new Set();
|
|
16324
|
+
const stripped = stripCodeContent(markdown);
|
|
16325
|
+
const mdImageRe = /!\[[^\]]*\]\(([^)"'\s]+)(?:\s+["'][^"']*["'])?\s*\)/g;
|
|
16326
|
+
let match;
|
|
16327
|
+
while ((match = mdImageRe.exec(stripped)) !== null) {
|
|
16328
|
+
const src = match[1].trim();
|
|
16329
|
+
if (isLocalPath(src)) {
|
|
16330
|
+
found.add(src);
|
|
16331
|
+
}
|
|
16332
|
+
}
|
|
16333
|
+
const htmlSrcRe = /<(?:img|source|video)[^>]+\bsrc=["']([^"']+)["'][^>]*>/gi;
|
|
16334
|
+
while ((match = htmlSrcRe.exec(stripped)) !== null) {
|
|
16335
|
+
const src = match[1].trim();
|
|
16336
|
+
if (isLocalPath(src)) {
|
|
16337
|
+
found.add(src);
|
|
16338
|
+
}
|
|
16339
|
+
}
|
|
16340
|
+
return Array.from(found);
|
|
16341
|
+
}
|
|
16342
|
+
function splitByCode(markdown) {
|
|
16343
|
+
const codeRe = /^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$|<pre\b[^>]*>[\s\S]*?<\/pre>|<code\b[^>]*>[\s\S]*?<\/code>|(`+)(?:(?!\2).)+\2/gim;
|
|
16344
|
+
const segments = [];
|
|
16345
|
+
let lastIndex = 0;
|
|
16346
|
+
for (const match of markdown.matchAll(codeRe)) {
|
|
16347
|
+
if (match.index > lastIndex) {
|
|
16348
|
+
segments.push(markdown.slice(lastIndex, match.index));
|
|
16349
|
+
}
|
|
16350
|
+
segments.push(match[0]);
|
|
16351
|
+
lastIndex = match.index + match[0].length;
|
|
16352
|
+
}
|
|
16353
|
+
if (lastIndex < markdown.length) {
|
|
16354
|
+
segments.push(markdown.slice(lastIndex));
|
|
16355
|
+
}
|
|
16356
|
+
return segments;
|
|
16357
|
+
}
|
|
16358
|
+
function isCode(segment) {
|
|
16359
|
+
const trimmed = segment.trimStart();
|
|
16360
|
+
return trimmed.startsWith("`") || trimmed.startsWith("~") || trimmed.startsWith("<pre") || trimmed.startsWith("<code");
|
|
16361
|
+
}
|
|
16362
|
+
function rewriteProseSegment(prose, assetsBaseUrl, pathMap) {
|
|
16363
|
+
let result = prose;
|
|
16364
|
+
result = result.replace(
|
|
16365
|
+
/(!\[[^\]]*\]\()([^)"'\s]+)((?:\s+["'][^"']*["'])?\s*\))/g,
|
|
16366
|
+
(full, pre, src, post) => {
|
|
16367
|
+
const trimmed = src.trim();
|
|
16368
|
+
if (!isLocalPath(trimmed)) return full;
|
|
16369
|
+
if (pathMap) {
|
|
16370
|
+
const mapped = pathMap.get(trimmed);
|
|
16371
|
+
if (mapped === void 0) return full;
|
|
16372
|
+
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
16373
|
+
}
|
|
16374
|
+
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
16375
|
+
}
|
|
16376
|
+
);
|
|
16377
|
+
result = result.replace(
|
|
16378
|
+
/(<(?:img|source|video)[^>]+\bsrc=["'])([^"']+)(["'][^>]*>)/gi,
|
|
16379
|
+
(full, pre, src, post) => {
|
|
16380
|
+
const trimmed = src.trim();
|
|
16381
|
+
if (!isLocalPath(trimmed)) return full;
|
|
16382
|
+
if (pathMap) {
|
|
16383
|
+
const mapped = pathMap.get(trimmed);
|
|
16384
|
+
if (mapped === void 0) return full;
|
|
16385
|
+
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
16386
|
+
}
|
|
16387
|
+
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
16388
|
+
}
|
|
16389
|
+
);
|
|
16390
|
+
return result;
|
|
16391
|
+
}
|
|
16392
|
+
function rewriteAssetPaths(markdown, assetsBaseUrl, pathMap) {
|
|
16393
|
+
return splitByCode(markdown).map((seg) => isCode(seg) ? seg : rewriteProseSegment(seg, assetsBaseUrl, pathMap)).join("");
|
|
16394
|
+
}
|
|
16395
|
+
function copyMarkdownAssets(options) {
|
|
16396
|
+
const {
|
|
16397
|
+
markdown,
|
|
16398
|
+
markdownDir,
|
|
16399
|
+
assetsDir,
|
|
16400
|
+
assetsBaseUrl,
|
|
16401
|
+
allowMissing = false
|
|
16402
|
+
} = options;
|
|
16403
|
+
const refs = scanMarkdownAssets(markdown);
|
|
16404
|
+
const pathMap = /* @__PURE__ */ new Map();
|
|
16405
|
+
const missing = [];
|
|
16406
|
+
for (const ref of refs) {
|
|
16407
|
+
const absPath = path4.resolve(markdownDir, ref);
|
|
16408
|
+
if (!fs4.existsSync(absPath)) {
|
|
16409
|
+
if (!allowMissing) {
|
|
16410
|
+
throw new Error(`Asset not found: ${absPath}`);
|
|
16411
|
+
}
|
|
16412
|
+
missing.push(ref);
|
|
16413
|
+
continue;
|
|
16414
|
+
}
|
|
16415
|
+
const relativeCopied = copyAsset(absPath, assetsDir);
|
|
16416
|
+
const fileName = relativeCopied.replace(/^assets\//, "");
|
|
16417
|
+
pathMap.set(ref, fileName);
|
|
16418
|
+
}
|
|
16419
|
+
const rewritten = rewriteAssetPaths(markdown, assetsBaseUrl, pathMap);
|
|
16420
|
+
return {
|
|
16421
|
+
markdown: rewritten,
|
|
16422
|
+
copiedCount: pathMap.size,
|
|
16423
|
+
missingCount: missing.length,
|
|
16424
|
+
missing
|
|
16425
|
+
};
|
|
16426
|
+
}
|
|
16427
|
+
|
|
16248
16428
|
// src/converters/adapters/jest.ts
|
|
16249
16429
|
function mapJestStatus(status) {
|
|
16250
16430
|
switch (status) {
|
|
@@ -17012,27 +17192,27 @@ function pickleStepArgumentToDocs(ps) {
|
|
|
17012
17192
|
}
|
|
17013
17193
|
|
|
17014
17194
|
// src/utils/git-info.ts
|
|
17015
|
-
var
|
|
17016
|
-
var
|
|
17195
|
+
var fs5 = __toESM(require("fs"), 1);
|
|
17196
|
+
var path5 = __toESM(require("path"), 1);
|
|
17017
17197
|
function readGitSha(cwd = process.cwd()) {
|
|
17018
17198
|
const envSha = process.env.GITHUB_SHA || process.env.GIT_COMMIT || process.env.CI_COMMIT_SHA;
|
|
17019
17199
|
if (envSha) return envSha;
|
|
17020
17200
|
const gitDir = findGitDir(cwd);
|
|
17021
17201
|
if (!gitDir) return void 0;
|
|
17022
17202
|
try {
|
|
17023
|
-
const headPath =
|
|
17024
|
-
const head =
|
|
17203
|
+
const headPath = path5.join(gitDir, "HEAD");
|
|
17204
|
+
const head = fs5.readFileSync(headPath, "utf8").trim();
|
|
17025
17205
|
if (!head.startsWith("ref:")) {
|
|
17026
17206
|
return head;
|
|
17027
17207
|
}
|
|
17028
17208
|
const refPath = head.replace("ref:", "").trim();
|
|
17029
|
-
const refFile =
|
|
17030
|
-
if (
|
|
17031
|
-
return
|
|
17209
|
+
const refFile = path5.join(gitDir, refPath);
|
|
17210
|
+
if (fs5.existsSync(refFile)) {
|
|
17211
|
+
return fs5.readFileSync(refFile, "utf8").trim();
|
|
17032
17212
|
}
|
|
17033
|
-
const packedRefs =
|
|
17034
|
-
if (
|
|
17035
|
-
const content =
|
|
17213
|
+
const packedRefs = path5.join(gitDir, "packed-refs");
|
|
17214
|
+
if (fs5.existsSync(packedRefs)) {
|
|
17215
|
+
const content = fs5.readFileSync(packedRefs, "utf8");
|
|
17036
17216
|
for (const line of content.split("\n")) {
|
|
17037
17217
|
if (!line || line.startsWith("#") || line.startsWith("^")) continue;
|
|
17038
17218
|
const [sha, ref] = line.split(" ");
|
|
@@ -17047,19 +17227,19 @@ function readGitSha(cwd = process.cwd()) {
|
|
|
17047
17227
|
function findGitDir(start) {
|
|
17048
17228
|
let current = start;
|
|
17049
17229
|
while (true) {
|
|
17050
|
-
const candidate =
|
|
17051
|
-
if (
|
|
17052
|
-
const stat =
|
|
17230
|
+
const candidate = path5.join(current, ".git");
|
|
17231
|
+
if (fs5.existsSync(candidate)) {
|
|
17232
|
+
const stat = fs5.statSync(candidate);
|
|
17053
17233
|
if (stat.isFile()) {
|
|
17054
|
-
const content =
|
|
17234
|
+
const content = fs5.readFileSync(candidate, "utf8").trim();
|
|
17055
17235
|
const match = content.match(/^gitdir: (.+)$/);
|
|
17056
17236
|
if (match) {
|
|
17057
|
-
return
|
|
17237
|
+
return path5.resolve(current, match[1]);
|
|
17058
17238
|
}
|
|
17059
17239
|
}
|
|
17060
17240
|
return candidate;
|
|
17061
17241
|
}
|
|
17062
|
-
const parent =
|
|
17242
|
+
const parent = path5.dirname(current);
|
|
17063
17243
|
if (parent === current) return void 0;
|
|
17064
17244
|
current = parent;
|
|
17065
17245
|
}
|
|
@@ -17070,8 +17250,8 @@ function readBranchName(cwd = process.cwd()) {
|
|
|
17070
17250
|
const gitDir = findGitDir(cwd);
|
|
17071
17251
|
if (!gitDir) return void 0;
|
|
17072
17252
|
try {
|
|
17073
|
-
const headPath =
|
|
17074
|
-
const head =
|
|
17253
|
+
const headPath = path5.join(gitDir, "HEAD");
|
|
17254
|
+
const head = fs5.readFileSync(headPath, "utf8").trim();
|
|
17075
17255
|
if (head.startsWith("ref:")) {
|
|
17076
17256
|
const refPath = head.replace("ref:", "").trim();
|
|
17077
17257
|
const match = refPath.match(/^refs\/heads\/(.+)$/);
|
|
@@ -17108,8 +17288,8 @@ function nanosecondsToMs(ns) {
|
|
|
17108
17288
|
}
|
|
17109
17289
|
|
|
17110
17290
|
// src/utils/metadata.ts
|
|
17111
|
-
var
|
|
17112
|
-
var
|
|
17291
|
+
var fs6 = __toESM(require("fs"), 1);
|
|
17292
|
+
var path6 = __toESM(require("path"), 1);
|
|
17113
17293
|
var versionCache = /* @__PURE__ */ new Map();
|
|
17114
17294
|
function readPackageVersion(root) {
|
|
17115
17295
|
if (versionCache.has(root)) {
|
|
@@ -17120,18 +17300,18 @@ function readPackageVersion(root) {
|
|
|
17120
17300
|
return version;
|
|
17121
17301
|
}
|
|
17122
17302
|
function findPackageVersion(startDir) {
|
|
17123
|
-
let current =
|
|
17303
|
+
let current = path6.resolve(startDir);
|
|
17124
17304
|
while (true) {
|
|
17125
|
-
const pkgPath =
|
|
17305
|
+
const pkgPath = path6.join(current, "package.json");
|
|
17126
17306
|
try {
|
|
17127
|
-
if (
|
|
17128
|
-
const raw =
|
|
17307
|
+
if (fs6.existsSync(pkgPath)) {
|
|
17308
|
+
const raw = fs6.readFileSync(pkgPath, "utf8");
|
|
17129
17309
|
const parsed = JSON.parse(raw);
|
|
17130
17310
|
return parsed.version;
|
|
17131
17311
|
}
|
|
17132
17312
|
} catch {
|
|
17133
17313
|
}
|
|
17134
|
-
const parent =
|
|
17314
|
+
const parent = path6.dirname(current);
|
|
17135
17315
|
if (parent === current) {
|
|
17136
17316
|
return void 0;
|
|
17137
17317
|
}
|
|
@@ -18057,6 +18237,7 @@ function listScenarios(args, _deps) {
|
|
|
18057
18237
|
|
|
18058
18238
|
// src/index.ts
|
|
18059
18239
|
var FORMAT_EXTENSIONS = {
|
|
18240
|
+
astro: ".md",
|
|
18060
18241
|
markdown: ".md",
|
|
18061
18242
|
html: ".html",
|
|
18062
18243
|
"cucumber-html": ".cucumber.html",
|
|
@@ -18089,11 +18270,11 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
18089
18270
|
const ext = FORMAT_EXTENSIONS[format];
|
|
18090
18271
|
const effectiveName = outputName + (outputNameSuffix ?? "");
|
|
18091
18272
|
if (mode === "aggregated") {
|
|
18092
|
-
return toPosix(
|
|
18273
|
+
return toPosix(path7.join(baseOutputDir, `${effectiveName}${ext}`));
|
|
18093
18274
|
}
|
|
18094
18275
|
const normalizedSource = toPosix(sourceFile);
|
|
18095
|
-
const dirOfSource =
|
|
18096
|
-
let baseName =
|
|
18276
|
+
const dirOfSource = path7.posix.dirname(normalizedSource);
|
|
18277
|
+
let baseName = path7.posix.basename(normalizedSource);
|
|
18097
18278
|
for (const testExt of TEST_EXTENSIONS) {
|
|
18098
18279
|
if (baseName.endsWith(testExt)) {
|
|
18099
18280
|
baseName = baseName.slice(0, -testExt.length);
|
|
@@ -18102,9 +18283,9 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
18102
18283
|
}
|
|
18103
18284
|
const fileName = `${baseName}.${effectiveName}${ext}`;
|
|
18104
18285
|
if (colocatedStyle === "adjacent") {
|
|
18105
|
-
return toPosix(
|
|
18286
|
+
return toPosix(path7.posix.join(dirOfSource, fileName));
|
|
18106
18287
|
}
|
|
18107
|
-
return toPosix(
|
|
18288
|
+
return toPosix(path7.posix.join(baseOutputDir, dirOfSource, fileName));
|
|
18108
18289
|
}
|
|
18109
18290
|
function groupTestCasesByOutput(testCases, format, options, logger, outputNameSuffix) {
|
|
18110
18291
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -18175,7 +18356,7 @@ var ReportGenerator = class {
|
|
|
18175
18356
|
excludeTags: options.excludeTags ?? [],
|
|
18176
18357
|
formats: options.formats ?? ["cucumber-json"],
|
|
18177
18358
|
outputDir: options.outputDir ?? "reports",
|
|
18178
|
-
outputName: options.outputName ?? "
|
|
18359
|
+
outputName: options.outputName ?? "index",
|
|
18179
18360
|
outputNameTimestamp: options.outputNameTimestamp ?? false,
|
|
18180
18361
|
sortTestCases: options.sortTestCases ?? "none",
|
|
18181
18362
|
output: {
|
|
@@ -18230,6 +18411,24 @@ var ReportGenerator = class {
|
|
|
18230
18411
|
includeSourceLinks: options.markdown?.includeSourceLinks ?? true,
|
|
18231
18412
|
customRenderers: options.markdown?.customRenderers
|
|
18232
18413
|
},
|
|
18414
|
+
astro: {
|
|
18415
|
+
assetsDir: options.astro?.assetsDir ?? "public/stories/assets",
|
|
18416
|
+
assetsBaseUrl: options.astro?.assetsBaseUrl ?? "/stories/assets",
|
|
18417
|
+
markdown: {
|
|
18418
|
+
title: options.astro?.markdown?.title ?? "User Stories",
|
|
18419
|
+
includeStatusIcons: options.astro?.markdown?.includeStatusIcons ?? true,
|
|
18420
|
+
includeErrors: options.astro?.markdown?.includeErrors ?? true,
|
|
18421
|
+
scenarioHeadingLevel: options.astro?.markdown?.scenarioHeadingLevel ?? 3,
|
|
18422
|
+
groupBy: options.astro?.markdown?.groupBy ?? "file",
|
|
18423
|
+
sortScenarios: options.astro?.markdown?.sortScenarios ?? "source",
|
|
18424
|
+
suiteSeparator: options.astro?.markdown?.suiteSeparator ?? " - ",
|
|
18425
|
+
includeSourceLinks: options.astro?.markdown?.includeSourceLinks ?? true,
|
|
18426
|
+
permalinkBaseUrl: options.astro?.markdown?.permalinkBaseUrl,
|
|
18427
|
+
ticketUrlTemplate: options.astro?.markdown?.ticketUrlTemplate,
|
|
18428
|
+
traceUrlTemplate: options.astro?.markdown?.traceUrlTemplate,
|
|
18429
|
+
customRenderers: options.astro?.markdown?.customRenderers
|
|
18430
|
+
}
|
|
18431
|
+
},
|
|
18233
18432
|
assetMode: options.assetMode ?? "none",
|
|
18234
18433
|
allowMissingAssets: options.allowMissingAssets ?? false
|
|
18235
18434
|
};
|
|
@@ -18267,6 +18466,24 @@ var ReportGenerator = class {
|
|
|
18267
18466
|
});
|
|
18268
18467
|
}
|
|
18269
18468
|
}
|
|
18469
|
+
const astroPaths = results.get("astro");
|
|
18470
|
+
if (astroPaths) {
|
|
18471
|
+
for (const mdPath of astroPaths) {
|
|
18472
|
+
const content = await fsPromises.readFile(mdPath, "utf8");
|
|
18473
|
+
const mdDir = path7.dirname(mdPath);
|
|
18474
|
+
const assetsDir = path7.resolve(this.options.astro.assetsDir);
|
|
18475
|
+
const result = copyMarkdownAssets({
|
|
18476
|
+
markdown: content,
|
|
18477
|
+
markdownDir: mdDir,
|
|
18478
|
+
assetsDir,
|
|
18479
|
+
assetsBaseUrl: this.options.astro.assetsBaseUrl,
|
|
18480
|
+
allowMissing: this.options.allowMissingAssets
|
|
18481
|
+
});
|
|
18482
|
+
if (result.copiedCount > 0 || result.missingCount > 0) {
|
|
18483
|
+
await this.deps.writeFile(mdPath, result.markdown);
|
|
18484
|
+
}
|
|
18485
|
+
}
|
|
18486
|
+
}
|
|
18270
18487
|
}
|
|
18271
18488
|
return results;
|
|
18272
18489
|
}
|
|
@@ -18285,9 +18502,9 @@ var ReportGenerator = class {
|
|
|
18285
18502
|
if (groups.size === 0 && this.options.output.mode === "aggregated") {
|
|
18286
18503
|
const ext = FORMAT_EXTENSIONS[format];
|
|
18287
18504
|
const effectiveName = this.options.outputName + (outputNameSuffix ?? "");
|
|
18288
|
-
const outputPath = toPosix(
|
|
18505
|
+
const outputPath = toPosix(path7.join(this.options.outputDir, `${effectiveName}${ext}`));
|
|
18289
18506
|
const content = await this.formatContent(run, format);
|
|
18290
|
-
const dir =
|
|
18507
|
+
const dir = path7.dirname(outputPath);
|
|
18291
18508
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
18292
18509
|
await this.deps.writeFile(outputPath, content);
|
|
18293
18510
|
return [outputPath];
|
|
@@ -18299,7 +18516,7 @@ var ReportGenerator = class {
|
|
|
18299
18516
|
testCases
|
|
18300
18517
|
};
|
|
18301
18518
|
const content = await this.formatContent(groupRun, format);
|
|
18302
|
-
const dir =
|
|
18519
|
+
const dir = path7.dirname(outputPath);
|
|
18303
18520
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
18304
18521
|
await this.deps.writeFile(outputPath, content);
|
|
18305
18522
|
writtenPaths.push(outputPath);
|
|
@@ -18362,6 +18579,13 @@ var ReportGenerator = class {
|
|
|
18362
18579
|
});
|
|
18363
18580
|
return formatter.formatToString(run);
|
|
18364
18581
|
}
|
|
18582
|
+
case "astro": {
|
|
18583
|
+
const formatter = new AstroFormatter({
|
|
18584
|
+
assetsBaseUrl: this.options.astro.assetsBaseUrl,
|
|
18585
|
+
markdown: this.options.astro.markdown
|
|
18586
|
+
});
|
|
18587
|
+
return formatter.format(run);
|
|
18588
|
+
}
|
|
18365
18589
|
case "markdown": {
|
|
18366
18590
|
const formatter = new MarkdownFormatter({
|
|
18367
18591
|
title: this.options.markdown.title,
|
|
@@ -18399,7 +18623,7 @@ async function generateRunComparison(args) {
|
|
|
18399
18623
|
await fsPromises.mkdir(outputDir, { recursive: true });
|
|
18400
18624
|
for (const format of args.formats) {
|
|
18401
18625
|
const ext = format === "html" ? ".html" : ".md";
|
|
18402
|
-
const outputPath = toPosix(
|
|
18626
|
+
const outputPath = toPosix(path7.join(outputDir, `${outputName}${ext}`));
|
|
18403
18627
|
const content = format === "html" ? new RunDiffHtmlFormatter({ title: args.title }).format(diff) : new RunDiffMarkdownFormatter({ title: args.title }).format(diff);
|
|
18404
18628
|
await fsPromises.writeFile(outputPath, content, "utf8");
|
|
18405
18629
|
files.push(outputPath);
|
|
@@ -18420,6 +18644,7 @@ function normalizePlaywrightResults(testResults, adapterOptions, canonicalizeOpt
|
|
|
18420
18644
|
}
|
|
18421
18645
|
// Annotate the CommonJS export names for ESM import in node:
|
|
18422
18646
|
0 && (module.exports = {
|
|
18647
|
+
AstroFormatter,
|
|
18423
18648
|
CucumberHtmlFormatter,
|
|
18424
18649
|
CucumberJsonFormatter,
|
|
18425
18650
|
CucumberMessagesFormatter,
|
|
@@ -18443,6 +18668,7 @@ function normalizePlaywrightResults(testResults, adapterOptions, canonicalizeOpt
|
|
|
18443
18668
|
canonicalizeRun,
|
|
18444
18669
|
clearVersionCache,
|
|
18445
18670
|
computeTestMetrics,
|
|
18671
|
+
copyMarkdownAssets,
|
|
18446
18672
|
createPrCommentSummary,
|
|
18447
18673
|
createReportGenerator,
|
|
18448
18674
|
deriveStepResults,
|
|
@@ -18475,6 +18701,7 @@ function normalizePlaywrightResults(testResults, adapterOptions, canonicalizeOpt
|
|
|
18475
18701
|
resolveAttachments,
|
|
18476
18702
|
resolveTheme,
|
|
18477
18703
|
resolveTraceUrl,
|
|
18704
|
+
rewriteAssetPaths,
|
|
18478
18705
|
saveHistory,
|
|
18479
18706
|
sendNotifications,
|
|
18480
18707
|
sendSlackNotification,
|