diff --git a/code/addons/test/src/constants.ts b/code/addons/test/src/constants.ts index d57ff1b1da8a..58463326dcd7 100644 --- a/code/addons/test/src/constants.ts +++ b/code/addons/test/src/constants.ts @@ -12,6 +12,13 @@ export const DOCUMENTATION_FATAL_ERROR_LINK = `${DOCUMENTATION_LINK}#what-happen export const COVERAGE_DIRECTORY = 'coverage'; +export const SUPPORTED_FRAMEWORKS = [ + '@storybook/nextjs', + '@storybook/experimental-nextjs-vite', + '@storybook/sveltekit', +]; + +export const SUPPORTED_RENDERERS = ['@storybook/react', '@storybook/svelte', '@storybook/vue3']; export interface Config { coverage: boolean; a11y: boolean; diff --git a/code/addons/test/src/postinstall.ts b/code/addons/test/src/postinstall.ts index 5731d797d0ee..ac91f8aff5c7 100644 --- a/code/addons/test/src/postinstall.ts +++ b/code/addons/test/src/postinstall.ts @@ -25,6 +25,7 @@ import { coerce, satisfies } from 'semver'; import { dedent } from 'ts-dedent'; import { type PostinstallOptions } from '../../../lib/cli-storybook/src/add'; +import { SUPPORTED_FRAMEWORKS, SUPPORTED_RENDERERS } from './constants'; import { printError, printInfo, printSuccess, step } from './postinstall-logger'; import { getAddonNames } from './utils'; @@ -106,18 +107,11 @@ export default async function postInstall(options: PostinstallOptions) { } } - const annotationsImport = [ - '@storybook/nextjs', - '@storybook/experimental-nextjs-vite', - '@storybook/sveltekit', - ].includes(info.frameworkPackageName) + const annotationsImport = SUPPORTED_FRAMEWORKS.includes(info.frameworkPackageName) ? info.frameworkPackageName === '@storybook/nextjs' ? '@storybook/experimental-nextjs-vite' : info.frameworkPackageName - : info.rendererPackageName && - ['@storybook/react', '@storybook/svelte', '@storybook/vue3'].includes( - info.rendererPackageName - ) + : info.rendererPackageName && SUPPORTED_RENDERERS.includes(info.rendererPackageName) ? info.rendererPackageName : null; diff --git a/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.test.ts b/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.test.ts index 7bd831d082b7..87da579183cb 100644 --- a/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.test.ts +++ b/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.test.ts @@ -7,7 +7,13 @@ import dedent from 'ts-dedent'; import { getAddonNames } from '../helpers/mainConfigFile'; import { addonA11yAddonTest, transformSetupFile } from './addon-a11y-addon-test'; -vi.mock('../helpers/mainConfigFile'); +vi.mock('../helpers/mainConfigFile', async (importOriginal) => { + const mod = (await importOriginal()) as any; + return { + ...mod, + getAddonNames: vi.fn(), + }; +}); // mock fs.existsSync vi.mock('fs', async (importOriginal) => { @@ -46,6 +52,20 @@ describe('addonA11yAddonTest', () => { expect(result).toBeNull(); }); + it('should return null if provided framework is not supported', async () => { + vi.mocked(getAddonNames).mockReturnValue([ + '@storybook/addon-a11y', + '@storybook/experimental-addon-test', + ]); + const result = await addonA11yAddonTest.check({ + mainConfig: { + framework: '@storybook/angular', + }, + configDir: '', + } as any); + expect(result).toBeNull(); + }); + it('should return setupFile and transformedSetupCode if vitest.setup file exists', async () => { vi.mocked(getAddonNames).mockReturnValue([ '@storybook/addon-a11y', @@ -54,7 +74,12 @@ describe('addonA11yAddonTest', () => { vi.mocked(existsSync).mockReturnValue(true); vi.mocked(readFileSync).mockReturnValue('const annotations = setProjectAnnotations([]);'); - const result = await addonA11yAddonTest.check({ mainConfig, configDir } as any); + const result = await addonA11yAddonTest.check({ + mainConfig: { + framework: '@storybook/react-vite', + }, + configDir, + } as any); expect(result).toEqual({ setupFile: path.join(configDir, 'vitest.setup.js'), transformedSetupCode: expect.any(String), @@ -71,7 +96,12 @@ describe('addonA11yAddonTest', () => { throw new Error('Test error'); }); - const result = await addonA11yAddonTest.check({ mainConfig, configDir } as any); + const result = await addonA11yAddonTest.check({ + mainConfig: { + framework: '@storybook/sveltekit', + }, + configDir, + } as any); expect(result).toEqual({ setupFile: path.join(configDir, 'vitest.setup.js'), transformedSetupCode: null, diff --git a/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.ts b/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.ts index 6b85146407f6..a8cd25cdf371 100644 --- a/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.ts +++ b/code/lib/cli-storybook/src/automigrate/fixes/addon-a11y-addon-test.ts @@ -1,10 +1,17 @@ +import { rendererPackages } from 'storybook/internal/common'; + import { existsSync, readFileSync, writeFileSync } from 'fs'; import * as jscodeshift from 'jscodeshift'; import path from 'path'; import picocolors from 'picocolors'; import { dedent } from 'ts-dedent'; -import { getAddonNames } from '../helpers/mainConfigFile'; +// Relative path import to avoid dependency to @storybook/test +import { + SUPPORTED_FRAMEWORKS, + SUPPORTED_RENDERERS, +} from '../../../../../addons/test/src/constants'; +import { getAddonNames, getFrameworkPackageName, getRendererName } from '../helpers/mainConfigFile'; import type { Fix } from '../types'; export const vitestFileExtensions = ['.js', '.ts', '.cts', '.mts', '.cjs', '.mjs'] as const; @@ -35,11 +42,23 @@ export const addonA11yAddonTest: Fix = { async check({ mainConfig, configDir }) { const addons = getAddonNames(mainConfig); + const frameworkPackageName = getFrameworkPackageName(mainConfig); + const rendererPackageName = getRendererName(mainConfig); + const hasA11yAddon = !!addons.find((addon) => addon.includes('@storybook/addon-a11y')); const hasTestAddon = !!addons.find((addon) => addon.includes('@storybook/experimental-addon-test') ); + if ( + !SUPPORTED_FRAMEWORKS.find((framework) => frameworkPackageName?.includes(framework)) && + !SUPPORTED_RENDERERS.find((renderer) => + rendererPackageName?.includes(rendererPackages[renderer]) + ) + ) { + return null; + } + if (!hasA11yAddon || !hasTestAddon || !configDir) { return null; }