refinedev / refine

A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.
https://refine.dev
MIT License
25.95k stars 1.96k forks source link

[DOC] how to test with vitest/jest #6020

Open borisyordanov opened 3 weeks ago

borisyordanov commented 3 weeks ago

Documentation issue

The testing page does not have any instructions on tesing with partially-implemented browser environment, like jsdom

Describe the thing to improve

Apps built with refine can contain custom logic that needs to be tested. browser tests (e.g cypress/playwright) are a great way to make certain assertions but for other cases unit and integration tests headless testing (e.g vitest/jest) are much more apt.

When I include the Refine provider in a vitest environment tests start crashing with this error image

The lack of testing documentation means it's very difficult to make the tests run.

import routerProvider from '@refinedev/react-router-v6';
import refineDataProvider from '@refinedev/simple-rest';
import { render, RenderOptions } from '@testing-library/react';
import { Refine, ResourceProps } from '@refinedev/core';
import {  ThemeProvider } from '@mui/material/styles';

export const renderApp = (
  ui: ReactElement,
  options: RenderOptions & {
    resources: ResourceProps[];
  }
) => {
  return render(ui, {
    wrapper: ({ children }: { children: ReactNode }) => (
      <BrowserRouter>
        <ThemeProvider>
          <Refine
            dataProvider={{
              default: refineDataProvider('api'),
            }}
            routerProvider={routerProvider}
            resources={options.resources}
          >
            {children}
          </Refine>
        </ThemeProvider>
      </BrowserRouter>
    ),
    ...options,
  });
};

Describe the solution (optional)

https://github.com/refinedev/refine/tree/master/examples contains examples of a unit testing setup with vitest and jest and react testing library

Context

I'm working in a monorepo, built with https://nx.dev/ and pnpm workspaces

  System:
    OS: Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
    CPU: (24) x64 13th Gen Intel(R) Core(TM) i7-13700F
    Memory: 6.16 GB / 15.54 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 20.12.1 - ~/.nvm/versions/node/v20.12.1/bin/node
    pnpm: 8.15.8 - ~/.local/share/pnpm/pnpm
  npmPackages:
    @vitejs/plugin-react: ^4.2.1 => 4.2.1 
    vite: ^5.2.0 => 5.2.11 
    vitest: ^1.6.0 => 1.6.0 
    @refinedev/core: ^4.49.1 => 4.49.1 
    @refinedev/mui: ^5.15.1 => 5.15.1 
    @refinedev/react-hook-form: ^4.8.18 => 4.8.18 
    @refinedev/react-router-v6: ^4.5.8 => 4.5.8 
    @refinedev/simple-rest: ^5.0.5 => 5.0.5 
    @emotion/react: ^11.11.4 => 11.11.4 
    @emotion/styled: ^11.11.5 => 11.11.5 
    @mui/icons-material: ^5.15.15 => 5.15.16 
    @mui/material: ^5.15.16 => 5.15.16 
    @mui/x-data-grid: ^6.6.0 => 6.19.11 
    @mui/x-date-pickers: ^7.5.0 => 7.5.0 
/// <reference types='vitest' />
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import react from '@vitejs/plugin-react';
import path from 'path';
import { defineConfig } from 'vitest/config';

// eslint-disable-next-line no-restricted-syntax
export default defineConfig({
  build: {
    reportCompressedSize: true,
    rollupOptions: {
      /**
       * Ignore "use client" waning since we are not using SSR
       * @see {@link https://github.com/TanStack/query/pull/5161#issuecomment-1477389761 Preserve "use client" directives TanStack/query#5161}
       */
      onwarn(warning, warn) {
        if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && warning.message.includes(`"use client"`)) {
          return;
        }
        warn(warning);
      },
    },
  },
  cacheDir: '../../node_modules/.vite/marketplace-frontend',

  plugins: [react(), nxViteTsPaths()],

  preview: {
    host: 'localhost',
    port: 4300,
  },

  resolve: {
    alias: {
      test: path.resolve(__dirname, './test'),
      '~': path.resolve(__dirname, './src'),
    },
  },

  root: __dirname,

  server: {
    host: 'localhost',
    port: 4200,
  },

  test: {
    cache: {
      dir: '../../node_modules/.vitest',
    },
    coverage: {
      provider: 'v8',
      reportsDirectory: '../../coverage/marketplace-frontend',
    },
    environment: 'jsdom',
    globalSetup: './test/global-setup.ts',
    globals: true,
    include: ['src/**/test.{ts,tsx}'],

    reporters: ['default'],
    setupFiles: './test/setup.ts',
  },
});

tsconfig.app.json tsconfig.json tsconfig.spec.json

borisyordanov commented 3 weeks ago

If I modify the @refinedev/mui/dist/index.mjs in my node_modules to import import Box from "@mui/material/Box/index.js"; instead of import Box from "@mui/material/Box the import is resolved.

Before image

After image

borisyordanov commented 3 weeks ago

@aliemir I managed to get the tests running https://vitest.dev/config/#server-deps-inline

BatuhanW commented 3 weeks ago

Hey @borisyordanov thanks! It seems that could fix the problem, but we need to check possible side-effects for this one. We'll get back to you next week.

aliemir commented 3 weeks ago

Hey @borisyordanov, thank you for opening the issue and writing an explanation for your case 🙏 Adding a documentation section for vitest/jest testing and adding an example will be great for many users imho 🤔

Thank you for sharing your solution for the @refinedev/mui + vitest error 🙏 This is related with how we do imports from @mui/* packages, I'm not sure if there's any way that works for every platform in both ESM and CJS but maybe we can transform these imports for ESM and CJS bundles to make sure the imports are pointing to correct files with correct shape 🚀

Same issue also occurs when using Material UI with Remix in SPA mode (https://github.com/refinedev/refine/issues/6007). Unfortunately, Material UI has some issues with ESM exports (https://github.com/mui/material-ui/issues/30671), until they resolve those issues we will try to have workaround to get past them in our @refinedev/mui package.