executable-stories-formatters 0.7.10 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
2
  import "fs";
3
- import * as path7 from "path";
3
+ import * as path8 from "path";
4
4
  import * as fsPromises from "fs/promises";
5
5
 
6
6
  // src/converters/acl/status.ts
@@ -653,6 +653,10 @@ ${doc.markdown}`,
653
653
  }
654
654
  };
655
655
 
656
+ // src/formatters/html/renderers/index.ts
657
+ import * as fs2 from "fs";
658
+ import * as path2 from "path";
659
+
656
660
  // src/formatters/html/template.ts
657
661
  var JS_THEME = `
658
662
  // Theme management
@@ -2311,6 +2315,27 @@ body {
2311
2315
  border: 1px solid var(--border);
2312
2316
  }
2313
2317
 
2318
+ .attachment-unavailable {
2319
+ padding: 0.75rem 1rem;
2320
+ border: 1px dashed var(--border);
2321
+ border-radius: calc(var(--radius) - 2px);
2322
+ background: var(--muted, transparent);
2323
+ color: var(--muted-foreground);
2324
+ font-size: 0.8125rem;
2325
+ }
2326
+
2327
+ .attachment-unavailable-label {
2328
+ font-weight: 600;
2329
+ margin-bottom: 0.25rem;
2330
+ }
2331
+
2332
+ .attachment-unavailable-path {
2333
+ font-family: var(--font-mono, ui-monospace, monospace);
2334
+ font-size: 0.75rem;
2335
+ word-break: break-all;
2336
+ opacity: 0.8;
2337
+ }
2338
+
2314
2339
  /* ============================================================================
2315
2340
  Chevron Icon - smooth rotation
2316
2341
  ============================================================================ */
@@ -2876,6 +2901,27 @@ body {
2876
2901
  font-style: italic;
2877
2902
  }
2878
2903
 
2904
+ .doc-screenshot-missing {
2905
+ padding: 0.75rem 1rem;
2906
+ border: 1px dashed var(--border);
2907
+ border-radius: calc(var(--radius) - 2px);
2908
+ background: var(--muted, transparent);
2909
+ color: var(--muted-foreground);
2910
+ font-size: 0.8125rem;
2911
+ }
2912
+
2913
+ .doc-screenshot-missing-label {
2914
+ font-weight: 600;
2915
+ margin-bottom: 0.25rem;
2916
+ }
2917
+
2918
+ .doc-screenshot-missing-path {
2919
+ font-family: var(--font-mono, ui-monospace, monospace);
2920
+ font-size: 0.75rem;
2921
+ word-break: break-all;
2922
+ opacity: 0.8;
2923
+ }
2924
+
2879
2925
  /* ============================================================================
2880
2926
  Documentation Entries - Custom
2881
2927
  ============================================================================ */
@@ -12853,11 +12899,18 @@ function renderTagBar(args, deps) {
12853
12899
  </div>`;
12854
12900
  }
12855
12901
 
12902
+ // src/notifiers/ansi-strip.ts
12903
+ function stripAnsi(text2) {
12904
+ return text2.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
12905
+ }
12906
+
12856
12907
  // src/formatters/html/renderers/error-box.ts
12857
12908
  function renderErrorBox(args, deps) {
12858
- const body = args.stack != null ? `${deps.escapeHtml(args.message)}
12909
+ const message = stripAnsi(args.message);
12910
+ const stack = args.stack != null ? stripAnsi(args.stack) : void 0;
12911
+ const body = stack != null ? `${deps.escapeHtml(message)}
12859
12912
 
12860
- ${deps.escapeHtml(args.stack)}` : deps.escapeHtml(args.message);
12913
+ ${deps.escapeHtml(stack)}` : deps.escapeHtml(message);
12861
12914
  return `<div class="error-box">${body}</div>`;
12862
12915
  }
12863
12916
 
@@ -12870,6 +12923,7 @@ function renderAttachments(args, deps) {
12870
12923
  const isImage = att.mediaType.startsWith("image/");
12871
12924
  const isVideo = att.mediaType.startsWith("video/");
12872
12925
  const isBase64 = att.contentEncoding === "BASE64";
12926
+ const isUnreachableFsPath = deps.embedScreenshots && !isBase64 && typeof att.body === "string" && /^(?:[/\\]|[A-Za-z]:[/\\])/.test(att.body);
12873
12927
  if (isImage && deps.embedScreenshots && isBase64) {
12874
12928
  return `
12875
12929
  <div class="attachment">
@@ -12877,12 +12931,19 @@ function renderAttachments(args, deps) {
12877
12931
  <img class="attachment-image" src="data:${att.mediaType};base64,${att.body}" alt="${deps.escapeHtml(att.name)}" />
12878
12932
  </div>`;
12879
12933
  }
12880
- if (isVideo && deps.embedScreenshots) {
12934
+ if (isVideo && deps.embedScreenshots && !isUnreachableFsPath) {
12881
12935
  const src = isBase64 ? `data:${att.mediaType};base64,${att.body}` : att.body;
12882
12936
  return `
12883
12937
  <div class="attachment">
12884
12938
  ${deps.escapeHtml(att.name)}
12885
12939
  <video class="attachment-video" controls src="${deps.escapeHtml(src)}"></video>
12940
+ </div>`;
12941
+ }
12942
+ if (isUnreachableFsPath) {
12943
+ return `
12944
+ <div class="attachment attachment-unavailable">
12945
+ <div class="attachment-unavailable-label">${deps.escapeHtml(att.name)} unavailable</div>
12946
+ <div class="attachment-unavailable-path">${deps.escapeHtml(att.body)}</div>
12886
12947
  </div>`;
12887
12948
  }
12888
12949
  const href = isBase64 ? `data:${att.mediaType};base64,${att.body}` : att.body;
@@ -12963,7 +13024,20 @@ function renderDocMermaid(entry, deps) {
12963
13024
  }
12964
13025
  function renderDocScreenshot(entry, deps) {
12965
13026
  const alt = entry.alt ?? "Screenshot";
12966
- const src = entry.path;
13027
+ const embedEnabled = deps.embedScreenshots ?? true;
13028
+ const isRemote = /^(?:https?:|data:)/i.test(entry.path);
13029
+ const embedAttempted = !isRemote && embedEnabled && !!deps.readScreenshot;
13030
+ const inlined = embedAttempted ? deps.readScreenshot(entry.path) : void 0;
13031
+ const isAbsoluteFsPath = !isRemote && /^(?:[/\\]|[A-Za-z]:[/\\])/.test(entry.path);
13032
+ if (embedAttempted && inlined === void 0 && isAbsoluteFsPath) {
13033
+ const captionHtml = entry.alt ? `<div class="doc-screenshot-caption">${deps.escapeHtml(entry.alt)}</div>` : "";
13034
+ return `<div class="doc-screenshot doc-screenshot-missing">
13035
+ <div class="doc-screenshot-missing-label">Screenshot unavailable</div>
13036
+ <div class="doc-screenshot-missing-path">${deps.escapeHtml(entry.path)}</div>
13037
+ ${captionHtml}
13038
+ </div>`;
13039
+ }
13040
+ const src = inlined ?? entry.path;
12967
13041
  return `<div class="doc-screenshot">
12968
13042
  <img src="${deps.escapeHtml(src)}" alt="${deps.escapeHtml(alt)}" class="doc-screenshot-img" />
12969
13043
  ${entry.alt ? `<div class="doc-screenshot-caption">${deps.escapeHtml(entry.alt)}</div>` : ""}
@@ -13550,6 +13624,28 @@ function renderToc(args, deps) {
13550
13624
  }
13551
13625
 
13552
13626
  // src/formatters/html/renderers/index.ts
13627
+ var SCREENSHOT_MIME_BY_EXT = {
13628
+ png: "image/png",
13629
+ jpg: "image/jpeg",
13630
+ jpeg: "image/jpeg",
13631
+ gif: "image/gif",
13632
+ webp: "image/webp",
13633
+ svg: "image/svg+xml",
13634
+ avif: "image/avif",
13635
+ bmp: "image/bmp"
13636
+ };
13637
+ function readScreenshotAsDataUri(filePath) {
13638
+ try {
13639
+ const ext = path2.extname(filePath).slice(1).toLowerCase();
13640
+ const mime = SCREENSHOT_MIME_BY_EXT[ext];
13641
+ if (!mime) return void 0;
13642
+ if (!fs2.existsSync(filePath)) return void 0;
13643
+ const buf = fs2.readFileSync(filePath);
13644
+ return `data:${mime};base64,${buf.toString("base64")}`;
13645
+ } catch {
13646
+ return void 0;
13647
+ }
13648
+ }
13553
13649
  function normalizeOptions(options = {}) {
13554
13650
  return {
13555
13651
  title: options.title ?? "Test Results",
@@ -13573,7 +13669,9 @@ function createHtmlFormatter(options = {}) {
13573
13669
  escapeHtml,
13574
13670
  syntaxHighlighting: opts.syntaxHighlighting,
13575
13671
  markdownEnabled: opts.markdownEnabled,
13576
- mermaidEnabled: opts.mermaidEnabled
13672
+ mermaidEnabled: opts.mermaidEnabled,
13673
+ embedScreenshots: opts.embedScreenshots,
13674
+ readScreenshot: (filePath) => readScreenshotAsDataUri(filePath)
13577
13675
  };
13578
13676
  const renderDocs = (docs, containerClass) => {
13579
13677
  if (!docs || docs.length === 0) return "";
@@ -15002,8 +15100,8 @@ function extractDocAttachments(step) {
15002
15100
  }
15003
15101
  return attachments;
15004
15102
  }
15005
- function guessMediaType(path8) {
15006
- const lower = path8.toLowerCase();
15103
+ function guessMediaType(path9) {
15104
+ const lower = path9.toLowerCase();
15007
15105
  if (lower.endsWith(".png")) return "image/png";
15008
15106
  if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
15009
15107
  if (lower.endsWith(".gif")) return "image/gif";
@@ -16047,8 +16145,8 @@ function selectTestCases(args, deps) {
16047
16145
  }
16048
16146
 
16049
16147
  // src/bundler/bundle-assets.ts
16050
- import * as fs3 from "fs";
16051
- import * as path3 from "path";
16148
+ import * as fs4 from "fs";
16149
+ import * as path4 from "path";
16052
16150
 
16053
16151
  // src/bundler/scan-html-assets.ts
16054
16152
  function scanHtmlAssets(html) {
@@ -16078,21 +16176,21 @@ function isLocalAssetRef(ref) {
16078
16176
  }
16079
16177
 
16080
16178
  // src/bundler/copy-asset.ts
16081
- import * as fs2 from "fs";
16082
- import * as path2 from "path";
16179
+ import * as fs3 from "fs";
16180
+ import * as path3 from "path";
16083
16181
  import * as crypto from "crypto";
16084
16182
  function copyAsset(sourcePath, assetsDir) {
16085
- if (!fs2.existsSync(assetsDir)) {
16086
- fs2.mkdirSync(assetsDir, { recursive: true });
16183
+ if (!fs3.existsSync(assetsDir)) {
16184
+ fs3.mkdirSync(assetsDir, { recursive: true });
16087
16185
  }
16088
- const content = fs2.readFileSync(sourcePath);
16186
+ const content = fs3.readFileSync(sourcePath);
16089
16187
  const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
16090
- const ext = path2.extname(sourcePath);
16091
- const baseName = sanitize(path2.basename(sourcePath, ext));
16188
+ const ext = path3.extname(sourcePath);
16189
+ const baseName = sanitize(path3.basename(sourcePath, ext));
16092
16190
  const destName = `${baseName}-${hash}${ext}`;
16093
- const destPath = path2.join(assetsDir, destName);
16094
- if (!fs2.existsSync(destPath)) {
16095
- fs2.copyFileSync(sourcePath, destPath);
16191
+ const destPath = path3.join(assetsDir, destName);
16192
+ if (!fs3.existsSync(destPath)) {
16193
+ fs3.copyFileSync(sourcePath, destPath);
16096
16194
  }
16097
16195
  return `assets/${destName}`;
16098
16196
  }
@@ -16102,15 +16200,15 @@ function sanitize(name) {
16102
16200
 
16103
16201
  // src/bundler/bundle-assets.ts
16104
16202
  function bundleAssets(htmlPath, options = {}) {
16105
- const htmlDir = path3.dirname(htmlPath);
16106
- const assetsDir = path3.join(htmlDir, "assets");
16107
- let html = fs3.readFileSync(htmlPath, "utf8");
16203
+ const htmlDir = path4.dirname(htmlPath);
16204
+ const assetsDir = path4.join(htmlDir, "assets");
16205
+ let html = fs4.readFileSync(htmlPath, "utf8");
16108
16206
  const refs = scanHtmlAssets(html);
16109
16207
  let copiedCount = 0;
16110
16208
  const missing = [];
16111
16209
  for (const ref of refs) {
16112
- const absolutePath = path3.resolve(htmlDir, ref);
16113
- if (!fs3.existsSync(absolutePath)) {
16210
+ const absolutePath = path4.resolve(htmlDir, ref);
16211
+ if (!fs4.existsSync(absolutePath)) {
16114
16212
  missing.push(ref);
16115
16213
  continue;
16116
16214
  }
@@ -16123,7 +16221,7 @@ function bundleAssets(htmlPath, options = {}) {
16123
16221
  `Missing asset${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`
16124
16222
  );
16125
16223
  }
16126
- fs3.writeFileSync(htmlPath, html, "utf8");
16224
+ fs4.writeFileSync(htmlPath, html, "utf8");
16127
16225
  return {
16128
16226
  copiedCount,
16129
16227
  missingCount: missing.length,
@@ -16606,15 +16704,15 @@ function groupBy7(items, keyFn) {
16606
16704
  }
16607
16705
 
16608
16706
  // src/formatters/astro-assets.ts
16609
- import * as fs4 from "fs";
16610
- import * as path4 from "path";
16707
+ import * as fs5 from "fs";
16708
+ import * as path5 from "path";
16611
16709
  var SKIP_PREFIXES = ["http://", "https://", "data:", "#"];
16612
16710
  function isLocalPath(src) {
16613
16711
  const trimmed = src.trim();
16614
16712
  if (SKIP_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
16615
16713
  return false;
16616
16714
  }
16617
- return !path4.posix.isAbsolute(trimmed) && !path4.win32.isAbsolute(trimmed);
16715
+ return !path5.posix.isAbsolute(trimmed) && !path5.win32.isAbsolute(trimmed);
16618
16716
  }
16619
16717
  function stripCodeContent(markdown) {
16620
16718
  let result = markdown.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$/gm, "");
@@ -16708,8 +16806,8 @@ function copyMarkdownAssets(options) {
16708
16806
  const pathMap = /* @__PURE__ */ new Map();
16709
16807
  const missing = [];
16710
16808
  for (const ref of refs) {
16711
- const absPath = path4.resolve(markdownDir, ref);
16712
- if (!fs4.existsSync(absPath)) {
16809
+ const absPath = path5.resolve(markdownDir, ref);
16810
+ if (!fs5.existsSync(absPath)) {
16713
16811
  if (!allowMissing) {
16714
16812
  throw new Error(`Asset not found: ${absPath}`);
16715
16813
  }
@@ -17725,27 +17823,27 @@ function pickleStepArgumentToDocs(ps) {
17725
17823
  }
17726
17824
 
17727
17825
  // src/utils/git-info.ts
17728
- import * as fs5 from "fs";
17729
- import * as path5 from "path";
17826
+ import * as fs6 from "fs";
17827
+ import * as path6 from "path";
17730
17828
  function readGitSha(cwd = process.cwd()) {
17731
17829
  const envSha = process.env.GITHUB_SHA || process.env.GIT_COMMIT || process.env.CI_COMMIT_SHA;
17732
17830
  if (envSha) return envSha;
17733
17831
  const gitDir = findGitDir(cwd);
17734
17832
  if (!gitDir) return void 0;
17735
17833
  try {
17736
- const headPath = path5.join(gitDir, "HEAD");
17737
- const head = fs5.readFileSync(headPath, "utf8").trim();
17834
+ const headPath = path6.join(gitDir, "HEAD");
17835
+ const head = fs6.readFileSync(headPath, "utf8").trim();
17738
17836
  if (!head.startsWith("ref:")) {
17739
17837
  return head;
17740
17838
  }
17741
17839
  const refPath = head.replace("ref:", "").trim();
17742
- const refFile = path5.join(gitDir, refPath);
17743
- if (fs5.existsSync(refFile)) {
17744
- return fs5.readFileSync(refFile, "utf8").trim();
17840
+ const refFile = path6.join(gitDir, refPath);
17841
+ if (fs6.existsSync(refFile)) {
17842
+ return fs6.readFileSync(refFile, "utf8").trim();
17745
17843
  }
17746
- const packedRefs = path5.join(gitDir, "packed-refs");
17747
- if (fs5.existsSync(packedRefs)) {
17748
- const content = fs5.readFileSync(packedRefs, "utf8");
17844
+ const packedRefs = path6.join(gitDir, "packed-refs");
17845
+ if (fs6.existsSync(packedRefs)) {
17846
+ const content = fs6.readFileSync(packedRefs, "utf8");
17749
17847
  for (const line of content.split("\n")) {
17750
17848
  if (!line || line.startsWith("#") || line.startsWith("^")) continue;
17751
17849
  const [sha, ref] = line.split(" ");
@@ -17760,19 +17858,19 @@ function readGitSha(cwd = process.cwd()) {
17760
17858
  function findGitDir(start) {
17761
17859
  let current = start;
17762
17860
  while (true) {
17763
- const candidate = path5.join(current, ".git");
17764
- if (fs5.existsSync(candidate)) {
17765
- const stat = fs5.statSync(candidate);
17861
+ const candidate = path6.join(current, ".git");
17862
+ if (fs6.existsSync(candidate)) {
17863
+ const stat = fs6.statSync(candidate);
17766
17864
  if (stat.isFile()) {
17767
- const content = fs5.readFileSync(candidate, "utf8").trim();
17865
+ const content = fs6.readFileSync(candidate, "utf8").trim();
17768
17866
  const match = content.match(/^gitdir: (.+)$/);
17769
17867
  if (match) {
17770
- return path5.resolve(current, match[1]);
17868
+ return path6.resolve(current, match[1]);
17771
17869
  }
17772
17870
  }
17773
17871
  return candidate;
17774
17872
  }
17775
- const parent = path5.dirname(current);
17873
+ const parent = path6.dirname(current);
17776
17874
  if (parent === current) return void 0;
17777
17875
  current = parent;
17778
17876
  }
@@ -17783,8 +17881,8 @@ function readBranchName(cwd = process.cwd()) {
17783
17881
  const gitDir = findGitDir(cwd);
17784
17882
  if (!gitDir) return void 0;
17785
17883
  try {
17786
- const headPath = path5.join(gitDir, "HEAD");
17787
- const head = fs5.readFileSync(headPath, "utf8").trim();
17884
+ const headPath = path6.join(gitDir, "HEAD");
17885
+ const head = fs6.readFileSync(headPath, "utf8").trim();
17788
17886
  if (head.startsWith("ref:")) {
17789
17887
  const refPath = head.replace("ref:", "").trim();
17790
17888
  const match = refPath.match(/^refs\/heads\/(.+)$/);
@@ -17821,8 +17919,8 @@ function nanosecondsToMs(ns) {
17821
17919
  }
17822
17920
 
17823
17921
  // src/utils/metadata.ts
17824
- import * as fs6 from "fs";
17825
- import * as path6 from "path";
17922
+ import * as fs7 from "fs";
17923
+ import * as path7 from "path";
17826
17924
  var versionCache = /* @__PURE__ */ new Map();
17827
17925
  function readPackageVersion(root) {
17828
17926
  if (versionCache.has(root)) {
@@ -17833,18 +17931,18 @@ function readPackageVersion(root) {
17833
17931
  return version;
17834
17932
  }
17835
17933
  function findPackageVersion(startDir) {
17836
- let current = path6.resolve(startDir);
17934
+ let current = path7.resolve(startDir);
17837
17935
  while (true) {
17838
- const pkgPath = path6.join(current, "package.json");
17936
+ const pkgPath = path7.join(current, "package.json");
17839
17937
  try {
17840
- if (fs6.existsSync(pkgPath)) {
17841
- const raw = fs6.readFileSync(pkgPath, "utf8");
17938
+ if (fs7.existsSync(pkgPath)) {
17939
+ const raw = fs7.readFileSync(pkgPath, "utf8");
17842
17940
  const parsed = JSON.parse(raw);
17843
17941
  return parsed.version;
17844
17942
  }
17845
17943
  } catch {
17846
17944
  }
17847
- const parent = path6.dirname(current);
17945
+ const parent = path7.dirname(current);
17848
17946
  if (parent === current) {
17849
17947
  return void 0;
17850
17948
  }
@@ -17983,11 +18081,6 @@ function resolveTraceUrl(template, traceId) {
17983
18081
  return template.replace(/\{traceId\}/g, traceId);
17984
18082
  }
17985
18083
 
17986
- // src/notifiers/ansi-strip.ts
17987
- function stripAnsi(text2) {
17988
- return text2.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
17989
- }
17990
-
17991
18084
  // src/notifiers/slack.ts
17992
18085
  function truncate(text2, maxLen) {
17993
18086
  if (text2.length <= maxLen) return text2;
@@ -18834,11 +18927,11 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
18834
18927
  const ext = FORMAT_EXTENSIONS[format];
18835
18928
  const effectiveName = outputName + (outputNameSuffix ?? "");
18836
18929
  if (mode === "aggregated") {
18837
- return toPosix(path7.join(baseOutputDir, `${effectiveName}${ext}`));
18930
+ return toPosix(path8.join(baseOutputDir, `${effectiveName}${ext}`));
18838
18931
  }
18839
18932
  const normalizedSource = toPosix(sourceFile);
18840
- const dirOfSource = path7.posix.dirname(normalizedSource);
18841
- let baseName = path7.posix.basename(normalizedSource);
18933
+ const dirOfSource = path8.posix.dirname(normalizedSource);
18934
+ let baseName = path8.posix.basename(normalizedSource);
18842
18935
  for (const testExt of TEST_EXTENSIONS) {
18843
18936
  if (baseName.endsWith(testExt)) {
18844
18937
  baseName = baseName.slice(0, -testExt.length);
@@ -18847,9 +18940,9 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
18847
18940
  }
18848
18941
  const fileName = `${baseName}.${effectiveName}${ext}`;
18849
18942
  if (colocatedStyle === "adjacent") {
18850
- return toPosix(path7.posix.join(dirOfSource, fileName));
18943
+ return toPosix(path8.posix.join(dirOfSource, fileName));
18851
18944
  }
18852
- return toPosix(path7.posix.join(baseOutputDir, dirOfSource, fileName));
18945
+ return toPosix(path8.posix.join(baseOutputDir, dirOfSource, fileName));
18853
18946
  }
18854
18947
  function groupTestCasesByOutput(testCases, format, options, logger, outputNameSuffix) {
18855
18948
  const groups = /* @__PURE__ */ new Map();
@@ -19047,8 +19140,8 @@ var ReportGenerator = class {
19047
19140
  if (astroPaths) {
19048
19141
  for (const mdPath of astroPaths) {
19049
19142
  const content = await fsPromises.readFile(mdPath, "utf8");
19050
- const mdDir = path7.dirname(mdPath);
19051
- const assetsDir = path7.resolve(this.options.astro.assetsDir);
19143
+ const mdDir = path8.dirname(mdPath);
19144
+ const assetsDir = path8.resolve(this.options.astro.assetsDir);
19052
19145
  const result = copyMarkdownAssets({
19053
19146
  markdown: content,
19054
19147
  markdownDir: mdDir,
@@ -19079,9 +19172,9 @@ var ReportGenerator = class {
19079
19172
  if (groups.size === 0 && this.options.output.mode === "aggregated") {
19080
19173
  const ext = FORMAT_EXTENSIONS[format];
19081
19174
  const effectiveName = this.options.outputName + (outputNameSuffix ?? "");
19082
- const outputPath = toPosix(path7.join(this.options.outputDir, `${effectiveName}${ext}`));
19175
+ const outputPath = toPosix(path8.join(this.options.outputDir, `${effectiveName}${ext}`));
19083
19176
  const content = await this.formatContent(run, format);
19084
- const dir = path7.dirname(outputPath);
19177
+ const dir = path8.dirname(outputPath);
19085
19178
  await fsPromises.mkdir(dir, { recursive: true });
19086
19179
  await this.deps.writeFile(outputPath, content);
19087
19180
  return [outputPath];
@@ -19093,7 +19186,7 @@ var ReportGenerator = class {
19093
19186
  testCases
19094
19187
  };
19095
19188
  const content = await this.formatContent(groupRun, format);
19096
- const dir = path7.dirname(outputPath);
19189
+ const dir = path8.dirname(outputPath);
19097
19190
  await fsPromises.mkdir(dir, { recursive: true });
19098
19191
  await this.deps.writeFile(outputPath, content);
19099
19192
  writtenPaths.push(outputPath);
@@ -19216,7 +19309,7 @@ async function generateRunComparison(args) {
19216
19309
  await fsPromises.mkdir(outputDir, { recursive: true });
19217
19310
  for (const format of args.formats) {
19218
19311
  const ext = format === "html" ? ".html" : ".md";
19219
- const outputPath = toPosix(path7.join(outputDir, `${outputName}${ext}`));
19312
+ const outputPath = toPosix(path8.join(outputDir, `${outputName}${ext}`));
19220
19313
  const content = format === "html" ? new RunDiffHtmlFormatter({ title: args.title }).format(diff) : new RunDiffMarkdownFormatter({ title: args.title }).format(diff);
19221
19314
  await fsPromises.writeFile(outputPath, content, "utf8");
19222
19315
  files.push(outputPath);