Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
81e9c77
wip prototype for test fn plugin
yannbf May 22, 2025
1803fb0
continue prototype
yannbf May 25, 2025
78abf69
fixes
yannbf May 25, 2025
c2ecdb5
do not apply loader/plugin to svelte files
yannbf May 25, 2025
af298b5
no-op on non csf-factories
yannbf May 25, 2025
bf57669
dont throw on global settings write error, dont run in CI
JReinhold Jun 16, 2025
c458370
add more resilient utility for boolean environment variables
JReinhold Jun 18, 2025
5dc7ef7
Merge branch 'next' into yann/test-fn-prototype
yannbf Jul 24, 2025
1086746
Handle type 'test' in Storybook UI
yannbf Jul 25, 2025
f455ffa
workaround
yannbf Jul 25, 2025
ea74f25
Merge branch 'next' into jeppe/fix-global-settings-readonly
shilman Jul 31, 2025
502e7f9
Merge branch 'next' into jeppe/fix-global-settings-readonly
yannbf Jul 31, 2025
e642f4e
Refactor: Update isCI usage to function calls across multiple files
yannbf Jul 31, 2025
8c980e7
Merge branch 'next' into jeppe/fix-global-settings-readonly
yannbf Jul 31, 2025
8733611
Comment out userSince test in event-log-checker for discussion on CI …
yannbf Jul 31, 2025
9e0c214
bundle in utilities
yannbf Jul 31, 2025
c5354dc
Refactor: Update imports in initiate.ts to use centralized utilities
yannbf Jul 31, 2025
b3fa273
Write changelog for 9.2.0-alpha.0 [skip ci]
storybook-bot Jul 31, 2025
b60704c
Merge pull request #32165 from storybookjs/version-non-patch-from-9.1.0
yannbf Jul 31, 2025
4dad3f9
Bump version from "9.1.0" to "9.2.0-alpha.0" [skip ci]
storybook-bot Jul 31, 2025
29048f6
Docs: Further improvements
kylegach Jul 31, 2025
e4cd834
More details about project roots
kylegach Jul 31, 2025
8483d0b
Fixes
kylegach Jul 31, 2025
c8088d9
Merge branch 'next' into docs-automocking-2
kylegach Jul 31, 2025
f6868f0
Spell out `process.cwd` as root
kylegach Jul 31, 2025
09e097b
Telemetry: Send index stats on dev exit
shilman Aug 1, 2025
a08989b
Fix test install in agentic environments
shilman Aug 1, 2025
ebc6ced
Merge branch 'next' into shilman/add-dev-cancel-event
shilman Aug 1, 2025
c5d386f
Merge pull request #32168 from storybookjs/shilman/add-dev-cancel-event
shilman Aug 1, 2025
53e5d1d
Introduce a __STORYBOOK_UNSAFE_TOCBOT__ option from addon docs
yannbf Aug 1, 2025
0510d85
lazy load lazy-universal-dotenv
yannbf Aug 1, 2025
247db2d
Merge pull request #32176 from storybookjs/yann/expose-tocbot-instance
shilman Aug 1, 2025
d87db5c
Merge pull request #31785 from storybookjs/jeppe/fix-global-settings-…
yannbf Aug 1, 2025
4988688
Write changelog for 9.2.0-alpha.1 [skip ci]
storybook-bot Aug 1, 2025
83311e3
Merge pull request #32174 from storybookjs/version-non-patch-from-9.2…
yannbf Aug 1, 2025
f148fae
Move troubleshooting to bottom
kylegach Aug 1, 2025
04e1436
Bump version from "9.2.0-alpha.0" to "9.2.0-alpha.1" [skip ci]
storybook-bot Aug 1, 2025
84ea113
Merge pull request #32166 from storybookjs/docs-automocking-2
kylegach Aug 1, 2025
32fbe3a
Merge branch 'next-release' into next
storybook-bot Aug 1, 2025
53046fe
Onboarding: Tweak referral wording in survey
shilman Aug 4, 2025
74aa094
Merge pull request #32185 from storybookjs/shilman/tweak-survey
yannbf Aug 4, 2025
d92b88a
Update CHANGELOG.md for v9.1.1 [skip ci]
storybook-bot Aug 4, 2025
ff40d89
Merge branch 'next' into yann/test-fn-prototype
yannbf Aug 4, 2025
bc01f93
add vitest integration support
yannbf Aug 4, 2025
5f9bb80
Make vitest integration work
yannbf Aug 6, 2025
3c00cc8
more experiments
yannbf Aug 19, 2025
cde0b32
cleanup
yannbf Aug 19, 2025
6cc74e2
cleanup
yannbf Aug 19, 2025
9d544a6
prepare for index type test
yannbf Aug 19, 2025
bef2d9e
update tests
yannbf Aug 19, 2025
87446ca
update types
yannbf Aug 19, 2025
110822c
update tests
yannbf Aug 19, 2025
b803204
support function references
yannbf Aug 19, 2025
5dce7ad
add test render phase
yannbf Aug 19, 2025
08b3fb2
prepare for the UI work
yannbf Aug 20, 2025
40df0de
updates
yannbf Aug 20, 2025
8acca71
fix
yannbf Aug 20, 2025
67643a8
fix
yannbf Aug 20, 2025
d7dc33d
fix
yannbf Aug 20, 2025
991b3b5
fixes
yannbf Aug 20, 2025
beb32bf
fix
yannbf Aug 20, 2025
4e90611
Fix types
kasperpeulen Aug 20, 2025
9719ea6
Refactor test prototype
kasperpeulen Aug 20, 2025
82b84e4
Improve a bit
kasperpeulen Aug 20, 2025
eca1ace
fix unit tests
yannbf Aug 21, 2025
ee34e40
fix chromatic failures
yannbf Aug 21, 2025
6ab99d4
Fix override in portable stories
kasperpeulen Aug 21, 2025
024cde6
Merge remote-tracking branch 'origin/kasper/refactor-test-prototype' …
kasperpeulen Aug 21, 2025
7def7d9
add fixes for portable stories and prepareStory
yannbf Aug 21, 2025
3ab5db3
Improved doTest type
kasperpeulen Aug 21, 2025
8e74582
Improve test execution in StoryRender
kasperpeulen Aug 21, 2025
df6dce7
Merge pull request #32314 from storybookjs/kasper/refactor-test-proto…
yannbf Aug 21, 2025
ad68ec3
Next.js: Fix version mismatch error in Webpack
yannbf Aug 21, 2025
91f0fc4
bring back all tests
yannbf Aug 21, 2025
864ed55
update tests
yannbf Aug 21, 2025
d14ea0e
support story tests in single test run
yannbf Aug 21, 2025
32f7796
update comments
yannbf Aug 21, 2025
50fc0b7
fix vitest regex
yannbf Aug 21, 2025
512c1e6
Refactor to see stories as tests
kasperpeulen Aug 26, 2025
0358dcc
Remove some todos
kasperpeulen Aug 26, 2025
620663c
Rename
kasperpeulen Aug 26, 2025
91a0149
Fix
kasperpeulen Aug 26, 2025
68603a9
fix
yannbf Aug 26, 2025
a444184
fix tests and revamp test filtering
yannbf Aug 26, 2025
c47c4fa
Merge pull request #32328 from storybookjs/kasper/see-tests-as-stories
yannbf Aug 26, 2025
7b564ea
Add TestNode for sidebar
ghengeveld Aug 21, 2025
52a3cf3
implement test metrics
yannbf Aug 27, 2025
5c6ef7f
Some cleanup
ghengeveld Aug 27, 2025
d509fc3
Fix types, avoid any
ghengeveld Aug 27, 2025
05e57e6
Add missing deps
ghengeveld Aug 27, 2025
9c78432
Render test entries in sidebar and add-in wrapper entries for stories…
ghengeveld Aug 27, 2025
700ec5b
Add story with play function
ghengeveld Aug 27, 2025
cbbd7be
Ensure wrapper gets proper children and tags
ghengeveld Aug 27, 2025
5fe23d4
Fix filtering by test-fn tag
ghengeveld Aug 27, 2025
05a264c
fix search item icon for story tests
yannbf Aug 28, 2025
f6c090e
add more stories
yannbf Aug 28, 2025
ebe497a
Merge pull request #32335 from storybookjs/yann/test-metrics
yannbf Aug 28, 2025
e335dc4
Add subtype property to distinguish tests from stories
ghengeveld Aug 28, 2025
6fa8664
Add autodocs to test-fn stories for dev/test/debug
ghengeveld Aug 28, 2025
8dee332
Refactor story index transformation logic for improved filtering and …
ghengeveld Aug 29, 2025
d9bf94a
Fix sortStory
ghengeveld Aug 29, 2025
b6c82bc
fix tests
yannbf Aug 29, 2025
8e06a46
fix build/type issues
yannbf Aug 29, 2025
f70fbda
fix unit tests, write E2E
yannbf Aug 29, 2025
eefc73e
fix indexing of tests
yannbf Aug 28, 2025
5640b6e
Merge pull request #32337 from storybookjs/sidebar-test-type
yannbf Aug 29, 2025
5344b3f
fix snapshot
yannbf Aug 29, 2025
c166dc4
fix check
yannbf Aug 29, 2025
07d688d
Update tags filter UI
ghengeveld Sep 1, 2025
cf297c8
Enhance sidebar to support test entries and improve story handling
ghengeveld Sep 2, 2025
a95c291
Add default selection for tags in sidebar and update TagsFilter compo…
yannbf Sep 2, 2025
b6fbeda
add jsdocs
yannbf Sep 2, 2025
a632036
Remove console.log
ghengeveld Sep 2, 2025
0b3d490
Enhance Button story rendering and improve sidebar node expansion logic
ghengeveld Sep 2, 2025
9f16a26
Update VitestManager to use correct RegExp
ghengeveld Sep 2, 2025
5705bb5
update to use defaultSelection instead
yannbf Sep 2, 2025
24253d8
small rename
yannbf Sep 2, 2025
8d18419
cleanup
yannbf Sep 2, 2025
15e965e
Merge pull request #32373 from storybookjs/yann/add-tags-preset-to-main
yannbf Sep 2, 2025
4831e99
fix build
yannbf Sep 2, 2025
3e8c306
Implement indeterminate state for unrepresentable combination of defa…
ghengeveld Sep 3, 2025
1a4ee93
disable save from controls in story tests
yannbf Sep 3, 2025
cd66148
fix build
yannbf Sep 3, 2025
bab3780
Add story for non-initial state
ghengeveld Sep 3, 2025
f570532
Fix filtering out stories which have tests
ghengeveld Sep 3, 2025
7a03431
Fix default invert toggle setting
ghengeveld Sep 3, 2025
07e99ae
Refactor CsfFile to support test tags and update related methods for …
yannbf Sep 3, 2025
b6c6e94
Make it possible to distinguish tests from stories in StoryStore.extr…
ghengeveld Sep 3, 2025
639042c
small refactor
yannbf Sep 3, 2025
3fa6097
Merge pull request #32385 from storybookjs/yann/fix-test-tags-extraction
yannbf Sep 3, 2025
9b7fa17
fix tests
yannbf Sep 3, 2025
d61fba2
Merge branch 'yann/test-fn-prototype' into update-storystore-extract
yannbf Sep 3, 2025
319ace2
Merge pull request #32388 from storybookjs/update-storystore-extract
yannbf Sep 3, 2025
48cb2d9
Merge branch 'latest-release' into feature/test-syntax-in-csf
yannbf Sep 3, 2025
478e4f1
undo some merge changes
yannbf Sep 3, 2025
7aa48c2
Fix regression and failing E2E tests
yannbf Sep 3, 2025
f5e829d
fix test-runner tests
yannbf Sep 3, 2025
0b21aff
fix unit tests
yannbf Sep 3, 2025
f793686
Fix focused test run in Storybook sidebar
yannbf Sep 4, 2025
2d64830
Revert "Fix focused test run in Storybook sidebar"
yannbf Sep 4, 2025
86db945
Fix focused test run in Storybook sidebar
yannbf Sep 4, 2025
07beaea
remove log
yannbf Sep 4, 2025
c22aa61
use double spaces instead
yannbf Sep 4, 2025
f0cfe33
only use double space in parent stories
yannbf Sep 4, 2025
3113762
fix tests
yannbf Sep 4, 2025
c2aedef
Merge pull request #32403 from storybookjs/yann/fix-focused-test-runs
yannbf Sep 4, 2025
d98408f
Implement include/exclude toggle for each tag to replace global inver…
ghengeveld Sep 4, 2025
54ecd3a
Enhance codemod tests and support for non-conventional story formats …
yannbf Sep 4, 2025
41c83af
Merge pull request #32414 from storybookjs/yann/fix-csf-factories-cod…
yannbf Sep 4, 2025
c652477
Update tags filter UI and fix filter function logic
ghengeveld Sep 4, 2025
b52b74a
Merge branch 'feature/test-syntax-in-csf' into tags-filter-exclude
yannbf Sep 5, 2025
4c348d3
Copy the default included/excluded sets to avoid accidental mutation
ghengeveld Sep 5, 2025
d28127c
Rename defaultSelection to defaultFilterSelection for clarity
ghengeveld Sep 5, 2025
8a65895
Remove some built-in tags that will no longer exist
ghengeveld Sep 5, 2025
7985f43
Revert check icon when not hovering
ghengeveld Sep 5, 2025
67dfbfb
Delay tooltips
ghengeveld Sep 5, 2025
00e53ca
Merge pull request #32417 from storybookjs/tags-filter-exclude
yannbf Sep 5, 2025
8b9cc24
fix children calculation
yannbf Sep 5, 2025
87ddc71
fix children calculation pt. 2
yannbf Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ code/bench-results/
/packs
code/.nx/cache
code/.nx/workspace-data
code/.vite-inspect
.vite-inspect
.nx/cache
.nx/workspace-data
!**/fixtures/**/yarn.lock
Expand Down
1 change: 1 addition & 0 deletions code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const config = defineMain({
{
directory: '../core/src/component-testing/components',
titlePrefix: 'component-testing',
files: 'test-fn.stories.tsx',
},
{
directory: '../core/src/controls/components',
Expand Down
13 changes: 8 additions & 5 deletions code/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,21 @@ const decorators = [
* This decorator renders the stories side-by-side, stacked or default based on the theme switcher
* in the toolbar
*/
(StoryFn, { globals, playFunction, args, storyGlobals, parameters }) => {
(StoryFn, { globals, playFunction, testFunction, args, storyGlobals, parameters }) => {
let theme = globals.sb_theme;
let showPlayFnNotice = false;

// this makes the decorator be out of 'phase' with the actually selected theme in the toolbar
// but this is acceptable, I guess
// we need to ensure only a single rendering in chromatic
// a more 'correct' approach would be to set a specific theme global on every story that has a playFunction
if (playFunction && args.autoplay !== false && !(theme === 'light' || theme === 'dark')) {
if (
(testFunction || (playFunction && args.autoplay !== false)) &&
!(theme === 'light' || theme === 'dark')
) {
theme = 'light';
showPlayFnNotice = true;
} else if (isChromatic() && !storyGlobals.sb_theme && !playFunction) {
} else if (isChromatic() && !storyGlobals.sb_theme && !playFunction && !testFunction) {
theme = 'stacked';
}

Expand Down Expand Up @@ -281,8 +284,8 @@ const decorators = [
<>
<PlayFnNotice>
<span>
Detected play function in Chromatic. Rendering only light theme to avoid
multiple play functions in the same story.
Detected play/test function in Chromatic. Rendering only light theme to avoid
multiple play/test functions in the same story.
</span>
</PlayFnNotice>
<div style={{ marginBottom: 20 }} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ export class ExternalPreview<TRenderer extends Renderer = Renderer> extends Prev
title,
name,
type: 'story',
subtype: 'story',
};
});

// TODO: We probably need to do something here about story tests
this.onStoriesChanged({ storyIndex: this.storyIndex });

return csfFile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export const InSidebarContextMenu: Story = {
entry: {
id: 'story-id-1',
type: 'story',
subtype: 'story',
name: 'Example Story',
tags: [],
title: 'Example Story',
Expand Down
70 changes: 69 additions & 1 deletion code/addons/vitest/src/node/test-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import path from 'pathe';
import { STATUS_TYPE_ID_A11Y, STATUS_TYPE_ID_COMPONENT_TEST, storeOptions } from '../constants';
import type { StoreEvent, StoreState } from '../types';
import { TestManager, type TestManagerOptions } from './test-manager';
import { DOUBLE_SPACES } from './vitest-manager';

const setTestNamePattern = vi.hoisted(() => vi.fn());
const vitest = vi.hoisted(() => ({
Expand Down Expand Up @@ -102,6 +103,7 @@ global.fetch = vi.fn().mockResolvedValue({
entries: {
'story--one': {
type: 'story',
subtype: 'story',
id: 'story--one',
name: 'One',
title: 'story/one',
Expand All @@ -110,12 +112,32 @@ global.fetch = vi.fn().mockResolvedValue({
},
'another--one': {
type: 'story',
subtype: 'story',
id: 'another--one',
name: 'One',
title: 'another/one',
importPath: 'path/to/another/file',
tags: ['test'],
},
'parent--story': {
type: 'story',
subtype: 'story',
id: 'parent--story',
name: 'Parent story',
title: 'parent/story',
importPath: 'path/to/parent/file',
tags: ['test'],
},
'parent--story:test': {
type: 'story',
subtype: 'test',
id: 'parent--story:test',
name: 'Test name',
title: 'parent/story',
parent: 'parent--story',
importPath: 'path/to/parent/file',
tags: ['test', 'test-fn'],
},
},
} as StoryIndex)
),
Expand Down Expand Up @@ -183,10 +205,56 @@ describe('TestManager', () => {
triggeredBy: 'global',
},
});
expect(setTestNamePattern).toHaveBeenCalledWith(/^One$/);
expect(setTestNamePattern).toHaveBeenCalledWith(new RegExp(`^One$`));
expect(vitest.runTestSpecifications).toHaveBeenCalledWith(tests.slice(0, 1), true);
});

it('should trigger a single story render test', async () => {
vitest.globTestSpecifications.mockImplementation(() => tests);
const testManager = await TestManager.start(options);

await testManager.handleTriggerRunEvent({
type: 'TRIGGER_RUN',
payload: {
storyIds: ['another--one'],
triggeredBy: 'global',
},
});
// regex should be exact match of the story name
expect(setTestNamePattern).toHaveBeenCalledWith(new RegExp(`^One$`));
});

it('should trigger a single story test', async () => {
vitest.globTestSpecifications.mockImplementation(() => tests);
const testManager = await TestManager.start(options);

await testManager.handleTriggerRunEvent({
type: 'TRIGGER_RUN',
payload: {
storyIds: ['parent--story:test'],
triggeredBy: 'global',
},
});
// regex should be Parent Story Name + Test Name
expect(setTestNamePattern).toHaveBeenCalledWith(
new RegExp(`^Parent story${DOUBLE_SPACES} Test name$`)
);
});

it('should trigger all tests of a story', async () => {
vitest.globTestSpecifications.mockImplementation(() => tests);
const testManager = await TestManager.start(options);

await testManager.handleTriggerRunEvent({
type: 'TRIGGER_RUN',
payload: {
storyIds: ['parent--story'],
triggeredBy: 'global',
},
});
expect(setTestNamePattern).toHaveBeenCalledWith(new RegExp(`^Parent story${DOUBLE_SPACES}`));
});

it('should restart Vitest before a test run if coverage is enabled', async () => {
const testManager = await TestManager.start(options);
expect(createVitest).toHaveBeenCalledTimes(1);
Expand Down
53 changes: 48 additions & 5 deletions code/addons/vitest/src/node/vitest-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ const packageDir = dirname(require.resolve('@storybook/addon-vitest/package.json
// We have to tell Vitest that it runs as part of Storybook
process.env.VITEST_STORYBOOK = 'true';

/**
* The Storybook vitest plugin adds double space characters so that it's possible to do a regex for
* all test run use cases. Otherwise, if there were two unrelated stories like "Primary Button" and
* "Primary Button Mobile", once you run tests for "Primary Button" and its children it would also
* match "Primary Button Mobile". As it turns out, this limitation is also present in the Vitest
* VSCode extension and the issue would occur with normal vitest tests as well, but because we use
* double spaces, we circumvent the issue.
*/
export const DOUBLE_SPACES = ' ';
const getTestName = (name: string) => `${name}${DOUBLE_SPACES}`;

export class VitestManager {
vitest: Vitest | null = null;

Expand Down Expand Up @@ -169,7 +180,7 @@ export class VitestManager {
});
}

private async fetchStories(requestStoryIds?: string[]) {
private async fetchStories(requestStoryIds?: string[]): Promise<StoryIndexEntry[]> {
const indexUrl = this.testManager.store.getState().indexUrl;
if (!indexUrl) {
throw new Error(
Expand Down Expand Up @@ -265,18 +276,50 @@ export class VitestManager {
await this.cancelCurrentRun();

const testSpecifications = await this.getStorybookTestSpecifications();
const stories = await this.fetchStories(runPayload?.storyIds);
const allStories = await this.fetchStories();

const filteredStories = runPayload.storyIds
? allStories.filter((story) => runPayload.storyIds?.includes(story.id))
: allStories;

const isSingleStoryRun = runPayload.storyIds?.length === 1;
if (isSingleStoryRun) {
const storyName = stories[0].name;
const regex = new RegExp(`^${storyName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`);
const selectedStory = filteredStories.find((story) => story.id === runPayload.storyIds?.[0]);
if (!selectedStory) {
throw new Error(`Story ${runPayload.storyIds?.[0]} not found`);
}

const storyName = selectedStory.name;
let regex: RegExp;

const isParentStory = allStories.some((story) => selectedStory.id === story.parent);
const hasParentStory = allStories.some((story) => selectedStory.parent === story.id);
Comment on lines +295 to +296

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The logic for detecting parent/child relationships assumes story.parent property exists but this property isn't defined in the StoryIndexEntry type imports


if (isParentStory) {
// Use case 1: "Single" story run on a story with tests
// -> run all tests of that story, as storyName is a describe block
const parentName = getTestName(selectedStory.name);
regex = new RegExp(`^${parentName}`);
} else if (hasParentStory) {
// Use case 2: Single story run on a specific story test
// in this case the regex pattern should be the story parentName + space + story.name
const parentStory = allStories.find((story) => story.id === selectedStory.parent);
if (!parentStory) {
throw new Error(`Parent story not found for story ${selectedStory.id}`);
}

const parentName = getTestName(parentStory.name);
regex = new RegExp(`^${parentName} ${storyName}$`);
} else {
// Use case 3: Single story run on a story without tests, should be exact match of story name
regex = new RegExp(`^${storyName}$`);
}
this.vitest!.setGlobalTestNamePattern(regex);
}

const { filteredTestSpecifications, filteredStoryIds } = this.filterTestSpecifications(
testSpecifications,
stories
filteredStories
);

this.testManager.store.setState((s) => ({
Expand Down
29 changes: 22 additions & 7 deletions code/addons/vitest/src/vitest-plugin/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type RunnerTask, type TaskMeta, type TestContext } from 'vitest';

import type { ComponentAnnotations, ComposedStoryFn } from 'storybook/internal/types';
import { type Meta, type Story, getStoryChildren, isStory, toTestId } from 'storybook/internal/csf';
import type { ComponentAnnotations, ComposedStoryFn, Renderer } from 'storybook/internal/types';

import { server } from '@vitest/browser/context';
import { type Report, composeStory, getCsfFactoryAnnotations } from 'storybook/preview-api';
Expand Down Expand Up @@ -32,14 +33,24 @@ export const convertToFilePath = (url: string): string => {

export const testStory = (
exportName: string,
story: ComposedStoryFn,
meta: ComponentAnnotations,
skipTags: string[]
story: ComposedStoryFn | Story<Renderer>,
meta: ComponentAnnotations | Meta<Renderer>,
skipTags: string[],
storyId: string,
testName?: string
) => {
return async (context: TestContext & { story: ComposedStoryFn }) => {
const annotations = getCsfFactoryAnnotations(story, meta);

const test =
isStory(story) && testName
? getStoryChildren(story).find((child) => child.input.name === testName)
: undefined;

const storyAnnotations = test ? test.input : annotations.story;

const composedStory = composeStory(
annotations.story,
storyAnnotations,
annotations.meta!,
{ initialGlobals: (await getInitialGlobals?.()) ?? {} },
annotations.preview ?? globalThis.globalProjectAnnotations,
Expand All @@ -55,10 +66,14 @@ export const testStory = (
const _task = context.task as RunnerTask & {
meta: TaskMeta & { storyId: string; reports: Report[] };
};
_task.meta.storyId = composedStory.id;

// The id will always be present, calculated by CsfFile
// and is needed so that we can add the test to the story in Storybook's UI for the status
_task.meta.storyId = storyId;

await setViewport(composedStory.parameters, composedStory.globals);
await composedStory.run();

await composedStory.run(undefined);

_task.meta.reports = composedStory.reporting.reports;
};
Expand Down
Loading