Skip to content

Commit

Permalink
Merge pull request #28929 from storybookjs/yann/addon-vitest-transfor…
Browse files Browse the repository at this point in the history
…mation-fixes

Addon Vitest: Improve transformation logic to avoid duplicate tests
  • Loading branch information
yannbf authored Aug 20, 2024
2 parents 61b1a7b + fad8af0 commit a57a1ab
Show file tree
Hide file tree
Showing 5 changed files with 466 additions and 171 deletions.
31 changes: 26 additions & 5 deletions code/addons/vitest/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import { join, resolve } from 'node:path';

import type { Plugin } from 'vitest/config';

import { loadAllPresets, validateConfigurationFiles } from 'storybook/internal/common';
import { vitestTransform } from 'storybook/internal/csf-tools';
import {
getInterpretedFile,
loadAllPresets,
validateConfigurationFiles,
} from 'storybook/internal/common';
import { readConfig, vitestTransform } from 'storybook/internal/csf-tools';
import { MainFileMissingError } from 'storybook/internal/server-errors';
import type { StoriesEntry } from 'storybook/internal/types';

Expand All @@ -16,6 +20,16 @@ const defaultOptions: UserOptions = {
storybookUrl: 'http://localhost:6006',
};

const extractTagsFromPreview = async (configDir: string) => {
const previewConfigPath = getInterpretedFile(join(resolve(configDir), 'preview'));

if (!previewConfigPath) {
return [];
}
const previewConfig = await readConfig(previewConfigPath);
return previewConfig.getFieldValue(['tags']) ?? [];
};

export const storybookTest = (options?: UserOptions): Plugin => {
const finalOptions = {
...defaultOptions,
Expand Down Expand Up @@ -45,27 +59,33 @@ export const storybookTest = (options?: UserOptions): Plugin => {
finalOptions.configDir = resolve(process.cwd(), finalOptions.configDir);
}

let previewLevelTags: string[];

return {
name: 'vite-plugin-storybook-test',
enforce: 'pre',
async buildStart() {
// evaluate main.js and preview.js so we can extract
// stories for autotitle support and tags for tags filtering support
const configDir = finalOptions.configDir;
try {
await validateConfigurationFiles(finalOptions.configDir);
await validateConfigurationFiles(configDir);
} catch (err) {
throw new MainFileMissingError({
location: finalOptions.configDir,
location: configDir,
source: 'vitest',
});
}

const presets = await loadAllPresets({
configDir: finalOptions.configDir,
configDir,
corePresets: [],
overridePresets: [],
packageJson: {},
});

stories = await presets.apply('stories', []);
previewLevelTags = await extractTagsFromPreview(configDir);
},
async config(config) {
// If we end up needing to know if we are running in browser mode later
Expand Down Expand Up @@ -123,6 +143,7 @@ export const storybookTest = (options?: UserOptions): Plugin => {
configDir: finalOptions.configDir,
tagsFilter: finalOptions.tags,
stories,
previewLevelTags,
});
}
},
Expand Down
32 changes: 14 additions & 18 deletions code/addons/vitest/src/plugin/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,29 @@
/* eslint-disable no-underscore-dangle */
import { type RunnerTask, type TaskContext, type TaskMeta, type TestContext } from 'vitest';

import type { ComposedStoryFn } from 'storybook/internal/types';
import { composeStory } from 'storybook/internal/preview-api';
import type { ComponentAnnotations, ComposedStoryFn } from 'storybook/internal/types';

import type { UserOptions } from './types';
import { setViewport } from './viewports';

type TagsFilter = Required<UserOptions['tags']>;

export const isValidTest = (storyTags: string[], tagsFilter: TagsFilter) => {
const isIncluded =
tagsFilter?.include.length === 0 || tagsFilter?.include.some((tag) => storyTags.includes(tag));
const isNotExcluded = tagsFilter?.exclude.every((tag) => !storyTags.includes(tag));

return isIncluded && isNotExcluded;
};

export const testStory = (Story: ComposedStoryFn, tagsFilter: TagsFilter) => {
export const testStory = (
exportName: string,
story: ComposedStoryFn,
meta: ComponentAnnotations,
skipTags: string[]
) => {
const composedStory = composeStory(story, meta, undefined, undefined, exportName);
return async (context: TestContext & TaskContext & { story: ComposedStoryFn }) => {
if (Story === undefined || tagsFilter?.skip.some((tag) => Story.tags.includes(tag))) {
if (composedStory === undefined || skipTags?.some((tag) => composedStory.tags.includes(tag))) {
context.skip();
}

context.story = Story;
context.story = composedStory;

const _task = context.task as RunnerTask & { meta: TaskMeta & { storyId: string } };
_task.meta.storyId = Story.id;
_task.meta.storyId = composedStory.id;

await setViewport(Story.parameters.viewport);
await Story.run();
await setViewport(composedStory.parameters.viewport);
await composedStory.run();
};
};
5 changes: 4 additions & 1 deletion code/addons/vitest/src/plugin/viewports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ describe('setViewport', () => {
};

await setViewport(viewportsParam);
expect(page.viewport).toHaveBeenCalledWith(1200, 900);
expect(page.viewport).toHaveBeenCalledWith(
DEFAULT_VIEWPORT_DIMENSIONS.width,
DEFAULT_VIEWPORT_DIMENSIONS.height
);
});

it('should set the dimensions of viewport from INITIAL_VIEWPORTS', async () => {
Expand Down
Loading

0 comments on commit a57a1ab

Please sign in to comment.