rainbowkit icon indicating copy to clipboard operation
rainbowkit copied to clipboard

[bug] Package throws import errors when running jest test suites

Open brightiron opened this issue 2 years ago • 8 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

RainbowKit Version

0.2.2

wagmi Version

0.4.6

Current Behavior

Package causes jest to throw a 'Cannot use import statement outside a module' error

Hello Sers! Digging this project and appreciate all you guys are doing. Running into an issue when running our test suite where this package throws import errors. There are some things we can do on our side to workaround (i.e. mock import, transformIgnorePatterns, etc) but this is not something we've had to do for any other dependency.

To rule out our project specifically i've created a fresh create-react-app, installed rainbowkit, wagmi, and ethers. When running yarn test we experience the exact same behavior.

I imagine this is something others will soon encounter.

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /rainbowkit-jest-test/node_modules/@rainbow-me/rainbowkit/dist/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import {

Expected Behavior

Package should not throw import errors when running jest test suite and shouldn't have to mock package import.

Steps To Reproduce

Checkout: https://github.com/brightiron/rainbowkit-jest-test (Clean create-react-app project with only wagmi, rainbowkit and ethers installed)

Run: yarn install yarn test

Link to Minimal Reproducible Example (CodeSandbox, StackBlitz, etc.)

https://github.com/brightiron/rainbowkit-jest-test

Anything else?

No response

brightiron avatar Jun 02 '22 22:06 brightiron

Thanks for the detailed issue and minimal reproducible example @brightiron – we'll check it out!

nickbytes avatar Jun 02 '22 22:06 nickbytes

Quick update from my end. I was able to get our test suite running by appending --transformIgnorePatterns \"node_modules/(?!@rainbow-me)/\" to our test command in package.json. Example:

"test:unit": "react-scripts test --transformIgnorePatterns \"node_modules/(?!@rainbow-me)/\""

However jest now complains at this import import "@rainbow-me/rainbowkit/styles.css"; Cannot find module '@rainbow-me/rainbowkit/styles.css' This style import is documented here in the install instructions: https://www.rainbowkit.com/docs/installation.

The only two workarounds i've found are:

    1. Manually reference rainbowkit styling from inside our own project. (copy the styles from the package and import, yuck).
    1. add a moduleNameMapper config for jest in package.json and install the identity-obj-proxy package or reference an empty module
  "jest":{
     "moduleNameMapper": {
      "\\.(css)$": "identity-obj-proxy"
    },

The problem with the latter for us is that it increases the runtime of our test suite considerably.

In the longterm, it seems like each of these components in rainbowkit could potentially import their own styles vs relying on a style import from the project the library is installed in. Would also remove an install/configuration step for anyone using the package.

It'd also be awesome if we didn't have to use --transformIgnorePatterns as this is also affecting test run performance .

Appreciate you guys.

brightiron avatar Jun 07 '22 19:06 brightiron

Any updates on this? I'm having the same problems and was only able to workaround using @brightiron suggestion, but as mentioned it greatly increased runtime.

Arthurgallina1 avatar Jul 13 '22 17:07 Arthurgallina1

Having the same issues when using create-react-app + chakra.

bpeters avatar Jul 16 '22 21:07 bpeters

If you are using NextJS there is a known issue where next ignores your transformIgnorePatterns: https://github.com/vercel/next.js/issues/35634

fritzschoff avatar Jul 18 '22 10:07 fritzschoff

An alternative temporay fix is to mock the rainbowkit like this:

jest.mock("@rainbow-me/rainbowkit", () => ({
    ConnectButton: {
         Custom: jest.fn(),
    },
}));

Add this line to your jest.setup.ts or your test files directly.

pyk avatar Jul 20 '22 09:07 pyk

Reproducing the same with latest nextjs + tailwind + wagmi

sudoFerraz avatar Aug 08 '22 13:08 sudoFerraz

I was having issues with mocking only the Connect Button due to how we instantiate our providers and default supported chains, in case anyone is stumbling on the same issue you can mock the getDefaultWallets function in the same way by adding getDefaultWallets: jest.fn(() => ({})), to jest.setup.ts

sudoFerraz avatar Aug 08 '22 16:08 sudoFerraz

For those of you on NextJS, fixed it locally by mocking the ConnectButton and getDefaultWallets func per @sudoFerraz and @pyk

I can now run jest test locally without problem, however when running in github actions, tests seem to run indefinitely.

Running with the transformIgnorePatterns from @brightiron, I get this locally:

pragma cannot be set when runtime is automatic ,---- 39 | /** @jsx jsx */ : ^^^^^^^^^^^^^^^ `----

is there any other way to ignore rainbowkit with Jest tests?

edit: wagmi's createClient function seems to prevent jest from exiting so our GH Actions ran forever

added --forceExit flag to the jest command and


jest.mock('@rainbow-me/rainbowkit', () => ({
  ConnectButton: {
    Custom: jest.fn(),
  },
  RainbowKitProvider: jest.fn(),
  getDefaultWallets: jest.fn(() => ({})),
}));

in jest.setup

rocketman-21 avatar Aug 26 '22 21:08 rocketman-21

Tried solutions above but I'm getting Error: Uncaught [TypeError: (0 , rainbowkit_1.lightTheme) is not a function] as I'm using Rainbowkit's light and dark themes.

smakosh avatar Aug 31 '22 08:08 smakosh

We just published a fix for the CSS import issue mentioned above in RainbowKit v0.5.2.

We were using the exports field in package.json to alias dist/index.css as styles.css publicly but Jest doesn't support this, so we've published a fallback resolution method that should work in Jest.

@brightiron I'd be keen to hear how much of an improvement this is to your setup.

markdalgleish avatar Sep 13 '22 03:09 markdalgleish

Closing this as fixed. Feel free to continue the discussions! If anything else arises, we can reopen this issue.

jxom avatar Sep 15 '22 00:09 jxom

We just published a fix for the CSS import issue mentioned above in RainbowKit v0.5.2.

We were using the exports field in package.json to alias dist/index.css as styles.css publicly but Jest doesn't support this, so we've published a fallback resolution method that should work in Jest.

@brightiron I'd be keen to hear how much of an improvement this is to your setup.

@markdalgleish - ty for the fix. lemme do some benchmarking this week and reply here with some results. We're also in process of migrating to vite / vitest for local dev, and I have some mocks created that play nicely with rainbowkit & custom button implementations. I'll also reply when i get a minute with a more comprehensive mocking strategy. The vitest mocks should also play nicely with jest. may be worthwhile to add these to docs at some point in the future .

Appreciate you guys!

brightiron avatar Sep 15 '22 22:09 brightiron

In case you want to customize the mocked value for the ConnectButton you can mock using this:

jest.mock("@rainbow-me/rainbowkit", () => ({
  ConnectButton: () => <div>ConnectButton</div>,
  ...
}));

MateusAndrade avatar Aug 17 '23 21:08 MateusAndrade