executable-stories-formatters 0.7.9 → 0.7.11
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 +126 -96
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +95 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +94 -64
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -106,8 +106,8 @@ __export(src_exports, {
|
|
|
106
106
|
validateCanonicalRun: () => validateCanonicalRun
|
|
107
107
|
});
|
|
108
108
|
module.exports = __toCommonJS(src_exports);
|
|
109
|
-
var
|
|
110
|
-
var
|
|
109
|
+
var fs8 = require("fs");
|
|
110
|
+
var path8 = __toESM(require("path"), 1);
|
|
111
111
|
var fsPromises = __toESM(require("fs/promises"), 1);
|
|
112
112
|
|
|
113
113
|
// src/converters/acl/status.ts
|
|
@@ -760,6 +760,10 @@ ${doc.markdown}`,
|
|
|
760
760
|
}
|
|
761
761
|
};
|
|
762
762
|
|
|
763
|
+
// src/formatters/html/renderers/index.ts
|
|
764
|
+
var fs2 = __toESM(require("fs"), 1);
|
|
765
|
+
var path2 = __toESM(require("path"), 1);
|
|
766
|
+
|
|
763
767
|
// src/formatters/html/template.ts
|
|
764
768
|
var JS_THEME = `
|
|
765
769
|
// Theme management
|
|
@@ -13070,7 +13074,9 @@ function renderDocMermaid(entry, deps) {
|
|
|
13070
13074
|
}
|
|
13071
13075
|
function renderDocScreenshot(entry, deps) {
|
|
13072
13076
|
const alt = entry.alt ?? "Screenshot";
|
|
13073
|
-
const
|
|
13077
|
+
const embedEnabled = deps.embedScreenshots ?? true;
|
|
13078
|
+
const isRemote = /^(?:https?:|data:)/i.test(entry.path);
|
|
13079
|
+
const src = embedEnabled && !isRemote && deps.readScreenshot ? deps.readScreenshot(entry.path) ?? entry.path : entry.path;
|
|
13074
13080
|
return `<div class="doc-screenshot">
|
|
13075
13081
|
<img src="${deps.escapeHtml(src)}" alt="${deps.escapeHtml(alt)}" class="doc-screenshot-img" />
|
|
13076
13082
|
${entry.alt ? `<div class="doc-screenshot-caption">${deps.escapeHtml(entry.alt)}</div>` : ""}
|
|
@@ -13657,6 +13663,28 @@ function renderToc(args, deps) {
|
|
|
13657
13663
|
}
|
|
13658
13664
|
|
|
13659
13665
|
// src/formatters/html/renderers/index.ts
|
|
13666
|
+
var SCREENSHOT_MIME_BY_EXT = {
|
|
13667
|
+
png: "image/png",
|
|
13668
|
+
jpg: "image/jpeg",
|
|
13669
|
+
jpeg: "image/jpeg",
|
|
13670
|
+
gif: "image/gif",
|
|
13671
|
+
webp: "image/webp",
|
|
13672
|
+
svg: "image/svg+xml",
|
|
13673
|
+
avif: "image/avif",
|
|
13674
|
+
bmp: "image/bmp"
|
|
13675
|
+
};
|
|
13676
|
+
function readScreenshotAsDataUri(filePath) {
|
|
13677
|
+
try {
|
|
13678
|
+
const ext = path2.extname(filePath).slice(1).toLowerCase();
|
|
13679
|
+
const mime = SCREENSHOT_MIME_BY_EXT[ext];
|
|
13680
|
+
if (!mime) return void 0;
|
|
13681
|
+
if (!fs2.existsSync(filePath)) return void 0;
|
|
13682
|
+
const buf = fs2.readFileSync(filePath);
|
|
13683
|
+
return `data:${mime};base64,${buf.toString("base64")}`;
|
|
13684
|
+
} catch {
|
|
13685
|
+
return void 0;
|
|
13686
|
+
}
|
|
13687
|
+
}
|
|
13660
13688
|
function normalizeOptions(options = {}) {
|
|
13661
13689
|
return {
|
|
13662
13690
|
title: options.title ?? "Test Results",
|
|
@@ -13680,7 +13708,9 @@ function createHtmlFormatter(options = {}) {
|
|
|
13680
13708
|
escapeHtml,
|
|
13681
13709
|
syntaxHighlighting: opts.syntaxHighlighting,
|
|
13682
13710
|
markdownEnabled: opts.markdownEnabled,
|
|
13683
|
-
mermaidEnabled: opts.mermaidEnabled
|
|
13711
|
+
mermaidEnabled: opts.mermaidEnabled,
|
|
13712
|
+
embedScreenshots: opts.embedScreenshots,
|
|
13713
|
+
readScreenshot: (filePath) => readScreenshotAsDataUri(filePath)
|
|
13684
13714
|
};
|
|
13685
13715
|
const renderDocs = (docs, containerClass) => {
|
|
13686
13716
|
if (!docs || docs.length === 0) return "";
|
|
@@ -15109,8 +15139,8 @@ function extractDocAttachments(step) {
|
|
|
15109
15139
|
}
|
|
15110
15140
|
return attachments;
|
|
15111
15141
|
}
|
|
15112
|
-
function guessMediaType(
|
|
15113
|
-
const lower =
|
|
15142
|
+
function guessMediaType(path9) {
|
|
15143
|
+
const lower = path9.toLowerCase();
|
|
15114
15144
|
if (lower.endsWith(".png")) return "image/png";
|
|
15115
15145
|
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
15116
15146
|
if (lower.endsWith(".gif")) return "image/gif";
|
|
@@ -16154,8 +16184,8 @@ function selectTestCases(args, deps) {
|
|
|
16154
16184
|
}
|
|
16155
16185
|
|
|
16156
16186
|
// src/bundler/bundle-assets.ts
|
|
16157
|
-
var
|
|
16158
|
-
var
|
|
16187
|
+
var fs4 = __toESM(require("fs"), 1);
|
|
16188
|
+
var path4 = __toESM(require("path"), 1);
|
|
16159
16189
|
|
|
16160
16190
|
// src/bundler/scan-html-assets.ts
|
|
16161
16191
|
function scanHtmlAssets(html) {
|
|
@@ -16185,21 +16215,21 @@ function isLocalAssetRef(ref) {
|
|
|
16185
16215
|
}
|
|
16186
16216
|
|
|
16187
16217
|
// src/bundler/copy-asset.ts
|
|
16188
|
-
var
|
|
16189
|
-
var
|
|
16218
|
+
var fs3 = __toESM(require("fs"), 1);
|
|
16219
|
+
var path3 = __toESM(require("path"), 1);
|
|
16190
16220
|
var crypto = __toESM(require("crypto"), 1);
|
|
16191
16221
|
function copyAsset(sourcePath, assetsDir) {
|
|
16192
|
-
if (!
|
|
16193
|
-
|
|
16222
|
+
if (!fs3.existsSync(assetsDir)) {
|
|
16223
|
+
fs3.mkdirSync(assetsDir, { recursive: true });
|
|
16194
16224
|
}
|
|
16195
|
-
const content =
|
|
16225
|
+
const content = fs3.readFileSync(sourcePath);
|
|
16196
16226
|
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
16197
|
-
const ext =
|
|
16198
|
-
const baseName = sanitize(
|
|
16227
|
+
const ext = path3.extname(sourcePath);
|
|
16228
|
+
const baseName = sanitize(path3.basename(sourcePath, ext));
|
|
16199
16229
|
const destName = `${baseName}-${hash}${ext}`;
|
|
16200
|
-
const destPath =
|
|
16201
|
-
if (!
|
|
16202
|
-
|
|
16230
|
+
const destPath = path3.join(assetsDir, destName);
|
|
16231
|
+
if (!fs3.existsSync(destPath)) {
|
|
16232
|
+
fs3.copyFileSync(sourcePath, destPath);
|
|
16203
16233
|
}
|
|
16204
16234
|
return `assets/${destName}`;
|
|
16205
16235
|
}
|
|
@@ -16209,15 +16239,15 @@ function sanitize(name) {
|
|
|
16209
16239
|
|
|
16210
16240
|
// src/bundler/bundle-assets.ts
|
|
16211
16241
|
function bundleAssets(htmlPath, options = {}) {
|
|
16212
|
-
const htmlDir =
|
|
16213
|
-
const assetsDir =
|
|
16214
|
-
let html =
|
|
16242
|
+
const htmlDir = path4.dirname(htmlPath);
|
|
16243
|
+
const assetsDir = path4.join(htmlDir, "assets");
|
|
16244
|
+
let html = fs4.readFileSync(htmlPath, "utf8");
|
|
16215
16245
|
const refs = scanHtmlAssets(html);
|
|
16216
16246
|
let copiedCount = 0;
|
|
16217
16247
|
const missing = [];
|
|
16218
16248
|
for (const ref of refs) {
|
|
16219
|
-
const absolutePath =
|
|
16220
|
-
if (!
|
|
16249
|
+
const absolutePath = path4.resolve(htmlDir, ref);
|
|
16250
|
+
if (!fs4.existsSync(absolutePath)) {
|
|
16221
16251
|
missing.push(ref);
|
|
16222
16252
|
continue;
|
|
16223
16253
|
}
|
|
@@ -16230,7 +16260,7 @@ function bundleAssets(htmlPath, options = {}) {
|
|
|
16230
16260
|
`Missing asset${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`
|
|
16231
16261
|
);
|
|
16232
16262
|
}
|
|
16233
|
-
|
|
16263
|
+
fs4.writeFileSync(htmlPath, html, "utf8");
|
|
16234
16264
|
return {
|
|
16235
16265
|
copiedCount,
|
|
16236
16266
|
missingCount: missing.length,
|
|
@@ -16713,15 +16743,15 @@ function groupBy7(items, keyFn) {
|
|
|
16713
16743
|
}
|
|
16714
16744
|
|
|
16715
16745
|
// src/formatters/astro-assets.ts
|
|
16716
|
-
var
|
|
16717
|
-
var
|
|
16746
|
+
var fs5 = __toESM(require("fs"), 1);
|
|
16747
|
+
var path5 = __toESM(require("path"), 1);
|
|
16718
16748
|
var SKIP_PREFIXES = ["http://", "https://", "data:", "#"];
|
|
16719
16749
|
function isLocalPath(src) {
|
|
16720
16750
|
const trimmed = src.trim();
|
|
16721
16751
|
if (SKIP_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
|
|
16722
16752
|
return false;
|
|
16723
16753
|
}
|
|
16724
|
-
return !
|
|
16754
|
+
return !path5.posix.isAbsolute(trimmed) && !path5.win32.isAbsolute(trimmed);
|
|
16725
16755
|
}
|
|
16726
16756
|
function stripCodeContent(markdown) {
|
|
16727
16757
|
let result = markdown.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$/gm, "");
|
|
@@ -16815,8 +16845,8 @@ function copyMarkdownAssets(options) {
|
|
|
16815
16845
|
const pathMap = /* @__PURE__ */ new Map();
|
|
16816
16846
|
const missing = [];
|
|
16817
16847
|
for (const ref of refs) {
|
|
16818
|
-
const absPath =
|
|
16819
|
-
if (!
|
|
16848
|
+
const absPath = path5.resolve(markdownDir, ref);
|
|
16849
|
+
if (!fs5.existsSync(absPath)) {
|
|
16820
16850
|
if (!allowMissing) {
|
|
16821
16851
|
throw new Error(`Asset not found: ${absPath}`);
|
|
16822
16852
|
}
|
|
@@ -17832,27 +17862,27 @@ function pickleStepArgumentToDocs(ps) {
|
|
|
17832
17862
|
}
|
|
17833
17863
|
|
|
17834
17864
|
// src/utils/git-info.ts
|
|
17835
|
-
var
|
|
17836
|
-
var
|
|
17865
|
+
var fs6 = __toESM(require("fs"), 1);
|
|
17866
|
+
var path6 = __toESM(require("path"), 1);
|
|
17837
17867
|
function readGitSha(cwd = process.cwd()) {
|
|
17838
17868
|
const envSha = process.env.GITHUB_SHA || process.env.GIT_COMMIT || process.env.CI_COMMIT_SHA;
|
|
17839
17869
|
if (envSha) return envSha;
|
|
17840
17870
|
const gitDir = findGitDir(cwd);
|
|
17841
17871
|
if (!gitDir) return void 0;
|
|
17842
17872
|
try {
|
|
17843
|
-
const headPath =
|
|
17844
|
-
const head =
|
|
17873
|
+
const headPath = path6.join(gitDir, "HEAD");
|
|
17874
|
+
const head = fs6.readFileSync(headPath, "utf8").trim();
|
|
17845
17875
|
if (!head.startsWith("ref:")) {
|
|
17846
17876
|
return head;
|
|
17847
17877
|
}
|
|
17848
17878
|
const refPath = head.replace("ref:", "").trim();
|
|
17849
|
-
const refFile =
|
|
17850
|
-
if (
|
|
17851
|
-
return
|
|
17879
|
+
const refFile = path6.join(gitDir, refPath);
|
|
17880
|
+
if (fs6.existsSync(refFile)) {
|
|
17881
|
+
return fs6.readFileSync(refFile, "utf8").trim();
|
|
17852
17882
|
}
|
|
17853
|
-
const packedRefs =
|
|
17854
|
-
if (
|
|
17855
|
-
const content =
|
|
17883
|
+
const packedRefs = path6.join(gitDir, "packed-refs");
|
|
17884
|
+
if (fs6.existsSync(packedRefs)) {
|
|
17885
|
+
const content = fs6.readFileSync(packedRefs, "utf8");
|
|
17856
17886
|
for (const line of content.split("\n")) {
|
|
17857
17887
|
if (!line || line.startsWith("#") || line.startsWith("^")) continue;
|
|
17858
17888
|
const [sha, ref] = line.split(" ");
|
|
@@ -17867,19 +17897,19 @@ function readGitSha(cwd = process.cwd()) {
|
|
|
17867
17897
|
function findGitDir(start) {
|
|
17868
17898
|
let current = start;
|
|
17869
17899
|
while (true) {
|
|
17870
|
-
const candidate =
|
|
17871
|
-
if (
|
|
17872
|
-
const stat =
|
|
17900
|
+
const candidate = path6.join(current, ".git");
|
|
17901
|
+
if (fs6.existsSync(candidate)) {
|
|
17902
|
+
const stat = fs6.statSync(candidate);
|
|
17873
17903
|
if (stat.isFile()) {
|
|
17874
|
-
const content =
|
|
17904
|
+
const content = fs6.readFileSync(candidate, "utf8").trim();
|
|
17875
17905
|
const match = content.match(/^gitdir: (.+)$/);
|
|
17876
17906
|
if (match) {
|
|
17877
|
-
return
|
|
17907
|
+
return path6.resolve(current, match[1]);
|
|
17878
17908
|
}
|
|
17879
17909
|
}
|
|
17880
17910
|
return candidate;
|
|
17881
17911
|
}
|
|
17882
|
-
const parent =
|
|
17912
|
+
const parent = path6.dirname(current);
|
|
17883
17913
|
if (parent === current) return void 0;
|
|
17884
17914
|
current = parent;
|
|
17885
17915
|
}
|
|
@@ -17890,8 +17920,8 @@ function readBranchName(cwd = process.cwd()) {
|
|
|
17890
17920
|
const gitDir = findGitDir(cwd);
|
|
17891
17921
|
if (!gitDir) return void 0;
|
|
17892
17922
|
try {
|
|
17893
|
-
const headPath =
|
|
17894
|
-
const head =
|
|
17923
|
+
const headPath = path6.join(gitDir, "HEAD");
|
|
17924
|
+
const head = fs6.readFileSync(headPath, "utf8").trim();
|
|
17895
17925
|
if (head.startsWith("ref:")) {
|
|
17896
17926
|
const refPath = head.replace("ref:", "").trim();
|
|
17897
17927
|
const match = refPath.match(/^refs\/heads\/(.+)$/);
|
|
@@ -17928,8 +17958,8 @@ function nanosecondsToMs(ns) {
|
|
|
17928
17958
|
}
|
|
17929
17959
|
|
|
17930
17960
|
// src/utils/metadata.ts
|
|
17931
|
-
var
|
|
17932
|
-
var
|
|
17961
|
+
var fs7 = __toESM(require("fs"), 1);
|
|
17962
|
+
var path7 = __toESM(require("path"), 1);
|
|
17933
17963
|
var versionCache = /* @__PURE__ */ new Map();
|
|
17934
17964
|
function readPackageVersion(root) {
|
|
17935
17965
|
if (versionCache.has(root)) {
|
|
@@ -17940,18 +17970,18 @@ function readPackageVersion(root) {
|
|
|
17940
17970
|
return version;
|
|
17941
17971
|
}
|
|
17942
17972
|
function findPackageVersion(startDir) {
|
|
17943
|
-
let current =
|
|
17973
|
+
let current = path7.resolve(startDir);
|
|
17944
17974
|
while (true) {
|
|
17945
|
-
const pkgPath =
|
|
17975
|
+
const pkgPath = path7.join(current, "package.json");
|
|
17946
17976
|
try {
|
|
17947
|
-
if (
|
|
17948
|
-
const raw =
|
|
17977
|
+
if (fs7.existsSync(pkgPath)) {
|
|
17978
|
+
const raw = fs7.readFileSync(pkgPath, "utf8");
|
|
17949
17979
|
const parsed = JSON.parse(raw);
|
|
17950
17980
|
return parsed.version;
|
|
17951
17981
|
}
|
|
17952
17982
|
} catch {
|
|
17953
17983
|
}
|
|
17954
|
-
const parent =
|
|
17984
|
+
const parent = path7.dirname(current);
|
|
17955
17985
|
if (parent === current) {
|
|
17956
17986
|
return void 0;
|
|
17957
17987
|
}
|
|
@@ -18942,11 +18972,11 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
18942
18972
|
const ext = FORMAT_EXTENSIONS[format];
|
|
18943
18973
|
const effectiveName = outputName + (outputNameSuffix ?? "");
|
|
18944
18974
|
if (mode === "aggregated") {
|
|
18945
|
-
return toPosix(
|
|
18975
|
+
return toPosix(path8.join(baseOutputDir, `${effectiveName}${ext}`));
|
|
18946
18976
|
}
|
|
18947
18977
|
const normalizedSource = toPosix(sourceFile);
|
|
18948
|
-
const dirOfSource =
|
|
18949
|
-
let baseName =
|
|
18978
|
+
const dirOfSource = path8.posix.dirname(normalizedSource);
|
|
18979
|
+
let baseName = path8.posix.basename(normalizedSource);
|
|
18950
18980
|
for (const testExt of TEST_EXTENSIONS) {
|
|
18951
18981
|
if (baseName.endsWith(testExt)) {
|
|
18952
18982
|
baseName = baseName.slice(0, -testExt.length);
|
|
@@ -18955,9 +18985,9 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
18955
18985
|
}
|
|
18956
18986
|
const fileName = `${baseName}.${effectiveName}${ext}`;
|
|
18957
18987
|
if (colocatedStyle === "adjacent") {
|
|
18958
|
-
return toPosix(
|
|
18988
|
+
return toPosix(path8.posix.join(dirOfSource, fileName));
|
|
18959
18989
|
}
|
|
18960
|
-
return toPosix(
|
|
18990
|
+
return toPosix(path8.posix.join(baseOutputDir, dirOfSource, fileName));
|
|
18961
18991
|
}
|
|
18962
18992
|
function groupTestCasesByOutput(testCases, format, options, logger, outputNameSuffix) {
|
|
18963
18993
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -19155,8 +19185,8 @@ var ReportGenerator = class {
|
|
|
19155
19185
|
if (astroPaths) {
|
|
19156
19186
|
for (const mdPath of astroPaths) {
|
|
19157
19187
|
const content = await fsPromises.readFile(mdPath, "utf8");
|
|
19158
|
-
const mdDir =
|
|
19159
|
-
const assetsDir =
|
|
19188
|
+
const mdDir = path8.dirname(mdPath);
|
|
19189
|
+
const assetsDir = path8.resolve(this.options.astro.assetsDir);
|
|
19160
19190
|
const result = copyMarkdownAssets({
|
|
19161
19191
|
markdown: content,
|
|
19162
19192
|
markdownDir: mdDir,
|
|
@@ -19187,9 +19217,9 @@ var ReportGenerator = class {
|
|
|
19187
19217
|
if (groups.size === 0 && this.options.output.mode === "aggregated") {
|
|
19188
19218
|
const ext = FORMAT_EXTENSIONS[format];
|
|
19189
19219
|
const effectiveName = this.options.outputName + (outputNameSuffix ?? "");
|
|
19190
|
-
const outputPath = toPosix(
|
|
19220
|
+
const outputPath = toPosix(path8.join(this.options.outputDir, `${effectiveName}${ext}`));
|
|
19191
19221
|
const content = await this.formatContent(run, format);
|
|
19192
|
-
const dir =
|
|
19222
|
+
const dir = path8.dirname(outputPath);
|
|
19193
19223
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
19194
19224
|
await this.deps.writeFile(outputPath, content);
|
|
19195
19225
|
return [outputPath];
|
|
@@ -19201,7 +19231,7 @@ var ReportGenerator = class {
|
|
|
19201
19231
|
testCases
|
|
19202
19232
|
};
|
|
19203
19233
|
const content = await this.formatContent(groupRun, format);
|
|
19204
|
-
const dir =
|
|
19234
|
+
const dir = path8.dirname(outputPath);
|
|
19205
19235
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
19206
19236
|
await this.deps.writeFile(outputPath, content);
|
|
19207
19237
|
writtenPaths.push(outputPath);
|
|
@@ -19324,7 +19354,7 @@ async function generateRunComparison(args) {
|
|
|
19324
19354
|
await fsPromises.mkdir(outputDir, { recursive: true });
|
|
19325
19355
|
for (const format of args.formats) {
|
|
19326
19356
|
const ext = format === "html" ? ".html" : ".md";
|
|
19327
|
-
const outputPath = toPosix(
|
|
19357
|
+
const outputPath = toPosix(path8.join(outputDir, `${outputName}${ext}`));
|
|
19328
19358
|
const content = format === "html" ? new RunDiffHtmlFormatter({ title: args.title }).format(diff) : new RunDiffMarkdownFormatter({ title: args.title }).format(diff);
|
|
19329
19359
|
await fsPromises.writeFile(outputPath, content, "utf8");
|
|
19330
19360
|
files.push(outputPath);
|