Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Storybook test, toHaveBeenCalledWith with Date arguments #30503

Closed
blvdmitry opened this issue Feb 9, 2025 · 4 comments · Fixed by #30507
Closed

[Bug]: Storybook test, toHaveBeenCalledWith with Date arguments #30503

blvdmitry opened this issue Feb 9, 2025 · 4 comments · Fixed by #30507

Comments

@blvdmitry
Copy link

Describe the bug

I'm trying to migrate to a setup using only Storybook test instead of working with Jest/Vitest directly. When testing a calendar change handler, I found that Storybook is crashing when checking for the Date arguments matching.

Here is a story I wrote:

export const onChange: StoryObj<{ handleChange: ReturnType<typeof fn> }> = {
	name: "onChange",
	args: {
		handleChange: fn(),
	},
	render: (args) => (
		<Calendar defaultMonth={new Date(2020, 0, 1)} onChange={() => args.handleChange()} />
	),
	play: async ({ canvas, args }) => {
		const dateEls = canvas.getAllByRole("checkbox");

		await userEvent.click(dateEls[0]);

		expect(args.handleChange).toHaveBeenCalledTimes(1);
		expect(args.handleChange).toHaveBeenCalledWith({ value: new Date(2020, 0, 1) });
	},
};

This line is causing the issue and if I remove it the rest of the test is working fine:

expect(args.handleChange).toHaveBeenCalledWith({ value: new Date(2020, 0, 1) });

The error I see in the console when this line is present:

Image

I've also checked that changing it to new Date(...).toString() removes that e.split error and returns a correct assertion error since it's not matching the real Date argument anymore

Reproduction link

...

Reproduction steps

I will try to create a standalone reproduction link due to limited amount of time I have while working on this project but I can give access to my private repository branch with the storybook test setup for reproduction.

System

Storybook Environment Info:

  System:
    OS: macOS 15.2
    CPU: (14) arm64 Apple M3 Max
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.18.0 - ~/.nvm/versions/node/v20.18.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.18.0/bin/yarn <----- active
    npm: 10.8.2 - ~/.nvm/versions/node/v20.18.0/bin/npm
    pnpm: 9.15.4 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 132.0.6834.160
    Safari: 18.2
  npmPackages:
    @storybook/addon-a11y: 8.5.2 => 8.5.2 
    @storybook/addon-actions: 8.5.2 => 8.5.2 
    @storybook/addon-controls: 8.5.2 => 8.5.2 
    @storybook/addon-docs: 8.5.2 => 8.5.2 
    @storybook/addon-storysource: 8.5.2 => 8.5.2 
    @storybook/experimental-addon-test: 8.5.2 => 8.5.2 
    @storybook/react: 8.5.2 => 8.5.2 
    @storybook/react-vite: 8.5.2 => 8.5.2 
    chromatic: 11.19.0 => 11.19.0 
    storybook: 8.5.2 => 8.5.2

Additional context

No response

@ghengeveld
Copy link
Member

ghengeveld commented Feb 10, 2025

@blvdmitry Have you tried this?

expect(args.handleChange).toHaveBeenCalledWith({ value: new Date(2020, 0, 1).toISOString() });

Dates get serialized like that so that they can be sent as a ChannelMessage to the Storybook manager.

If this doesn't work, I suspect that what you're seeing printed is just the serialized version, while in fact the value is a Date object. It may simply be considered non-matching because you're comparing two Date objects, which have a different identity (despite having the same value, they aren't equal). Not sure if that's how toHaveBeenCalledWith behaves though.

@ghengeveld
Copy link
Member

ghengeveld commented Feb 10, 2025

I've addressed the e.split error in #30507.

@ghengeveld
Copy link
Member

ghengeveld commented Feb 10, 2025

@blvdmitry While trying to reproduce this bug, we found an apparent bug in your code. args.handleChange isn't being passed any arguments here:

<Calendar defaultMonth={new Date(2020, 0, 1)} onChange={() => args.handleChange()} />

I think you'll want this instead:

<Calendar defaultMonth={new Date(2020, 0, 1)} onChange={args.handleChange} />

@blvdmitry
Copy link
Author

Sorry, my mistake with the code snippet, that was one after testing different workarounds. The same happens when I just pass the function directly:

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants