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.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import "fs";
|
|
3
|
-
import * as
|
|
3
|
+
import * as path7 from "path";
|
|
4
4
|
import * as fsPromises from "fs/promises";
|
|
5
5
|
|
|
6
6
|
// src/converters/acl/status.ts
|
|
@@ -3351,6 +3351,12 @@ body {
|
|
|
3351
3351
|
font-weight: 600;
|
|
3352
3352
|
font-size: 0.875rem;
|
|
3353
3353
|
color: var(--foreground);
|
|
3354
|
+
text-decoration: none;
|
|
3355
|
+
cursor: pointer;
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
a.toc-title:hover {
|
|
3359
|
+
color: var(--primary);
|
|
3354
3360
|
}
|
|
3355
3361
|
|
|
3356
3362
|
.toc-feature {
|
|
@@ -3528,7 +3534,7 @@ function corporateBuildBody(args, deps) {
|
|
|
3528
3534
|
const sidebar = `
|
|
3529
3535
|
<nav class="toc">
|
|
3530
3536
|
<div class="toc-header">
|
|
3531
|
-
<
|
|
3537
|
+
<a href="#" class="toc-title" onclick="window.scrollTo({top:0,behavior:'smooth'});return false;">Test Report</a>
|
|
3532
3538
|
<div class="toc-stats">
|
|
3533
3539
|
<div class="toc-stat-row">
|
|
3534
3540
|
<span class="toc-stat-label">Total</span>
|
|
@@ -13156,7 +13162,7 @@ function renderScenario(args, deps) {
|
|
|
13156
13162
|
<div class="scenario-meta">${tags}${tickets}${sourceLink}${traceBadge}${metricBadges}</div>
|
|
13157
13163
|
</div>
|
|
13158
13164
|
<div class="scenario-actions">
|
|
13159
|
-
<button class="copy-scenario-btn" onclick="copyScenarioAsMarkdown('scenario-${tc.id}')" aria-label="Copy scenario as markdown" title="Copy as Markdown"
|
|
13165
|
+
<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>
|
|
13160
13166
|
<button class="permalink-anchor" onclick="copyPermalink('scenario-${tc.id}')" aria-label="Copy link to scenario" title="Copy link">#</button>
|
|
13161
13167
|
<span class="scenario-duration">${duration}</span>
|
|
13162
13168
|
</div>
|
|
@@ -13535,7 +13541,7 @@ function renderToc(args, deps) {
|
|
|
13535
13541
|
}
|
|
13536
13542
|
return `<nav class="toc-sidebar" aria-label="Table of contents">
|
|
13537
13543
|
<div class="toc-header">
|
|
13538
|
-
<
|
|
13544
|
+
<a href="#" class="toc-title" onclick="window.scrollTo({top:0,behavior:'smooth'});return false;">Contents</a>
|
|
13539
13545
|
</div>
|
|
13540
13546
|
<div class="toc-body">
|
|
13541
13547
|
${features.join("\n")}
|
|
@@ -14996,8 +15002,8 @@ function extractDocAttachments(step) {
|
|
|
14996
15002
|
}
|
|
14997
15003
|
return attachments;
|
|
14998
15004
|
}
|
|
14999
|
-
function guessMediaType(
|
|
15000
|
-
const lower =
|
|
15005
|
+
function guessMediaType(path8) {
|
|
15006
|
+
const lower = path8.toLowerCase();
|
|
15001
15007
|
if (lower.endsWith(".png")) return "image/png";
|
|
15002
15008
|
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
15003
15009
|
if (lower.endsWith(".gif")) return "image/gif";
|
|
@@ -15138,11 +15144,11 @@ var CucumberHtmlFormatter = class {
|
|
|
15138
15144
|
for (const envelope of envelopes) {
|
|
15139
15145
|
const accepted = htmlStream.write(envelope);
|
|
15140
15146
|
if (!accepted) {
|
|
15141
|
-
await new Promise((
|
|
15147
|
+
await new Promise((resolve7) => htmlStream.once("drain", resolve7));
|
|
15142
15148
|
}
|
|
15143
15149
|
}
|
|
15144
|
-
await new Promise((
|
|
15145
|
-
collector.on("finish",
|
|
15150
|
+
await new Promise((resolve7, reject) => {
|
|
15151
|
+
collector.on("finish", resolve7);
|
|
15146
15152
|
collector.on("error", reject);
|
|
15147
15153
|
htmlStream.end();
|
|
15148
15154
|
});
|
|
@@ -16144,6 +16150,177 @@ function replaceAssetRef(html, original, replacement) {
|
|
|
16144
16150
|
return html;
|
|
16145
16151
|
}
|
|
16146
16152
|
|
|
16153
|
+
// src/formatters/astro.ts
|
|
16154
|
+
var AstroFormatter = class _AstroFormatter {
|
|
16155
|
+
markdownFormatter;
|
|
16156
|
+
title;
|
|
16157
|
+
constructor(options = {}) {
|
|
16158
|
+
this.title = options.markdown?.title ?? "User Stories";
|
|
16159
|
+
this.markdownFormatter = new MarkdownFormatter({
|
|
16160
|
+
...options.markdown,
|
|
16161
|
+
title: this.title,
|
|
16162
|
+
stepStyle: "gherkin",
|
|
16163
|
+
includeFrontMatter: false,
|
|
16164
|
+
includeSummaryTable: false,
|
|
16165
|
+
includeMetadata: false
|
|
16166
|
+
});
|
|
16167
|
+
}
|
|
16168
|
+
format(run) {
|
|
16169
|
+
const markdown = this.markdownFormatter.format(run);
|
|
16170
|
+
const body = markdown.replace(/^# .+\n\n?/, "");
|
|
16171
|
+
const frontmatter = this.buildFrontmatter(run);
|
|
16172
|
+
return `${frontmatter}
|
|
16173
|
+
${body}`;
|
|
16174
|
+
}
|
|
16175
|
+
buildFrontmatter(run) {
|
|
16176
|
+
const badge = _AstroFormatter.computeBadge(run.testCases);
|
|
16177
|
+
const count = run.testCases.length;
|
|
16178
|
+
const description = `${count} scenario${count !== 1 ? "s" : ""} \u2014 ${badge.text.toLowerCase()}`;
|
|
16179
|
+
const lines = [
|
|
16180
|
+
"---",
|
|
16181
|
+
`title: ${this.title}`,
|
|
16182
|
+
`description: ${description}`,
|
|
16183
|
+
"sidebar:",
|
|
16184
|
+
" badge:",
|
|
16185
|
+
` text: ${badge.text}`,
|
|
16186
|
+
` variant: ${badge.variant}`,
|
|
16187
|
+
"---"
|
|
16188
|
+
];
|
|
16189
|
+
return lines.join("\n");
|
|
16190
|
+
}
|
|
16191
|
+
static computeBadge(testCases) {
|
|
16192
|
+
const statuses = new Set(testCases.map((tc) => tc.status));
|
|
16193
|
+
if (statuses.has("failed")) return { text: "Failed", variant: "danger" };
|
|
16194
|
+
if (statuses.has("pending")) return { text: "Pending", variant: "caution" };
|
|
16195
|
+
if (statuses.has("skipped") && !statuses.has("passed")) return { text: "Skipped", variant: "caution" };
|
|
16196
|
+
return { text: "Passed", variant: "success" };
|
|
16197
|
+
}
|
|
16198
|
+
};
|
|
16199
|
+
|
|
16200
|
+
// src/formatters/astro-assets.ts
|
|
16201
|
+
import * as fs4 from "fs";
|
|
16202
|
+
import * as path4 from "path";
|
|
16203
|
+
var SKIP_PREFIXES = ["http://", "https://", "data:", "#"];
|
|
16204
|
+
function isLocalPath(src) {
|
|
16205
|
+
const trimmed = src.trim();
|
|
16206
|
+
if (SKIP_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
|
|
16207
|
+
return false;
|
|
16208
|
+
}
|
|
16209
|
+
return !path4.posix.isAbsolute(trimmed) && !path4.win32.isAbsolute(trimmed);
|
|
16210
|
+
}
|
|
16211
|
+
function stripCodeContent(markdown) {
|
|
16212
|
+
let result = markdown.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$/gm, "");
|
|
16213
|
+
result = result.replace(/(`+)(?:(?!\1).)+\1/g, "");
|
|
16214
|
+
result = result.replace(/<pre\b[^>]*>[\s\S]*?<\/pre>/gi, "");
|
|
16215
|
+
result = result.replace(/<code\b[^>]*>[\s\S]*?<\/code>/gi, "");
|
|
16216
|
+
return result;
|
|
16217
|
+
}
|
|
16218
|
+
function scanMarkdownAssets(markdown) {
|
|
16219
|
+
const found = /* @__PURE__ */ new Set();
|
|
16220
|
+
const stripped = stripCodeContent(markdown);
|
|
16221
|
+
const mdImageRe = /!\[[^\]]*\]\(([^)"'\s]+)(?:\s+["'][^"']*["'])?\s*\)/g;
|
|
16222
|
+
let match;
|
|
16223
|
+
while ((match = mdImageRe.exec(stripped)) !== null) {
|
|
16224
|
+
const src = match[1].trim();
|
|
16225
|
+
if (isLocalPath(src)) {
|
|
16226
|
+
found.add(src);
|
|
16227
|
+
}
|
|
16228
|
+
}
|
|
16229
|
+
const htmlSrcRe = /<(?:img|source|video)[^>]+\bsrc=["']([^"']+)["'][^>]*>/gi;
|
|
16230
|
+
while ((match = htmlSrcRe.exec(stripped)) !== null) {
|
|
16231
|
+
const src = match[1].trim();
|
|
16232
|
+
if (isLocalPath(src)) {
|
|
16233
|
+
found.add(src);
|
|
16234
|
+
}
|
|
16235
|
+
}
|
|
16236
|
+
return Array.from(found);
|
|
16237
|
+
}
|
|
16238
|
+
function splitByCode(markdown) {
|
|
16239
|
+
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;
|
|
16240
|
+
const segments = [];
|
|
16241
|
+
let lastIndex = 0;
|
|
16242
|
+
for (const match of markdown.matchAll(codeRe)) {
|
|
16243
|
+
if (match.index > lastIndex) {
|
|
16244
|
+
segments.push(markdown.slice(lastIndex, match.index));
|
|
16245
|
+
}
|
|
16246
|
+
segments.push(match[0]);
|
|
16247
|
+
lastIndex = match.index + match[0].length;
|
|
16248
|
+
}
|
|
16249
|
+
if (lastIndex < markdown.length) {
|
|
16250
|
+
segments.push(markdown.slice(lastIndex));
|
|
16251
|
+
}
|
|
16252
|
+
return segments;
|
|
16253
|
+
}
|
|
16254
|
+
function isCode(segment) {
|
|
16255
|
+
const trimmed = segment.trimStart();
|
|
16256
|
+
return trimmed.startsWith("`") || trimmed.startsWith("~") || trimmed.startsWith("<pre") || trimmed.startsWith("<code");
|
|
16257
|
+
}
|
|
16258
|
+
function rewriteProseSegment(prose, assetsBaseUrl, pathMap) {
|
|
16259
|
+
let result = prose;
|
|
16260
|
+
result = result.replace(
|
|
16261
|
+
/(!\[[^\]]*\]\()([^)"'\s]+)((?:\s+["'][^"']*["'])?\s*\))/g,
|
|
16262
|
+
(full, pre, src, post) => {
|
|
16263
|
+
const trimmed = src.trim();
|
|
16264
|
+
if (!isLocalPath(trimmed)) return full;
|
|
16265
|
+
if (pathMap) {
|
|
16266
|
+
const mapped = pathMap.get(trimmed);
|
|
16267
|
+
if (mapped === void 0) return full;
|
|
16268
|
+
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
16269
|
+
}
|
|
16270
|
+
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
16271
|
+
}
|
|
16272
|
+
);
|
|
16273
|
+
result = result.replace(
|
|
16274
|
+
/(<(?:img|source|video)[^>]+\bsrc=["'])([^"']+)(["'][^>]*>)/gi,
|
|
16275
|
+
(full, pre, src, post) => {
|
|
16276
|
+
const trimmed = src.trim();
|
|
16277
|
+
if (!isLocalPath(trimmed)) return full;
|
|
16278
|
+
if (pathMap) {
|
|
16279
|
+
const mapped = pathMap.get(trimmed);
|
|
16280
|
+
if (mapped === void 0) return full;
|
|
16281
|
+
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
16282
|
+
}
|
|
16283
|
+
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
16284
|
+
}
|
|
16285
|
+
);
|
|
16286
|
+
return result;
|
|
16287
|
+
}
|
|
16288
|
+
function rewriteAssetPaths(markdown, assetsBaseUrl, pathMap) {
|
|
16289
|
+
return splitByCode(markdown).map((seg) => isCode(seg) ? seg : rewriteProseSegment(seg, assetsBaseUrl, pathMap)).join("");
|
|
16290
|
+
}
|
|
16291
|
+
function copyMarkdownAssets(options) {
|
|
16292
|
+
const {
|
|
16293
|
+
markdown,
|
|
16294
|
+
markdownDir,
|
|
16295
|
+
assetsDir,
|
|
16296
|
+
assetsBaseUrl,
|
|
16297
|
+
allowMissing = false
|
|
16298
|
+
} = options;
|
|
16299
|
+
const refs = scanMarkdownAssets(markdown);
|
|
16300
|
+
const pathMap = /* @__PURE__ */ new Map();
|
|
16301
|
+
const missing = [];
|
|
16302
|
+
for (const ref of refs) {
|
|
16303
|
+
const absPath = path4.resolve(markdownDir, ref);
|
|
16304
|
+
if (!fs4.existsSync(absPath)) {
|
|
16305
|
+
if (!allowMissing) {
|
|
16306
|
+
throw new Error(`Asset not found: ${absPath}`);
|
|
16307
|
+
}
|
|
16308
|
+
missing.push(ref);
|
|
16309
|
+
continue;
|
|
16310
|
+
}
|
|
16311
|
+
const relativeCopied = copyAsset(absPath, assetsDir);
|
|
16312
|
+
const fileName = relativeCopied.replace(/^assets\//, "");
|
|
16313
|
+
pathMap.set(ref, fileName);
|
|
16314
|
+
}
|
|
16315
|
+
const rewritten = rewriteAssetPaths(markdown, assetsBaseUrl, pathMap);
|
|
16316
|
+
return {
|
|
16317
|
+
markdown: rewritten,
|
|
16318
|
+
copiedCount: pathMap.size,
|
|
16319
|
+
missingCount: missing.length,
|
|
16320
|
+
missing
|
|
16321
|
+
};
|
|
16322
|
+
}
|
|
16323
|
+
|
|
16147
16324
|
// src/converters/adapters/jest.ts
|
|
16148
16325
|
function mapJestStatus(status) {
|
|
16149
16326
|
switch (status) {
|
|
@@ -16911,27 +17088,27 @@ function pickleStepArgumentToDocs(ps) {
|
|
|
16911
17088
|
}
|
|
16912
17089
|
|
|
16913
17090
|
// src/utils/git-info.ts
|
|
16914
|
-
import * as
|
|
16915
|
-
import * as
|
|
17091
|
+
import * as fs5 from "fs";
|
|
17092
|
+
import * as path5 from "path";
|
|
16916
17093
|
function readGitSha(cwd = process.cwd()) {
|
|
16917
17094
|
const envSha = process.env.GITHUB_SHA || process.env.GIT_COMMIT || process.env.CI_COMMIT_SHA;
|
|
16918
17095
|
if (envSha) return envSha;
|
|
16919
17096
|
const gitDir = findGitDir(cwd);
|
|
16920
17097
|
if (!gitDir) return void 0;
|
|
16921
17098
|
try {
|
|
16922
|
-
const headPath =
|
|
16923
|
-
const head =
|
|
17099
|
+
const headPath = path5.join(gitDir, "HEAD");
|
|
17100
|
+
const head = fs5.readFileSync(headPath, "utf8").trim();
|
|
16924
17101
|
if (!head.startsWith("ref:")) {
|
|
16925
17102
|
return head;
|
|
16926
17103
|
}
|
|
16927
17104
|
const refPath = head.replace("ref:", "").trim();
|
|
16928
|
-
const refFile =
|
|
16929
|
-
if (
|
|
16930
|
-
return
|
|
17105
|
+
const refFile = path5.join(gitDir, refPath);
|
|
17106
|
+
if (fs5.existsSync(refFile)) {
|
|
17107
|
+
return fs5.readFileSync(refFile, "utf8").trim();
|
|
16931
17108
|
}
|
|
16932
|
-
const packedRefs =
|
|
16933
|
-
if (
|
|
16934
|
-
const content =
|
|
17109
|
+
const packedRefs = path5.join(gitDir, "packed-refs");
|
|
17110
|
+
if (fs5.existsSync(packedRefs)) {
|
|
17111
|
+
const content = fs5.readFileSync(packedRefs, "utf8");
|
|
16935
17112
|
for (const line of content.split("\n")) {
|
|
16936
17113
|
if (!line || line.startsWith("#") || line.startsWith("^")) continue;
|
|
16937
17114
|
const [sha, ref] = line.split(" ");
|
|
@@ -16946,19 +17123,19 @@ function readGitSha(cwd = process.cwd()) {
|
|
|
16946
17123
|
function findGitDir(start) {
|
|
16947
17124
|
let current = start;
|
|
16948
17125
|
while (true) {
|
|
16949
|
-
const candidate =
|
|
16950
|
-
if (
|
|
16951
|
-
const stat =
|
|
17126
|
+
const candidate = path5.join(current, ".git");
|
|
17127
|
+
if (fs5.existsSync(candidate)) {
|
|
17128
|
+
const stat = fs5.statSync(candidate);
|
|
16952
17129
|
if (stat.isFile()) {
|
|
16953
|
-
const content =
|
|
17130
|
+
const content = fs5.readFileSync(candidate, "utf8").trim();
|
|
16954
17131
|
const match = content.match(/^gitdir: (.+)$/);
|
|
16955
17132
|
if (match) {
|
|
16956
|
-
return
|
|
17133
|
+
return path5.resolve(current, match[1]);
|
|
16957
17134
|
}
|
|
16958
17135
|
}
|
|
16959
17136
|
return candidate;
|
|
16960
17137
|
}
|
|
16961
|
-
const parent =
|
|
17138
|
+
const parent = path5.dirname(current);
|
|
16962
17139
|
if (parent === current) return void 0;
|
|
16963
17140
|
current = parent;
|
|
16964
17141
|
}
|
|
@@ -16969,8 +17146,8 @@ function readBranchName(cwd = process.cwd()) {
|
|
|
16969
17146
|
const gitDir = findGitDir(cwd);
|
|
16970
17147
|
if (!gitDir) return void 0;
|
|
16971
17148
|
try {
|
|
16972
|
-
const headPath =
|
|
16973
|
-
const head =
|
|
17149
|
+
const headPath = path5.join(gitDir, "HEAD");
|
|
17150
|
+
const head = fs5.readFileSync(headPath, "utf8").trim();
|
|
16974
17151
|
if (head.startsWith("ref:")) {
|
|
16975
17152
|
const refPath = head.replace("ref:", "").trim();
|
|
16976
17153
|
const match = refPath.match(/^refs\/heads\/(.+)$/);
|
|
@@ -17007,8 +17184,8 @@ function nanosecondsToMs(ns) {
|
|
|
17007
17184
|
}
|
|
17008
17185
|
|
|
17009
17186
|
// src/utils/metadata.ts
|
|
17010
|
-
import * as
|
|
17011
|
-
import * as
|
|
17187
|
+
import * as fs6 from "fs";
|
|
17188
|
+
import * as path6 from "path";
|
|
17012
17189
|
var versionCache = /* @__PURE__ */ new Map();
|
|
17013
17190
|
function readPackageVersion(root) {
|
|
17014
17191
|
if (versionCache.has(root)) {
|
|
@@ -17019,18 +17196,18 @@ function readPackageVersion(root) {
|
|
|
17019
17196
|
return version;
|
|
17020
17197
|
}
|
|
17021
17198
|
function findPackageVersion(startDir) {
|
|
17022
|
-
let current =
|
|
17199
|
+
let current = path6.resolve(startDir);
|
|
17023
17200
|
while (true) {
|
|
17024
|
-
const pkgPath =
|
|
17201
|
+
const pkgPath = path6.join(current, "package.json");
|
|
17025
17202
|
try {
|
|
17026
|
-
if (
|
|
17027
|
-
const raw =
|
|
17203
|
+
if (fs6.existsSync(pkgPath)) {
|
|
17204
|
+
const raw = fs6.readFileSync(pkgPath, "utf8");
|
|
17028
17205
|
const parsed = JSON.parse(raw);
|
|
17029
17206
|
return parsed.version;
|
|
17030
17207
|
}
|
|
17031
17208
|
} catch {
|
|
17032
17209
|
}
|
|
17033
|
-
const parent =
|
|
17210
|
+
const parent = path6.dirname(current);
|
|
17034
17211
|
if (parent === current) {
|
|
17035
17212
|
return void 0;
|
|
17036
17213
|
}
|
|
@@ -17955,6 +18132,7 @@ function listScenarios(args, _deps) {
|
|
|
17955
18132
|
|
|
17956
18133
|
// src/index.ts
|
|
17957
18134
|
var FORMAT_EXTENSIONS = {
|
|
18135
|
+
astro: ".md",
|
|
17958
18136
|
markdown: ".md",
|
|
17959
18137
|
html: ".html",
|
|
17960
18138
|
"cucumber-html": ".cucumber.html",
|
|
@@ -17987,11 +18165,11 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
17987
18165
|
const ext = FORMAT_EXTENSIONS[format];
|
|
17988
18166
|
const effectiveName = outputName + (outputNameSuffix ?? "");
|
|
17989
18167
|
if (mode === "aggregated") {
|
|
17990
|
-
return toPosix(
|
|
18168
|
+
return toPosix(path7.join(baseOutputDir, `${effectiveName}${ext}`));
|
|
17991
18169
|
}
|
|
17992
18170
|
const normalizedSource = toPosix(sourceFile);
|
|
17993
|
-
const dirOfSource =
|
|
17994
|
-
let baseName =
|
|
18171
|
+
const dirOfSource = path7.posix.dirname(normalizedSource);
|
|
18172
|
+
let baseName = path7.posix.basename(normalizedSource);
|
|
17995
18173
|
for (const testExt of TEST_EXTENSIONS) {
|
|
17996
18174
|
if (baseName.endsWith(testExt)) {
|
|
17997
18175
|
baseName = baseName.slice(0, -testExt.length);
|
|
@@ -18000,9 +18178,9 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
18000
18178
|
}
|
|
18001
18179
|
const fileName = `${baseName}.${effectiveName}${ext}`;
|
|
18002
18180
|
if (colocatedStyle === "adjacent") {
|
|
18003
|
-
return toPosix(
|
|
18181
|
+
return toPosix(path7.posix.join(dirOfSource, fileName));
|
|
18004
18182
|
}
|
|
18005
|
-
return toPosix(
|
|
18183
|
+
return toPosix(path7.posix.join(baseOutputDir, dirOfSource, fileName));
|
|
18006
18184
|
}
|
|
18007
18185
|
function groupTestCasesByOutput(testCases, format, options, logger, outputNameSuffix) {
|
|
18008
18186
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -18073,7 +18251,7 @@ var ReportGenerator = class {
|
|
|
18073
18251
|
excludeTags: options.excludeTags ?? [],
|
|
18074
18252
|
formats: options.formats ?? ["cucumber-json"],
|
|
18075
18253
|
outputDir: options.outputDir ?? "reports",
|
|
18076
|
-
outputName: options.outputName ?? "
|
|
18254
|
+
outputName: options.outputName ?? "index",
|
|
18077
18255
|
outputNameTimestamp: options.outputNameTimestamp ?? false,
|
|
18078
18256
|
sortTestCases: options.sortTestCases ?? "none",
|
|
18079
18257
|
output: {
|
|
@@ -18128,6 +18306,24 @@ var ReportGenerator = class {
|
|
|
18128
18306
|
includeSourceLinks: options.markdown?.includeSourceLinks ?? true,
|
|
18129
18307
|
customRenderers: options.markdown?.customRenderers
|
|
18130
18308
|
},
|
|
18309
|
+
astro: {
|
|
18310
|
+
assetsDir: options.astro?.assetsDir ?? "public/stories/assets",
|
|
18311
|
+
assetsBaseUrl: options.astro?.assetsBaseUrl ?? "/stories/assets",
|
|
18312
|
+
markdown: {
|
|
18313
|
+
title: options.astro?.markdown?.title ?? "User Stories",
|
|
18314
|
+
includeStatusIcons: options.astro?.markdown?.includeStatusIcons ?? true,
|
|
18315
|
+
includeErrors: options.astro?.markdown?.includeErrors ?? true,
|
|
18316
|
+
scenarioHeadingLevel: options.astro?.markdown?.scenarioHeadingLevel ?? 3,
|
|
18317
|
+
groupBy: options.astro?.markdown?.groupBy ?? "file",
|
|
18318
|
+
sortScenarios: options.astro?.markdown?.sortScenarios ?? "source",
|
|
18319
|
+
suiteSeparator: options.astro?.markdown?.suiteSeparator ?? " - ",
|
|
18320
|
+
includeSourceLinks: options.astro?.markdown?.includeSourceLinks ?? true,
|
|
18321
|
+
permalinkBaseUrl: options.astro?.markdown?.permalinkBaseUrl,
|
|
18322
|
+
ticketUrlTemplate: options.astro?.markdown?.ticketUrlTemplate,
|
|
18323
|
+
traceUrlTemplate: options.astro?.markdown?.traceUrlTemplate,
|
|
18324
|
+
customRenderers: options.astro?.markdown?.customRenderers
|
|
18325
|
+
}
|
|
18326
|
+
},
|
|
18131
18327
|
assetMode: options.assetMode ?? "none",
|
|
18132
18328
|
allowMissingAssets: options.allowMissingAssets ?? false
|
|
18133
18329
|
};
|
|
@@ -18165,6 +18361,24 @@ var ReportGenerator = class {
|
|
|
18165
18361
|
});
|
|
18166
18362
|
}
|
|
18167
18363
|
}
|
|
18364
|
+
const astroPaths = results.get("astro");
|
|
18365
|
+
if (astroPaths) {
|
|
18366
|
+
for (const mdPath of astroPaths) {
|
|
18367
|
+
const content = await fsPromises.readFile(mdPath, "utf8");
|
|
18368
|
+
const mdDir = path7.dirname(mdPath);
|
|
18369
|
+
const assetsDir = path7.resolve(this.options.astro.assetsDir);
|
|
18370
|
+
const result = copyMarkdownAssets({
|
|
18371
|
+
markdown: content,
|
|
18372
|
+
markdownDir: mdDir,
|
|
18373
|
+
assetsDir,
|
|
18374
|
+
assetsBaseUrl: this.options.astro.assetsBaseUrl,
|
|
18375
|
+
allowMissing: this.options.allowMissingAssets
|
|
18376
|
+
});
|
|
18377
|
+
if (result.copiedCount > 0 || result.missingCount > 0) {
|
|
18378
|
+
await this.deps.writeFile(mdPath, result.markdown);
|
|
18379
|
+
}
|
|
18380
|
+
}
|
|
18381
|
+
}
|
|
18168
18382
|
}
|
|
18169
18383
|
return results;
|
|
18170
18384
|
}
|
|
@@ -18183,9 +18397,9 @@ var ReportGenerator = class {
|
|
|
18183
18397
|
if (groups.size === 0 && this.options.output.mode === "aggregated") {
|
|
18184
18398
|
const ext = FORMAT_EXTENSIONS[format];
|
|
18185
18399
|
const effectiveName = this.options.outputName + (outputNameSuffix ?? "");
|
|
18186
|
-
const outputPath = toPosix(
|
|
18400
|
+
const outputPath = toPosix(path7.join(this.options.outputDir, `${effectiveName}${ext}`));
|
|
18187
18401
|
const content = await this.formatContent(run, format);
|
|
18188
|
-
const dir =
|
|
18402
|
+
const dir = path7.dirname(outputPath);
|
|
18189
18403
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
18190
18404
|
await this.deps.writeFile(outputPath, content);
|
|
18191
18405
|
return [outputPath];
|
|
@@ -18197,7 +18411,7 @@ var ReportGenerator = class {
|
|
|
18197
18411
|
testCases
|
|
18198
18412
|
};
|
|
18199
18413
|
const content = await this.formatContent(groupRun, format);
|
|
18200
|
-
const dir =
|
|
18414
|
+
const dir = path7.dirname(outputPath);
|
|
18201
18415
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
18202
18416
|
await this.deps.writeFile(outputPath, content);
|
|
18203
18417
|
writtenPaths.push(outputPath);
|
|
@@ -18260,6 +18474,13 @@ var ReportGenerator = class {
|
|
|
18260
18474
|
});
|
|
18261
18475
|
return formatter.formatToString(run);
|
|
18262
18476
|
}
|
|
18477
|
+
case "astro": {
|
|
18478
|
+
const formatter = new AstroFormatter({
|
|
18479
|
+
assetsBaseUrl: this.options.astro.assetsBaseUrl,
|
|
18480
|
+
markdown: this.options.astro.markdown
|
|
18481
|
+
});
|
|
18482
|
+
return formatter.format(run);
|
|
18483
|
+
}
|
|
18263
18484
|
case "markdown": {
|
|
18264
18485
|
const formatter = new MarkdownFormatter({
|
|
18265
18486
|
title: this.options.markdown.title,
|
|
@@ -18297,7 +18518,7 @@ async function generateRunComparison(args) {
|
|
|
18297
18518
|
await fsPromises.mkdir(outputDir, { recursive: true });
|
|
18298
18519
|
for (const format of args.formats) {
|
|
18299
18520
|
const ext = format === "html" ? ".html" : ".md";
|
|
18300
|
-
const outputPath = toPosix(
|
|
18521
|
+
const outputPath = toPosix(path7.join(outputDir, `${outputName}${ext}`));
|
|
18301
18522
|
const content = format === "html" ? new RunDiffHtmlFormatter({ title: args.title }).format(diff) : new RunDiffMarkdownFormatter({ title: args.title }).format(diff);
|
|
18302
18523
|
await fsPromises.writeFile(outputPath, content, "utf8");
|
|
18303
18524
|
files.push(outputPath);
|
|
@@ -18317,6 +18538,7 @@ function normalizePlaywrightResults(testResults, adapterOptions, canonicalizeOpt
|
|
|
18317
18538
|
return canonicalizeRun(raw, canonicalizeOptions);
|
|
18318
18539
|
}
|
|
18319
18540
|
export {
|
|
18541
|
+
AstroFormatter,
|
|
18320
18542
|
CucumberHtmlFormatter,
|
|
18321
18543
|
CucumberJsonFormatter,
|
|
18322
18544
|
CucumberMessagesFormatter,
|
|
@@ -18340,6 +18562,7 @@ export {
|
|
|
18340
18562
|
canonicalizeRun,
|
|
18341
18563
|
clearVersionCache,
|
|
18342
18564
|
computeTestMetrics,
|
|
18565
|
+
copyMarkdownAssets,
|
|
18343
18566
|
createPrCommentSummary,
|
|
18344
18567
|
createReportGenerator,
|
|
18345
18568
|
deriveStepResults,
|
|
@@ -18372,6 +18595,7 @@ export {
|
|
|
18372
18595
|
resolveAttachments,
|
|
18373
18596
|
resolveTheme,
|
|
18374
18597
|
resolveTraceUrl,
|
|
18598
|
+
rewriteAssetPaths,
|
|
18375
18599
|
saveHistory,
|
|
18376
18600
|
sendNotifications,
|
|
18377
18601
|
sendSlackNotification,
|