Skip to content

CSF4: Fix duplicate preview loading issue in Vitest#34361

Merged
valentinpalkovic merged 3 commits into
nextfrom
valentin/fix-csf4-vitest-issue
Mar 27, 2026
Merged

CSF4: Fix duplicate preview loading issue in Vitest#34361
valentinpalkovic merged 3 commits into
nextfrom
valentin/fix-csf4-vitest-issue

Conversation

@valentinpalkovic
Copy link
Copy Markdown
Contributor

@valentinpalkovic valentinpalkovic commented Mar 27, 2026

Closes #34317

What I did

I've fixed a bug where the preview file wasn't deduplicated when users used CSF factories in Vitest tests. The fix actually removes the user's preview.js from the internal setup files and always calls get project annotations, even for CSF factory users. Although setting preview annotations for CSF factory users is obsolete, the internal import of preview annotations via a virtual file will result in deduplication of imports.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Refactor
    • Removed automatic detection/parsing of Storybook preview/config during Vitest plugin setup.
    • Simplified initialization so project annotation requirements are determined from test config and options only.
    • Eliminated conditional inclusion of an extra internal setup step tied to preview/config presence.
    • Minor formatting update to documentation JSON file.

Co-authored-by: Kasper Peulen <kasperpeulen@gmail.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 27, 2026

Fails
🚫 The "#### Manual testing" section must be filled in. Please describe how to test the changes you've made, step by step, so that reviewers can confirm your PR works as intended.

Generated by 🚫 dangerJS against 3ebc4fe

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 27, 2026

View your CI Pipeline Execution ↗ for commit 3ebc4fe

Command Status Duration Result
nx run-many -t compile,check,knip,test,lint,fmt... ✅ Succeeded 7m 5s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-27 11:42:08 UTC

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: df2d2925-d435-4bb1-beb0-30afd2595d59

📥 Commits

Reviewing files that changed from the base of the PR and between cfb9819 and 3ebc4fe.

📒 Files selected for processing (1)
  • docs/versions/next.json
✅ Files skipped from review due to trivial changes (1)
  • docs/versions/next.json

📝 Walkthrough

Walkthrough

Removed Storybook preview/config loading and CSF4 detection from the Vitest plugin. requiresProjectAnnotations no longer accepts isCSF4 and now bases its result solely on detecting setProjectAnnotations in user setup files; plugin no longer conditionally injects the CSF4-specific internal setup file.

Changes

Cohort / File(s) Summary
Vitest plugin core
code/addons/vitest/src/vitest-plugin/index.ts
Removed logic that loaded/parses Storybook preview/config and the conditional addition of a CSF4-specific internal setup file. Now calls requiresProjectAnnotations(...) without preview/config data.
Vitest plugin utils
code/addons/vitest/src/vitest-plugin/utils.ts
Removed isCSF4 parameter from requiresProjectAnnotations signature and eliminated the CSF4-dependent branch; function now returns based solely on presence of setProjectAnnotations in user setup files.
Docs formatting
docs/versions/next.json
Reformatted JSON to multi-line with trailing newline; no semantic changes to content.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
code/addons/vitest/src/vitest-plugin/utils.ts (1)

41-63: ⚠️ Potential issue | 🟠 Major

Don't restrict manual setProjectAnnotations detection to configDir.

Line 42 is now the only opt-out after removing isCSF4. A repo-root vitest.setup.ts or nested .storybook/.../setup.ts that still calls setProjectAnnotations(...) won't match this exact-parent-dir check, so we'll inject setup-file-with-project-annotations on top of the user's setup and double-register preview annotations.

Possible fix
-import { readFileSync } from 'node:fs';
+import { existsSync, readFileSync } from 'node:fs';
...
-import { dirname, resolve } from 'pathe';
+import { resolve } from 'pathe';
...
   const hasStorybookAnnotations = userSetupFiles.find((setupFile) => {
-    const hasStorybookSetupFileName = dirname(setupFile) === finalOptions.configDir;
-
-    if (!hasStorybookSetupFileName) {
+    if (!existsSync(setupFile)) {
       return false;
     }
 
-    // Check if the file contains setProjectAnnotations
     const setupFileContent = readFileSync(setupFile, 'utf-8');
     return setupFileContent.includes('setProjectAnnotations');
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/addons/vitest/src/vitest-plugin/utils.ts` around lines 41 - 63, The
current detection for manual setProjectAnnotations is restricted by checking
dirname(setupFile) === finalOptions.configDir; change the predicate used for
hasStorybookAnnotations so it no longer requires the setup file to live directly
under finalOptions.configDir: iterate over userSetupFiles and for each file read
its contents (readFileSync) and return true if the content includes
'setProjectAnnotations' (remove the hasStorybookSetupFileName check), leaving
the existing logBoxOnce and return false behavior intact so any setup file
anywhere (e.g., repo-root vitest.setup.ts or nested .storybook/*) will opt out
of automatic preview annotation injection.
🧹 Nitpick comments (1)
code/addons/vitest/src/vitest-plugin/index.ts (1)

306-317: Please add a regression test for both provisioning paths.

These lines now do two load-bearing things at once: default-enable project annotations and stop injecting the preview file itself. A browser test that proves preview-level parameters.msw.handlers inheritance still works, plus a legacy case with an explicit setProjectAnnotations setup file, would keep both the MSW fix and the duplicate-loading avoidance from regressing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/addons/vitest/src/vitest-plugin/index.ts` around lines 306 - 317, Add
two regression tests to cover both provisioning paths introduced around
requiresProjectAnnotations/areProjectAnnotationRequired and internalSetupFiles:
(1) a browser-style test that mounts a story using preview-level
parameters.msw.handlers and asserts the MSW handlers are inherited (verifying we
still inject the preview handlers and don't break preview-level inheritance),
and (2) a legacy case that supplies an explicit setup file which calls
setProjectAnnotations and asserts handlers are applied only once (verifying
duplicate-loading avoidance). Place tests alongside the vitest-plugin test suite
that exercises index.ts behavior and reference the symbols
requiresProjectAnnotations, areProjectAnnotationRequired, internalSetupFiles,
and the setup-file paths ('@storybook/addon-vitest/internal/setup-file' and
'.../setup-file-with-project-annotations') so they cover both branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@code/addons/vitest/src/vitest-plugin/utils.ts`:
- Around line 41-63: The current detection for manual setProjectAnnotations is
restricted by checking dirname(setupFile) === finalOptions.configDir; change the
predicate used for hasStorybookAnnotations so it no longer requires the setup
file to live directly under finalOptions.configDir: iterate over userSetupFiles
and for each file read its contents (readFileSync) and return true if the
content includes 'setProjectAnnotations' (remove the hasStorybookSetupFileName
check), leaving the existing logBoxOnce and return false behavior intact so any
setup file anywhere (e.g., repo-root vitest.setup.ts or nested .storybook/*)
will opt out of automatic preview annotation injection.

---

Nitpick comments:
In `@code/addons/vitest/src/vitest-plugin/index.ts`:
- Around line 306-317: Add two regression tests to cover both provisioning paths
introduced around requiresProjectAnnotations/areProjectAnnotationRequired and
internalSetupFiles: (1) a browser-style test that mounts a story using
preview-level parameters.msw.handlers and asserts the MSW handlers are inherited
(verifying we still inject the preview handlers and don't break preview-level
inheritance), and (2) a legacy case that supplies an explicit setup file which
calls setProjectAnnotations and asserts handlers are applied only once
(verifying duplicate-loading avoidance). Place tests alongside the vitest-plugin
test suite that exercises index.ts behavior and reference the symbols
requiresProjectAnnotations, areProjectAnnotationRequired, internalSetupFiles,
and the setup-file paths ('@storybook/addon-vitest/internal/setup-file' and
'.../setup-file-with-project-annotations') so they cover both branches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2e71c675-6804-42ae-956c-5d82c3fe8b4a

📥 Commits

Reviewing files that changed from the base of the PR and between 4bcba4d and cfb9819.

📒 Files selected for processing (2)
  • code/addons/vitest/src/vitest-plugin/index.ts
  • code/addons/vitest/src/vitest-plugin/utils.ts

@valentinpalkovic valentinpalkovic added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Mar 27, 2026
@valentinpalkovic valentinpalkovic merged commit 69c8442 into next Mar 27, 2026
130 of 131 checks passed
@valentinpalkovic valentinpalkovic deleted the valentin/fix-csf4-vitest-issue branch March 27, 2026 12:13
@github-actions github-actions Bot mentioned this pull request Mar 27, 2026
18 tasks
@SalahAdDin
Copy link
Copy Markdown

CSF4?

@github-actions github-actions Bot mentioned this pull request Mar 31, 2026
19 tasks
valentinpalkovic added a commit that referenced this pull request Mar 31, 2026
…ssue

CSF4: Fix duplicate preview loading issue in Vitest
(cherry picked from commit 69c8442)
@github-actions github-actions Bot mentioned this pull request Apr 2, 2026
19 tasks
@github-actions github-actions Bot added the patch:done Patch/release PRs already cherry-picked to main/release branch label Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug ci:normal patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: addon-vitest browser tests do not reliably inherit preview-level parameters.msw.handlers defaults

3 participants