From 6acf3f8e1bbefc9ef8a8b99b36565403ee643008 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 8 Jan 2025 14:03:25 +0100 Subject: [PATCH] Addon Test: Improve support for mono-repos --- code/addons/test/src/node/vitest-manager.ts | 11 +++++++++ code/addons/test/src/postinstall.ts | 16 +++++++++++-- .../vitest-plugin-vitest-workspace.md | 23 ++++++++++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/code/addons/test/src/node/vitest-manager.ts b/code/addons/test/src/node/vitest-manager.ts index 4145acf18a3f..8696126fd920 100644 --- a/code/addons/test/src/node/vitest-manager.ts +++ b/code/addons/test/src/node/vitest-manager.ts @@ -14,6 +14,7 @@ import type { TestingModuleRunRequestPayload } from 'storybook/internal/core-eve import type { DocsIndexEntry, StoryIndex, StoryIndexEntry } from '@storybook/types'; +import { findUp } from 'find-up'; import path, { dirname, join, normalize } from 'pathe'; import slash from 'slash'; @@ -23,6 +24,8 @@ import type { StorybookCoverageReporterOptions } from './coverage-reporter'; import { StorybookReporter } from './reporter'; import type { TestManager } from './test-manager'; +const VITEST_CONFIG_FILE_EXTENSIONS = ['mts', 'mjs', 'cts', 'cjs', 'ts', 'tsx', 'js', 'jsx']; + type TagsFilter = { include: string[]; exclude: string[]; @@ -68,7 +71,15 @@ export class VitestManager { : { enabled: false } ) as CoverageOptions; + const vitestWorkspaceConfig = await findUp([ + 'vitest.workspace.ts', + 'vitest.workspace.js', + 'vitest.workspace.json', + ...VITEST_CONFIG_FILE_EXTENSIONS.map((ext) => `vitest.config.${ext}`), + ]); + this.vitest = await createVitest('test', { + root: vitestWorkspaceConfig ? dirname(vitestWorkspaceConfig) : process.cwd(), watch: true, passWithNoTests: false, // TODO: diff --git a/code/addons/test/src/postinstall.ts b/code/addons/test/src/postinstall.ts index b4949927736b..0ac20b91f9d4 100644 --- a/code/addons/test/src/postinstall.ts +++ b/code/addons/test/src/postinstall.ts @@ -419,6 +419,12 @@ export default async function postInstall(options: PostinstallOptions) { dedent` import { defineWorkspace } from 'vitest/config'; import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin';${vitestInfo.frameworkPluginImport} + import path from 'node:path'; + import { fileURLToPath } from 'node:url'; + + const dirname = typeof __dirname !== 'undefined' + ? __dirname + : path.dirname(fileURLToPath(import.meta.url)); // More info at: https://storybook.js.org/docs/writing-tests/test-addon export default defineWorkspace([ @@ -428,7 +434,7 @@ export default async function postInstall(options: PostinstallOptions) { plugins: [ // The plugin will run tests for the stories defined in your Storybook config // See options at: https://storybook.js.org/docs/writing-tests/test-addon#storybooktest - storybookTest({ configDir: '${options.configDir}' }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall} + storybookTest({ configDir: path.join(dirname, '${options.configDir}') }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall} ], test: { name: 'storybook', @@ -459,13 +465,19 @@ export default async function postInstall(options: PostinstallOptions) { dedent` import { defineConfig } from 'vitest/config'; import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin';${vitestInfo.frameworkPluginImport} + import path from 'node:path'; + import { fileURLToPath } from 'node:url'; + + const dirname = typeof __dirname !== 'undefined' + ? __dirname + : path.dirname(fileURLToPath(import.meta.url)); // More info at: https://storybook.js.org/docs/writing-tests/test-addon 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/test-addon#storybooktest - storybookTest({ configDir: '${options.configDir}' }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall} + storybookTest({ configDir: path.join(dirname, '${options.configDir}') }),${vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall} ], test: { name: 'storybook', diff --git a/docs/_snippets/vitest-plugin-vitest-workspace.md b/docs/_snippets/vitest-plugin-vitest-workspace.md index bce2c89ce97a..95c875dee56f 100644 --- a/docs/_snippets/vitest-plugin-vitest-workspace.md +++ b/docs/_snippets/vitest-plugin-vitest-workspace.md @@ -1,9 +1,15 @@ ```ts filename="vitest.workspace.ts" renderer="react" import { defineWorkspace } from 'vitest/config'; import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + // 👇 If you're using Next.js, apply this framework plugin as well // import { storybookNextJsPlugin } from '@storybook/experimental-nextjs-vite/vite-plugin'; +const dirname = + typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); + export default defineWorkspace([ // This is the path to your existing Vitest config file './vitest.config.ts', @@ -13,7 +19,7 @@ export default defineWorkspace([ plugins: [ storybookTest({ // The location of your Storybook config, main.js|ts - configDir: './.storybook', + configDir: path.join(dirname, '.storybook'), // This should match your package.json script to run Storybook // The --ci flag will skip prompts and not open a browser storybookScript: 'yarn storybook --ci', @@ -40,9 +46,14 @@ export default defineWorkspace([ import { defineConfig, mergeConfig } from 'vitest/config'; import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin'; import { storybookVuePlugin } from '@storybook/vue3-vite/vite-plugin'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import viteConfig from './vite.config'; +const dirname = + typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); + export default defineWorkspace([ // This is the path to your existing Vitest config file './vitest.config.ts', @@ -52,7 +63,7 @@ export default defineWorkspace([ plugins: [ storybookTest({ // The location of your Storybook config, main.js|ts - configDir: './.storybook', + configDir: path.join(dirname, './.storybook'), // This should match your package.json script to run Storybook // The --ci flag will skip prompts and not open a browser storybookScript: 'yarn storybook --ci', @@ -78,11 +89,17 @@ export default defineWorkspace([ ```ts filename="vitest.config.ts" renderer="svelte" import { defineConfig, mergeConfig } from 'vitest/config'; import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + // 👇 If you're using Sveltekit, apply this framework plugin as well // import { storybookSveltekitPlugin } from '@storybook/sveltekit/vite-plugin'; import viteConfig from './vite.config'; +const dirname = + typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); + export default defineWorkspace([ // This is the path to your existing Vitest config file './vitest.config.ts', @@ -92,7 +109,7 @@ export default defineWorkspace([ plugins: [ storybookTest({ // The location of your Storybook config, main.js|ts - configDir: './.storybook', + configDir: path.join(dirname, './.storybook'), // This should match your package.json script to run Storybook // The --ci flag will skip prompts and not open a browser storybookScript: 'yarn storybook --ci',