From 774298e7a6b524b72b49938422050b80a1beebc9 Mon Sep 17 00:00:00 2001 From: yannbf Date: Mon, 6 Jul 2026 10:16:33 +0200 Subject: [PATCH] Fix addon-a11y-addon-test automigration prompting when there is nothing to do MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check only evaluated the "already migrated" skip conditions when both .storybook/vitest.setup.* and .storybook/preview.* existed. Projects without a vitest.setup file (the norm since the vitest plugin auto-provisions preview annotations in 10.3+) were always prompted, even when preview already had parameters.a11y.test configured — and running the migration was a no-op. The skip flags are now computed independently per file: a missing setup file counts as nothing-to-transform on the setup side, and the preview file is checked on its own. This also fixes re-transforming an already-migrated setup file (duplicate a11yAddonAnnotations import) when no preview file existed. Co-Authored-By: Claude Fable 5 --- .../fixes/addon-a11y-addon-test.test.ts | 43 +++++++++++++++++-- .../fixes/addon-a11y-addon-test.ts | 34 ++++++++++----- 2 files changed, 63 insertions(+), 14 deletions(-) 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 ecd4059961c2..6e6f7ec82ec4 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 @@ -159,7 +159,7 @@ describe('addonA11yAddonTest', () => { }); }); - it.skip('should return previewFile and transformedPreviewCode if preview file exists', async () => { + it('should return previewFile and transformedPreviewCode if preview file exists', async () => { vi.mocked(getAddonNames).mockReturnValue([ '@storybook/addon-a11y', '@storybook/addon-vitest', @@ -191,8 +191,45 @@ describe('addonA11yAddonTest', () => { transformedPreviewCode: expect.any(String), transformedSetupCode: null, skipPreviewTransformation: false, - skipVitestSetupTransformation: false, + skipVitestSetupTransformation: true, + }); + }); + + it('should return null if vitest.setup file does not exist and preview file has the necessary transformations', async () => { + vi.mocked(getAddonNames).mockReturnValue([ + '@storybook/addon-a11y', + '@storybook/addon-vitest', + ]); + vi.mocked(existsSync).mockImplementation((p) => { + if (p.toString().includes('preview')) { + return true; + } else { + return false; + } + }); + vi.mocked(readFileSync).mockImplementation((p) => { + if (p.toString().includes('preview')) { + return ` + export default { + parameters: { + a11y: { + test: 'todo' + } + } + } + `; + } else { + return ''; + } }); + + const result = await addonA11yAddonTest.check({ + mainConfig: { + framework: '@storybook/react-vite', + }, + configDir, + } as any); + expect(result).toBeNull(); }); it('should return setupFile and null transformedSetupCode if transformation fails', async () => { @@ -265,7 +302,7 @@ describe('addonA11yAddonTest', () => { transformedPreviewCode: null, transformedSetupCode: null, skipPreviewTransformation: false, - skipVitestSetupTransformation: false, + skipVitestSetupTransformation: true, }); }); 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 e87b7f7f7107..cf6f4e17c05d 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 @@ -72,21 +72,33 @@ export const addonA11yAddonTest: Fix = { .map((ext) => path.join(configDir, `preview${ext}`)) .find((filePath) => existsSync(filePath)) ?? null; - let skipVitestSetupTransformation = hasCsfFactoryPreview; + // Without a setup file there is nothing to transform: since Storybook 10.3 + // the vitest plugin auto-provisions preview annotations (including addon-a11y's). + let skipVitestSetupTransformation = hasCsfFactoryPreview || !vitestSetupFile; let skipPreviewTransformation = false; - if (vitestSetupFile && previewFile) { - const vitestSetupSource = readFileSync(vitestSetupFile, 'utf8'); - const previewSetupSource = readFileSync(previewFile, 'utf8'); - - skipVitestSetupTransformation ||= vitestSetupSource.includes('@storybook/addon-a11y'); - skipPreviewTransformation ||= !shouldPreviewFileBeTransformed(previewSetupSource); + if (vitestSetupFile && !skipVitestSetupTransformation) { + try { + const vitestSetupSource = readFileSync(vitestSetupFile, 'utf8'); + skipVitestSetupTransformation = vitestSetupSource.includes('@storybook/addon-a11y'); + } catch { + // leave the flag as-is; getTransformedSetupCode handles unreadable files + } + } - if (skipVitestSetupTransformation && skipPreviewTransformation) { - return null; + if (previewFile) { + try { + const previewSetupSource = readFileSync(previewFile, 'utf8'); + skipPreviewTransformation = !shouldPreviewFileBeTransformed(previewSetupSource); + } catch { + // leave the flag as-is; getTransformedPreviewCode handles unreadable files } } + if (skipVitestSetupTransformation && skipPreviewTransformation) { + return null; + } + const getTransformedSetupCode = () => { if (!vitestSetupFile || skipVitestSetupTransformation) { return null; @@ -95,7 +107,7 @@ export const addonA11yAddonTest: Fix = { try { const vitestSetupSource = readFileSync(vitestSetupFile, 'utf8'); return transformSetupFile(vitestSetupSource); - } catch (e) { + } catch { return null; } }; @@ -108,7 +120,7 @@ export const addonA11yAddonTest: Fix = { try { const previewSetupSource = readFileSync(previewFile, 'utf8'); return transformPreviewFile(previewSetupSource, previewFile); - } catch (e) { + } catch { return null; } };