Skip to content

Commit

Permalink
Merge pull request #29367 from storybookjs/yann/automatic-stories-glob
Browse files Browse the repository at this point in the history
Addon Test: Refactor test addon to include stories automatically
  • Loading branch information
ndelangen authored Dec 4, 2024
2 parents caca692 + 5c9c675 commit fd02aa5
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 26 deletions.
11 changes: 2 additions & 9 deletions code/.storybook/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,13 @@ export default mergeConfig(
],
test: {
name: 'storybook-ui',
include: [
'../addons/**/*.{story,stories}.?(c|m)[jt]s?(x)',
// '../core/template/stories/**/*.{story,stories}.?(c|m)[jt]s?(x)',
'../core/src/manager/**/*.{story,stories}.?(c|m)[jt]s?(x)',
'../core/src/preview-api/**/*.{story,stories}.?(c|m)[jt]s?(x)',
'../core/src/components/{brand,components}/**/*.{story,stories}.?(c|m)[jt]s?(x)',
],
exclude: [
...defaultExclude,
'../node_modules/**',
'**/__mockdata__/**',
'../**/__mockdata__/**',
// expected to fail in Vitest because of fetching /iframe.html to cause ECONNREFUSED
'**/Zoom.stories.tsx',
'**/Zoom.stories.tsx', // expected to fail in Vitest because of fetching /iframe.html to cause ECONNREFUSED
'**/lib/blocks/src/**', // won't work because of https://github.com/storybookjs/storybook/issues/29783
],
// TODO: bring this back once portable stories support @storybook/core/preview-api hooks
// @ts-expect-error this type does not exist but the property does!
Expand Down
1 change: 1 addition & 0 deletions code/addons/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"execa": "^8.0.1",
"find-up": "^7.0.0",
"formik": "^2.2.9",
"glob": "^10.0.0",
"istanbul-lib-report": "^3.0.1",
"pathe": "^1.1.2",
"picocolors": "^1.1.0",
Expand Down
10 changes: 3 additions & 7 deletions code/addons/test/src/postinstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,6 @@ export default async function postInstall(options: PostinstallOptions) {
// If there's an existing config, we create a workspace file so we can run Storybook tests alongside.
const extension = extname(rootConfig);
const browserWorkspaceFile = resolve(dirname(rootConfig), `vitest.workspace${extension}`);
// to be set in vitest config
const vitestSetupFilePath = relative(dirname(browserWorkspaceFile), vitestSetupFile);

logger.line(1);
logger.plain(`${step} Creating a Vitest project workspace file:`);
Expand All @@ -355,6 +353,7 @@ export default async function postInstall(options: PostinstallOptions) {
{
extends: '${viteConfigFile ? relative(dirname(browserWorkspaceFile), viteConfigFile) : ''}',
plugins: [
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/writing-tests/vitest-plugin#storybooktest
storybookTest({ configDir: '${options.configDir}' }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall}
],
Expand All @@ -366,9 +365,7 @@ export default async function postInstall(options: PostinstallOptions) {
name: 'chromium',
provider: 'playwright',
},
// Make sure to adjust this pattern to match your stories files.
include: ['**/*.stories.?(m)[jt]s?(x)'],
setupFiles: ['${vitestSetupFilePath}'],
setupFiles: ['./.storybook/vitest.setup.ts'],
},
},
]);
Expand All @@ -393,6 +390,7 @@ export default async function postInstall(options: PostinstallOptions) {
// More info at: https://storybook.js.org/docs/writing-tests/vitest-plugin
export default defineConfig({
plugins: [
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/writing-tests/vitest-plugin#storybooktest
storybookTest({ configDir: '${options.configDir}' }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall}
],
Expand All @@ -404,8 +402,6 @@ export default async function postInstall(options: PostinstallOptions) {
name: 'chromium',
provider: 'playwright',
},
// Make sure to adjust this pattern to match your stories files.
include: ['**/*.stories.?(m)[jt]s?(x)'],
setupFiles: ['${vitestSetupFilePath}'],
},
});
Expand Down
47 changes: 41 additions & 6 deletions code/addons/test/src/vitest-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import type { Plugin } from 'vitest/config';
import {
getInterpretedFile,
loadAllPresets,
normalizeStories,
validateConfigurationFiles,
} from 'storybook/internal/common';
import { StoryIndexGenerator } from 'storybook/internal/core-server';
import { readConfig, vitestTransform } from 'storybook/internal/csf-tools';
import { MainFileMissingError } from 'storybook/internal/server-errors';
import type { StoriesEntry } from 'storybook/internal/types';
import type { DocsOptions, StoriesEntry } from 'storybook/internal/types';

