Skip to content

Commit

Permalink
Merge pull request #30216 from storybookjs/valentin/improve-monorepo-…
Browse files Browse the repository at this point in the history
…support-for-addon-test

Addon Test: Improve support for mono-repos
  • Loading branch information
valentinpalkovic authored Jan 9, 2025
2 parents e890a40 + 39c08e9 commit e3b6c66
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 8 deletions.
10 changes: 10 additions & 0 deletions code/addons/test/src/node/vitest-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -23,6 +24,9 @@ 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'];
const VITEST_WORKSPACE_FILE_EXTENSION = ['ts', 'js', 'json'];

type TagsFilter = {
include: string[];
exclude: string[];
Expand Down Expand Up @@ -68,7 +72,13 @@ export class VitestManager {
: { enabled: false }
) as CoverageOptions;

const vitestWorkspaceConfig = await findUp([
...VITEST_WORKSPACE_FILE_EXTENSION.map((ext) => `vitest.workspace.${ext}`),
...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:
Expand Down
16 changes: 14 additions & 2 deletions code/addons/test/src/postinstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand All @@ -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',
Expand Down Expand Up @@ -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',
Expand Down
21 changes: 18 additions & 3 deletions docs/_snippets/vitest-plugin-vitest-config.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
```ts filename="vitest.config.ts" renderer="react"
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 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));

import viteConfig from './vite.config';

export default mergeConfig(
Expand All @@ -12,7 +17,7 @@ export default mergeConfig(
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',
Expand All @@ -38,16 +43,21 @@ export default mergeConfig(
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 mergeConfig(
viteConfig,
defineConfig({
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',
Expand All @@ -72,9 +82,14 @@ export default mergeConfig(
```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';

const dirname =
typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));

import viteConfig from './vite.config';

export default mergeConfig(
Expand All @@ -83,7 +98,7 @@ export default mergeConfig(
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',
Expand Down
23 changes: 20 additions & 3 deletions docs/_snippets/vitest-plugin-vitest-workspace.md
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand Down
9 changes: 9 additions & 0 deletions scripts/tasks/sandbox-parts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,13 +480,22 @@ export async function setupVitest(details: TemplateDetails, options: PassedOptio
dedent`
import { defineWorkspace, defaultExclude } from "vitest/config";
import { storybookTest } from "@storybook/experimental-addon-test/vitest-plugin";
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import viteConfig from './vite.config';
${frameworkPluginImport}
const dirname =
typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
export default defineWorkspace([
{
${!isNextjs ? `extends: "${viteConfigPath}",` : ''}
plugins: [
storybookTest({
configDir: path.join(dirname, '.storybook'),
storybookScript: "yarn storybook --ci",
tags: {
include: ["vitest"],
Expand Down

0 comments on commit e3b6c66

Please sign in to comment.