From 24f6fc0625a3760ff362480668e2030366670f65 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Mon, 26 Aug 2024 16:07:58 +0200 Subject: [PATCH 1/5] Only log Next.js message when dealing with a Next.js project --- code/addons/vitest/src/postinstall.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index 53361975704b..3e78950ea35e 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -60,16 +60,16 @@ export default async function postInstall(options: PostinstallOptions) { const packages = ['vitest@latest', '@vitest/browser@latest', 'playwright@latest']; - logger.info( - dedent` - We detected that you're using Next.js. - We will configure the vite-plugin-storybook-nextjs plugin to allow you to run tests in Vitest. - ` - ); - if (info.frameworkPackageName === '@storybook/nextjs') { + logger.info( + dedent` + We detected that you're using Next.js. + We will configure the vite-plugin-storybook-nextjs plugin to allow you to run tests in Vitest. + ` + ); packages.push('vite-plugin-storybook-nextjs@latest'); } + logger.info(c.bold('Installing packages...')); logger.info(packages.join(', ')); await packageManager.addDependencies({ installAsDevDependencies: true }, packages); @@ -92,9 +92,9 @@ export default async function postInstall(options: PostinstallOptions) { import { beforeAll } from 'vitest' import { setProjectAnnotations } from '${annotationsImport}' ${previewExists ? `import * as projectAnnotations from './preview'` : ''} - + const project = setProjectAnnotations(${previewExists ? 'projectAnnotations' : '[]'}) - + beforeAll(project.beforeAll) ` ); @@ -138,7 +138,7 @@ export default async function postInstall(options: PostinstallOptions) { provider: 'playwright', headless: true, }, - // Disabling isolation is faster and is similar to how tests are isolated in storybook itself. + // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. // Consider removing this if you are seeing problems with your tests. isolate: false, setupFiles: ['./.storybook/vitest.setup.ts'], @@ -168,7 +168,7 @@ export default async function postInstall(options: PostinstallOptions) { provider: 'playwright', headless: true, }, - // Disabling isolation is faster and is similar to how tests are isolated in storybook itself. + // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. // Consider removing this, if you have flaky tests. isolate: false, setupFiles: ['./.storybook/vitest.setup.ts'], @@ -180,7 +180,7 @@ export default async function postInstall(options: PostinstallOptions) { logger.info( dedent` - The Vitest addon is now configured and you're ready to run your tests! + The Vitest addon is now configured and you're ready to run your tests! Check the documentation for more information about its features and options at: https://storybook.js.org/docs/writing-tests/test-runner-with-vitest ` @@ -215,7 +215,6 @@ async function getFrameworkInfo({ configDir, packageManager: pkgMgr }: Postinsta validateFrameworkName(frameworkName); const frameworkPackageName = extractProperFrameworkName(frameworkName); - console.log(configDir); const presets = await loadAllPresets({ corePresets: [join(frameworkName, 'preset')], overridePresets: [ From 896e3f06af32635b58e8fc58a18b1a41a13111df Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Mon, 26 Aug 2024 16:40:23 +0200 Subject: [PATCH 2/5] Also create workspace file if there's a Vite config file, and extend the test config from that Vite config file --- code/addons/vitest/src/postinstall.ts | 103 +++++++++++++------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index 3e78950ea35e..b17e982d3a3e 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -99,14 +99,15 @@ export default async function postInstall(options: PostinstallOptions) { ` ); - const configFiles = extensions.map((ext) => 'vitest.config' + ext); - - const rootConfig = await findUp(configFiles, { - cwd: process.cwd(), - }); + // Check for an existing config file. Can be from Vitest (preferred) or Vite (with `test` option). + const viteConfigFiles = extensions.map((ext) => 'vite.config' + ext); + const viteConfig = await findUp(viteConfigFiles, { cwd: process.cwd() }); + const vitestConfigFiles = extensions.map((ext) => 'vitest.config' + ext); + const rootConfig = (await findUp(vitestConfigFiles, { cwd: process.cwd() })) || viteConfig; if (rootConfig) { - const extname = rootConfig ? path.extname(rootConfig) : '.ts'; + // If there's an existing config, we create a workspace file so we can run Storybook tests alongside. + const extname = path.extname(rootConfig); const browserWorkspaceFile = resolve(dirname(rootConfig), `vitest.workspace${extname}`); if (existsSync(browserWorkspaceFile)) { logger.info( @@ -121,60 +122,62 @@ export default async function postInstall(options: PostinstallOptions) { await writeFile( browserWorkspaceFile, dedent` - import { defineWorkspace } from 'vitest/config'; - import { storybookTest } from '@storybook/experimental-addon-vitest/plugin'; - ${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''} - export default defineWorkspace([ - '${relative(dirname(browserWorkspaceFile), rootConfig)}', - { - plugins: [ - storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} - ], - test: { - include: ['**/*.stories.?(m)[jt]s?(x)'], - browser: { - enabled: true, - name: 'chromium', - provider: 'playwright', - headless: true, + import { defineWorkspace } from 'vitest/config'; + import { storybookTest } from '@storybook/experimental-addon-vitest/plugin'; + ${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''} + export default defineWorkspace([ + '${relative(dirname(browserWorkspaceFile), rootConfig)}', + { + extends: '${viteConfig || ''}', + plugins: [ + storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} + ], + test: { + include: ['**/*.stories.?(m)[jt]s?(x)'], + browser: { + enabled: true, + name: 'chromium', + provider: 'playwright', + headless: true, + }, + // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. + // Consider removing this if you are seeing problems with your tests. + isolate: false, + setupFiles: ['./.storybook/vitest.setup.ts'], }, - // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. - // Consider removing this if you are seeing problems with your tests. - isolate: false, - setupFiles: ['./.storybook/vitest.setup.ts'], }, - }, - ]); - ` + ]); + `.replace(/\s+extends: '',/, '') ); } } else { + // If there's no existing Vitest/Vite config, we create a new Vitest config file. logger.info(c.bold('Writing vitest.config.ts file...')); await writeFile( resolve('vitest.config.ts'), dedent` - import { defineConfig } from "vitest/config"; - import { storybookTest } from "@storybook/experimental-addon-vitest/plugin"; - ${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''} - export default defineConfig({ - plugins: [ - storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} - ], - test: { - include: ['**/*.stories.?(m)[jt]s?(x)'], - browser: { - enabled: true, - name: 'chromium', - provider: 'playwright', - headless: true, + import { defineConfig } from "vitest/config"; + import { storybookTest } from "@storybook/experimental-addon-vitest/plugin"; + ${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''} + export default defineConfig({ + plugins: [ + storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} + ], + test: { + include: ['**/*.stories.?(m)[jt]s?(x)'], + browser: { + enabled: true, + name: 'chromium', + provider: 'playwright', + headless: true, + }, + // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. + // Consider removing this, if you have flaky tests. + isolate: false, + setupFiles: ['./.storybook/vitest.setup.ts'], }, - // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. - // Consider removing this, if you have flaky tests. - isolate: false, - setupFiles: ['./.storybook/vitest.setup.ts'], - }, - }); - ` + }); + ` ); } From d3d6fd2ebe311dac681589d4da8f777d336867b3 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 27 Aug 2024 13:13:48 +0200 Subject: [PATCH 3/5] Remove (disable) isolate option because it sometimes doesn't show stories --- code/addons/vitest/src/postinstall.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index b17e982d3a3e..adb1acbf2081 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -133,16 +133,13 @@ export default async function postInstall(options: PostinstallOptions) { storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} ], test: { - include: ['**/*.stories.?(m)[jt]s?(x)'], browser: { enabled: true, + headless: true, name: 'chromium', provider: 'playwright', - headless: true, }, - // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. - // Consider removing this if you are seeing problems with your tests. - isolate: false, + include: ['**/*.stories.?(m)[jt]s?(x)'], setupFiles: ['./.storybook/vitest.setup.ts'], }, }, @@ -164,16 +161,13 @@ export default async function postInstall(options: PostinstallOptions) { storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} ], test: { - include: ['**/*.stories.?(m)[jt]s?(x)'], browser: { enabled: true, + headless: true, name: 'chromium', provider: 'playwright', - headless: true, }, - // Disabling isolation is faster and is similar to how tests are isolated in Storybook itself. - // Consider removing this, if you have flaky tests. - isolate: false, + include: ['**/*.stories.?(m)[jt]s?(x)'], setupFiles: ['./.storybook/vitest.setup.ts'], }, }); From ad31d48593cb031453737507ff5176d18fbfa765 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 27 Aug 2024 14:26:28 +0200 Subject: [PATCH 4/5] Support JSX file extensions as well --- code/addons/vitest/src/postinstall.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index adb1acbf2081..aa7496c72cba 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -19,7 +19,7 @@ import dedent from 'ts-dedent'; import { type PostinstallOptions } from '../../../lib/cli-storybook/src/add'; -const extensions = ['.ts', '.mts', '.cts', '.js', '.mjs', '.cjs']; +const extensions = ['.js', '.jsx', '.ts', '.tsx', '.cts', '.mts', '.cjs', '.mjs']; export default async function postInstall(options: PostinstallOptions) { const packageManager = JsPackageManagerFactory.getPackageManager({ @@ -83,7 +83,7 @@ export default async function postInstall(options: PostinstallOptions) { logger.info(c.bold('Writing .storybook/vitest.setup.ts file...')); const previewExists = extensions - .map((ext) => path.resolve(path.join(options.configDir, `preview${ext}`))) + .map((ext) => path.resolve(options.configDir, `preview${ext}`)) .some((config) => existsSync(config)); await writeFile( From 534fb2b72af9e7b9e4a61af514169e183a92b0c4 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 27 Aug 2024 17:10:15 +0200 Subject: [PATCH 5/5] Use relative path from workspace to vite.config in extends path --- code/addons/vitest/src/postinstall.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index aa7496c72cba..2358bcbc9724 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -128,7 +128,7 @@ export default async function postInstall(options: PostinstallOptions) { export default defineWorkspace([ '${relative(dirname(browserWorkspaceFile), rootConfig)}', { - extends: '${viteConfig || ''}', + extends: '${viteConfig ? relative(dirname(browserWorkspaceFile), viteConfig) : ''}', plugins: [ storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginCall : ''} ],