Problem testing material-ui datagrid with react-testing-library
Asked Answered
I

6

26

I want to test the content of my material-ui datagrid but only the first 3 columns (out of 8) are rendered in the test. I can test the content of these 3 columns, no problem with that.
Everything renders correctly on a web browser.

My best guess is that's it due to the width and height of the rendered datagrid as these warnings say, but I haven't been able to find a solution in the docs.

Material-UI: useResizeContainer - The parent of the grid has an empty width.
You need to make sure the container has an intrinsic width.
The grid displays with a width of 0px.

You can find a solution in the docs:
https://material-ui.com/components/data-grid/rendering/#layout

Material-UI: useResizeContainer - The parent of the grid has an empty height.
You need to make sure the container has an intrinsic height.
The grid displays with a height of 0px.

You can find a solution in the docs:
https://material-ui.com/components/data-grid/rendering/#layout

It could also be due to the mount function : (According to the material-ui docs, you should use enzyme's mount function as argument for the createMount function, but I am using react 17 and the official enzyme adapter is not out yet. I tried with @wojtekmaj/enzyme-adapter-react-17 but it didn't change anything. I am currently using 'render' from @testing-library/react)

const mount = createMount({mount:render})

Here is a simpler version of my component :

import React from "react";
import { DataGrid } from '@material-ui/data-grid';
import Button from "@material-ui/core/Button";


const Gridtest = (props) => {

const columns = [
    {field: 'id', headerName: 'ID', type: 'number',headerAlign: 'left', width: 130 },
    {field: 'tenant_id', headerName: 'Tenant ID', type: 'number',headerAlign: 'left', width: 130 },
    {field: 'user_reference', headerName: 'Customer user reference', type: 'string',headerAlign: 'left', width: 250 },
    {field: 'provider_name', headerName: 'Provider name', type: 'string',headerAlign: 'left', width: 220 },
    {field: 'provider_id', headerName: 'Provider ID', type: 'number',headerAlign: 'left', width: 130 },
    {field: 'expiration_date', headerName: 'Expiration date', type: 'dateTime',headerAlign: 'left', width: 220 },
    {field: 'last_start', headerName: 'Last start date', type: 'dateTime',headerAlign: 'left', width: 130 },
    {field: 'Action',
        headerName: 'Action',
        headerAlign: 'left',
        width: 100,
        renderCell: (params) => {
            return (
                <div>
                    <Button variant="contained" size="small" color="primary" disableRipple
                            onClick={() => null}>
                        Details
                    </Button>
                </div>
            )
        },
    },
];

const rows = [
    {
        "id": "10190",
        "tenant_id": "12201",
        "user_reference": "Xuser_ref",
        "provider_name": "Xprovider",
        "provider_id": "122",
        "expiration_date": "2020-04-07T17:36:40+02:00",
        "last_start": "2020-07-06T17:36:40+02:00"

    },
    {
        "id": "23541",
        "tenant_id": "96542",
        "user_reference": "Yuser_ref",
        "provider_name": "Yprovider",
        "provider_id": "856",
        "expiration_date": "2010-07-07T17:36:40+02:00",
        "last_start": "2010-09-06T17:36:40+02:00"

    }]

return(
    <main>
        <div style={{ display: 'flex', height: '100%',width: '100%', flexGrow: 1 }}>
            <DataGrid style={{height: '100%', width: '100%'}} autoHeight rows={rows} columns={columns} pageSize={5} checkboxSelection={false} hideFooterSelectedRowCount/>
        </div>
    </main>
)};

export default Gridtest;

The test file for my simpler component (the test succeeds) :

import {screen, render, act, findByTestId} from '@testing-library/react'
import React from 'react'
import '@testing-library/jest-dom/extend-expect'
import Gridtest from '../../src/Gridtest'
import { createMount } from '@material-ui/core/test-utils';

describe('grid test', () => {

    const mount = createMount({mount:render})

    test('grid render', async () => {
        await act(async () => {
            mount(
                <Gridtest />
            );
        });
        expect(await screen.findByRole('grid')).toBeInTheDocument()
        expect(await screen.findAllByRole('columnheader')).toHaveLength(3)
        screen.debug(await screen.findByRole('grid'))
    })
})

screen.debug(await screen.findByRole('grid')) returns :

<div
  aria-colcount="8"
  aria-label="grid"
  aria-multiselectable="false"
  aria-rowcount="2"
  class="MuiDataGrid-root MuiDataGrid-root"
  role="grid"
  style="width: 0px; height: 175px;"
  tabindex="0"
>
  <div />
  <div
    class="MuiDataGrid-mainGridContainer"
  >
    <div
      class="MuiDataGrid-columnsContainer"
      style="min-height: 56px; max-height: 56px; line-height: 56px;"
    >
      <div
        aria-rowindex="1"
        class="MuiDataGrid-colCellWrapper scroll"
        role="row"
        style="transform: translate3d(-0px, 0, 0); min-width: 1310px;"
      >
        <div
          aria-colindex="1"
          class="MuiDataGrid-colCell MuiDataGrid-colCellSortable MuiDataGrid-colCellNumeric"
          data-field="id"
          role="columnheader"
          style="width: 130px; min-width: 130px; max-width: 130px;"
          tabindex="-1"
        >
          <div
            class="MuiDataGrid-colCell-draggable"
            draggable="false"
          >
            <div
              class="MuiDataGrid-colCellTitleContainer"
            >
              <div
                aria-label="ID"
                class="MuiDataGrid-colCellTitle"
                title=""
              >
                ID
              </div>
            </div>
          </div>
          <div
            class="MuiDataGrid-columnSeparator"
            style="min-height: 56px; opacity: 1;"
          >
            <svg
              aria-hidden="true"
              class="MuiSvgIcon-root MuiDataGrid-iconSeparator"
              focusable="false"
              viewBox="0 0 24 24"
            >
              <path
                d="M11 19V5h2v14z"
              />
            </svg>
          </div>
        </div>
        <div
          aria-colindex="2"
          class="MuiDataGrid-colCell MuiDataGrid-colCellSortable MuiDataGrid-colCellNumeric"
          data-field="tenant_id"
          role="columnheader"
          style="width: 130px; min-width: 130px; max-width: 130px;"
          tabindex="-1"
        >
          <div
            class="MuiDataGrid-colCell-draggable"
            draggable="false"
          >
            <div
              class="MuiDataGrid-colCellTitleContainer"
            >
              <div
                aria-label="Tenant ID"
                class="MuiDataGrid-colCellTitle"
                title=""
              >
                Tenant ID
              </div>
            </div>
          </div>
          <div
            class="MuiDataGrid-columnSeparator"
            style="min-height: 56px; opacity: 1;"
          >
            <svg
              aria-hidden="true"
              class="MuiSvgIcon-root MuiDataGrid-iconSeparator"
              focusable="false"
              viewBox="0 0 24 24"
            >
              <path
                d="M11 19V5h2v14z"
              />
            </svg>
          </div>
        </div>
        <div
          aria-colindex="3"
          class="MuiDataGrid-colCell MuiDataGrid-colCellSortable"
          data-field="user_reference"
          role="columnheader"
          style="width: 250px; min-width: 250px; max-width: 250px;"
          tabindex="-1"
        >
          <div
            class="MuiDataGrid-colCell-draggable"
            draggable="false"
          >
            <div
              class="MuiDataGrid-colCellTitleContainer"
            >
              <div
                aria-label="Customer user reference"
                class="MuiDataGrid-colCellTitle"
                title=""
              >
                Customer user reference
              </div>
            </div>
          </div>
          <div
            class="MuiDataGrid-columnSeparator"
            style="min-height: 56px; opacity: 1;"
          >
            <svg
              aria-hidden="true"
              class="MuiSvgIcon-root MuiDataGrid-iconSeparator"
              focusable="false"
              viewBox="0 0 24 24"
            >
              <path
                d="M11 19V5h2v14z"
              />
            </svg>
          </div>
        </div>
        <div
          class="MuiDataGrid-cell MuiDataGrid-cellLeft"
          role="cell"
          style="min-width: 800px; max-width: 800px; line-height: 55px; min-height: 56px; max-height: 56px;"
        />
      </div>
    </div>
    <div
      class="MuiDataGrid-window"
      style="top: 56px; overflow-y: hidden;"
    >
      <div
        class="MuiDataGrid-dataContainer data-container"
        style="min-height: 119px; min-width: 1310px;"
      >
        <div
          class="MuiDataGrid-viewport"
          style="min-width: 0; max-width: 0; min-height: 104px; max-height: 104px;"
        >
          <div
            class="rendering-zone"
            style="max-height: 275px; width: 1310px; pointer-events: unset; transform: translate3d(-0px, -0px, 0);"
          >
            <div
              aria-rowindex="2"
              aria-selected="false"
              class="MuiDataGrid-row Mui-even"
              data-id="10190"
              data-rowindex="0"
              role="row"
              style="max-height: 52px; min-height: 52px;"
            >
              <div
                aria-colindex="0"
                class="MuiDataGrid-cell MuiDataGrid-cellRight"
                data-field="id"
                data-rowindex="0"
                data-value="10190"
                role="cell"
                style="min-width: 130px; max-width: 130px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="0"
              >
                10190
              </div>
              <div
                aria-colindex="1"
                class="MuiDataGrid-cell MuiDataGrid-cellRight"
                data-field="tenant_id"
                data-rowindex="0"
                data-value="12201"
                role="cell"
                style="min-width: 130px; max-width: 130px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="-1"
              >
                12201
              </div>
              <div
                aria-colindex="2"
                class="MuiDataGrid-cell MuiDataGrid-cellLeft"
                data-field="user_reference"
                data-rowindex="0"
                data-value="Xuser_ref"
                role="cell"
                style="min-width: 250px; max-width: 250px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="-1"
              >
                Xuser_ref
              </div>
              <div
                class="MuiDataGrid-cell MuiDataGrid-cellLeft"
                role="cell"
                style="min-width: 800px; max-width: 800px; line-height: 51px; min-height: 52px; max-height: 52px;"
              />
            </div>
            <div
              aria-rowindex="3"
              aria-selected="false"
              class="MuiDataGrid-row Mui-odd"
              data-id="23541"
              data-rowindex="1"
              role="row"
              style="max-height: 52px; min-height: 52px;"
            >
              <div
                aria-colindex="0"
                class="MuiDataGrid-cell MuiDataGrid-cellRight"
                data-field="id"
                data-rowindex="1"
                data-value="23541"
                role="cell"
                style="min-width: 130px; max-width: 130px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="-1"
              >
                23541
              </div>
              <div
                aria-colindex="1"
                class="MuiDataGrid-cell MuiDataGrid-cellRight"
                data-field="tenant_id"
                data-rowindex="1"
                data-value="96542"
                role="cell"
                style="min-width: 130px; max-width: 130px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="-1"
              >
                96542
              </div>
              <div
                aria-colindex="2"
                class="MuiDataGrid-cell MuiDataGrid-cellLeft"
                data-field="user_reference"
                data-rowindex="1"
                data-value="Yuser_ref"
                role="cell"
                style="min-width: 250px; max-width: 250px; line-height: 51px; min-height: 52px; max-height: 52px;"
                tabindex="-1"
              >
                Yuser_ref
              </div>
              <div
                class="MuiDataGrid-cell MuiDataGrid-cellLeft"
                role="cell"
                style="min-width: 800px; max-width: 800px; line-height: 51px; min-height: 52px; max-height: 52px;"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div>
    <div
      class="MuiDataGrid-footer"
    >
      <div />
      <div
        class="MuiTablePagination-root"
      >
        <div
          class="MuiToolbar-root MuiToolbar-regular MuiTablePagination-toolbar MuiToolbar-gutters"
        >
          <div
            class="MuiTablePagination-spacer"
          />
          <p
            class="MuiTypography-root MuiTablePagination-caption makeStyles-caption-1 MuiTypography-body2 MuiTypography-colorInherit"
          >
            1-2 of 2
          </p>
          <div
            class="MuiTablePagination-actions"
          >
            <button
              aria-label="Previous page"
              class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
              disabled=""
              tabindex="-1"
              title="Previous page"
              type="button"
            >
              <span
                class="MuiIconButton-label"
              >
                <svg
                  aria-hidden="true"
                  class="MuiSvgIcon-root"
                  focusable="false"
                  viewBox="0 0 24 24"
                >
                  <path
                    d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"
                  />
                </svg>
              </span>
            </button>
            <button
              aria-label="Next page"
              class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit Mui-disabled Mui-disabled"
              disabled=""
              tabindex="-1"
              title="Next page"
              type="button"
            >
              <span
                class="MuiIconButton-label"
              >
                <svg
                  aria-hidden="true"
                  class="MuiSvgIcon-root"
                  focusable="false"
                  viewBox="0 0 24 24"
                >
                  <path
                    d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"
                  />
                </svg>
              </span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

Thank you for your help

Ila answered 11/1, 2021 at 15:27 Comment(2)
The sample code you posted has some problems. First, the component does not show where columns comes from, which is perhaps the most important detail to your question. Also, your test contains a lot of code that does not seem relevant to your question, such as mocking out an API, dealing with routing, and performing mutations. I suggest you write a much simpler component/test to demonstrate the problem, and also include the DOM (from screen.debug).Angio
I'm also annoyed by the warning messages about the DataGrid container having 0 width, and I am also using React Testing Library. It shouldn't matter which testing solution is used. The "grid has 0 width" technique smells like a hack.Amaris
A
4

This is because of a virtualization. you can disable it like

<Gridtest disableVirtualization />
Amphibolous answered 28/4, 2023 at 5:23 Comment(1)
Solved my issue. Thanks!Kilohertz
I
26

I have found a solution : you can set the columnBuffer prop of the datagrid.
For exemple columnBuffer={8} for 8 columns.

Ila answered 14/1, 2021 at 14:25 Comment(3)
Yes, but I still get the MUI warning: "Material-UI: useResizeContainer - The parent of the grid has an empty width" in the logs, which obfuscate my test run outcomes.Joubert
@Joubert Looks like this was an issue with the package, if you update to a newer version it's fixed. The error is wrapped in some logic to test if the test environment is JSDOMRuddock
In the more recent version you can disable virtualisation entirely with the disableVirtualization prop. This forces the grid to render all cells. mui.com/components/data-grid/virtualization/…Leotaleotard
A
4

This is because of a virtualization. you can disable it like

<Gridtest disableVirtualization />
Amphibolous answered 28/4, 2023 at 5:23 Comment(1)
Solved my issue. Thanks!Kilohertz
M
2

It has nothing to do with DataGrid, make sure your exterior most container by default occupies 100% height and width. I was running into the same issue as shown below:

enter image description here

On reading the warnings, I realized that the container needs to be resized so I changed the CSS of my external most container to be a flexbox with the entire width as shown below:

{
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
}

If you see my two images, you will notice the difference that was causing the table to fail from displaying properly.

enter image description here

Malan answered 16/9, 2021 at 13:41 Comment(2)
this is correct answerPressroom
This is because of virtualization, which you can solve with a DataGrid attribute using @김효일's answerKilohertz
I
2

Reason: This is because of a virtualization.

Solution: In test file, you can mock the DataGrid (which can be DataGrid, DataGridPro, DataGridPremium) with disableVirtualization flag.

Example:

import { DataGrid as OriginalDataGrid, DataGridProps } from '@material-ui/data-grid';

// Export if you want to use in all test files where DataGrid is used.
export const DataGrid = (props: DataGridProps) => {
    return <OriginalDataGrid {...props} disableVirtualization />;
};
import { DataGridPro as OriginalDataGridPro, DataGridProProps } from '@mui/x-data-grid-pro';

const DataGridPro = (props: DataGridProProps) => {
    return <OriginalDataGridPro {...props} disableVirtualization />;
};

// Your test case starts from here... or you can export and use but mostly for test cases
import { DataGridPremium as OriginalDataGridPremium, DataGridPremiumProps } from '@mui/x-data-grid-premium';

const DataGridPro = (props: DataGridPremiumProps) => {
    return <OriginalDataGridPremium {...props} disableVirtualization />;
};

// Your test case starts from here... or you can export and use but mostly for test cases

From Doc:

Disable virtualization

The virtualization can be disabled completely using the disableVirtualization prop. You may want to turn it off to be able to test the data grid with a headless browser, like jsdom.

<DataGrid {...data} disableVirtualization />

Disabling the virtualization will increase the size of the DOM and drastically reduce the performance. Use it only for testing purposes or on small datasets.

Ref: https://mui.com/x/react-data-grid/virtualization/#disable-virtualization

Instigation answered 2/4 at 14:44 Comment(0)
S
1

You can also set up a global mock for this if you want to retain virtualization in your real data grid but turn it off for tests

import { DataGridPro as OriginalDataGridPro, DataGridProProps } from '@mui/x-data-grid-pro';

// Sets up a mock for disableVirtualization on DataGrid
// Allows tests to check all columns
// Explained by https://github.com/mui/mui-x/issues/1151

export * from '@mui/x-data-grid-pro';
export const DataGridPro = (props: DataGridProProps) => {
    return <OriginalDataGridPro {...props} disableVirtualization />;
};
Secretarial answered 16/5, 2023 at 16:18 Comment(0)
S
0

If anyone else hits this page and is still getting the Material-UI: useResizeContainer: If you are using the happy-dom environment instead of jsdom, the following code in mui-x is the reason:

      // jsdom has no layout capabilities
      const isJSDOM = /jsdom/.test(window.navigator.userAgent);

      if (size.height === 0 && !errorShown.current && !props.autoHeight && !isJSDOM) {
        logger.error(
          [
            'The parent DOM element of the data grid has an empty height.',
            'Please make sure that this element has an intrinsic height.',
            'The grid displays with a height of 0px.',
            '',
            'More details: https://mui.com/r/x-data-grid-no-dimensions.',
          ].join('\n'),
        );
        errorShown.current = true;
      }

A workaround for this is to modify the useragent. If you are using vitest and happy-dom, as of happy-dom 12.0.0, this can be by adding the following to your vitest defineConfig to trick it:

    environmentOptions: {
      happyDOM: {
        settings: {
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          navigator: {
            userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/22.1.0',
          },
        },
      },
    },

(The @ts-ignore is because at time of writing vitest doesn't include navigator.userAgent in its typing for happy-dom)

Hopefully mui-x will be updated to detect HappyDOM in the useragent string which is now added and the workaround won't be needed.

Shimberg answered 18/9, 2023 at 4:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.