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 package not working #92

Open
Bronowsm opened this issue Jul 31, 2024 · 15 comments
Open

[Bug] @storybook/test package not working #92

Bronowsm opened this issue Jul 31, 2024 · 15 comments
Labels
bug Something isn't working

Comments

@Bronowsm
Copy link

Bronowsm commented Jul 31, 2024

Describe the bug

Whenever I add @storybook/addon-react-native-web package to addons array, @storybook/test package stops working.
When I comment out or remove @storybook/addon-react-native-web from addons array, the error is gone (screenshot of error below)

Here is my setup:

.storybook/main.js file:

const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");

const config = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-webpack5-compiler-swc",
    "@storybook/addon-onboarding",
    "@chromatic-com/storybook",
    "@storybook/addon-interactions",
    "storybook-dark-mode",
    "@storybook/addon-react-native-web", // it makes @storybook/test not working :D
  ],
  framework: {
    name: "@storybook/react-webpack5",
    options: {},
  },
  core: {
    builder: "webpack5",
  },
  webpackFinal: async (config, { configType }) => {
    config.plugins.push(new NodePolyfillPlugin());

    return config;
  },
};
export default config;

.storybook/preview:

const preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
};

export default preview;

.babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": ["react-native-web"]
}

package.json:

{
  "name": "before-storybook",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "author": "",
  "scripts": {
    "dev": "webpack serve --open",
    "build": "webpack build",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "@babel/core": "latest",
    "@babel/preset-env": "latest",
    "@babel/preset-react": "latest",
    "@babel/preset-typescript": "latest",
    "@react-native/babel-preset": "^0.74.86",
    "@storybook/addon-react-native-web": "^0.0.24",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "babel-loader": "latest",
    "babel-plugin-react-native-web": "^0.19.12",
    "babel-preset-react-app": "latest",
    "babel-preset-react-native": "^4.0.1",
    "html-webpack-plugin": "latest",
    "metro-react-native-babel-preset": "^0.77.0",
    "node-polyfill-webpack-plugin": "^4.0.0",
    "react": "^18",
    "react-dom": "^18.3.1",
    "react-native-web": "^0.19.12",
    "storybook-dark-mode": "^4.0.2",
    "tty-browserify": "^0.0.1",
    "typescript": "^4.8",
    "webpack": "^5",
    "webpack-cli": "latest",
    "webpack-dev-server": "latest"
  },
  "devDependencies": {
    "@chromatic-com/storybook": "^1.6.1",
    "@storybook/addon-a11y": "8.2.6",
    "@storybook/addon-actions": "8.2.6",
    "@storybook/addon-backgrounds": "8.2.6",
    "@storybook/addon-controls": "8.2.6",
    "@storybook/addon-docs": "8.2.6",
    "@storybook/addon-essentials": "^8.2.6",
    "@storybook/addon-highlight": "8.2.6",
    "@storybook/addon-interactions": "^8.2.6",
    "@storybook/addon-jest": "8.2.6",
    "@storybook/addon-links": "^8.2.6",
    "@storybook/addon-mdx-gfm": "8.2.6",
    "@storybook/addon-measure": "8.2.6",
    "@storybook/addon-onboarding": "^8.2.6",
    "@storybook/addon-outline": "8.2.6",
    "@storybook/addon-storysource": "8.2.6",
    "@storybook/addon-themes": "8.2.6",
    "@storybook/addon-toolbars": "8.2.6",
    "@storybook/addon-viewport": "8.2.6",
    "@storybook/addon-webpack5-compiler-swc": "^1.0.5",
    "@storybook/blocks": "^8.2.6",
    "@storybook/builder-manager": "8.2.6",
    "@storybook/builder-vite": "8.2.6",
    "@storybook/builder-webpack5": "8.2.6",
    "@storybook/channels": "8.2.6",
    "@storybook/cli": "8.2.6",
    "@storybook/client-logger": "8.2.6",
    "@storybook/codemod": "8.2.6",
    "@storybook/components": "8.2.6",
    "@storybook/core": "8.2.6",
    "@storybook/core-common": "8.2.6",
    "@storybook/core-events": "8.2.6",
    "@storybook/core-server": "8.2.6",
    "@storybook/core-webpack": "8.2.6",
    "@storybook/csf-plugin": "8.2.6",
    "@storybook/csf-tools": "8.2.6",
    "@storybook/docs-tools": "8.2.6",
    "@storybook/ember": "8.2.6",
    "@storybook/html": "8.2.6",
    "@storybook/html-vite": "8.2.6",
    "@storybook/html-webpack5": "8.2.6",
    "@storybook/instrumenter": "8.2.6",
    "@storybook/manager": "8.2.6",
    "@storybook/manager-api": "8.2.6",
    "@storybook/nextjs": "8.2.6",
    "@storybook/node-logger": "8.2.6",
    "@storybook/preact": "8.2.6",
    "@storybook/preact-vite": "8.2.6",
    "@storybook/preact-webpack5": "8.2.6",
    "@storybook/preset-create-react-app": "8.2.6",
    "@storybook/preset-html-webpack": "8.2.6",
    "@storybook/preset-preact-webpack": "8.2.6",
    "@storybook/preset-react-webpack": "8.2.6",
    "@storybook/preset-server-webpack": "8.2.6",
    "@storybook/preset-svelte-webpack": "8.2.6",
    "@storybook/preset-vue3-webpack": "8.2.6",
    "@storybook/preview": "8.2.6",
    "@storybook/preview-api": "8.2.6",
    "@storybook/react": "^8.2.6",
    "@storybook/react-dom-shim": "8.2.6",
    "@storybook/react-vite": "8.2.6",
    "@storybook/react-webpack5": "8.2.6",
    "@storybook/router": "8.2.6",
    "@storybook/server": "8.2.6",
    "@storybook/server-webpack5": "8.2.6",
    "@storybook/source-loader": "8.2.6",
    "@storybook/svelte": "8.2.6",
    "@storybook/svelte-vite": "8.2.6",
    "@storybook/svelte-webpack5": "8.2.6",
    "@storybook/sveltekit": "8.2.6",
    "@storybook/telemetry": "8.2.6",
    "@storybook/test": "^8.2.6",
    "@storybook/theming": "8.2.6",
    "@storybook/types": "8.2.6",
    "@storybook/vue3": "8.2.6",
    "@storybook/vue3-vite": "8.2.6",
    "@storybook/vue3-webpack5": "8.2.6",
    "@storybook/web-components": "8.2.6",
    "@storybook/web-components-vite": "8.2.6",
    "@storybook/web-components-webpack5": "8.2.6",
    "jackspeak": "2.1.1",
    "sb": "8.2.6",
    "storybook": "^8.2.6"
  }
}

webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");

process.env.NODE_ENV = "development";
const host = process.env.HOST || "localhost";

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  entry: "./src/index.tsx",
  output: {
    filename: "static/js/bundle.js",
  },
  devServer: {
    compress: true,
    hot: true,
    host,
    port: 3000,
  },
  plugins: [new HtmlWebpackPlugin()],
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx|mjs)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
  resolve: {
    extensions: [".mjs", ".js", ".cjs", ".jsx", ".tsx", ".ts"],
    modules: ["node_modules"],
  },
};

Screenshots and/or logs

Zrzut ekranu 2024-07-31 o 10 36 30

Environment

  • OS: macOS
  • Node.js version: 18.19.0
  • NPM version: 8.5.5
@Bronowsm Bronowsm added the bug Something isn't working label Jul 31, 2024
@Bronowsm Bronowsm changed the title [Bug] [Bug] @storybook/test package not working Jul 31, 2024
@dannyhw
Copy link
Member

dannyhw commented Jul 31, 2024

@Bronowsm hey, thanks for raising this issue. I have actually seen a similar issue but I'm not familiar with the test package implementation so I'll have to defer to others. Will look into it.

@JavanPoirier
Copy link

+1 👀

@dannyhw
Copy link
Member

dannyhw commented Sep 10, 2024

Sorry for the delay! This slipped off my radar but I will make sure to ask around tomorrow.

@dannyhw
Copy link
Member

dannyhw commented Sep 11, 2024

so looking back in my chat history with some people the information that I have is that it may have something to do with the CJS of the storybook/test package being messed up and forcing the mjs version could help. Not sure how to do that with webpack yet but leaving this note here for context.

@dannyhw
Copy link
Member

dannyhw commented Sep 11, 2024

I think first step would be to create a more minimal reproduction of the problem and then to verify which entrypoint is being used (i.e cjs/mjs)

one thing to try is adding to webpack final something like:

config.resolve.extensions = ['mjs', ...config.resolve.extensions]

to get mjs loading before cjs

@Bronowsm
Copy link
Author

Bronowsm commented Oct 7, 2024

@dannyhw thanks for hints, they were very useful - it was about forcing storybook/test package to use .mjs extension. But overriding config.resolve.extensions didn't do the trick. What I did instead, was to point out to the exact file in node_modules and storybook/test is working again!

  config.resolve.alias = {
      ...config.resolve.alias,
      '@storybook/test': path.resolve(__dirname, '../node_modules/@storybook/test/dist/index.mjs'),
    };

@JavanPoirier
Copy link

'@storybook/test': path.resolve(__dirname, '../node_modules/@storybook/test/dist/index.mjs'),

Why didn't I think of that!? I moved on with the failure of the extension priority. Anywho, thanks @Bronowsm, works for me!

@dannyhw
Copy link
Member

dannyhw commented Oct 7, 2024

Interesting, its so strange that the wrong extension is always getting resolved 😕 . I wonder if theres something wrong with the exports in package.json for the storybook/test package.

Or maybe it has something to do with the babel loader that addon-react-native-web is including, not sure

@JavanPoirier
Copy link

JavanPoirier commented Oct 8, 2024

Found another issue, it appears that the solution @Bronowsm proposed does work for stories, but not when mocking. The underlying implementation of fn appears to be just an export from @vitest/spy, so not immediately sure why this doesn't work.

Works: Button.stories.ts

import { fn } from '@storybook/test';
const meta = {
  title: 'Example/Button',
  component: Button,
  args: { onClick: fn() },
} satisfies Meta<typeof Button>;

Works: useRouter.mock.ts

import { fn } from '@vitest/spy';
import * as actual from './useRouter';

export const useRouter = fn(actual.useRouter).mockName('useRouter').mockReturnValue({ 
    back: () => null,
    push: () => null,
    replace: () => null,
    parseNextPath: () => '',
});

Does NOT Work:

import { fn } from '@storybook/test';
import * as actual from './useRouter';

export const useRouter = fn(actual.useRouter).mockName('useRouter').mockReturnValue({ 
    back: () => null,
    push: () => null,
    replace: () => null,
    parseNextPath: () => '',
});

@dannyhw
Copy link
Member

dannyhw commented Oct 8, 2024

@JavanPoirier when you use the mock from storybook/test what problem/error do you get?

@JavanPoirier
Copy link

@JavanPoirier when you use the mock from storybook/test what problem/error do you get?

Just that it does not exist. Changing the import resolves it.

@kasperpeulen
Copy link

@JavanPoirier Does this happen in storybook 8.3? We changed the order of the export condition in 8.3.
So that ESM always has highest prio:

  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.js",
      "node": "./dist/index.js",
      "default": "./dist/index.mjs"
    },
    "./package.json": "./package.json"
  },

@JavanPoirier
Copy link

JavanPoirier commented Oct 8, 2024

Looks like I sorted it out, using the @vitest/spy import made it so the default mockReturnValue I specified in the useRouter.mock.ts was applied without directly importing it into the story to use in beforeEach (as the docs do say to do). I could then overwrite the default mock by importing it and specifying a chained mockReturnValue call.

Now when using the @storybook/test export I must ALWAYS have a beforeEach statement, import the mock and call mockReturnValue.

I kinda liked the ability to not have to add the beforeEach call and having just function stubs in place.

I am on storybook@npm:8.3.4

Example:

useRouter.mock.ts

import { fn } from '@vitest/spy';
import * as actual from './useRouter';

export const useRouter = fn(actual.useRouter).mockName('useRouter').mockReturnValue({ 
    back: () => null,
    push: () => null,
    replace: () => null,
    parseNextPath: () => '',
});

I never needed to import it anywhere or call beforeEach, the mock just worked.

Now with @storybook/test, I must import the mock into preview.tsx or a story and call mockReturnValue

@yannbf
Copy link
Member

yannbf commented Oct 8, 2024

Hey @JavanPoirier that's pretty weird. You should be using fn from @storybook/test instead. Could you share a reproduction repo so we can see what's going on?

@JavanPoirier
Copy link

Hey @JavanPoirier that's pretty weird. You should be using fn from @storybook/test instead. Could you share a reproduction repo so we can see what's going on?

https://github.com/JavanPoirier/rn-web-sb-mock

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants