mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.13k stars 1.28k forks source link

[data grid] DataGrid fails to render in react-test-renderer #6582

Open sap-dshapovalov opened 1 year ago

sap-dshapovalov commented 1 year ago

Duplicates

Latest version

Current behavior 😯

Please, see the following code snippet:

import renderer, {act} from 'react-test-renderer';
import {render} from '@testing-library/react';
import {DataGrid} from '@mui/x-data-grid';

const testComponent = <DataGrid
    columns={[
        {field: 'id'},
    ]}
    rows={[{
        id: 'UID1',
    }, {
        id: 'UID2',
    }]}
/>;

test('searchGroupMembers method should be called', async () => {
    await act(async () => {
        render(testComponent);
    });
        expect(....
});

test('renders correctly if searchGroupMembers returns data', async () => {
    let r: ReactTestRenderer;
    await act(async () => {
        r = renderer.create(testComponent);
    });
    expect(r!.toJSON()).toMatchSnapshot();
});

First test renders without errors, second test fails to render with various null reference errors:

 _MUI: GridErrorHandler - An unexpected error occurred. Error: Cannot set properties of null (setting 'scrollLeft').  TypeError: Cannot set properties of null (setting 'scrollLeft')
      at \node_modules\@mui\x-data-grid\node\hooks\features\columnHeaders\useGridColumnHeaders.js:101:72

  MUI: GridErrorHandler - An unexpected error occurred. Error: Cannot read properties of null (reading 'parentElement').  TypeError: Cannot read properties of null (reading 'parentElement')
      at \node_modules\@mui\x-data-grid\node\components\GridAutoSizer.js:82:45_

Expected behavior 🤔

Both tests should render DataGrid successfully

Steps to reproduce 🕹

No response

Context 🔦

No response

Your environment 🌎

npx @mui/envinfo ``` System: OS: Windows 10 10.0.22000 Binaries: Node: 16.17.0 - C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: 8.19.1 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: Not Found Edge: Not Found npmPackages: @emotion/react: latest => 11.10.4 @emotion/styled: latest => 11.10.4 @mui/base: 5.0.0-alpha.102 @mui/core-downloads-tracker: 5.10.10 @mui/material: latest => 5.10.10 @mui/private-theming: 5.10.9 @mui/styled-engine: 5.10.8 @mui/system: 5.10.10 @mui/types: 7.2.0 @mui/utils: 5.10.9 @mui/x-data-grid: latest => 5.17.8 @types/react: latest => 18.0.21 react: latest => 18.2.0 react-dom: latest => 18.2.0 typescript: latest => 4.8.4 ```

Order ID 💳 (optional)

No response

cherniavskii commented 1 year ago

Hey @sap-dshapovalov Please provide a minimal reproduction example. Thanks!

sap-dshapovalov commented 1 year ago

@cherniavskii sure thing, please see this repo: https://github.com/sap-dshapovalov/datagrid-test-issue

If you run npm test there, you should see the issue

m4theushw commented 1 year ago

According to https://github.com/facebook/react/issues/7740#issuecomment-247335106, react-test-renderer always passes null to the refs, so when we do ref.scrollLeft = 0 it crashes. In jsdom or a real browser the refs are available correctly. We could make the test run by doing the following change:

diff --git a/packages/grid/x-data-grid/src/components/GridAutoSizer.tsx b/packages/grid/x-data-grid/src/components/GridAutoSizer.tsx
index 1955042a6..52ea0c29c 100644
--- a/packages/grid/x-data-grid/src/components/GridAutoSizer.tsx
+++ b/packages/grid/x-data-grid/src/components/GridAutoSizer.tsx
@@ -116,7 +116,7 @@ const GridAutoSizer = React.forwardRef<HTMLDivElement, AutoSizerProps>(function
   useEnhancedEffect(() => {
     parentElement.current = rootRef.current!.parentElement;

-    if (!parentElement) {
+    if (!parentElement.current) {
       return undefined;
     }

Then, pass a createNodeMock when rendering the component:

  it('should work with react-test-renderer', () => {
    const testRenderer = TestRenderer.create(
      <div style={{ width: 300, height: 500 }}>
        <DataGrid {...baselineProps} hideFooter />
      </div>,
      {
        createNodeMock: (node) => {
          return document.createElement(node.type);
        },
      },
    );
  });

It will work but note that no row will be rendered—because the mocked node has no dimensions—, so I don't know if it's worth to invest in snapshot testing. Given this limitation, I would say to continue using @testing-library/react.

Related to https://github.com/mui/mui-x/issues/1151