Skip to content

Conversation

@kasperpeulen
Copy link
Contributor

@kasperpeulen kasperpeulen commented Aug 21, 2025

Closes #

What I did

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

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 canary-release-pr.yml --field pr=<PR_NUMBER>

Greptile Summary

This PR introduces a major new testing feature for Storybook that allows test functions to be co-located with stories using a new CSF4 (Component Story Format 4) API. The refactor adds comprehensive support for story-level testing through several key components:

Core Infrastructure Changes:

  • Adds TestFunction type definitions across the CSF type system (code/core/src/csf/story.ts, code/core/src/types/modules/csf.ts)
  • Introduces new CSF factory methods enabling meta.story() and story.test() APIs for defining stories and their associated tests
  • Implements test execution phases in the story rendering pipeline, adding 'testing' and 'tested' phases alongside existing play function phases
  • Extends story processing to handle test functions through the entire pipeline from CSF parsing to story execution

Testing API Implementation:

  • Stories can now define multiple tests using story.test(name, testFunction) with optional story annotation overrides
  • Tests are executed with full story context including canvas, userEvent, and args
  • New toTestId() function generates hierarchical test IDs using colon separator (e.g., story-id:test-name)
  • Portable stories gain a run() method that can execute specific tests by name

Vitest Integration:

  • Enhances the Vitest transformer to generate describe blocks for stories with tests, creating individual test cases for each story test annotation
  • Updates test utilities to support both traditional composed stories and the new Story API with test functions
  • Enables execution of individual test functions within story contexts

UI Enhancements:

  • Adds visual differentiation for test stories in the sidebar with green-colored beaker icons
  • Stories tagged with 'test-fn' display with distinct styling and adjusted padding
  • Includes new TreeNode story types and IconSymbols for test representation

CSF Processing:

  • Updates CSF file parsing to extract and index test functions attached to stories
  • Modifies story indexing to create separate entries for tests while maintaining parent-child relationships
  • Extends preview configuration to support CSF4 factory patterns with __definePreview

The feature enables developers to write tests directly alongside their stories using familiar testing patterns while leveraging Storybook's component context and utilities. Tests inherit story configuration but can override args, parameters, and globals as needed.

Confidence score: 2/5

  • This PR contains significant development artifacts and debugging code that should not be merged in production
  • Several files include console.log statements, TODO comments about unresolved type errors, and temporary hack implementations that need refinement
  • The vitest workspace configuration disables all existing tests, suggesting this is experimental prototype work rather than production-ready code

@kasperpeulen kasperpeulen changed the base branch from next to yann/test-fn-prototype August 21, 2025 11:05
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

38 files reviewed, 5 comments

Edit Code Review Bot Settings | Greptile

stories: Record<StoryId, NormalizedStoryAnnotations<TRenderer>>;
stories: Record<
StoryId,
NormalizedStoryAnnotations<TRenderer> & { testFunction?: TestFunction<TRenderer> }
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Type parameter inconsistency: NormalizedStoryAnnotations uses TestFunction<TRenderer, TRenderer['args']> but CSFFile uses TestFunction<TRenderer> without the args parameter

Suggested change
NormalizedStoryAnnotations<TRenderer> & { testFunction?: TestFunction<TRenderer> }
NormalizedStoryAnnotations<TRenderer> & { testFunction?: TestFunction<TRenderer, TRenderer['args']> }

run: (
context?: Partial<StoryContext<TRenderer, Partial<TArgs>>>,
testName?: string
test?: (context: StoryContext<TRenderer>) => void | Promise<void>
Copy link
Contributor

Choose a reason for hiding this comment

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

style: The test parameter uses the full StoryContext<TRenderer> type while the context parameter uses Partial<TArgs> - verify this type inconsistency is intentional

export function normalizeStory<TRenderer extends Renderer>(
key: StoryId,
storyAnnotations: StoryAnnotationsOrFn<TRenderer>,
storyAnnotations: StoryAnnotationsOrFn<TRenderer> & { testFunction?: any },
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Using any type for testFunction reduces type safety. Consider defining a proper TestFunction type from the CSF types.

@@ -1,3 +1,4 @@
//* @vitest-environment happy-dom */
Copy link
Contributor

Choose a reason for hiding this comment

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

syntax: Comment syntax is incorrect - should use // instead of //*

Suggested change
//* @vitest-environment happy-dom */
// @vitest-environment happy-dom */

// @ts-ignore TODO: Kasper to figure out later
this.input.__tests![name] = testStory;
const annotations = typeof overridesOrTestFn !== 'function' ? overridesOrTestFn : {};
const testFunction = typeof overridesOrTestFn !== 'function' ? testFn! : overridesOrTestFn;
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Using non-null assertion testFn! assumes testFn is always provided when overridesOrTestFn is not a function, but TypeScript overloads don't guarantee this at runtime

Suggested change
const testFunction = typeof overridesOrTestFn !== 'function' ? testFn! : overridesOrTestFn;
const testFunction = typeof overridesOrTestFn !== 'function' ? testFn : overridesOrTestFn;

@nx-cloud
Copy link

nx-cloud bot commented Aug 21, 2025

View your CI Pipeline Execution ↗ for commit 8e74582

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 1m 19s View ↗

☁️ Nx Cloud last updated this comment at 2025-08-21 12:06:22 UTC

@storybook-app-bot
Copy link

storybook-app-bot bot commented Aug 21, 2025

Package Benchmarks

Commit: 8e74582, ran on 21 August 2025 at 12:07:59 UTC

The following packages have significant changes to their size or dependencies:

@storybook/angular

Before After Difference
Dependency count 198 199 🚨 +1 🚨
Self size 191 KB 191 KB 0 B
Dependency size 29.59 MB 29.73 MB 🚨 +146 KB 🚨
Bundle Size Analyzer Link Link

@kasperpeulen kasperpeulen changed the title Refactor-test-prototype Test: Refactor .test prototype Aug 21, 2025
@yannbf yannbf merged commit df6dce7 into yann/test-fn-prototype Aug 21, 2025
21 of 24 checks passed
@yannbf yannbf deleted the kasper/refactor-test-prototype branch August 21, 2025 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants