Skip to content

Vitest reporter options

Use the /reporter subpath in your config so Vitest is not loaded in the config context:

import { StoryReporter } from 'executable-stories-vitest/reporter';
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
reporters: [
'default',
new StoryReporter({
/* options */
}),
],
},
});

The reporter uses FormatterOptions from executable-stories-formatters. All options are optional. When you pass no options, the formatters package defaults apply (for example formats: ["cucumber-json"], outputDir: "reports"). To get Markdown written to docs/user-stories.md, pass options explicitly as in the examples below.

OptionTypeDefaultDescription
formatsOutputFormat[]["cucumber-json"]Output formats: "markdown", "html", "junit", "cucumber-json", "cucumber-messages", "cucumber-html".
outputDirstring"reports"Base directory for output files.
outputNamestring"test-results"Base filename (without extension).
outputNameTimestampbooleanfalseAppend a UTC timestamp suffix to the output filename.
outputOutputConfig{ mode: "aggregated" }Output routing configuration.
FieldTypeDefaultDescription
mode"aggregated" | "colocated""aggregated"Single file vs one file per source.
colocatedStyle"mirrored" | "adjacent""mirrored"Colocated: mirrored under outputDir or next to source file.
rulesOutputRule[][]Pattern-based overrides (first match wins).

Nested under markdown:

OptionTypeDefaultDescription
titlestring"User Stories"Report title.
includeStatusIconsbooleantrueShow ✅❌⏩ icons.
includeErrorsbooleantrueShow failure details.
includeMetadatabooleantrueShow date/version/git SHA.
sortScenarios"alpha" | "source""source"Sort order for scenarios.
suiteSeparatorstring" - "Separator for nested describes.
includeFrontMatterbooleanfalseInclude YAML front-matter.
includeSummaryTablebooleanfalseAdd summary statistics table.
permalinkBaseUrlstringBase URL for source links (e.g. GitHub blob).
ticketUrlTemplatestringURL template for ticket links. Use {ticket} as placeholder.
traceUrlTemplatestringURL template for trace links. Use {traceId} as placeholder.
includeSourceLinksbooleantrueInclude source links when permalinkBaseUrl is set.

Top-level FormatterOptions also support:

  • include / exclude for filtering by sourceFile
  • includeTags / excludeTags for filtering by story tags
  • history.filePath and history.maxRuns for HTML flakiness, stability, and performance trends
  • notification.* for Slack, Teams, and generic webhook notifications
OptionTypeDescription
htmlHtmlOptionstitle, darkMode, searchable, startCollapsed, embedScreenshots.
junitJUnitOptionssuiteName, includeOutput.
cucumberJson{ pretty?: boolean }Pretty-print JSON output.
OptionTypeDefaultDescription
enableGithubActionsSummarybooleantrueWhen GITHUB_ACTIONS, append report to job summary.
rawRunPathstringWrite the raw run JSON to disk for later CLI use.
import { StoryReporter } from 'executable-stories-vitest/reporter';
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
reporters: [
'default',
new StoryReporter({
formats: ['markdown'],
outputDir: 'docs',
outputName: 'user-stories',
output: { mode: 'aggregated' },
markdown: {
title: 'User Stories',
includeStatusIcons: true,
includeMetadata: true,
},
}),
],
},
});
new StoryReporter({
formats: ['markdown', 'html', 'cucumber-json'],
outputDir: 'reports',
outputName: 'test-results',
output: { mode: 'aggregated' },
});
new StoryReporter({
formats: ['markdown'],
outputDir: 'docs',
output: {
mode: 'colocated',
colocatedStyle: 'mirrored', // Files mirror source structure under outputDir
},
});
new StoryReporter({
formats: ['markdown'],
output: {
mode: 'aggregated',
rules: [
{
match: '**/*.story.test.ts',
mode: 'colocated',
colocatedStyle: 'adjacent',
},
{ match: 'e2e/**', mode: 'aggregated', outputDir: 'docs/e2e' },
],
},
});