// eslint-disable-next-line depend/ban-dependencies
import { escape } from 'glob';
import { join, resolve } from 'pathe';

import type { InternalOptions, UserOptions } from './types';
Expand Down Expand Up @@ -51,15 +55,15 @@ export const storybookTest = (options?: UserOptions): Plugin => {
process.env.__STORYBOOK_URL__ = storybookUrl;
process.env.__STORYBOOK_SCRIPT__ = finalOptions.storybookScript;

let stories: StoriesEntry[];

if (!finalOptions.configDir) {
finalOptions.configDir = resolve(join(process.cwd(), '.storybook'));
} else {
finalOptions.configDir = resolve(process.cwd(), finalOptions.configDir);
}

let previewLevelTags: string[];
let storiesGlobs: StoriesEntry[];
let storiesFiles: string[];

return {
name: 'vite-plugin-storybook-test',
Expand All @@ -82,7 +86,27 @@ export const storybookTest = (options?: UserOptions): Plugin => {
packageJson: {},
});

stories = await presets.apply('stories', []);
const workingDir = process.cwd();
const directories = {
configDir,
workingDir,
};
storiesGlobs = await presets.apply('stories');
const indexers = await presets.apply('experimental_indexers', []);
const docsOptions = await presets.apply<DocsOptions>('docs', {});
const normalizedStories = normalizeStories(await storiesGlobs, directories);

const generator = new StoryIndexGenerator(normalizedStories, {
...directories,
indexers: indexers,
docs: docsOptions,
workingDir,
});

await generator.initialize();

storiesFiles = generator.storyFileNames();

previewLevelTags = await extractTagsFromPreview(configDir);

const framework = await presets.apply('framework', undefined);
Expand All @@ -93,8 +117,19 @@ export const storybookTest = (options?: UserOptions): Plugin => {
// const isRunningInBrowserMode = config.plugins.find((plugin: Plugin) =>
// plugin.name?.startsWith('vitest:browser')
// )

config.test ??= {};

config.test.include ??= [];
config.test.include.push(
// Escape magic characters in paths because they shouldn't be treated as glob patterns
// Paths are resolved using `pathe` to convert Windows paths to POSIX paths first
...storiesFiles.map((path) => escape(resolve(path)))
);

config.test.exclude ??= [];
config.test.exclude.push('**/*.mdx');

config.test.env ??= {};
config.test.env = {
...storybookEnv,
Expand Down Expand Up @@ -167,13 +202,13 @@ export const storybookTest = (options?: UserOptions): Plugin => {
return code;
}

if (id.match(/(story|stories)\.[cm]?[jt]sx?$/)) {
if (storiesFiles.includes(id)) {
return vitestTransform({
code,
fileName: id,
configDir: finalOptions.configDir,
tagsFilter: finalOptions.tags,
stories,
stories: storiesGlobs,
previewLevelTags,
});
}
Expand Down
1 change: 1 addition & 0 deletions code/core/src/core-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './build-static';
export * from './build-dev';
export * from './withTelemetry';
export { default as build } from './standalone';
export { StoryIndexGenerator } from './utils/StoryIndexGenerator';
1 change: 1 addition & 0 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6623,6 +6623,7 @@ __metadata:
execa: "npm:^8.0.1"
find-up: "npm:^7.0.0"
formik: "npm:^2.2.9"
glob: "npm:^10.0.0"
istanbul-lib-report: "npm:^3.0.1"
pathe: "npm:^1.1.2"
picocolors: "npm:^1.1.0"
Expand Down
5 changes: 1 addition & 4 deletions scripts/tasks/sandbox-parts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,14 +498,11 @@ export async function setupVitest(details: TemplateDetails, options: PassedOptio
test: {
name: "storybook",
pool: "threads",
include: [
"src/**/*.{story,stories}.?(c|m)[jt]s?(x)",
"template-stories/**/*.{story,stories}.?(c|m)[jt]s?(x)",
],
exclude: [
...defaultExclude,
// TODO: investigate TypeError: Cannot read properties of null (reading 'useContext')
"**/*argtypes*",
${template.expected.renderer === '@storybook/svelte' ? '"**/*.stories.svelte",' : ''}
],
/**
* TODO: Either fix or acknowledge limitation of:
Expand Down

0 comments on commit fd02aa5

Please sign in to comment.