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

Actions are not mocked for interaction tests in production build #206

Closed
bodograumann opened this issue Jan 14, 2022 · 5 comments · Fixed by #482
Closed

Actions are not mocked for interaction tests in production build #206

bodograumann opened this issue Jan 14, 2022 · 5 comments · Fixed by #482

Comments

@bodograumann
Copy link
Contributor

After switching from webpack builder to this vite builder, the action args are not mocked correctly anymore.

Reproduction: https://github.com/bodograumann/storybook-vite-action-interaction

Use as:

git clone https://github.com/bodograumann/storybook-vite-action-interaction
cd storybook-vite-action-interaction
yarn install
yarn build-storybook
python -m http.server --directory storybook-static 6677
xdg-open http://localhost:6677/?path=/story/example-button--primary

Now the Interactions tab will be marked as failed with the message:

expect(received).toHaveBeenCalled()

Matcher error: received value must be a mock or spy function

Received has type:  function
Received has value: "[Function anonymous]"

In contrast, when running with yarn storybook, everything is fine.

@bodograumann bodograumann changed the title Actions are not mocked for interaction tests Actions are not mocked for interaction tests in production build Jan 14, 2022
@bodograumann
Copy link
Contributor Author

I was pointed to this file: https://github.com/storybookjs/storybook/blob/next/addons/interactions/src/preset/preview.ts

Debugging, I found, that the reduce in addActionsFromArgTypes is called correctly, but that the arg name val.name is minified to "ae" by rollup instead of being equal to "actionHandler" as it should be.

The name "actionHandler" is defined here: https://github.com/storybookjs/storybook/blob/next/addons/actions/src/preview/action.ts#L47 and I verified that the problem occurs in dev mode as well if I change it there.

So the culprit here is esbuild, point 5 at https://esbuild.github.io/api/#minify-considerations says:

By default esbuild does not preserve the value of .name on function and class objects. This is because most code doesn't rely on this property and using shorter names is an important size optimization. However, some code does rely on the .name property for registration and binding purposes. If you need to rely on this you should enable the keep names option.

So as an easy fix, we could enable the keep names option in esbuild.
On the other hand it is not such a good idea to rely on function names in the first place 🤔

@IanVS
Copy link
Member

IanVS commented May 10, 2022

Great sleuthing, @bodograumann.

@ghengeveld it looks like you wrote most of this, and are probably the most familiar. Can you think of any other ways https://github.com/storybookjs/storybook/blob/0b3e2ea7066def01de91126892e2aafe3f2dd540/addons/interactions/src/preset/preview.ts#L23 could be done other than looking at the .name value of the function, since it is minified in production, as @bodograumann shows above?

@swallowtail62
Copy link

The following will work.

const { mergeConfig } = require('vite');

module.exports = {
  ...,  // other configs
  async viteFinal(config) {
    return mergeConfig(config, {
      esbuild: {
        keepNames: true,
      },
    });
  },
};

@bodograumann
Copy link
Contributor Author

Can we get a fix in for this, @IanVS / @ghengeveld?

We could enable keepNames in the vite builder by default.

@IanVS
Copy link
Member

IanVS commented Aug 17, 2022

Thanks, I had lost track of this. @bodograumann would you be willing to submit a PR? It should just be a matter of adding the option to

return {
configFile: false,
root: path.resolve(options.configDir, '..'),
cacheDir: 'node_modules/.vite-storybook',
envPrefix,
define: {},
resolve:
framework === 'vue3'
? {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
}
: {},
plugins: await pluginConfig(options, _type),
};
, and verifying that it does the right thing in the example projects.

I'm a bit pre-occupied at the moment with helping to get the vite builder working in storybook 7.0.

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

Successfully merging a pull request may close this issue.

3 participants