executable-stories-formatters 0.10.0 → 0.11.0
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/README.md +35 -0
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- package/dist/cli.js +1093 -104
- package/dist/cli.js.map +1 -1
- package/dist/{index-CbWFyoTx.d.cts → index-DF16Xl5i.d.cts} +7 -0
- package/dist/{index-CbWFyoTx.d.ts → index-DF16Xl5i.d.ts} +7 -0
- package/dist/index.cjs +130 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -6
- package/dist/index.d.ts +42 -6
- package/dist/index.js +129 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/schemas/raw-run.schema.json +19 -0
- package/schemas/story-report-v1.json +17 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CIInfo, T as TestRunResult, a as TestCaseResult, S as StoryStep, D as DocEntry, b as TestStatus$1, N as NormalizedTicket, A as Attachment, c as DocPhase, O as OtelSpan, d as StepResult, e as CIProvider, R as RawStatus, f as RawAttachment, g as RawRun, h as RawCIInfo, i as adaptJestRun, j as adaptPlaywrightRun, k as adaptVitestRun } from './index-
|
|
2
|
-
export { l as CIInfo, m as CoverageSummary, J as JestAdapterOptions, n as JestAggregatedResult, o as JestFileResult, p as JestTestResult, q as OtelAttributeValue, P as PlaywrightAdapterOptions, r as PlaywrightAnnotation, s as PlaywrightAttachment, t as PlaywrightError, u as PlaywrightLocation, v as PlaywrightStatus, w as PlaywrightTestCase, x as PlaywrightTestResult, y as RawStepEvent, z as RawTestCase, B as STORY_META_KEY, E as StepKeyword, F as StepMode, G as StoryFileReport, H as StoryMeta, I as TestCaseAttempt, K as TestCaseEvidence, V as VitestAdapterOptions, L as VitestSerializedError, M as VitestState, Q as VitestTestCase, U as VitestTestModule, W as VitestTestResult, X as toCIInfo, Y as toRawCIInfo } from './index-
|
|
1
|
+
import { C as CIInfo, T as TestRunResult, a as TestCaseResult, S as StoryStep, D as DocEntry, b as TestStatus$1, N as NormalizedTicket, A as Attachment, c as DocPhase, O as OtelSpan, d as StepResult, e as CIProvider, R as RawStatus, f as RawAttachment, g as RawRun, h as RawCIInfo, i as adaptJestRun, j as adaptPlaywrightRun, k as adaptVitestRun } from './index-DF16Xl5i.cjs';
|
|
2
|
+
export { l as CIInfo, m as CoverageSummary, J as JestAdapterOptions, n as JestAggregatedResult, o as JestFileResult, p as JestTestResult, q as OtelAttributeValue, P as PlaywrightAdapterOptions, r as PlaywrightAnnotation, s as PlaywrightAttachment, t as PlaywrightError, u as PlaywrightLocation, v as PlaywrightStatus, w as PlaywrightTestCase, x as PlaywrightTestResult, y as RawStepEvent, z as RawTestCase, B as STORY_META_KEY, E as StepKeyword, F as StepMode, G as StoryFileReport, H as StoryMeta, I as TestCaseAttempt, K as TestCaseEvidence, V as VitestAdapterOptions, L as VitestSerializedError, M as VitestState, Q as VitestTestCase, U as VitestTestModule, W as VitestTestResult, X as toCIInfo, Y as toRawCIInfo } from './index-DF16Xl5i.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Notification types for webhook integrations (Slack, Teams).
|
|
@@ -155,8 +155,14 @@ type OutputFormat = "astro" | "behavior-manifest-json" | "confluence" | "cucumbe
|
|
|
155
155
|
type SortTestCasesMode = "id" | "source" | "none";
|
|
156
156
|
/** Output mode for report routing */
|
|
157
157
|
type OutputMode = "aggregated" | "colocated";
|
|
158
|
-
/**
|
|
159
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Colocated output style:
|
|
160
|
+
* - `mirrored` — preserve the source directory tree under outputDir (default)
|
|
161
|
+
* - `adjacent` — write next to each source file (ignores outputDir)
|
|
162
|
+
* - `flat` — one page per file directly under outputDir, named by its clean
|
|
163
|
+
* stem (e.g. `convert-currency.md`); best for a browsable docs nav
|
|
164
|
+
*/
|
|
165
|
+
type ColocatedStyle = "mirrored" | "adjacent" | "flat";
|
|
160
166
|
/** Output rule for routing reports based on source file patterns */
|
|
161
167
|
interface OutputRule {
|
|
162
168
|
/** Glob pattern to match sourceFile (uses micromatch, forward slashes) */
|
|
@@ -706,7 +712,7 @@ interface ReportCoverageSummary {
|
|
|
706
712
|
functionsPct?: number;
|
|
707
713
|
statementsPct?: number;
|
|
708
714
|
}
|
|
709
|
-
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocCustom;
|
|
715
|
+
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocCustom;
|
|
710
716
|
interface ReportDocNote {
|
|
711
717
|
kind: "note";
|
|
712
718
|
text: string;
|
|
@@ -770,6 +776,14 @@ interface ReportDocScreenshot {
|
|
|
770
776
|
phase: DocPhase;
|
|
771
777
|
children?: ReportDocEntry[];
|
|
772
778
|
}
|
|
779
|
+
interface ReportDocVideo {
|
|
780
|
+
kind: "video";
|
|
781
|
+
path: string;
|
|
782
|
+
caption?: string;
|
|
783
|
+
poster?: string;
|
|
784
|
+
phase: DocPhase;
|
|
785
|
+
children?: ReportDocEntry[];
|
|
786
|
+
}
|
|
773
787
|
interface ReportDocCustom {
|
|
774
788
|
kind: "custom";
|
|
775
789
|
type: string;
|
|
@@ -1987,13 +2001,27 @@ interface StarlightBadge {
|
|
|
1987
2001
|
}
|
|
1988
2002
|
interface AstroFormatterOptions {
|
|
1989
2003
|
assetsBaseUrl?: string;
|
|
2004
|
+
/**
|
|
2005
|
+
* Title each page by its own suite/file rather than the configured title.
|
|
2006
|
+
* Set by colocated mode (one page per file) so the docs nav reads with
|
|
2007
|
+
* distinct, meaningful labels.
|
|
2008
|
+
*/
|
|
2009
|
+
perFileTitle?: boolean;
|
|
1990
2010
|
markdown?: Omit<MarkdownOptions, "includeFrontMatter" | "includeSummaryTable" | "includeMetadata" | "stepStyle">;
|
|
1991
2011
|
}
|
|
1992
2012
|
declare class AstroFormatter {
|
|
1993
2013
|
private markdownFormatter;
|
|
1994
2014
|
private title;
|
|
2015
|
+
private perFileTitle;
|
|
1995
2016
|
constructor(options?: AstroFormatterOptions);
|
|
1996
2017
|
format(run: TestRunResult): string;
|
|
2018
|
+
/**
|
|
2019
|
+
* Title for the page. A per-file page (one source file — i.e. colocated mode)
|
|
2020
|
+
* is titled by its suite/describe name, falling back to a humanized filename,
|
|
2021
|
+
* so the docs nav reads "Convert Currency" not "User Stories" six times over.
|
|
2022
|
+
* Multi-file (aggregated) pages keep the configured title.
|
|
2023
|
+
*/
|
|
2024
|
+
private deriveTitle;
|
|
1997
2025
|
private buildFrontmatter;
|
|
1998
2026
|
static computeBadge(testCases: Pick<TestCaseResult, "status">[]): StarlightBadge;
|
|
1999
2027
|
}
|
|
@@ -3038,6 +3066,14 @@ interface GenerateCompareResult {
|
|
|
3038
3066
|
files: string[];
|
|
3039
3067
|
diff: RunDiffResult;
|
|
3040
3068
|
}
|
|
3069
|
+
/**
|
|
3070
|
+
* Join an output name with a format extension, collapsing a stutter when the
|
|
3071
|
+
* chosen name already carries the format's tag. With the default name "index",
|
|
3072
|
+
* `story-report-json` writes `index.story-report.json`; but if the caller names
|
|
3073
|
+
* the file `story-report`, this yields `story-report.json`, not
|
|
3074
|
+
* `story-report.story-report.json`.
|
|
3075
|
+
*/
|
|
3076
|
+
declare function joinNameAndExt(name: string, ext: string): string;
|
|
3041
3077
|
/**
|
|
3042
3078
|
* High-level report generator that combines multiple formatters.
|
|
3043
3079
|
*
|
|
@@ -3107,4 +3143,4 @@ declare function normalizeVitestResults(testModules: Parameters<typeof adaptVite
|
|
|
3107
3143
|
*/
|
|
3108
3144
|
declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
|
|
3109
3145
|
|
|
3110
|
-
export { type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, Attachment, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, CIProvider, type CanonicalizeOptions, type ChangeType, type ChangedFile, type ChangedFileReview, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DocEntry, DocPhase, ES_THEME_TOKENS_CSS, ES_THEME_TOKEN_VALUES, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type HistoryEntry, type HistoryStore, HtmlFormatter, type HtmlOptions, type HtmlTheme, type HtmlThemeName, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, NormalizedTicket, type NotificationSummary, type NotifyCondition, OtelSpan, type OtelTraceContext, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, type PerformanceTrend, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, RawAttachment, RawCIInfo, RawRun, RawStatus, type ReportAttachment, type ReportCIInfo, type ReportCoverageSummary, type ReportDocCode, type ReportDocCustom, type ReportDocEntry, type ReportDocKv, type ReportDocLink, type ReportDocMermaid, type ReportDocNote, type ReportDocScreenshot, type ReportDocSection, type ReportDocTable, type ReportDocTag, type ReportFeature, ReportGenerator, type ReportScenario, type ReportStep, type ReportSummary, type ReportTicket, type ResolvedFormatterOptions, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, STORY_REPORT_SCHEMA_MAJOR, STORY_REPORT_SCHEMA_VERSION, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StepResult, type StoryReport, StoryReportJsonFormatter, type StoryReportJsonOptions, type StoryReportSchemaVersion, StoryStep, TestCaseResult, type TestHistory, type TestMetrics, TestRunResult, TestStatus$1 as TestStatus, CIInfo as TypedCIInfo, type ValidationResult, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assertValidRun, buildReview, bundleAssets, calculateFlakiness, calculateStability, canonicalizeRun, classifyStatusChange, clearVersionCache, computeTestMetrics, copyMarkdownAssets, createPrCommentSummary, createReportGenerator, deriveAudience, deriveChangeType, deriveStepResults, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, findGitDir, formatDuration, generateRunComparison, generateRunId, generateTestCaseId, getAvailableThemes, getCssOnlyThemes, gradeEvidence, hasSufficientHistory, isReviewableSource, isTestFile, listScenarios, loadHistory, mergeStepResults, msToNanoseconds, nanosecondsToMs, normalizeJestResults, normalizePlaywrightResults, normalizeStatus, normalizeVitestResults, parseEnvelopes, parseNdjson, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readPackageVersion, regenerateArtifacts, resolveAttachment, resolveAttachments, resolveTheme, resolveTraceUrl, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, signBody, slugify, startWatch, stripAnsi, toBehaviorManifest, toScenarioIndex, toStoryReport, tryGetActiveOtelContext, updateHistory, validateCanonicalRun };
|
|
3146
|
+
export { type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, Attachment, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, CIProvider, type CanonicalizeOptions, type ChangeType, type ChangedFile, type ChangedFileReview, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DocEntry, DocPhase, ES_THEME_TOKENS_CSS, ES_THEME_TOKEN_VALUES, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type HistoryEntry, type HistoryStore, HtmlFormatter, type HtmlOptions, type HtmlTheme, type HtmlThemeName, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, NormalizedTicket, type NotificationSummary, type NotifyCondition, OtelSpan, type OtelTraceContext, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, type PerformanceTrend, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, RawAttachment, RawCIInfo, RawRun, RawStatus, type ReportAttachment, type ReportCIInfo, type ReportCoverageSummary, type ReportDocCode, type ReportDocCustom, type ReportDocEntry, type ReportDocKv, type ReportDocLink, type ReportDocMermaid, type ReportDocNote, type ReportDocScreenshot, type ReportDocSection, type ReportDocTable, type ReportDocTag, type ReportFeature, ReportGenerator, type ReportScenario, type ReportStep, type ReportSummary, type ReportTicket, type ResolvedFormatterOptions, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, STORY_REPORT_SCHEMA_MAJOR, STORY_REPORT_SCHEMA_VERSION, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StepResult, type StoryReport, StoryReportJsonFormatter, type StoryReportJsonOptions, type StoryReportSchemaVersion, StoryStep, TestCaseResult, type TestHistory, type TestMetrics, TestRunResult, TestStatus$1 as TestStatus, CIInfo as TypedCIInfo, type ValidationResult, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assertValidRun, buildReview, bundleAssets, calculateFlakiness, calculateStability, canonicalizeRun, classifyStatusChange, clearVersionCache, computeTestMetrics, copyMarkdownAssets, createPrCommentSummary, createReportGenerator, deriveAudience, deriveChangeType, deriveStepResults, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, findGitDir, formatDuration, generateRunComparison, generateRunId, generateTestCaseId, getAvailableThemes, getCssOnlyThemes, gradeEvidence, hasSufficientHistory, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, mergeStepResults, msToNanoseconds, nanosecondsToMs, normalizeJestResults, normalizePlaywrightResults, normalizeStatus, normalizeVitestResults, parseEnvelopes, parseNdjson, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readPackageVersion, regenerateArtifacts, resolveAttachment, resolveAttachments, resolveTheme, resolveTraceUrl, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, signBody, slugify, startWatch, stripAnsi, toBehaviorManifest, toScenarioIndex, toStoryReport, tryGetActiveOtelContext, updateHistory, validateCanonicalRun };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CIInfo, T as TestRunResult, a as TestCaseResult, S as StoryStep, D as DocEntry, b as TestStatus$1, N as NormalizedTicket, A as Attachment, c as DocPhase, O as OtelSpan, d as StepResult, e as CIProvider, R as RawStatus, f as RawAttachment, g as RawRun, h as RawCIInfo, i as adaptJestRun, j as adaptPlaywrightRun, k as adaptVitestRun } from './index-
|
|
2
|
-
export { l as CIInfo, m as CoverageSummary, J as JestAdapterOptions, n as JestAggregatedResult, o as JestFileResult, p as JestTestResult, q as OtelAttributeValue, P as PlaywrightAdapterOptions, r as PlaywrightAnnotation, s as PlaywrightAttachment, t as PlaywrightError, u as PlaywrightLocation, v as PlaywrightStatus, w as PlaywrightTestCase, x as PlaywrightTestResult, y as RawStepEvent, z as RawTestCase, B as STORY_META_KEY, E as StepKeyword, F as StepMode, G as StoryFileReport, H as StoryMeta, I as TestCaseAttempt, K as TestCaseEvidence, V as VitestAdapterOptions, L as VitestSerializedError, M as VitestState, Q as VitestTestCase, U as VitestTestModule, W as VitestTestResult, X as toCIInfo, Y as toRawCIInfo } from './index-
|
|
1
|
+
import { C as CIInfo, T as TestRunResult, a as TestCaseResult, S as StoryStep, D as DocEntry, b as TestStatus$1, N as NormalizedTicket, A as Attachment, c as DocPhase, O as OtelSpan, d as StepResult, e as CIProvider, R as RawStatus, f as RawAttachment, g as RawRun, h as RawCIInfo, i as adaptJestRun, j as adaptPlaywrightRun, k as adaptVitestRun } from './index-DF16Xl5i.js';
|
|
2
|
+
export { l as CIInfo, m as CoverageSummary, J as JestAdapterOptions, n as JestAggregatedResult, o as JestFileResult, p as JestTestResult, q as OtelAttributeValue, P as PlaywrightAdapterOptions, r as PlaywrightAnnotation, s as PlaywrightAttachment, t as PlaywrightError, u as PlaywrightLocation, v as PlaywrightStatus, w as PlaywrightTestCase, x as PlaywrightTestResult, y as RawStepEvent, z as RawTestCase, B as STORY_META_KEY, E as StepKeyword, F as StepMode, G as StoryFileReport, H as StoryMeta, I as TestCaseAttempt, K as TestCaseEvidence, V as VitestAdapterOptions, L as VitestSerializedError, M as VitestState, Q as VitestTestCase, U as VitestTestModule, W as VitestTestResult, X as toCIInfo, Y as toRawCIInfo } from './index-DF16Xl5i.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Notification types for webhook integrations (Slack, Teams).
|
|
@@ -155,8 +155,14 @@ type OutputFormat = "astro" | "behavior-manifest-json" | "confluence" | "cucumbe
|
|
|
155
155
|
type SortTestCasesMode = "id" | "source" | "none";
|
|
156
156
|
/** Output mode for report routing */
|
|
157
157
|
type OutputMode = "aggregated" | "colocated";
|
|
158
|
-
/**
|
|
159
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Colocated output style:
|
|
160
|
+
* - `mirrored` — preserve the source directory tree under outputDir (default)
|
|
161
|
+
* - `adjacent` — write next to each source file (ignores outputDir)
|
|
162
|
+
* - `flat` — one page per file directly under outputDir, named by its clean
|
|
163
|
+
* stem (e.g. `convert-currency.md`); best for a browsable docs nav
|
|
164
|
+
*/
|
|
165
|
+
type ColocatedStyle = "mirrored" | "adjacent" | "flat";
|
|
160
166
|
/** Output rule for routing reports based on source file patterns */
|
|
161
167
|
interface OutputRule {
|
|
162
168
|
/** Glob pattern to match sourceFile (uses micromatch, forward slashes) */
|
|
@@ -706,7 +712,7 @@ interface ReportCoverageSummary {
|
|
|
706
712
|
functionsPct?: number;
|
|
707
713
|
statementsPct?: number;
|
|
708
714
|
}
|
|
709
|
-
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocCustom;
|
|
715
|
+
type ReportDocEntry = ReportDocNote | ReportDocTag | ReportDocKv | ReportDocCode | ReportDocTable | ReportDocLink | ReportDocSection | ReportDocMermaid | ReportDocScreenshot | ReportDocVideo | ReportDocCustom;
|
|
710
716
|
interface ReportDocNote {
|
|
711
717
|
kind: "note";
|
|
712
718
|
text: string;
|
|
@@ -770,6 +776,14 @@ interface ReportDocScreenshot {
|
|
|
770
776
|
phase: DocPhase;
|
|
771
777
|
children?: ReportDocEntry[];
|
|
772
778
|
}
|
|
779
|
+
interface ReportDocVideo {
|
|
780
|
+
kind: "video";
|
|
781
|
+
path: string;
|
|
782
|
+
caption?: string;
|
|
783
|
+
poster?: string;
|
|
784
|
+
phase: DocPhase;
|
|
785
|
+
children?: ReportDocEntry[];
|
|
786
|
+
}
|
|
773
787
|
interface ReportDocCustom {
|
|
774
788
|
kind: "custom";
|
|
775
789
|
type: string;
|
|
@@ -1987,13 +2001,27 @@ interface StarlightBadge {
|
|
|
1987
2001
|
}
|
|
1988
2002
|
interface AstroFormatterOptions {
|
|
1989
2003
|
assetsBaseUrl?: string;
|
|
2004
|
+
/**
|
|
2005
|
+
* Title each page by its own suite/file rather than the configured title.
|
|
2006
|
+
* Set by colocated mode (one page per file) so the docs nav reads with
|
|
2007
|
+
* distinct, meaningful labels.
|
|
2008
|
+
*/
|
|
2009
|
+
perFileTitle?: boolean;
|
|
1990
2010
|
markdown?: Omit<MarkdownOptions, "includeFrontMatter" | "includeSummaryTable" | "includeMetadata" | "stepStyle">;
|
|
1991
2011
|
}
|
|
1992
2012
|
declare class AstroFormatter {
|
|
1993
2013
|
private markdownFormatter;
|
|
1994
2014
|
private title;
|
|
2015
|
+
private perFileTitle;
|
|
1995
2016
|
constructor(options?: AstroFormatterOptions);
|
|
1996
2017
|
format(run: TestRunResult): string;
|
|
2018
|
+
/**
|
|
2019
|
+
* Title for the page. A per-file page (one source file — i.e. colocated mode)
|
|
2020
|
+
* is titled by its suite/describe name, falling back to a humanized filename,
|
|
2021
|
+
* so the docs nav reads "Convert Currency" not "User Stories" six times over.
|
|
2022
|
+
* Multi-file (aggregated) pages keep the configured title.
|
|
2023
|
+
*/
|
|
2024
|
+
private deriveTitle;
|
|
1997
2025
|
private buildFrontmatter;
|
|
1998
2026
|
static computeBadge(testCases: Pick<TestCaseResult, "status">[]): StarlightBadge;
|
|
1999
2027
|
}
|
|
@@ -3038,6 +3066,14 @@ interface GenerateCompareResult {
|
|
|
3038
3066
|
files: string[];
|
|
3039
3067
|
diff: RunDiffResult;
|
|
3040
3068
|
}
|
|
3069
|
+
/**
|
|
3070
|
+
* Join an output name with a format extension, collapsing a stutter when the
|
|
3071
|
+
* chosen name already carries the format's tag. With the default name "index",
|
|
3072
|
+
* `story-report-json` writes `index.story-report.json`; but if the caller names
|
|
3073
|
+
* the file `story-report`, this yields `story-report.json`, not
|
|
3074
|
+
* `story-report.story-report.json`.
|
|
3075
|
+
*/
|
|
3076
|
+
declare function joinNameAndExt(name: string, ext: string): string;
|
|
3041
3077
|
/**
|
|
3042
3078
|
* High-level report generator that combines multiple formatters.
|
|
3043
3079
|
*
|
|
@@ -3107,4 +3143,4 @@ declare function normalizeVitestResults(testModules: Parameters<typeof adaptVite
|
|
|
3107
3143
|
*/
|
|
3108
3144
|
declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
|
|
3109
3145
|
|
|
3110
|
-
export { type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, Attachment, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, CIProvider, type CanonicalizeOptions, type ChangeType, type ChangedFile, type ChangedFileReview, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DocEntry, DocPhase, ES_THEME_TOKENS_CSS, ES_THEME_TOKEN_VALUES, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type HistoryEntry, type HistoryStore, HtmlFormatter, type HtmlOptions, type HtmlTheme, type HtmlThemeName, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, NormalizedTicket, type NotificationSummary, type NotifyCondition, OtelSpan, type OtelTraceContext, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, type PerformanceTrend, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, RawAttachment, RawCIInfo, RawRun, RawStatus, type ReportAttachment, type ReportCIInfo, type ReportCoverageSummary, type ReportDocCode, type ReportDocCustom, type ReportDocEntry, type ReportDocKv, type ReportDocLink, type ReportDocMermaid, type ReportDocNote, type ReportDocScreenshot, type ReportDocSection, type ReportDocTable, type ReportDocTag, type ReportFeature, ReportGenerator, type ReportScenario, type ReportStep, type ReportSummary, type ReportTicket, type ResolvedFormatterOptions, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, STORY_REPORT_SCHEMA_MAJOR, STORY_REPORT_SCHEMA_VERSION, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StepResult, type StoryReport, StoryReportJsonFormatter, type StoryReportJsonOptions, type StoryReportSchemaVersion, StoryStep, TestCaseResult, type TestHistory, type TestMetrics, TestRunResult, TestStatus$1 as TestStatus, CIInfo as TypedCIInfo, type ValidationResult, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assertValidRun, buildReview, bundleAssets, calculateFlakiness, calculateStability, canonicalizeRun, classifyStatusChange, clearVersionCache, computeTestMetrics, copyMarkdownAssets, createPrCommentSummary, createReportGenerator, deriveAudience, deriveChangeType, deriveStepResults, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, findGitDir, formatDuration, generateRunComparison, generateRunId, generateTestCaseId, getAvailableThemes, getCssOnlyThemes, gradeEvidence, hasSufficientHistory, isReviewableSource, isTestFile, listScenarios, loadHistory, mergeStepResults, msToNanoseconds, nanosecondsToMs, normalizeJestResults, normalizePlaywrightResults, normalizeStatus, normalizeVitestResults, parseEnvelopes, parseNdjson, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readPackageVersion, regenerateArtifacts, resolveAttachment, resolveAttachments, resolveTheme, resolveTraceUrl, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, signBody, slugify, startWatch, stripAnsi, toBehaviorManifest, toScenarioIndex, toStoryReport, tryGetActiveOtelContext, updateHistory, validateCanonicalRun };
|
|
3146
|
+
export { type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, Attachment, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, CIProvider, type CanonicalizeOptions, type ChangeType, type ChangedFile, type ChangedFileReview, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DocEntry, DocPhase, ES_THEME_TOKENS_CSS, ES_THEME_TOKEN_VALUES, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type HistoryEntry, type HistoryStore, HtmlFormatter, type HtmlOptions, type HtmlTheme, type HtmlThemeName, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, NormalizedTicket, type NotificationSummary, type NotifyCondition, OtelSpan, type OtelTraceContext, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, type PerformanceTrend, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, RawAttachment, RawCIInfo, RawRun, RawStatus, type ReportAttachment, type ReportCIInfo, type ReportCoverageSummary, type ReportDocCode, type ReportDocCustom, type ReportDocEntry, type ReportDocKv, type ReportDocLink, type ReportDocMermaid, type ReportDocNote, type ReportDocScreenshot, type ReportDocSection, type ReportDocTable, type ReportDocTag, type ReportFeature, ReportGenerator, type ReportScenario, type ReportStep, type ReportSummary, type ReportTicket, type ResolvedFormatterOptions, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, STORY_REPORT_SCHEMA_MAJOR, STORY_REPORT_SCHEMA_VERSION, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StepResult, type StoryReport, StoryReportJsonFormatter, type StoryReportJsonOptions, type StoryReportSchemaVersion, StoryStep, TestCaseResult, type TestHistory, type TestMetrics, TestRunResult, TestStatus$1 as TestStatus, CIInfo as TypedCIInfo, type ValidationResult, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assertValidRun, buildReview, bundleAssets, calculateFlakiness, calculateStability, canonicalizeRun, classifyStatusChange, clearVersionCache, computeTestMetrics, copyMarkdownAssets, createPrCommentSummary, createReportGenerator, deriveAudience, deriveChangeType, deriveStepResults, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, findGitDir, formatDuration, generateRunComparison, generateRunId, generateTestCaseId, getAvailableThemes, getCssOnlyThemes, gradeEvidence, hasSufficientHistory, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, mergeStepResults, msToNanoseconds, nanosecondsToMs, normalizeJestResults, normalizePlaywrightResults, normalizeStatus, normalizeVitestResults, parseEnvelopes, parseNdjson, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readPackageVersion, regenerateArtifacts, resolveAttachment, resolveAttachments, resolveTheme, resolveTraceUrl, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, signBody, slugify, startWatch, stripAnsi, toBehaviorManifest, toScenarioIndex, toStoryReport, tryGetActiveOtelContext, updateHistory, validateCanonicalRun };
|
package/dist/index.js
CHANGED
|
@@ -763,6 +763,15 @@ function copyDocEntry(entry) {
|
|
|
763
763
|
phase: entry.phase,
|
|
764
764
|
...children
|
|
765
765
|
};
|
|
766
|
+
case "video":
|
|
767
|
+
return {
|
|
768
|
+
kind: "video",
|
|
769
|
+
path: entry.path,
|
|
770
|
+
...entry.caption ? { caption: entry.caption } : {},
|
|
771
|
+
...entry.poster ? { poster: entry.poster } : {},
|
|
772
|
+
phase: entry.phase,
|
|
773
|
+
...children
|
|
774
|
+
};
|
|
766
775
|
case "custom":
|
|
767
776
|
return {
|
|
768
777
|
kind: "custom",
|
|
@@ -13924,6 +13933,23 @@ function renderDocScreenshot(entry, deps) {
|
|
|
13924
13933
|
${entry.alt ? `<div class="doc-screenshot-caption">${deps.escapeHtml(entry.alt)}</div>` : ""}
|
|
13925
13934
|
</div>`;
|
|
13926
13935
|
}
|
|
13936
|
+
function renderDocVideo(entry, deps) {
|
|
13937
|
+
const isRemote = /^(?:https?:|data:)/i.test(entry.path);
|
|
13938
|
+
const isAbsoluteFsPath = !isRemote && /^(?:[/\\]|[A-Za-z]:[/\\])/.test(entry.path);
|
|
13939
|
+
const captionHtml = entry.caption ? `<div class="doc-video-caption">${deps.escapeHtml(entry.caption)}</div>` : "";
|
|
13940
|
+
if ((deps.embedScreenshots ?? true) && isAbsoluteFsPath) {
|
|
13941
|
+
return `<div class="doc-video doc-video-missing">
|
|
13942
|
+
<div class="doc-video-missing-label">Video unavailable</div>
|
|
13943
|
+
<div class="doc-video-missing-path">${deps.escapeHtml(entry.path)}</div>
|
|
13944
|
+
${captionHtml}
|
|
13945
|
+
</div>`;
|
|
13946
|
+
}
|
|
13947
|
+
const poster = entry.poster ? ` poster="${deps.escapeHtml(entry.poster)}"` : "";
|
|
13948
|
+
return `<div class="doc-video">
|
|
13949
|
+
<video class="doc-video-player" controls preload="metadata"${poster} src="${deps.escapeHtml(entry.path)}"></video>
|
|
13950
|
+
${captionHtml}
|
|
13951
|
+
</div>`;
|
|
13952
|
+
}
|
|
13927
13953
|
function renderDocCustom(entry, deps) {
|
|
13928
13954
|
if (entry.type === "visual" && entry.data && typeof entry.data === "object") {
|
|
13929
13955
|
const data = entry.data;
|
|
@@ -13977,6 +14003,9 @@ function renderDocEntry(entry, deps) {
|
|
|
13977
14003
|
case "screenshot":
|
|
13978
14004
|
html = renderDocScreenshot(entry, deps);
|
|
13979
14005
|
break;
|
|
14006
|
+
case "video":
|
|
14007
|
+
html = renderDocVideo(entry, deps);
|
|
14008
|
+
break;
|
|
13980
14009
|
case "custom":
|
|
13981
14010
|
html = renderDocCustom(entry, deps);
|
|
13982
14011
|
break;
|
|
@@ -15303,6 +15332,19 @@ var MarkdownFormatter = class {
|
|
|
15303
15332
|
case "screenshot":
|
|
15304
15333
|
lines.push(`${indent}`);
|
|
15305
15334
|
break;
|
|
15335
|
+
case "video": {
|
|
15336
|
+
const poster = entry.poster ? ` poster="${entry.poster}"` : "";
|
|
15337
|
+
lines.push(`${indent}`);
|
|
15338
|
+
lines.push(`${indent}<video controls preload="metadata"${poster} class="doc-video">`);
|
|
15339
|
+
lines.push(`${indent} <source src="${entry.path}" />`);
|
|
15340
|
+
lines.push(`${indent}</video>`);
|
|
15341
|
+
if (entry.caption) {
|
|
15342
|
+
lines.push(`${indent}`);
|
|
15343
|
+
lines.push(`${indent}*${entry.caption}*`);
|
|
15344
|
+
}
|
|
15345
|
+
lines.push(`${indent}`);
|
|
15346
|
+
break;
|
|
15347
|
+
}
|
|
15306
15348
|
case "custom":
|
|
15307
15349
|
if (entry.type === "visual" && entry.data && typeof entry.data === "object") {
|
|
15308
15350
|
const data = entry.data;
|
|
@@ -16462,6 +16504,8 @@ function formatDocEntry(doc) {
|
|
|
16462
16504
|
return `${escapeHtml2(doc.title ?? "mermaid diagram")}: <code>${escapeHtml2(doc.code)}</code>`;
|
|
16463
16505
|
case "screenshot":
|
|
16464
16506
|
return `${doc.alt ? `${escapeHtml2(doc.alt)}: ` : ""}${escapeHtml2(doc.path)}`;
|
|
16507
|
+
case "video":
|
|
16508
|
+
return `${doc.caption ? `${escapeHtml2(doc.caption)}: ` : ""}${escapeHtml2(doc.path)}`;
|
|
16465
16509
|
case "custom":
|
|
16466
16510
|
return `${escapeHtml2(doc.type)}: ${escapeHtml2(JSON.stringify(doc.data))}`;
|
|
16467
16511
|
}
|
|
@@ -16918,6 +16962,8 @@ function formatDocEntry2(doc) {
|
|
|
16918
16962
|
return `${doc.title ?? "mermaid diagram"}: \`${doc.code}\``;
|
|
16919
16963
|
case "screenshot":
|
|
16920
16964
|
return `${doc.alt ? `${doc.alt}: ` : ""}${doc.path}`;
|
|
16965
|
+
case "video":
|
|
16966
|
+
return `${doc.caption ? `${doc.caption}: ` : ""}${doc.path}`;
|
|
16921
16967
|
case "custom":
|
|
16922
16968
|
return `${doc.type}: ${JSON.stringify(doc.data)}`;
|
|
16923
16969
|
}
|
|
@@ -17163,19 +17209,35 @@ function replaceAssetRef(html, original, replacement) {
|
|
|
17163
17209
|
return html;
|
|
17164
17210
|
}
|
|
17165
17211
|
|
|
17212
|
+
// src/utils/source-file.ts
|
|
17213
|
+
function cleanTestStem(fileName) {
|
|
17214
|
+
const base = fileName.split(/[\\/]/).pop() ?? fileName;
|
|
17215
|
+
const stripped = base.replace(/\.(story\.)?(test|spec|cy)\.[cm]?[jt]sx?$/i, "");
|
|
17216
|
+
if (stripped !== base) return stripped;
|
|
17217
|
+
return base.replace(/\.[^.]+$/, "");
|
|
17218
|
+
}
|
|
17219
|
+
function humanizeSourceFile(fileName) {
|
|
17220
|
+
return cleanTestStem(fileName).split(/[-_.\s]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
17221
|
+
}
|
|
17222
|
+
|
|
17166
17223
|
// src/formatters/astro.ts
|
|
17167
17224
|
var AstroFormatter = class _AstroFormatter {
|
|
17168
17225
|
markdownFormatter;
|
|
17169
17226
|
title;
|
|
17227
|
+
perFileTitle;
|
|
17170
17228
|
constructor(options = {}) {
|
|
17171
17229
|
this.title = options.markdown?.title ?? "User Stories";
|
|
17230
|
+
this.perFileTitle = options.perFileTitle ?? false;
|
|
17172
17231
|
this.markdownFormatter = new MarkdownFormatter({
|
|
17173
17232
|
...options.markdown,
|
|
17174
17233
|
title: this.title,
|
|
17175
17234
|
stepStyle: "gherkin",
|
|
17176
17235
|
includeFrontMatter: false,
|
|
17177
17236
|
includeSummaryTable: false,
|
|
17178
|
-
includeMetadata: false
|
|
17237
|
+
includeMetadata: false,
|
|
17238
|
+
// A per-file page is one file already — group by suite/describe so the
|
|
17239
|
+
// body shows clean section headings, not the redundant source path.
|
|
17240
|
+
groupBy: this.perFileTitle ? "suite" : options.markdown?.groupBy ?? "file"
|
|
17179
17241
|
});
|
|
17180
17242
|
}
|
|
17181
17243
|
format(run) {
|
|
@@ -17185,13 +17247,31 @@ var AstroFormatter = class _AstroFormatter {
|
|
|
17185
17247
|
return `${frontmatter}
|
|
17186
17248
|
${body}`;
|
|
17187
17249
|
}
|
|
17250
|
+
/**
|
|
17251
|
+
* Title for the page. A per-file page (one source file — i.e. colocated mode)
|
|
17252
|
+
* is titled by its suite/describe name, falling back to a humanized filename,
|
|
17253
|
+
* so the docs nav reads "Convert Currency" not "User Stories" six times over.
|
|
17254
|
+
* Multi-file (aggregated) pages keep the configured title.
|
|
17255
|
+
*/
|
|
17256
|
+
deriveTitle(run) {
|
|
17257
|
+
if (!this.perFileTitle) return this.title;
|
|
17258
|
+
const sourceFiles = new Set(
|
|
17259
|
+
run.testCases.map((tc) => tc.sourceFile).filter((f) => f && f !== "unknown")
|
|
17260
|
+
);
|
|
17261
|
+
if (sourceFiles.size !== 1) return this.title;
|
|
17262
|
+
const suites = new Set(
|
|
17263
|
+
run.testCases.map((tc) => tc.titlePath?.[0]).filter((s) => Boolean(s))
|
|
17264
|
+
);
|
|
17265
|
+
if (suites.size === 1) return [...suites][0];
|
|
17266
|
+
return humanizeSourceFile([...sourceFiles][0]) || this.title;
|
|
17267
|
+
}
|
|
17188
17268
|
buildFrontmatter(run) {
|
|
17189
17269
|
const badge = _AstroFormatter.computeBadge(run.testCases);
|
|
17190
17270
|
const count = run.testCases.length;
|
|
17191
17271
|
const description = `${count} scenario${count !== 1 ? "s" : ""} \u2014 ${badge.text.toLowerCase()}`;
|
|
17192
17272
|
const lines = [
|
|
17193
17273
|
"---",
|
|
17194
|
-
`title: ${this.
|
|
17274
|
+
`title: ${yamlScalar(this.deriveTitle(run))}`,
|
|
17195
17275
|
`description: ${description}`,
|
|
17196
17276
|
"sidebar:",
|
|
17197
17277
|
" badge:",
|
|
@@ -17209,6 +17289,12 @@ ${body}`;
|
|
|
17209
17289
|
return { text: "Passed", variant: "success" };
|
|
17210
17290
|
}
|
|
17211
17291
|
};
|
|
17292
|
+
function yamlScalar(value) {
|
|
17293
|
+
if (/[:#[\]{}&*!|>'"%@`]|^[\s-]|\s$/.test(value)) {
|
|
17294
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
17295
|
+
}
|
|
17296
|
+
return value;
|
|
17297
|
+
}
|
|
17212
17298
|
|
|
17213
17299
|
// src/formatters/confluence.ts
|
|
17214
17300
|
var ConfluenceFormatter = class {
|
|
@@ -17485,6 +17571,15 @@ ${tc.errorStack}` : "");
|
|
|
17485
17571
|
])
|
|
17486
17572
|
);
|
|
17487
17573
|
break;
|
|
17574
|
+
case "video":
|
|
17575
|
+
content.push(
|
|
17576
|
+
paragraph([
|
|
17577
|
+
text(entry.caption ?? "Video", strong()),
|
|
17578
|
+
text(": "),
|
|
17579
|
+
link(entry.path, entry.path)
|
|
17580
|
+
])
|
|
17581
|
+
);
|
|
17582
|
+
break;
|
|
17488
17583
|
case "custom":
|
|
17489
17584
|
content.push(paragraph([text(`[${entry.type}]`, strong())]));
|
|
17490
17585
|
content.push(codeBlock(JSON.stringify(entry.data ?? null, null, 2), "json"));
|
|
@@ -17654,6 +17749,13 @@ function scanMarkdownAssets(markdown) {
|
|
|
17654
17749
|
found.add(src);
|
|
17655
17750
|
}
|
|
17656
17751
|
}
|
|
17752
|
+
const posterRe = /<video[^>]+\bposter=["']([^"']+)["'][^>]*>/gi;
|
|
17753
|
+
while ((match = posterRe.exec(stripped)) !== null) {
|
|
17754
|
+
const src = match[1].trim();
|
|
17755
|
+
if (isLocalPath(src)) {
|
|
17756
|
+
found.add(src);
|
|
17757
|
+
}
|
|
17758
|
+
}
|
|
17657
17759
|
return Array.from(found);
|
|
17658
17760
|
}
|
|
17659
17761
|
function splitByCode(markdown) {
|
|
@@ -17704,6 +17806,19 @@ function rewriteProseSegment(prose, assetsBaseUrl, pathMap) {
|
|
|
17704
17806
|
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
17705
17807
|
}
|
|
17706
17808
|
);
|
|
17809
|
+
result = result.replace(
|
|
17810
|
+
/(<video[^>]+\bposter=["'])([^"']+)(["'][^>]*>)/gi,
|
|
17811
|
+
(full, pre, src, post) => {
|
|
17812
|
+
const trimmed = src.trim();
|
|
17813
|
+
if (!isLocalPath(trimmed)) return full;
|
|
17814
|
+
if (pathMap) {
|
|
17815
|
+
const mapped = pathMap.get(trimmed);
|
|
17816
|
+
if (mapped === void 0) return full;
|
|
17817
|
+
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
17818
|
+
}
|
|
17819
|
+
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
17820
|
+
}
|
|
17821
|
+
);
|
|
17707
17822
|
return result;
|
|
17708
17823
|
}
|
|
17709
17824
|
function rewriteAssetPaths(markdown, assetsBaseUrl, pathMap) {
|
|
@@ -20734,6 +20849,10 @@ var FORMAT_EXTENSIONS = {
|
|
|
20734
20849
|
"scenario-index-json": ".scenarios-index.json",
|
|
20735
20850
|
"story-report-json": ".story-report.json"
|
|
20736
20851
|
};
|
|
20852
|
+
function joinNameAndExt(name, ext) {
|
|
20853
|
+
const stutter = `.${name}.`;
|
|
20854
|
+
return ext.startsWith(stutter) ? `${name}.${ext.slice(stutter.length)}` : `${name}${ext}`;
|
|
20855
|
+
}
|
|
20737
20856
|
var TEST_EXTENSIONS = [
|
|
20738
20857
|
".test.ts",
|
|
20739
20858
|
".test.tsx",
|
|
@@ -20759,7 +20878,7 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
20759
20878
|
const ext = FORMAT_EXTENSIONS[format];
|
|
20760
20879
|
const effectiveName = outputName + (outputNameSuffix ?? "");
|
|
20761
20880
|
if (mode === "aggregated") {
|
|
20762
|
-
return toPosix(path10.join(baseOutputDir,
|
|
20881
|
+
return toPosix(path10.join(baseOutputDir, joinNameAndExt(effectiveName, ext)));
|
|
20763
20882
|
}
|
|
20764
20883
|
const normalizedSource = toPosix(sourceFile);
|
|
20765
20884
|
const dirOfSource = path10.posix.dirname(normalizedSource);
|
|
@@ -20774,6 +20893,9 @@ function computeOutputPath(sourceFile, format, mode, colocatedStyle, baseOutputD
|
|
|
20774
20893
|
if (colocatedStyle === "adjacent") {
|
|
20775
20894
|
return toPosix(path10.posix.join(dirOfSource, fileName));
|
|
20776
20895
|
}
|
|
20896
|
+
if (colocatedStyle === "flat") {
|
|
20897
|
+
return toPosix(path10.posix.join(baseOutputDir, `${cleanTestStem(normalizedSource)}${ext}`));
|
|
20898
|
+
}
|
|
20777
20899
|
return toPosix(path10.posix.join(baseOutputDir, dirOfSource, fileName));
|
|
20778
20900
|
}
|
|
20779
20901
|
function groupTestCasesByOutput(testCases, format, options, logger, outputNameSuffix) {
|
|
@@ -21013,7 +21135,7 @@ var ReportGenerator = class {
|
|
|
21013
21135
|
if (groups.size === 0 && this.options.output.mode === "aggregated") {
|
|
21014
21136
|
const ext = FORMAT_EXTENSIONS[format];
|
|
21015
21137
|
const effectiveName = this.options.outputName + (outputNameSuffix ?? "");
|
|
21016
|
-
const outputPath = toPosix(path10.join(this.options.outputDir,
|
|
21138
|
+
const outputPath = toPosix(path10.join(this.options.outputDir, joinNameAndExt(effectiveName, ext)));
|
|
21017
21139
|
const content = await this.formatContent(run, format);
|
|
21018
21140
|
const dir = path10.dirname(outputPath);
|
|
21019
21141
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
@@ -21093,6 +21215,8 @@ var ReportGenerator = class {
|
|
|
21093
21215
|
case "astro": {
|
|
21094
21216
|
const formatter = new AstroFormatter({
|
|
21095
21217
|
assetsBaseUrl: this.options.astro.assetsBaseUrl,
|
|
21218
|
+
// Colocated = one page per file, so title each by its own suite/file.
|
|
21219
|
+
perFileTitle: this.options.output.mode === "colocated",
|
|
21096
21220
|
markdown: this.options.astro.markdown
|
|
21097
21221
|
});
|
|
21098
21222
|
return formatter.format(run);
|
|
@@ -21245,6 +21369,7 @@ export {
|
|
|
21245
21369
|
hasSufficientHistory,
|
|
21246
21370
|
isReviewableSource,
|
|
21247
21371
|
isTestFile,
|
|
21372
|
+
joinNameAndExt,
|
|
21248
21373
|
listScenarios,
|
|
21249
21374
|
loadHistory,
|
|
21250
21375
|
mergeStepResults,
|