From 23abe64e37a33bf186aa79112324735feee2364d Mon Sep 17 00:00:00 2001 From: Matheus Wichman Date: Fri, 22 Jul 2022 19:51:56 -0300 Subject: [PATCH 1/7] Init --- benchmark/package.json | 4 +- docs/package.json | 6 +- package.json | 11 +- .../aggregation.DataGridPremium.test.tsx | 16 +- .../exportExcel.DataGridPremium.test.tsx | 16 +- .../rowGrouping.DataGridPremium.test.tsx | 76 ++--- .../statePersistence.DataGridPremium.test.tsx | 24 +- .../cellEditing.DataGridPro.new.test.tsx | 242 +++++++++++----- .../cellEditing.DataGridPro.old.test.tsx | 213 ++++++++++---- .../src/tests/clipboard.DataGridPro.test.tsx | 14 +- .../tests/columnPinning.DataGridPro.test.tsx | 32 +- .../tests/columnReorder.DataGridPro.test.tsx | 6 +- .../tests/columnSpanning.DataGridPro.test.tsx | 54 ++-- .../src/tests/columns.DataGridPro.test.tsx | 41 ++- .../columnsVisibility.DataGridPro.test.tsx | 36 +-- .../tests/detailPanel.DataGridPro.test.tsx | 14 +- .../editComponents.DataGridPro.new.test.tsx | 20 +- .../editComponents.DataGridPro.old.test.tsx | 81 ++++-- .../src/tests/events.DataGridPro.test.tsx | 15 +- .../src/tests/export.DataGridPro.test.tsx | 16 +- .../tests/filterPanel.DataGridPro.test.tsx | 4 +- .../src/tests/filtering.DataGridPro.test.tsx | 42 +-- .../src/tests/layout.DataGridPro.test.tsx | 6 +- .../src/tests/printExport.DataGrid.test.tsx | 32 +- .../tests/rowEditing.DataGridPro.new.test.tsx | 273 ++++++++++++------ .../tests/rowEditing.DataGridPro.old.test.tsx | 93 ++++-- .../src/tests/rows.DataGridPro.test.tsx | 130 ++++----- .../src/tests/selection.DataGridPro.test.tsx | 78 ++--- .../src/tests/sorting.DataGridPro.test.tsx | 28 +- .../statePersistence.DataGridPro.test.tsx | 68 +++-- .../src/tests/treeData.DataGridPro.test.tsx | 26 +- .../utils/useGridApiEventHandler.test.tsx | 8 +- .../src/tests/components.DataGrid.test.tsx | 10 +- .../src/tests/export.DataGrid.test.tsx | 2 +- .../src/tests/filterPanel.DataGrid.test.tsx | 9 +- .../src/tests/keyboard.DataGrid.test.tsx | 12 +- .../src/tests/layout.DataGrid.test.tsx | 3 +- .../src/tests/pagination.DataGrid.test.tsx | 34 ++- .../src/tests/rows.DataGrid.test.tsx | 21 +- .../src/tests/selection.DataGrid.test.tsx | 4 +- .../src/tests/toolbar.DataGrid.test.tsx | 9 +- packages/storybook/package.json | 4 +- .../DesktopDateRangePicker.test.tsx | 6 +- .../MobileDateRangePicker.test.tsx | 2 +- test/utils/init.js | 15 +- test/utils/setup.js | 13 + yarn.lock | 158 +++++----- 47 files changed, 1236 insertions(+), 791 deletions(-) rename packages/grid/{x-data-grid-pro => x-data-grid}/src/tests/export.DataGrid.test.tsx (99%) diff --git a/benchmark/package.json b/benchmark/package.json index 483c9b617f48..73a923855f4a 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -19,8 +19,8 @@ "html-webpack-plugin": "^5.5.0", "mui-plus": "^0.0.15", "playwright": "^1.21.1", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-spring": "^9.2.4", "react-virtualized": "^9.22.3", "serve-handler": "^6.1.3", diff --git a/docs/package.json b/docs/package.json index e0ebc1b8ed38..7d0dd48b5901 100644 --- a/docs/package.json +++ b/docs/package.json @@ -65,11 +65,11 @@ "prismjs": "^1.28.0", "prop-types": "^15.8.1", "raw-loader": "^1.0.0", - "react": "^17.0.2", + "react": "^18.2.0", "react-docgen": "^5.4.3", - "react-dom": "^17.0.2", + "react-dom": "^18.2.0", "react-hook-form": "^7.33.1", - "react-is": "^17.0.2", + "react-is": "^18.2.0", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-text-mask": "^5.4.3", diff --git a/package.json b/package.json index 14a6806caa18..0069167484e9 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "@emotion/cache": "^11.9.3", "@emotion/react": "^11.9.3", "@emotion/styled": "^11.9.3", - "@eps1lon/enzyme-adapter-react-17": "^0.1.0", + "@mnajdova/enzyme-adapter-react-18": "^0.2.0", "@mui/icons-material": "^5.8.0", "@mui/material": "^5.8.0", "@mui/monorepo": "https://github.com/mui/material-ui.git#master", @@ -87,7 +87,7 @@ "@octokit/plugin-retry": "^3.0.9", "@octokit/rest": "^18.12.0", "@playwright/test": "1.21.1", - "@testing-library/react": "^12.1.5", + "@testing-library/react": "^13.3.0", "@types/babel__core": "^7.1.19", "@types/chai": "^4.3.1", "@types/chai-dom": "^0.0.13", @@ -150,8 +150,8 @@ "nyc": "^15.1.0", "playwright": "^1.21.1", "prettier": "^2.7.1", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "serve": "^13.0.4", "sinon": "^14.0.0", "stream-browserify": "^3.0.0", @@ -178,5 +178,8 @@ }, "dependencies": { "html-webpack-plugin": "^5.5.0" + }, + "resolutions": { + "**/react-is": "^18.2.0" } } diff --git a/packages/grid/x-data-grid-premium/src/tests/aggregation.DataGridPremium.test.tsx b/packages/grid/x-data-grid-premium/src/tests/aggregation.DataGridPremium.test.tsx index 3535c7a19af5..f645a848ea2e 100644 --- a/packages/grid/x-data-grid-premium/src/tests/aggregation.DataGridPremium.test.tsx +++ b/packages/grid/x-data-grid-premium/src/tests/aggregation.DataGridPremium.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, screen, userEvent, within } from '@mui/monorepo/test/utils'; +import { createRenderer, screen, userEvent, within, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { getColumnValues } from 'test/utils/helperFn'; import { SinonSpy, spy } from 'sinon'; @@ -286,7 +286,7 @@ describe(' - Aggregation', () => { it('should render select on aggregable column', () => { render(); - apiRef.current.showColumnMenu('id'); + act(() => apiRef.current.showColumnMenu('id')); clock.runToLast(); expect(screen.queryByLabelText('Aggregation')).not.to.equal(null); @@ -297,7 +297,7 @@ describe(' - Aggregation', () => { expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4', '5']); - apiRef.current.showColumnMenu('id'); + act(() => apiRef.current.showColumnMenu('id')); clock.runToLast(); userEvent.mousePress(screen.queryByLabelText('Aggregation')); userEvent.mousePress( @@ -439,7 +439,7 @@ describe(' - Aggregation', () => { />, ); - apiRef.current.showColumnMenu('id'); + act(() => apiRef.current.showColumnMenu('id')); clock.runToLast(); expect(screen.queryAllByLabelText('Aggregation')).to.have.length(0); @@ -478,9 +478,11 @@ describe(' - Aggregation', () => { ); expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4', '5']); - apiRef.current.updateColumns([ - { field: 'id', private_availableAggregationFunctions: ['min', 'max'] }, - ]); + act(() => + apiRef.current.updateColumns([ + { field: 'id', private_availableAggregationFunctions: ['min', 'max'] }, + ]), + ); expect(getColumnValues(0)).to.deep.equal(['0', '1', '2', '3', '4', '5', '5' /* Agg */]); }); }); diff --git a/packages/grid/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx b/packages/grid/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx index eebfdb591b10..285a26f80dea 100644 --- a/packages/grid/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx +++ b/packages/grid/x-data-grid-premium/src/tests/exportExcel.DataGridPremium.test.tsx @@ -9,14 +9,14 @@ import { GridActionsCellItem, } from '@mui/x-data-grid-premium'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, screen, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, screen, fireEvent, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import Excel from 'exceljs'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe(' - Export Excel', () => { - const { render } = createRenderer(); + const { render } = createRenderer({ clock: 'fake' }); let apiRef: React.MutableRefObject; @@ -51,9 +51,9 @@ describe(' - Export Excel', () => { }; describe('export interface', () => { - it('should generate a file', () => { + it('should generate a file', async () => { render(); - expect(apiRef.current.getDataAsExcel()).not.to.equal(null); + expect(await act(() => apiRef.current.getDataAsExcel())).not.to.equal(null); }); it('should display export option', () => { @@ -98,7 +98,7 @@ describe(' - Export Excel', () => { }; render(); - const workbook = await apiRef.current.getDataAsExcel(); + const workbook = await act(() => apiRef.current.getDataAsExcel()); const worksheet = workbook!.worksheets[0]; expect(worksheet.getCell('A1').value).to.equal('str'); @@ -142,7 +142,7 @@ describe(' - Export Excel', () => { }; render(); - const workbook = await apiRef.current.getDataAsExcel(); + const workbook = await act(() => apiRef.current.getDataAsExcel()); const worksheet = workbook!.worksheets[0]; expect(worksheet.getCell('A1').value).to.equal('option'); @@ -180,7 +180,7 @@ describe(' - Export Excel', () => { }; render(); - const workbook = await apiRef.current.getDataAsExcel(); + const workbook = await act(() => apiRef.current.getDataAsExcel()); const worksheet = workbook!.worksheets[0]; expect(worksheet.getCell('A1').value).to.equal('str'); @@ -218,7 +218,7 @@ describe(' - Export Excel', () => { }; render(); - const workbook = await apiRef.current.getDataAsExcel(); + const workbook = await act(() => apiRef.current.getDataAsExcel()); const worksheet = workbook!.worksheets[0]; // 1-based index + 1 for column header row diff --git a/packages/grid/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx b/packages/grid/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx index 3c1cb46ef54b..c752801253a9 100644 --- a/packages/grid/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx +++ b/packages/grid/x-data-grid-premium/src/tests/rowGrouping.DataGridPremium.test.tsx @@ -494,7 +494,7 @@ describe(' - Row Grouping', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'category1', 'category2']); // No menu item on column menu to add / remove grouping criteria - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const category1Menuitem = screen.queryByRole('menuitem', { @@ -502,11 +502,11 @@ describe(' - Row Grouping', () => { }); expect(category1Menuitem).to.equal(null); - apiRef.current.hideColumnMenu(); + act(() => apiRef.current.hideColumnMenu()); clock.runToLast(); expect(screen.queryByRole('menu')).to.equal(null); - apiRef.current.showColumnMenu('category2'); + act(() => apiRef.current.showColumnMenu('category2')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const category2Menuitem = screen.queryByRole('menuitem', { name: 'Group by category2' }); @@ -715,16 +715,20 @@ describe(' - Row Grouping', () => { ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '200px' }); - apiRef.current.updateColumns([ - { field: GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, width: 100 }, - ]); + act(() => + apiRef.current.updateColumns([ + { field: GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, width: 100 }, + ]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); - apiRef.current.updateColumns([ - { - field: 'id', - headerName: 'New id', - }, - ]); + act(() => + apiRef.current.updateColumns([ + { + field: 'id', + headerName: 'New id', + }, + ]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); }); @@ -1043,17 +1047,21 @@ describe(' - Row Grouping', () => { expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '200px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '300px' }); - apiRef.current.updateColumns([ - { field: getRowGroupingFieldFromGroupingCriteria('category1'), width: 100 }, - ]); + act(() => + apiRef.current.updateColumns([ + { field: getRowGroupingFieldFromGroupingCriteria('category1'), width: 100 }, + ]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '300px' }); - apiRef.current.updateColumns([ - { - field: 'id', - headerName: 'New id', - }, - ]); + act(() => + apiRef.current.updateColumns([ + { + field: 'id', + headerName: 'New id', + }, + ]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '300px' }); }); @@ -1524,7 +1532,7 @@ describe(' - Row Grouping', () => { ]} />, ); - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const menuItem = screen.queryByRole('menuitem', { name: 'Group by category1' }); @@ -1546,7 +1554,7 @@ describe(' - Row Grouping', () => { ]} />, ); - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); expect(screen.queryByRole('menuitem', { name: 'Group by category1' })).to.equal(null); @@ -1570,7 +1578,7 @@ describe(' - Row Grouping', () => { }} />, ); - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const menuItem = screen.queryByRole('menuitem', { name: 'Stop grouping by category1' }); @@ -1601,7 +1609,7 @@ describe(' - Row Grouping', () => { />, ); - apiRef.current.showColumnMenu('__row_group_by_columns_group_category1__'); + act(() => apiRef.current.showColumnMenu('__row_group_by_columns_group_category1__')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const menuItemCategory1 = screen.queryByRole('menuitem', { @@ -1610,11 +1618,11 @@ describe(' - Row Grouping', () => { fireEvent.click(menuItemCategory1); expect(apiRef.current.state.rowGrouping.model).to.deep.equal(['category2']); - apiRef.current.hideColumnMenu(); + act(() => apiRef.current.hideColumnMenu()); clock.runToLast(); expect(screen.queryByRole('menu')).to.equal(null); - apiRef.current.showColumnMenu('__row_group_by_columns_group_category2__'); + act(() => apiRef.current.showColumnMenu('__row_group_by_columns_group_category2__')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const menuItemCategory2 = screen.queryByRole('menuitem', { @@ -1647,7 +1655,7 @@ describe(' - Row Grouping', () => { />, ); - apiRef.current.showColumnMenu('__row_group_by_columns_group__'); + act(() => apiRef.current.showColumnMenu('__row_group_by_columns_group__')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); const menuItemCategory1 = screen.queryByRole('menuitem', { @@ -1676,7 +1684,7 @@ describe(' - Row Grouping', () => { ]} />, ); - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); expect(screen.queryByRole('menuitem', { name: 'Group by Category 1' })).not.to.equal(null); @@ -1701,7 +1709,7 @@ describe(' - Row Grouping', () => { }} />, ); - apiRef.current.showColumnMenu('category1'); + act(() => apiRef.current.showColumnMenu('category1')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); expect(screen.queryByRole('menuitem', { name: 'Stop grouping by Category 1' })).not.to.equal( @@ -2270,13 +2278,13 @@ describe(' - Row Grouping', () => { describe('apiRef: addRowGroupingCriteria', () => { it('should add grouping criteria to model', () => { render(); - apiRef.current.addRowGroupingCriteria('category2'); + act(() => apiRef.current.addRowGroupingCriteria('category2')); expect(apiRef.current.state.rowGrouping.model).to.deep.equal(['category1', 'category2']); }); it('should add grouping criteria to model at the right position', () => { render(); - apiRef.current.addRowGroupingCriteria('category2', 0); + act(() => apiRef.current.addRowGroupingCriteria('category2', 0)); expect(apiRef.current.state.rowGrouping.model).to.deep.equal(['category2', 'category1']); }); }); @@ -2284,7 +2292,7 @@ describe(' - Row Grouping', () => { describe('apiRef: removeRowGroupingCriteria', () => { it('should remove field from model', () => { render(); - apiRef.current.removeRowGroupingCriteria('category1'); + act(() => apiRef.current.removeRowGroupingCriteria('category1')); expect(apiRef.current.state.rowGrouping.model).to.deep.equal([]); }); }); @@ -2292,7 +2300,7 @@ describe(' - Row Grouping', () => { describe('apiRef: setRowGroupingCriteriaIndex', () => { it('should change the grouping criteria order', () => { render(); - apiRef.current.setRowGroupingCriteriaIndex('category1', 1); + act(() => apiRef.current.setRowGroupingCriteriaIndex('category1', 1)); expect(apiRef.current.state.rowGrouping.model).to.deep.equal(['category2', 'category1']); }); }); diff --git a/packages/grid/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx b/packages/grid/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx index 002bc427d240..cec965124698 100644 --- a/packages/grid/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx +++ b/packages/grid/x-data-grid-premium/src/tests/statePersistence.DataGridPremium.test.tsx @@ -9,7 +9,7 @@ import { useGridApiRef, } from '@mui/x-data-grid-premium'; // @ts-ignore Remove once the test utils are typed -import { createRenderer } from '@mui/monorepo/test/utils'; +import { createRenderer, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { getColumnValues } from '../../../../../test/utils/helperFn'; @@ -98,10 +98,12 @@ describe(' - State Persistence', () => { it('should export the current version of the exportable state', () => { render(); - apiRef.current.setRowGroupingModel(['category']); - apiRef.current.private_setAggregationModel({ - id: 'size', - }); + act(() => apiRef.current.setRowGroupingModel(['category'])); + act(() => + apiRef.current.private_setAggregationModel({ + id: 'size', + }), + ); const exportedState = apiRef.current.exportState(); expect(exportedState.rowGrouping).to.deep.equal(FULL_INITIAL_STATE.rowGrouping); @@ -112,10 +114,12 @@ describe(' - State Persistence', () => { it('should export the current version of the exportable state when using exportOnlyDirtyModels', () => { render(); - apiRef.current.setRowGroupingModel(['category']); - apiRef.current.private_setAggregationModel({ - id: 'size', - }); + act(() => apiRef.current.setRowGroupingModel(['category'])); + act(() => + apiRef.current.private_setAggregationModel({ + id: 'size', + }), + ); const exportedState = apiRef.current.exportState({ exportOnlyDirtyModels: true }); expect(exportedState.rowGrouping).to.deep.equal(FULL_INITIAL_STATE.rowGrouping); @@ -159,7 +163,7 @@ describe(' - State Persistence', () => { it('should restore the whole exportable state', () => { render(); - apiRef.current.restoreState(FULL_INITIAL_STATE); + act(() => apiRef.current.restoreState(FULL_INITIAL_STATE)); expect(getColumnValues(0)).to.deep.equal([ 'Cat A (3)', '', diff --git a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx index 6ba3d5b4fdc8..e4ded923bb34 100644 --- a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.new.test.tsx @@ -110,7 +110,7 @@ describe(' - Cell Editing', () => { expect(renderEditCell.lastCall.args[0].value).to.equal('usdgbp'); }); - it('should pass to renderEditCell the row with the value updated', () => { + it('should pass to renderEditCell the row with the value updated', async () => { columnProps.valueSetter = ({ value, row }: GridValueSetterParams) => ({ ...row, currencyPair: value.trim(), @@ -118,7 +118,9 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect(renderEditCell.lastCall.args[0].row).to.deep.equal(defaultData.rows[0]); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: ' usdgbp ' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: ' usdgbp ' }), + ); expect(renderEditCell.lastCall.args[0].row).to.deep.equal({ ...defaultData.rows[0], currencyPair: 'usdgbp', @@ -141,7 +143,9 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect( - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ), ).to.equal(true); }); @@ -151,13 +155,17 @@ describe(' - Cell Editing', () => { ); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - const promise = apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', + let promise: Promise | null = null; + // We want to flush updates before preProcessEditCellProps resolves + act(() => { + promise = apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }) as Promise; }); expect(renderEditCell.lastCall.args[0].isProcessingProps).to.equal(true); - return promise; + return act(() => promise); }); it('should call preProcessEditCellProps with the correct params', async () => { @@ -166,7 +174,13 @@ describe(' - Cell Editing', () => { ); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }), + ); const args = columnProps.preProcessEditCellProps.lastCall.args[0]; expect(args.id).to.equal(0); expect(args.row).to.deep.equal(defaultData.rows[0]); @@ -186,7 +200,9 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect(renderEditCell.lastCall.args[0].foo).to.equal(undefined); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); expect(renderEditCell.lastCall.args[0].foo).to.equal('bar'); }); @@ -198,7 +214,9 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect(renderEditCell.lastCall.args[0].value).to.equal('USDGBP'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); expect(renderEditCell.lastCall.args[0].value).to.equal('USD GBP'); }); @@ -206,15 +224,18 @@ describe(' - Cell Editing', () => { columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => props; render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - const promise = apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - }) as Promise; - expect(renderEditCell.lastCall.args[0].isProcessingProps).to.equal(true); - return promise.then(() => { - expect(renderEditCell.lastCall.args[0].isProcessingProps).to.equal(false); + let promise: Promise | null = null; + // We want to flush updates before preProcessEditCellProps resolves + act(() => { + promise = apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }) as Promise; }); + expect(renderEditCell.lastCall.args[0].isProcessingProps).to.equal(true); + await act(() => promise); + expect(renderEditCell.lastCall.args[0].isProcessingProps).to.equal(false); }); it('should return false if preProcessEditCellProps sets an error', async () => { @@ -225,36 +246,48 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect( - await apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - }), + await act(() => + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }), + ), ).to.equal(false); }); - it('should return false if the cell left the edit mode while calling preProcessEditCellProps', async () => { + it('should return false if the cell left the edit mode while calling preProcessEditCellProps', (done) => { + let resolveCallback: () => void; columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => new Promise((resolve) => { - // Simulates the user cancelling the editing while processing the props - act(() => - apiRef.current.stopCellEditMode({ - id: 0, - field: 'currencyPair', - ignoreModifications: true, - }), - ); - resolve(props); + resolveCallback = () => resolve(props); }); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - expect( - await apiRef.current.setEditCellValue({ + + let promise: Promise; + act(() => { + promise = apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP', + }) as Promise; + }); + + promise!.then((result) => { + expect(result).to.equal(false); + done(); + }); + + act(() => + apiRef.current.stopCellEditMode({ + id: 0, + field: 'currencyPair', + ignoreModifications: true, }), - ).to.equal(false); + ); + + resolveCallback!(); }); describe('with debounceMs > 0', () => { @@ -305,7 +338,9 @@ describe(' - Cell Editing', () => { it('should update the row with the new value stored', async () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).textContent).to.equal('USD GBP'); }); @@ -313,7 +348,9 @@ describe(' - Cell Editing', () => { it('should not update the row if ignoreModifications=true', async () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, @@ -325,21 +362,30 @@ describe(' - Cell Editing', () => { }); it('should do nothing if props are still being processed and ignoreModifications=false', async () => { + let resolveCallback: () => void; columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => new Promise((resolve) => { - // Simulates the user stopping the editing while processing the props - act(() => - apiRef.current.stopCellEditMode({ - id: 0, - field: 'currencyPair', - }), - ); - resolve(props); + resolveCallback = () => resolve(props); }); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + + let promise: Promise; + act(() => { + promise = apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }) as Promise; + }); + + act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); + expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); + + resolveCallback!(); + + await act(() => promise); // Run all updates scheduled for when preProcessEditCellProps resolves }); it('should do nothing if props contain error=true', async () => { @@ -349,7 +395,9 @@ describe(' - Cell Editing', () => { }); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); }); @@ -362,11 +410,15 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: '' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: '' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).className).not.to.contain('MuiDataGrid-cell--editing'); }); @@ -375,7 +427,9 @@ describe(' - Cell Editing', () => { render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(getCell(0, 1).className).not.to.contain('MuiDataGrid-cell--editing'); }); @@ -384,9 +438,11 @@ describe(' - Cell Editing', () => { const processRowUpdate = spy((row) => ({ ...row, currencyPair: 'USD-GBP' })); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(processRowUpdate.callCount).to.equal(1); expect(getCell(0, 1).textContent).to.equal('USD-GBP'); }); @@ -395,8 +451,11 @@ describe(' - Cell Editing', () => { const processRowUpdate = spy((newRow, oldRow) => ({ ...oldRow, ...newRow })); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(processRowUpdate.lastCall.args[0]).to.deep.equal({ ...defaultData.rows[0], currencyPair: 'USD GBP', @@ -455,10 +514,12 @@ describe(' - Cell Editing', () => { it('should pass the new value through the value setter before calling processRowUpdate', async () => { columnProps.valueSetter = spy(({ value, row }) => ({ ...row, _currencyPair: value })); - const processRowUpdate = spy((newRow) => newRow); + const processRowUpdate = spy(); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(processRowUpdate.lastCall.args[0]).to.deep.equal({ ...defaultData.rows[0], @@ -538,15 +599,21 @@ describe(' - Cell Editing', () => { }); it('should run all pending value mutations before calling processRowUpdate', async () => { - const processRowUpdate = spy((newRow) => newRow); + const processRowUpdate = spy(); render(); act(() => apiRef.current.startCellEditMode({ id: 0, field: 'currencyPair' })); - apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - debounceMs: 100, - }); + await act( + () => + new Promise((resolve) => { + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + debounceMs: 100, + }); + resolve(); + }), + ); act(() => apiRef.current.stopCellEditMode({ id: 0, field: 'currencyPair' })); expect(renderEditCell.lastCall.args[0].value).to.equal('USD GBP'); expect(processRowUpdate.lastCall.args[0].currencyPair).to.equal('USD GBP'); @@ -846,13 +913,18 @@ describe(' - Cell Editing', () => { }); }); - it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', () => { - columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', async () => { + columnProps.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopCellEditMode = spy(apiRef.current, 'stopCellEditMode'); fireEvent.doubleClick(getCell(0, 1)); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act( + () => + new Promise((resolve) => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + resolve(); + }), + ); fireEvent.click(getCell(1, 1)); expect(spiedStopCellEditMode.callCount).to.equal(1); expect(spiedStopCellEditMode.lastCall.args[0].ignoreModifications).to.equal(true); @@ -922,16 +994,21 @@ describe(' - Cell Editing', () => { }); }); - it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', () => { - columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', async () => { + columnProps.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopCellEditMode = spy(apiRef.current, 'stopCellEditMode'); const cell = getCell(0, 1); fireEvent.mouseUp(cell); fireEvent.click(cell); fireEvent.doubleClick(cell); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act( + () => + new Promise((resolve) => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + resolve(); + }), + ); fireEvent.keyDown(cell, { key: 'Enter' }); expect(spiedStopCellEditMode.callCount).to.equal(1); expect(spiedStopCellEditMode.lastCall.args[0].ignoreModifications).to.equal(true); @@ -969,16 +1046,21 @@ describe(' - Cell Editing', () => { }); }); - it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', () => { - columnProps.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopCellEditMode with ignoreModifications=true if the props are being processed', async () => { + columnProps.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopCellEditMode = spy(apiRef.current, 'stopCellEditMode'); const cell = getCell(0, 1); fireEvent.mouseUp(cell); fireEvent.click(cell); fireEvent.doubleClick(cell); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act( + () => + new Promise((resolve) => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + resolve(); + }), + ); fireEvent.keyDown(cell, { key: 'Tab' }); expect(spiedStopCellEditMode.callCount).to.equal(1); expect(spiedStopCellEditMode.lastCall.args[0].ignoreModifications).to.equal(true); @@ -1010,7 +1092,9 @@ describe(' - Cell Editing', () => { const { setProps } = render( , ); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); setProps({ cellModesModel: { 0: { currencyPair: { mode: GridCellModes.View, ignoreModifications: true } }, @@ -1023,7 +1107,9 @@ describe(' - Cell Editing', () => { const { setProps } = render( , ); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); setProps({ cellModesModel: { 0: { currencyPair: { mode: GridCellModes.View, cellToFocusAfter: 'below' } }, diff --git a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.old.test.tsx b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.old.test.tsx index 2321cd6a3e93..c45a0d710451 100644 --- a/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.old.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/cellEditing.DataGridPro.old.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { GridApi, DataGridProProps, useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro'; import Portal from '@mui/base/Portal'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, waitFor } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, waitFor, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { getActiveCell, getCell, getColumnHeaderCell } from 'test/utils/helperFn'; import { stub, spy } from 'sinon'; @@ -73,7 +73,7 @@ describe(' - Cell Editing', () => { const cellAdidas = getCell(1, 0); expect(cellAdidas).to.have.class('MuiDataGrid-cell--editable'); - apiRef.current.setCellMode(0, 'brand', 'edit'); + act(() => apiRef.current.setCellMode(0, 'brand', 'edit')); expect(cellNike).to.have.class('MuiDataGrid-cell--editing'); }); @@ -109,7 +109,7 @@ describe(' - Cell Editing', () => { expect(input).not.to.have.attribute('aria-invalid'); fireEvent.change(input, { target: { value: 'n' } }); clock.runToLast(); - apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } }); + act(() => apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } })); fireEvent.keyDown(input, { key: 'Enter' }); await waitFor(() => { expect(input).to.have.attribute('aria-invalid', 'true'); @@ -125,9 +125,11 @@ describe(' - Cell Editing', () => { expect(input).not.to.have.attribute('aria-invalid'); fireEvent.change(input, { target: { value: 'n' } }); clock.runToLast(); - apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } }); - apiRef.current.commitCellChange({ id: 1, field: 'brand' }); - apiRef.current.setCellMode(1, 'brand', 'view'); + act(() => { + apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } }); + apiRef.current.commitCellChange({ id: 1, field: 'brand' }); + apiRef.current.setCellMode(1, 'brand', 'view'); + }); expect(cell).to.have.text('Adidas'); }); @@ -140,9 +142,11 @@ describe(' - Cell Editing', () => { expect(input).not.to.have.attribute('aria-invalid'); fireEvent.change(input, { target: { value: 'n' } }); clock.runToLast(); - apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } }); - apiRef.current.commitCellChange({ id: 1, field: 'brand' }); - apiRef.current.setCellMode(1, 'brand', 'view'); + act(() => { + apiRef.current.setEditRowsModel({ 1: { brand: { error: true, value: 'n' } } }); + apiRef.current.commitCellChange({ id: 1, field: 'brand' }); + apiRef.current.setCellMode(1, 'brand', 'view'); + }); expect(onCellEditCommit.callCount).to.equal(0); }); }); @@ -157,7 +161,10 @@ describe(' - Cell Editing', () => { fireEvent.change(input, { target: { value: '1970' } }); clock.tick(500); expect(input.value).to.equal('1970'); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await waitFor(() => { expect(cell).to.have.text('1970'); }); @@ -171,7 +178,10 @@ describe(' - Cell Editing', () => { expect(input.value).to.equal('1961'); fireEvent.change(input, { target: { value: '1970' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await waitFor(() => { expect(cell.querySelector('input')).not.to.equal(null); }); @@ -192,7 +202,10 @@ describe(' - Cell Editing', () => { expect(onEditRowsModelChange.lastCall.firstArg).to.deep.equal({ 1: { year: { value: '1970' } }, }); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await waitFor(() => { expect(cell).to.have.text('1970'); }); @@ -218,7 +231,10 @@ describe(' - Cell Editing', () => { 1: { year: { value: '1970' } }, }); setProps({ editRowsModel: { 1: { year: { value: 1971 } } } }); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await waitFor(() => { expect(onEditRowsModelChange.lastCall.firstArg).to.deep.equal({}); }); @@ -230,14 +246,14 @@ describe(' - Cell Editing', () => { it('should allow to switch between cell mode', () => { render(); - apiRef.current.setCellMode(1, 'brand', 'edit'); + act(() => apiRef.current.setCellMode(1, 'brand', 'edit')); const cell = getCell(1, 0); expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).to.have.class('MuiDataGrid-cell--editing'); expect(cell.querySelector('input')!.value).to.equal('Adidas'); - apiRef.current.setCellMode(1, 'brand', 'view'); + act(() => apiRef.current.setCellMode(1, 'brand', 'view')); expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); expect(cell.querySelector('input')).to.equal(null); @@ -331,14 +347,16 @@ describe(' - Cell Editing', () => { const cell = getCell(1, 0); fireClickEvent(cell); expect(cell).to.have.text('Adidas'); - const params = apiRef.current.getCellParams(1, 'brand'); - apiRef.current.publishEvent('cellKeyDown', params, { - key: 'a', - code: 1, - target: cell, - currentTarget: cell, - isPropagationStopped: () => false, - } as any); + act(() => { + const params = apiRef.current.getCellParams(1, 'brand'); + return apiRef.current.publishEvent('cellKeyDown', params, { + key: 'a', + code: 1, + target: cell, + currentTarget: cell, + isPropagationStopped: () => false, + } as any); + }); // fireEvent.keyDown(cell, { key: 'a', code: 1, target: cell }); expect(cell).to.have.class('MuiDataGrid-cell--editable'); @@ -373,7 +391,11 @@ describe(' - Cell Editing', () => { expect(cell.querySelector('input')!.value).to.equal('n'); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -393,7 +415,11 @@ describe(' - Cell Editing', () => { expect(cell.querySelector('input')!.value).to.equal('n'); clock.tick(500); - fireEvent.keyDown(input, { key: 'Tab' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Tab' }); + }); + await waitFor(() => { expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -413,7 +439,11 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1970'); - fireEvent.keyDown(input, { key: 'Tab', shiftKey: true }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Tab', shiftKey: true }); + }); + await waitFor(() => { expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -435,8 +465,12 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1970'); - const otherCell = getCell(2, 1); - fireClickEvent(otherCell); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + const otherCell = getCell(2, 1); + fireClickEvent(otherCell); + }); + await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); expect(cell).to.have.text('1970'); @@ -457,8 +491,12 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1970'); - const columnHeader = getColumnHeaderCell(0); - fireEvent.dragStart(columnHeader.firstChild); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + const columnHeader = getColumnHeaderCell(0); + fireEvent.dragStart(columnHeader.firstChild); + }); + await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); expect(cell).to.have.text('1970'); @@ -478,7 +516,11 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1970'); - fireEvent.focus(getColumnHeaderCell(1)); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.focus(getColumnHeaderCell(1)); + }); + await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); expect(cell).to.have.text('1970'); @@ -487,7 +529,7 @@ describe(' - Cell Editing', () => { it('should work correctly when the cell editing was initiated programmatically', async () => { render(); - apiRef.current.setCellMode(1, 'year', 'edit'); + act(() => apiRef.current.setCellMode(1, 'year', 'edit')); const cell = getCell(1, 1); fireClickEvent(cell); expect(getActiveCell()).to.equal('1-1'); @@ -498,8 +540,11 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1970'); - const otherCell = getCell(2, 1); - fireClickEvent(otherCell); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + const otherCell = getCell(2, 1); + fireClickEvent(otherCell); + }); await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -511,16 +556,17 @@ describe(' - Cell Editing', () => { it('should move the focus to the new field', async () => { render(); // Turn first cell into edit mode - apiRef.current.setCellMode(0, 'brand', 'edit'); - - // Turn second cell into edit mode - fireClickEvent(getCell(1, 0)); - apiRef.current.setCellMode(1, 'brand', 'edit'); + act(() => apiRef.current.setCellMode(0, 'brand', 'edit')); + act(() => apiRef.current.setCellMode(1, 'brand', 'edit')); expect(document.querySelectorAll('input').length).to.equal(2); - // Try to focus the first cell's input - const input0 = getCell(0, 0).querySelector('input'); - fireClickEvent(input0!); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + // Try to focus the first cell's input + const input0 = getCell(0, 0).querySelector('input'); + fireClickEvent(input0!); + }); + await waitFor(() => { expect(document.activeElement).to.have.property('value', 'Nike'); }); @@ -548,10 +594,15 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('1962'); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); }); + expect(cell).to.have.text('1962'); expect(valueParser.callCount).to.equal(1); expect(valueParser.args[0][0]).to.equal('62'); @@ -655,7 +706,11 @@ describe(' - Cell Editing', () => { clock.tick(500); expect(cell.querySelector('input')!.value).to.equal('n'); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -694,7 +749,12 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'n' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(onCellEditCommit.callCount).to.equal(1); expect(onCellEditCommit.lastCall.args[0]).to.deep.equal({ @@ -727,7 +787,12 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Peter Smith' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(apiRef.current.getRowModels().get(0)).to.deep.equal({ id: 0, @@ -755,7 +820,12 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'n' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(preProcessEditCellProps.lastCall.args[0]).to.deep.equal({ id: baselineProps.rows[1].id, @@ -783,7 +853,12 @@ describe(' - Cell Editing', () => { expect(input).not.to.have.attribute('aria-invalid'); fireEvent.change(input, { target: { value: 'n' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(input).to.have.attribute('aria-invalid', 'true'); expect(cell).to.have.class('MuiDataGrid-cell--editing'); @@ -808,7 +883,12 @@ describe(' - Cell Editing', () => { expect(input).not.to.have.attribute('aria-invalid'); fireEvent.change(input, { target: { value: 'n' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(input).to.have.attribute('aria-invalid', 'true'); expect(cell).to.have.class('MuiDataGrid-cell--editing'); @@ -839,7 +919,11 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -871,7 +955,11 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -904,9 +992,12 @@ describe(' - Cell Editing', () => { const cell = getCell(0, 0); fireEvent.doubleClick(cell); - const input = cell.querySelector('input')!; - fireEvent.change(input, { target: { value: 'Adidas' } }); - clock.tick(500); + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'Adidas' } }); + clock.tick(500); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -924,7 +1015,12 @@ describe(' - Cell Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); expect(cell).to.have.class('MuiDataGrid-cell--editing'); - fireClickEvent(getCell(1, 0)); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireClickEvent(getCell(1, 0)); + }); + await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); clock.runToLast(); @@ -938,7 +1034,12 @@ describe(' - Cell Editing', () => { fireEvent.doubleClick(cell); const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); - fireClickEvent(getCell(1, 0)); + + // Wrap in `act` to flush updates after the promise from the commit + await act(async () => { + fireClickEvent(getCell(1, 0)); + }); + await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise // We don't need to wait for debounce when commiting expect(onCellEditCommit.lastCall.args[0].value).to.equal('Adidas'); diff --git a/packages/grid/x-data-grid-pro/src/tests/clipboard.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/clipboard.DataGridPro.test.tsx index a018264e91ad..2de18c29972e 100644 --- a/packages/grid/x-data-grid-pro/src/tests/clipboard.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/clipboard.DataGridPro.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { GridApi, useGridApiRef, DataGridPro, DataGridProProps } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { stub, SinonStub } from 'sinon'; import { getCell } from 'test/utils/helperFn'; @@ -66,15 +66,15 @@ describe(' - Clipboard', () => { it('should copy the selected rows to the clipboard', () => { render(); - apiRef.current.selectRows([0, 1]); - apiRef.current.unstable_copySelectedRowsToClipboard(); + act(() => apiRef.current.selectRows([0, 1])); + act(() => apiRef.current.unstable_copySelectedRowsToClipboard()); expect(writeText.firstCall.args[0]).to.equal(['0\tNike', '1\tAdidas'].join('\r\n')); }); it('should include the headers when includeHeaders=true', () => { render(); - apiRef.current.selectRows([0, 1]); - apiRef.current.unstable_copySelectedRowsToClipboard(true); + act(() => apiRef.current.selectRows([0, 1])); + act(() => apiRef.current.unstable_copySelectedRowsToClipboard(true)); expect(writeText.firstCall.args[0]).to.equal( ['id\tBrand', '0\tNike', '1\tAdidas'].join('\r\n'), ); @@ -83,7 +83,7 @@ describe(' - Clipboard', () => { ['ctrlKey', 'metaKey'].forEach((key) => { it(`should copy the selected rows to the clipboard when ${key} + C is pressed`, () => { render(); - apiRef.current.selectRows([0, 1]); + act(() => apiRef.current.selectRows([0, 1])); const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.click(cell); @@ -94,7 +94,7 @@ describe(' - Clipboard', () => { it(`should copy the selected rows and headers to the clipboard when Alt + C is pressed`, () => { render(); - apiRef.current.selectRows([0, 1]); + act(() => apiRef.current.selectRows([0, 1])); const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.click(cell); diff --git a/packages/grid/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx index cda6f0a43442..b48cf845aa7c 100644 --- a/packages/grid/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/columnPinning.DataGridPro.test.tsx @@ -10,7 +10,7 @@ import { import { spy } from 'sinon'; import { expect } from 'chai'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, createEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, createEvent, act } from '@mui/monorepo/test/utils'; import { getCell, getColumnHeaderCell, getColumnHeadersTextContent } from 'test/utils/helperFn'; import { useData } from 'storybook/src/hooks/useData'; @@ -47,7 +47,7 @@ describe(' - Column pinning', () => { render(); const virtualScroller = document.querySelector(`.${gridClasses.virtualScroller}`)!; virtualScroller.scrollLeft = 100; - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); const cell = getCell(0, 2); fireEvent.mouseUp(cell); fireEvent.click(cell); @@ -224,12 +224,12 @@ describe(' - Column pinning', () => { it('should call when a column is pinned', () => { const handlePinnedColumnsChange = spy(); render(); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); expect(handlePinnedColumnsChange.lastCall.args[0]).to.deep.equal({ left: ['currencyPair'], right: [], }); - apiRef.current.pinColumn('price17M', GridPinnedPosition.right); + act(() => apiRef.current.pinColumn('price17M', GridPinnedPosition.right)); expect(handlePinnedColumnsChange.lastCall.args[0]).to.deep.equal({ left: ['currencyPair'], right: ['price17M'], @@ -247,7 +247,7 @@ describe(' - Column pinning', () => { expect( document.querySelectorAll(`.${gridClasses['pinnedColumns--left']} [role="cell"]`), ).to.have.length(1); - apiRef.current.pinColumn('price17M', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('price17M', GridPinnedPosition.left)); expect( document.querySelectorAll(`.${gridClasses['pinnedColumns--left']} [role="cell"]`), ).to.have.length(1); @@ -274,7 +274,7 @@ describe(' - Column pinning', () => { `.${gridClasses['pinnedColumns--left']} [data-field="currencyPair"]`, ), ).not.to.equal(null); - apiRef.current.pinColumn('price17M', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('price17M', GridPinnedPosition.left)); expect( document.querySelector( `.${gridClasses['pinnedColumns--left']} [data-field="currencyPair"]`, @@ -371,7 +371,7 @@ describe(' - Column pinning', () => { `.${gridClasses.virtualScrollerRenderZone}`, )!; expect(renderZone.querySelector('[data-field="currencyPair"]')).not.to.equal(null); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); const leftColumns = document.querySelector( `.${gridClasses['pinnedColumns--left']}`, )!; @@ -387,14 +387,14 @@ describe(' - Column pinning', () => { expect(renderZone.querySelector('[data-field="currencyPair"]')).not.to.equal(null); expect(renderZone.querySelector('[data-field="currencyPair"]')).not.to.equal(null); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); const leftColumns = document.querySelector( `.${gridClasses['pinnedColumns--left']}`, )!; expect(leftColumns.querySelector('[data-field="currencyPair"]')).not.to.equal(null); expect(renderZone.querySelector('[data-field="currencyPair"]')).to.equal(null); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.right); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.right)); const rightColumns = document.querySelector( `.${gridClasses['pinnedColumns--right']}`, )!; @@ -404,12 +404,12 @@ describe(' - Column pinning', () => { it('should not change the columns when called on a pinned column with the same side ', () => { render(); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); const leftColumns = document.querySelector( `.${gridClasses['pinnedColumns--left']}`, )!; expect(leftColumns.querySelector('[data-id="0"]')?.children).to.have.length(1); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); expect(leftColumns.querySelector('[data-id="0"]')?.children).to.have.length(1); }); }); @@ -417,9 +417,9 @@ describe(' - Column pinning', () => { describe('unpinColumn', () => { it('should unpin the given column', () => { render(); - apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left); + act(() => apiRef.current.pinColumn('currencyPair', GridPinnedPosition.left)); expect(document.querySelector(`.${gridClasses['pinnedColumns--left']}`)).not.to.equal(null); - apiRef.current.unpinColumn('currencyPair'); + act(() => apiRef.current.unpinColumn('currencyPair')); expect(document.querySelector(`.${gridClasses['pinnedColumns--left']}`)).to.equal(null); const renderZone = document.querySelector( `.${gridClasses.virtualScrollerRenderZone}`, @@ -543,7 +543,7 @@ describe(' - Column pinning', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair']); setProps({ pinnedColumns: { left: ['currencyPair'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id']); - apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }]); + act(() => apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }])); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id', 'foo', 'bar']); setProps({ pinnedColumns: { left: ['currencyPair', 'foo'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'foo', 'id', 'bar']); @@ -556,7 +556,7 @@ describe(' - Column pinning', () => { , ); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair']); - apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }]); + act(() => apiRef.current.updateColumns([{ field: 'foo' }, { field: 'bar' }])); expect(getColumnHeadersTextContent()).to.deep.equal(['foo', 'id', 'Currency Pair', 'bar']); setProps({ pinnedColumns: {} }); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair', 'foo', 'bar']); @@ -583,7 +583,7 @@ describe(' - Column pinning', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'Currency Pair', '1M', '2M']); // price1M's index = 2 setProps({ pinnedColumns: { left: ['price1M'] } }); expect(getColumnHeadersTextContent()).to.deep.equal(['1M', 'id', 'Currency Pair', '2M']); - apiRef.current.setColumnIndex('id', 2); + act(() => apiRef.current.setColumnIndex('id', 2)); expect(getColumnHeadersTextContent()).to.deep.equal(['1M', 'Currency Pair', 'id', '2M']); setProps({ pinnedColumns: {} }); expect(getColumnHeadersTextContent()).to.deep.equal(['Currency Pair', 'id', '1M', '2M']); // price1M's index = 2 diff --git a/packages/grid/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx index b888dc613b37..8e128217449e 100644 --- a/packages/grid/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/columnReorder.DataGridPro.test.tsx @@ -67,9 +67,7 @@ describe(' - Columns reorder', () => { const { setProps } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'brand']); - act(() => { - apiRef.current.setColumnIndex('id', 1); - }); + act(() => apiRef.current.setColumnIndex('id', 1)); setProps({ width: 200 }); await raf(); expect(getColumnHeadersTextContent()).to.deep.equal(['brand', 'id']); @@ -92,7 +90,7 @@ describe(' - Columns reorder', () => { const { forceUpdate } = render(); expect(getColumnHeadersTextContent()).to.deep.equal(['brand', 'desc', 'type']); - apiRef!.current.setColumnIndex('brand', 2); + act(() => apiRef.current.setColumnIndex('brand', 2)); expect(getColumnHeadersTextContent()).to.deep.equal(['desc', 'type', 'brand']); forceUpdate(); // test stability expect(getColumnHeadersTextContent()).to.deep.equal(['desc', 'type', 'brand']); diff --git a/packages/grid/x-data-grid-pro/src/tests/columnSpanning.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/columnSpanning.DataGridPro.test.tsx index d3fd73dfdac4..131378e1b8f9 100644 --- a/packages/grid/x-data-grid-pro/src/tests/columnSpanning.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/columnSpanning.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { DataGridPro, GridApi, useGridApiRef, GridColDef, gridClasses } from '@mui/x-data-grid-pro'; import { getActiveCell, getCell, getColumnHeaderCell } from 'test/utils/helperFn'; @@ -106,7 +106,7 @@ describe(' - Column Spanning', () => { render(); - apiRef!.current.setColumnIndex('price', 1); + act(() => apiRef!.current.setColumnIndex('price', 1)); fireClickEvent(getCell(1, 1)); fireEvent.keyDown(getCell(1, 1), { key: 'ArrowRight' }); @@ -139,7 +139,7 @@ describe(' - Column Spanning', () => { render(); - apiRef!.current.setColumnIndex('brand', 1); + act(() => apiRef!.current.setColumnIndex('brand', 1)); // Nike row expect(() => getCell(0, 0)).to.not.throw(); @@ -215,29 +215,31 @@ describe(' - Column Spanning', () => { render(); - apiRef!.current.setRows([ - { - id: 0, - brand: 'Adidas', - category: 'Shoes', - price: '$100', - rating: '4.5', - }, - { - id: 1, - brand: 'Nike', - category: 'Shoes', - price: '$120', - rating: '4.5', - }, - { - id: 2, - brand: 'Reebok', - category: 'Shoes', - price: '$90', - rating: '4.5', - }, - ]); + act(() => + apiRef!.current.setRows([ + { + id: 0, + brand: 'Adidas', + category: 'Shoes', + price: '$100', + rating: '4.5', + }, + { + id: 1, + brand: 'Nike', + category: 'Shoes', + price: '$120', + rating: '4.5', + }, + { + id: 2, + brand: 'Reebok', + category: 'Shoes', + price: '$90', + rating: '4.5', + }, + ]), + ); // Adidas row expect(() => getCell(0, 0)).to.not.throw(); diff --git a/packages/grid/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx index 9114ba0901fc..48534dbbd957 100644 --- a/packages/grid/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, waitFor } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { @@ -53,19 +53,18 @@ describe(' - Columns', () => { it('should open the column menu', async () => { render(); expect(screen.queryByRole('menu')).to.equal(null); - apiRef.current.showColumnMenu('brand'); - await waitFor(() => expect(screen.queryByRole('menu')).not.to.equal(null)); + act(() => apiRef.current.showColumnMenu('brand')); + expect(screen.queryByRole('menu')).not.to.equal(null); }); it('should set the correct id and aria-labelledby', async () => { render(); expect(screen.queryByRole('menu')).to.equal(null); - apiRef.current.showColumnMenu('brand'); - await waitFor(() => { - const menu = screen.queryByRole('menu'); - expect(menu.id).to.match(/^mui-[0-9]+/); - expect(menu.getAttribute('aria-labelledby')).to.match(/^mui-[0-9]+/); - }); + act(() => apiRef.current.showColumnMenu('brand')); + clock.runToLast(); + const menu = screen.queryByRole('menu'); + expect(menu.id).to.match(/:r[0-9a-z]+:/); + expect(menu.getAttribute('aria-labelledby')).to.match(/:r[0-9a-z]+:/); }); }); @@ -73,10 +72,10 @@ describe(' - Columns', () => { it('should toggle the column menu', async () => { render(); expect(screen.queryByRole('menu')).to.equal(null); - apiRef.current.toggleColumnMenu('brand'); + act(() => apiRef.current.toggleColumnMenu('brand')); clock.runToLast(); expect(screen.queryByRole('menu')).not.to.equal(null); - apiRef.current.toggleColumnMenu('brand'); + act(() => apiRef.current.toggleColumnMenu('brand')); clock.runToLast(); expect(screen.queryByRole('menu')).to.equal(null); }); @@ -169,7 +168,7 @@ describe(' - Columns', () => { expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '198px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '100px' }); - apiRef.current.setColumnWidth('brand', 150); + act(() => apiRef.current.setColumnWidth('brand', 150)); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '148px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '150px' }); @@ -209,7 +208,7 @@ describe(' - Columns', () => { expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '198px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '100px' }); - apiRef.current.setColumnWidth('brand', 150); + act(() => apiRef.current.setColumnWidth('brand', 150)); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '175px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '150px' }); @@ -226,7 +225,7 @@ describe(' - Columns', () => { expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '98px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '200px' }); - apiRef.current.setColumnWidth('brand', 150); + act(() => apiRef.current.setColumnWidth('brand', 150)); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '125px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '150px' }); @@ -289,7 +288,7 @@ describe(' - Columns', () => { expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '198px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '100px' }); - apiRef.current.setColumnWidth('brand', 150); + act(() => apiRef.current.setColumnWidth('brand', 150)); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '148px' }); expect(getColumnHeaderCell(1)).toHaveInlineStyle({ width: '150px' }); @@ -350,26 +349,26 @@ describe(' - Columns', () => { describe('column pipe processing', () => { it('should not loose column width when re-applying pipe processing', () => { render(); - apiRef.current.setColumnWidth('brand', 300); + act(() => apiRef.current.setColumnWidth('brand', 300)); expect(gridColumnLookupSelector(apiRef).brand.computedWidth).to.equal(300); - apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns'); + act(() => apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns')); expect(gridColumnLookupSelector(apiRef).brand.computedWidth).to.equal(300); }); it('should not loose column index when re-applying pipe processing', () => { render(); expect(gridColumnFieldsSelector(apiRef).indexOf('brand')).to.equal(2); - apiRef.current.setColumnIndex('brand', 1); + act(() => apiRef.current.setColumnIndex('brand', 1)); expect(gridColumnFieldsSelector(apiRef).indexOf('brand')).to.equal(1); - apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns'); + act(() => apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns')); expect(gridColumnFieldsSelector(apiRef).indexOf('brand')).to.equal(1); }); it('should not loose imperatively added columns when re-applying pipe processing', () => { render(); - apiRef.current.updateColumn({ field: 'id' }); + act(() => apiRef.current.updateColumn({ field: 'id' })); expect(gridColumnFieldsSelector(apiRef)).to.deep.equal(['__check__', 'brand', 'id']); - apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns'); + act(() => apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns')); expect(gridColumnFieldsSelector(apiRef)).to.deep.equal(['__check__', 'brand', 'id']); }); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/columnsVisibility.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/columnsVisibility.DataGridPro.test.tsx index 1dab9fb398ad..b008353ddd66 100644 --- a/packages/grid/x-data-grid-pro/src/tests/columnsVisibility.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/columnsVisibility.DataGridPro.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { spy } from 'sinon'; import { expect } from 'chai'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, act } from '@mui/monorepo/test/utils'; import { DataGridPro, DataGridProProps, @@ -27,7 +27,7 @@ const columns: GridColumns = [{ field: 'id' }, { field: 'idBis' }]; * TODO v6: Remove deprecated tests */ describe(' - Columns Visibility', () => { - const { render } = createRenderer(); + const { render } = createRenderer({ clock: 'fake' }); let apiRef: React.MutableRefObject; @@ -60,7 +60,7 @@ describe(' - Columns Visibility', () => { />, ); - apiRef.current.updateColumns([{ field: 'id', width: 300 }]); + act(() => apiRef.current.updateColumns([{ field: 'id', width: 300 }])); expect(onColumnVisibilityModelChange.callCount).to.equal(0); }); @@ -73,7 +73,7 @@ describe(' - Columns Visibility', () => { />, ); - apiRef.current.updateColumns([{ field: 'id', hide: true }]); + act(() => apiRef.current.updateColumns([{ field: 'id', hide: true }])); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ id: false, @@ -90,14 +90,14 @@ describe(' - Columns Visibility', () => { initialState={{ columns: { columnVisibilityModel: { idBis: false } } }} />, ); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(gridColumnLookupSelector(apiRef).id.hide).to.equal(false); expect(gridColumnVisibilityModelSelector(apiRef)).to.deep.equal({ id: false, idBis: false, }); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(gridColumnLookupSelector(apiRef).id.hide).to.equal(false); expect(gridColumnVisibilityModelSelector(apiRef)).to.deep.equal({ id: true, @@ -115,14 +115,14 @@ describe(' - Columns Visibility', () => { />, ); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ id: false, idBis: false, }); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(onColumnVisibilityModelChange.callCount).to.equal(2); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ idBis: false, @@ -140,10 +140,10 @@ describe(' - Columns Visibility', () => { />, ); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(onColumnVisibilityChange.callCount).to.equal(0); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(onColumnVisibilityChange.callCount).to.equal(0); }); }); @@ -152,14 +152,14 @@ describe(' - Columns Visibility', () => { it('should update `columnVisibilityModel` and `GridColDef.hide` in state', () => { render(); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(gridColumnLookupSelector(apiRef).id.hide).to.equal(true); expect(gridColumnVisibilityModelSelector(apiRef)).to.deep.equal({ id: false, idBis: true, }); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(gridColumnLookupSelector(apiRef).id.hide).to.equal(false); expect(gridColumnVisibilityModelSelector(apiRef)).to.deep.equal({ id: true, @@ -172,14 +172,14 @@ describe(' - Columns Visibility', () => { render(); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ id: false, idBis: true, }); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(onColumnVisibilityModelChange.callCount).to.equal(2); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({ id: true, @@ -192,12 +192,12 @@ describe(' - Columns Visibility', () => { render(); - apiRef.current.setColumnVisibility('id', false); + act(() => apiRef.current.setColumnVisibility('id', false)); expect(onColumnVisibilityChange.callCount).to.equal(1); expect(onColumnVisibilityChange.lastCall.firstArg).to.have.property('isVisible', false); expect(onColumnVisibilityChange.lastCall.firstArg).to.have.property('field', 'id'); - apiRef.current.setColumnVisibility('id', true); + act(() => apiRef.current.setColumnVisibility('id', true)); expect(onColumnVisibilityChange.callCount).to.equal(2); expect(onColumnVisibilityChange.lastCall.firstArg).to.have.property('isVisible', true); expect(onColumnVisibilityChange.lastCall.firstArg).to.have.property('field', 'id'); @@ -215,13 +215,13 @@ describe(' - Columns Visibility', () => { onColumnVisibilityModelChange={onColumnVisibilityModelChange} />, ); - apiRef.current.setColumnVisibilityModel({}); + act(() => apiRef.current.setColumnVisibilityModel({})); expect(onColumnVisibilityModelChange.callCount).to.equal(1); expect(onColumnVisibilityModelChange.lastCall.firstArg).to.deep.equal({}); }); }); - it('should not hide column when resizing a column after hiding it and showing it again ', () => { + it('should not hide column when resizing a column after hiding it and showing it again', () => { const { getByText } = render( - Detail panel', () => { expect(getColumnValues(1)[0]).to.equal('0'); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; virtualScroller.scrollTop = 250; // 50 + 50 (detail panel) + 50 + 100 (detail panel * 2) - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); expect(getColumnValues(1)[0]).to.equal('2'); // If there was no expanded row, the first rendered would be 5 }); @@ -565,9 +565,9 @@ describe(' - Detail panel', () => { it('should toggle the panel of the given row id', () => { render(
Detail
} />); expect(screen.queryByText('Detail')).to.equal(null); - apiRef.current.toggleDetailPanel(0); + act(() => apiRef.current.toggleDetailPanel(0)); expect(screen.queryByText('Detail')).not.to.equal(null); - apiRef.current.toggleDetailPanel(0); + act(() => apiRef.current.toggleDetailPanel(0)); expect(screen.queryByText('Detail')).to.equal(null); }); @@ -578,7 +578,7 @@ describe(' - Detail panel', () => { getDetailPanelContent={({ id }) => (id === 0 ?
Detail
: null)} />, ); - apiRef.current.toggleDetailPanel(1); + act(() => apiRef.current.toggleDetailPanel(1)); expect(document.querySelector('.MuiDataGrid-detailPanels')).to.equal(null); expect(getRow(1)).not.toHaveComputedStyle({ marginBottom: '50px' }); }); @@ -596,7 +596,7 @@ describe(' - Detail panel', () => { }} />, ); - expect(apiRef.current.getExpandedDetailPanels()).to.deep.equal([0, 1]); + act(() => expect(apiRef.current.getExpandedDetailPanels()).to.deep.equal([0, 1])); }); }); @@ -615,7 +615,7 @@ describe(' - Detail panel', () => { expect(screen.queryByText('Row 0')).not.to.equal(null); expect(screen.queryByText('Row 1')).to.equal(null); expect(screen.queryByText('Row 2')).to.equal(null); - apiRef.current.setExpandedDetailPanels([1, 2]); + act(() => apiRef.current.setExpandedDetailPanels([1, 2])); expect(screen.queryByText('Row 0')).to.equal(null); expect(screen.queryByText('Row 1')).not.to.equal(null); expect(screen.queryByText('Row 2')).not.to.equal(null); diff --git a/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.new.test.tsx b/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.new.test.tsx index 7d1b4ef7e615..b198898c5578 100644 --- a/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.new.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.new.test.tsx @@ -118,11 +118,11 @@ describe(' - Edit Components', () => { expect(screen.queryByTestId('LoadIcon')).to.equal(null); fireEvent.change(input, { target: { value: 'Puma' } }); - clock.tick(200); + act(() => clock.tick(200)); expect(screen.queryByTestId('LoadIcon')).not.to.equal(null); clock.tick(500); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(screen.queryByTestId('LoadIcon')).to.equal(null); }); @@ -139,7 +139,7 @@ describe(' - Edit Components', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Puma' } }); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(onValueChange.callCount).to.equal(1); expect(onValueChange.lastCall.args[1]).to.equal('Puma'); @@ -199,9 +199,9 @@ describe(' - Edit Components', () => { expect(input.value).to.equal('100'); fireEvent.change(input, { target: { value: '110' } }); - clock.tick(200); + act(() => clock.tick(200)); expect(preProcessEditCellPropsSpy.lastCall.args[0].props.value).to.equal(110); - await new Promise((resolve) => nativeSetTimeout(resolve)); // To avoid mutating the state after unmount + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); // To avoid mutating the state after unmount }); it('should display a indicator while processing the props', async () => { @@ -223,7 +223,7 @@ describe(' - Edit Components', () => { expect(screen.queryByTestId('LoadIcon')).not.to.equal(null); clock.tick(500); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(screen.queryByTestId('LoadIcon')).to.equal(null); }); }); @@ -340,7 +340,7 @@ describe(' - Edit Components', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: '2022-02-10' } }); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(onValueChange.callCount).to.equal(1); expect((onValueChange.lastCall.args[1]! as Date).toISOString()).to.equal( @@ -548,14 +548,14 @@ describe(' - Edit Components', () => { expect(screen.queryAllByRole('option')[1]).to.have.text('adidas'); }); - it('should pass the value prop to the select', () => { + it('should pass the value prop to the select', async () => { render(); const cell = getCell(0, 0); fireEvent.doubleClick(cell); expect(cell.textContent!.replace(/[\W]+/, '')).to.equal('Nike'); // We use .replace to remove ​ - apiRef.current.setEditCellValue({ id: 0, field: 'brand', value: 'Adidas' }); + await act(() => apiRef.current.setEditCellValue({ id: 0, field: 'brand', value: 'Adidas' })); expect(cell.textContent!.replace(/[\W]+/, '')).to.equal('Adidas'); }); @@ -614,7 +614,7 @@ describe(' - Edit Components', () => { const input = cell.querySelector('input')!; fireEvent.click(input); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(onValueChange.callCount).to.equal(1); expect(onValueChange.lastCall.args[1]).to.equal(true); diff --git a/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.old.test.tsx b/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.old.test.tsx index 4daf3dae83a4..b927c6bbebb4 100644 --- a/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.old.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/editComponents.DataGridPro.old.test.tsx @@ -120,7 +120,11 @@ describe(' - Edit Components', () => { const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); - fireEvent.click(screen.queryAllByRole('option')[1]); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.click(screen.queryAllByRole('option')[1]); + }); await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -168,7 +172,11 @@ describe(' - Edit Components', () => { const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); - fireEvent.click(screen.queryAllByRole('option')[1]); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.click(screen.queryAllByRole('option')[1]); + }); await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -201,7 +209,11 @@ describe(' - Edit Components', () => { const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); - fireEvent.click(screen.queryAllByRole('option')[1]); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.click(screen.queryAllByRole('option')[1]); + }); await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -249,7 +261,11 @@ describe(' - Edit Components', () => { const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); - fireEvent.click(screen.queryAllByRole('option')[1]); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.click(screen.queryAllByRole('option')[1]); + }); await waitFor(() => { expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -341,7 +357,12 @@ describe(' - Edit Components', () => { fireEvent.keyDown(cell, { key: 'Enter' }); fireEvent.keyDown(screen.queryByRole('option', { name: 'Nike' }), { key: 'ArrowDown' }); - fireEvent.keyDown(screen.queryByRole('option', { name: 'Adidas' }), { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.keyDown(screen.queryByRole('option', { name: 'Adidas' }), { key: 'Enter' }); + }); + await waitFor(() => { expect(getCell(1, 0)).toHaveFocus(); }); @@ -396,7 +417,12 @@ describe(' - Edit Components', () => { fireEvent.doubleClick(cell); expect(cell).to.have.class('MuiDataGrid-cell--editing'); const option = screen.queryAllByRole('option')[1]; - fireClickEvent(option); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + fireClickEvent(option); + }); + await waitFor(() => { expect(cell.firstChild).to.have.class('Mui-error'); }); @@ -427,7 +453,12 @@ describe(' - Edit Components', () => { fireEvent.doubleClick(cell); const option = screen.queryByRole('option', { name: 'Adidas' }); fireEvent.mouseUp(option); - fireEvent.click(option); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.click(option); + }); + clock.tick(500); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -466,10 +497,14 @@ describe(' - Edit Components', () => { fireEvent.change(input, { target: { value: '1942' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).to.have.text('1,942'); - expect(apiRef.current.getRow(baselineProps.rows[0].id)!.year).to.equal(1942); + act(() => expect(apiRef.current.getRow(baselineProps.rows[0].id)!.year).to.equal(1942)); }); }); @@ -560,9 +595,7 @@ describe(' - Edit Components', () => { fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); const newValue = new Date(2021, 6, 4); - act(() => { - apiRef.current.setEditCellValue({ id: 0, field: 'date', value: newValue }); - }); + act(() => apiRef.current.setEditCellValue({ id: 0, field: 'date', value: newValue })); const input = cell.querySelector('input')!; await waitFor(() => { expect(input.value).to.equal('2021-07-04'); @@ -627,7 +660,11 @@ describe(' - Edit Components', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: '2022-01-12' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -702,9 +739,7 @@ describe(' - Edit Components', () => { fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); const newValue = new Date(2021, 6, 4, 17, 30); - act(() => { - apiRef.current.setEditCellValue({ id: 0, field: 'date', value: newValue }); - }); + act(() => apiRef.current.setEditCellValue({ id: 0, field: 'date', value: newValue })); const input = cell.querySelector('input')!; await waitFor(() => { expect(input.value).to.equal('2021-07-04T17:30'); @@ -798,7 +833,7 @@ describe(' - Edit Components', () => { }); describe('column type: boolean', () => { - it('should call onEditCellPropsChange with the correct params', () => { + it('should call onEditCellPropsChange with the correct params', async () => { const onEditCellPropsChange = spy(); render( - Edit Components', () => { fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); const input = cell.querySelector('input')!; - fireEvent.click(input); + + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + fireEvent.click(input); + }); + expect(onEditCellPropsChange.args[0][0]).to.deep.equal({ id: 0, field: 'isAdmin', @@ -852,7 +892,10 @@ describe(' - Edit Components', () => { fireEvent.click(input); fireEvent.doubleClick(getCell(1, 0)); - await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise + // Wrap in `act` to flush updates after the promise from the `onChange` callback has resolved + await act(async () => { + await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise + }); expect(preProcessEditCellProps.callCount).to.equal(1); expect(preProcessEditCellProps.lastCall.args[0].props).to.deep.equal({ diff --git a/packages/grid/x-data-grid-pro/src/tests/events.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/events.DataGridPro.test.tsx index 350e18764347..97f044617190 100644 --- a/packages/grid/x-data-grid-pro/src/tests/events.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/events.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, waitFor } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, waitFor, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { DataGridPro, @@ -225,10 +225,17 @@ describe(' - Events Params', () => { const cell = getCell(1, 1); fireEvent.doubleClick(cell); const input = cell.querySelector('input')!; + fireEvent.change(input, { target: { value: 'Lisa' } }); + clock.tick(500); expect(handleEditCellPropsChange.callCount).to.equal(1); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).to.have.text('Jack'); }); @@ -329,7 +336,7 @@ describe(' - Events Params', () => { it('publishing GRID_ROWS_SCROLL should call onRowsScrollEnd callback', () => { const handleRowsScrollEnd = spy(); render(); - apiRef.current.publishEvent('rowsScroll', { left: 0, top: 3 * 52 }); + act(() => apiRef.current.publishEvent('rowsScroll', { left: 0, top: 3 * 52 })); expect(handleRowsScrollEnd.callCount).to.equal(1); }); @@ -383,7 +390,7 @@ describe(' - Events Params', () => { const { unmount } = render(); - apiRef.current.subscribeEvent('unmount', onUnmount); + act(() => apiRef.current.subscribeEvent('unmount', onUnmount)); unmount(); expect(onUnmount.calledOnce).to.equal(true); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/export.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/export.DataGridPro.test.tsx index a62da3cb5188..9541c5b15daa 100644 --- a/packages/grid/x-data-grid-pro/src/tests/export.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/export.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import { GridColumns, useGridApiRef, DataGridPro, GridApi } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer } from '@mui/monorepo/test/utils'; +import { createRenderer, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import * as React from 'react'; @@ -51,12 +51,14 @@ describe(' - Export', () => { expect(apiRef.current.getDataAsCsv()).to.equal( ['id,Brand', '0,Nike', '1,Adidas', '2,Puma'].join('\r\n'), ); - apiRef.current.updateRows([ - { - id: 1, - brand: 'Adidas,Reebok', - }, - ]); + act(() => + apiRef.current.updateRows([ + { + id: 1, + brand: 'Adidas,Reebok', + }, + ]), + ); expect(apiRef.current.getDataAsCsv()).to.equal( ['id,Brand', '0,Nike', '1,"Adidas,Reebok"', '2,Puma'].join('\r\n'), ); diff --git a/packages/grid/x-data-grid-pro/src/tests/filterPanel.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/filterPanel.DataGridPro.test.tsx index e2b366084a58..7102ef025d61 100644 --- a/packages/grid/x-data-grid-pro/src/tests/filterPanel.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/filterPanel.DataGridPro.test.tsx @@ -8,7 +8,7 @@ import { useGridApiRef, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer } from '@mui/monorepo/test/utils'; +import { createRenderer, act } from '@mui/monorepo/test/utils'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -35,7 +35,7 @@ describe(' - Filter panel', () => { it('should add an id and operatorValue to the filter item created when opening the filter panel', () => { render(); - apiRef.current.showFilterPanel('brand'); + act(() => apiRef.current.showFilterPanel('brand')); const model = gridFilterModelSelector(apiRef); expect(model.items).to.have.length(1); expect(model.items[0].id).to.not.equal(null); diff --git a/packages/grid/x-data-grid-pro/src/tests/filtering.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/filtering.DataGridPro.test.tsx index cb0ece8e1ae2..5a1065417240 100644 --- a/packages/grid/x-data-grid-pro/src/tests/filtering.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/filtering.DataGridPro.test.tsx @@ -11,7 +11,7 @@ import { DataGridPro, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import * as React from 'react'; import { spy } from 'sinon'; @@ -92,28 +92,30 @@ describe(' - Filter', () => { brand: 'Hugo', }, ]; - apiRef.current.setRows(newRows); + act(() => apiRef.current.setRows(newRows)); expect(getColumnValues(0)).to.deep.equal(['Asics']); }); it('should apply the filterModel prop correctly on GridApiRef update row data', () => { render(); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); - apiRef.current.updateRows([{ id: 0, brand: 'Patagonia' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); + act(() => apiRef.current.updateRows([{ id: 0, brand: 'Patagonia' }])); expect(getColumnValues(0)).to.deep.equal(['Patagonia', 'Fila', 'Puma']); }); it('should allow apiRef to setFilterModel', () => { render(); - apiRef.current.setFilterModel({ - items: [ - { - columnField: 'brand', - value: 'a', - operatorValue: 'startsWith', - }, - ], - }); + act(() => + apiRef.current.setFilterModel({ + items: [ + { + columnField: 'brand', + value: 'a', + operatorValue: 'startsWith', + }, + ], + }), + ); expect(getColumnValues(0)).to.deep.equal(['Adidas']); }); @@ -156,7 +158,7 @@ describe(' - Filter', () => { }, ], }; - apiRef.current.setFilterModel(newModel); + act(() => apiRef.current.setFilterModel(newModel)); expect(getColumnValues(0)).to.deep.equal(['Adidas']); }); @@ -434,14 +436,14 @@ describe(' - Filter', () => { screen.getByRole('grid').scrollIntoView(); const initialScrollPosition = window.scrollY; expect(initialScrollPosition).not.to.equal(0); - apiRef.current.hidePreferences(); + act(() => apiRef.current.hidePreferences()); clock.tick(100); - apiRef.current.showPreferences(GridPreferencePanelsValue.filters); + act(() => apiRef.current.showPreferences(GridPreferencePanelsValue.filters)); expect(window.scrollY).to.equal(initialScrollPosition); }); describe('Server', () => { - it('should refresh the filter panel when adding filters', () => { + it('should refresh the filter panel when adding filters', async () => { function loadServerRows(commodityFilterValue: string | undefined) { const serverRows = [ { id: '1', commodity: 'rice' }, @@ -510,7 +512,11 @@ describe(' - Filter', () => { ); } - render(); + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + render(); + }); + const addButton = screen.getByRole('button', { name: /Add Filter/i }); fireEvent.click(addButton); const filterForms = document.querySelectorAll(`.MuiDataGrid-filterForm`); diff --git a/packages/grid/x-data-grid-pro/src/tests/layout.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/layout.DataGridPro.test.tsx index 6c2c146d02c1..0984bdaca585 100644 --- a/packages/grid/x-data-grid-pro/src/tests/layout.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/layout.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, screen, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { createTheme, ThemeProvider } from '@mui/material/styles'; import { GridApi, useGridApiRef, DataGridPro, ptBR, DataGridProProps } from '@mui/x-data-grid-pro'; @@ -127,7 +127,7 @@ describe(' - Layout', () => { width: '198px', // because of the 2px border }); - apiRef!.current.setColumnVisibility('age', true); + act(() => apiRef!.current.setColumnVisibility('age', true)); firstColumn = document.querySelector('[role="columnheader"][aria-colindex="1"]'); expect(firstColumn).toHaveInlineStyle({ width: '148px', // because of the 2px border @@ -186,7 +186,7 @@ describe(' - Layout', () => { width: '198px', // because of the 2px border }); - apiRef!.current.setColumnVisibility('age', true); + act(() => apiRef!.current.setColumnVisibility('age', true)); firstColumn = document.querySelector('[role="columnheader"][aria-colindex="1"]'); expect(firstColumn).toHaveInlineStyle({ width: '148px', // because of the 2px border diff --git a/packages/grid/x-data-grid-pro/src/tests/printExport.DataGrid.test.tsx b/packages/grid/x-data-grid-pro/src/tests/printExport.DataGrid.test.tsx index 6fd5d5f6ce7f..60dd7acc05f0 100644 --- a/packages/grid/x-data-grid-pro/src/tests/printExport.DataGrid.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/printExport.DataGrid.test.tsx @@ -7,13 +7,13 @@ import { DataGridProProps, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, screen, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, screen, fireEvent, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { getData } from 'storybook/src/data/data-service'; describe(' - Print export', () => { - const { render } = createRenderer(); + const { render, clock } = createRenderer(); const NB_ROWS = 2; const defaultData = getData(NB_ROWS, 2); @@ -55,11 +55,12 @@ describe(' - Print export', () => { ]; describe('Export toolbar', () => { + clock.withFakeTimers(); + it('should display print button by default', () => { render(); fireEvent.click(screen.queryByRole('button', { name: 'Export' })); expect(screen.queryByRole('menu')).not.to.equal(null); - expect(screen.queryByRole('menuitem', { name: 'Print' })).not.to.equal(null); }); @@ -71,7 +72,6 @@ describe(' - Print export', () => { />, ); fireEvent.click(screen.queryByRole('button', { name: 'Export' })); - expect(screen.queryByRole('menu')).not.to.equal(null); expect(screen.queryByRole('menuitem', { name: 'Print' })).to.equal(null); }); @@ -100,9 +100,11 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ - fields: printVisible ? ['currencyPair', 'id'] : ['id'], - }); + await act(() => + apiRef.current.exportDataAsPrint({ + fields: printVisible ? ['currencyPair', 'id'] : ['id'], + }), + ); expect(onColumnVisibilityModelChange.callCount).to.equal(2); // verify column visibility has been set @@ -139,9 +141,11 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ - fields: printVisible ? ['currencyPair', 'id'] : ['id'], - }); + await act(() => + apiRef.current.exportDataAsPrint({ + fields: printVisible ? ['currencyPair', 'id'] : ['id'], + }), + ); expect(onColumnVisibilityModelChange.callCount).to.equal(2); @@ -168,7 +172,7 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ fields: ['id'], allColumns: true }); + await act(() => apiRef.current.exportDataAsPrint({ fields: ['id'], allColumns: true })); expect(onColumnVisibilityModelChange.firstCall.firstArg).to.deep.equal({ currencyPair: false, @@ -188,7 +192,7 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ fields: ['id'], allColumns: true }); + await act(() => apiRef.current.exportDataAsPrint({ fields: ['id'], allColumns: true })); expect(onColumnVisibilityModelChange.firstCall.firstArg).to.deep.equal({ currencyPair: false, @@ -208,7 +212,7 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ allColumns: true }); + await act(() => apiRef.current.exportDataAsPrint({ allColumns: true })); expect(onColumnVisibilityModelChange.firstCall.firstArg).to.deep.equal({ currencyPair: true, @@ -228,7 +232,7 @@ describe(' - Print export', () => { expect(onColumnVisibilityModelChange.callCount).to.equal(0); - await apiRef.current.exportDataAsPrint({ allColumns: true }); + await act(() => apiRef.current.exportDataAsPrint({ allColumns: true })); expect(onColumnVisibilityModelChange.firstCall.firstArg).to.deep.equal({ currencyPair: true, diff --git a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx index f1934eb6ed35..e7a81dca5351 100644 --- a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.new.test.tsx @@ -93,9 +93,9 @@ describe(' - Row Editing', () => { it('should throw when the row is already in edit mode', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - expect(() => { - apiRef.current.startRowEditMode({ id: 0 }); - }).to.throw('MUI: The row with id=0 is not in view mode.'); + expect(() => act(() => apiRef.current.startRowEditMode({ id: 0 }))).to.throw( + 'MUI: The row with id=0 is not in view mode.', + ); }); it('should update the CSS class of all editable cells', () => { @@ -153,7 +153,9 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(renderEditCell1.lastCall.args[0].value).to.equal('USDGBP'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'usdgbp' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'usdgbp' }), + ); expect(renderEditCell1.lastCall.args[0].value).to.equal('usdgbp'); }); @@ -165,8 +167,10 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(renderEditCell1.lastCall.args[0].row).to.deep.equal(defaultData.rows[0]); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: ' usdgbp ' }); - await apiRef.current.setEditCellValue({ id: 0, field: 'price1M', value: 100 }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: ' usdgbp ' }), + ); + await act(() => apiRef.current.setEditCellValue({ id: 0, field: 'price1M', value: 100 })); expect(renderEditCell1.lastCall.args[0].row).to.deep.equal({ ...defaultData.rows[0], currencyPair: 'usdgbp', @@ -179,7 +183,9 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(column1Props.valueParser.callCount).to.equal(0); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); expect(column1Props.valueParser.callCount).to.equal(1); expect(renderEditCell1.lastCall.args[0].value).to.equal('usd gbp'); }); @@ -188,17 +194,23 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect( - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ), ).to.equal(true); }); it('should set isProcessingProps to true before calling preProcessEditCellProps', async () => { - column1Props.preProcessEditCellProps = spy( - ({ props }: GridPreProcessEditCellProps) => props, - ); + column1Props.preProcessEditCellProps = () => new Promise(() => {}); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act( + () => + new Promise((resolve) => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + resolve(); + }), + ); expect(renderEditCell1.lastCall.args[0].isProcessingProps).to.equal(true); }); @@ -211,7 +223,9 @@ describe(' - Row Editing', () => { ); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); const args1 = column1Props.preProcessEditCellProps.lastCall.args[0]; expect(args1.id).to.equal(0); @@ -242,7 +256,9 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(renderEditCell1.lastCall.args[0].foo).to.equal(undefined); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); expect(renderEditCell1.lastCall.args[0].foo).to.equal('bar'); }); @@ -254,26 +270,45 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(renderEditCell1.lastCall.args[0].value).to.equal('USDGBP'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); expect(renderEditCell1.lastCall.args[0].value).to.equal('USD GBP'); }); it('should set isProcessingProps to false after calling preProcessEditCellProps', async () => { - column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => props; - column2Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => props; + let resolve1: () => void; + let resolve2: () => void; + column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => + new Promise((resolve) => { + resolve1 = () => resolve(props); + }); + column2Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => + new Promise((resolve) => { + resolve2 = () => resolve(props); + }); + render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - const promise = apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - }) as Promise; + let promise: Promise; + await act( + () => + new Promise((resolve) => { + promise = apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }) as Promise; + resolve(); + }), + ); expect(renderEditCell1.lastCall.args[0].isProcessingProps).to.equal(true); expect(renderEditCell2.lastCall.args[0].isProcessingProps).to.equal(true); - return promise.then(() => { - expect(renderEditCell1.lastCall.args[0].isProcessingProps).to.equal(false); - expect(renderEditCell2.lastCall.args[0].isProcessingProps).to.equal(false); - }); + resolve1!(); + resolve2!(); + await act(() => promise); + expect(renderEditCell1.lastCall.args[0].isProcessingProps).to.equal(false); + expect(renderEditCell2.lastCall.args[0].isProcessingProps).to.equal(false); }); it('should return false if preProcessEditCellProps sets an error', async () => { @@ -284,33 +319,47 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect( - await apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - }), + await act(() => + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }), + ), ).to.equal(false); }); - it('should return false if the cell left the edit mode while calling preProcessEditCellProps', async () => { + it('should return false if the cell left the edit mode while calling preProcessEditCellProps', (done) => { + let resolveCallback: () => void; column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => new Promise((resolve) => { - // Simulates the user cancelling the editing while processing the props - apiRef.current.stopRowEditMode({ - id: 0, - ignoreModifications: true, - }); - resolve(props); + resolveCallback = () => resolve(props); }); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - expect( - await apiRef.current.setEditCellValue({ + + let promise: Promise; + act(() => { + promise = apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP', + }) as Promise; + }); + + promise!.then((result) => { + expect(result).to.equal(false); + done(); + }); + + act(() => + apiRef.current.stopRowEditMode({ + id: 0, + ignoreModifications: true, }), - ).to.equal(false); + ); + + resolveCallback!(); }); describe('with debounceMs > 0', () => { @@ -321,18 +370,22 @@ describe(' - Row Editing', () => { act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(renderEditCell1.lastCall.args[0].value).to.equal('USDGBP'); renderEditCell1.resetHistory(); - apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD', - debounceMs: 100, + act(() => { + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD', + debounceMs: 100, + }); }); expect(renderEditCell1.callCount).to.equal(0); - apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - debounceMs: 100, + act(() => { + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + debounceMs: 100, + }); }); expect(renderEditCell1.callCount).to.equal(0); clock.tick(100); @@ -353,7 +406,9 @@ describe(' - Row Editing', () => { it('should update the row with the new value stored', async () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); expect(getCell(0, 1).textContent).to.equal('USD GBP'); }); @@ -361,22 +416,40 @@ describe(' - Row Editing', () => { it('should not update the row if ignoreModifications=true', async () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0, ignoreModifications: true })); expect(getCell(0, 1).textContent).to.equal('USDGBP'); }); it('should do nothing if props are still being processed and ignoreModifications=false', async () => { + let resolveCallback: () => void; column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => new Promise((resolve) => { - // Simulates the user stopping the editing while processing the props - act(() => apiRef.current.stopRowEditMode({ id: 0 })); - resolve(props); + resolveCallback = () => resolve(props); }); + render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + + let promise: Promise; + act(() => { + promise = apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + }) as Promise; + }); + + // Simulates the user stopping the editing while processing the props + act(() => apiRef.current.stopRowEditMode({ id: 0 })); + expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); + + resolveCallback!(); + + await act(() => promise); // Run all updates scheduled for when preProcessEditCellProps resolves }); it('should do nothing if props of any column contain error=true', async () => { @@ -386,7 +459,9 @@ describe(' - Row Editing', () => { }); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); }); @@ -399,11 +474,15 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: '' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: '' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); expect(getCell(0, 1).className).not.to.contain('MuiDataGrid-cell--editing'); }); @@ -412,7 +491,9 @@ describe(' - Row Editing', () => { render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); expect(getCell(0, 1).className).to.contain('MuiDataGrid-cell--editing'); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); expect(getCell(0, 1).className).not.to.contain('MuiDataGrid-cell--editing'); }); @@ -421,9 +502,11 @@ describe(' - Row Editing', () => { const processRowUpdate = spy((row) => ({ ...row, currencyPair: 'USD-GBP' })); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); - await new Promise((resolve) => nativeSetTimeout(resolve)); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(processRowUpdate.callCount).to.equal(1); expect(getCell(0, 1).textContent).to.equal('USD-GBP'); }); @@ -432,8 +515,11 @@ describe(' - Row Editing', () => { const processRowUpdate = spy((newRow, oldRow) => ({ ...oldRow, ...newRow })); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(processRowUpdate.lastCall.args[0]).to.deep.equal({ ...defaultData.rows[0], currencyPair: 'USD GBP', @@ -494,8 +580,11 @@ describe(' - Row Editing', () => { const processRowUpdate = spy((newRow) => newRow); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); act(() => apiRef.current.stopRowEditMode({ id: 0 })); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(processRowUpdate.lastCall.args[0]).to.deep.equal({ ...defaultData.rows[0], currencyPair: 'USDGBP', @@ -558,13 +647,16 @@ describe(' - Row Editing', () => { const processRowUpdate = spy((newRow) => newRow); render(); act(() => apiRef.current.startRowEditMode({ id: 0 })); - apiRef.current.setEditCellValue({ - id: 0, - field: 'currencyPair', - value: 'USD GBP', - debounceMs: 100, + await act(() => { + apiRef.current.setEditCellValue({ + id: 0, + field: 'currencyPair', + value: 'USD GBP', + debounceMs: 100, + }); }); act(() => apiRef.current.stopRowEditMode({ id: 0 })); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(renderEditCell1.lastCall.args[0].value).to.equal('USD GBP'); expect(processRowUpdate.lastCall.args[0].currencyPair).to.equal('USD GBP'); }); @@ -826,13 +918,14 @@ describe(' - Row Editing', () => { }); }); - it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', () => { - column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', async () => { + column1Props.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopRowEditMode = spy(apiRef.current, 'stopRowEditMode'); fireEvent.doubleClick(getCell(0, 1)); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + act(() => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + }); fireEvent.click(getCell(1, 1)); clock.runToLast(); expect(spiedStopRowEditMode.callCount).to.equal(1); @@ -903,16 +996,17 @@ describe(' - Row Editing', () => { }); }); - it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', () => { - column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', async () => { + column1Props.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopRowEditMode = spy(apiRef.current, 'stopRowEditMode'); const cell = getCell(0, 1); fireEvent.mouseUp(cell); fireEvent.click(cell); fireEvent.doubleClick(cell); - apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + act(() => { + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + }); fireEvent.keyDown(cell.querySelector('input'), { key: 'Enter' }); expect(spiedStopRowEditMode.callCount).to.equal(1); expect(spiedStopRowEditMode.lastCall.args[0].ignoreModifications).to.equal(true); @@ -980,16 +1074,17 @@ describe(' - Row Editing', () => { }); }); - it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', () => { - column1Props.preProcessEditCellProps = ({ props }: GridPreProcessEditCellProps) => - new Promise((resolve) => resolve(props)); + it('should call stopRowEditMode with ignoreModifications=true if the props are being processed', async () => { + column1Props.preProcessEditCellProps = () => new Promise(() => {}); render(); const spiedStopRowEditMode = spy(apiRef.current, 'stopRowEditMode'); const cell = getCell(0, 2); fireEvent.mouseUp(cell); fireEvent.click(cell); fireEvent.doubleClick(cell); - apiRef.current.setEditCellValue({ id: 0, field: 'price1M', value: 'USD GBP' }); + await act(() => { + apiRef.current.setEditCellValue({ id: 0, field: 'price1M', value: 'USD GBP' }); + }); fireEvent.keyDown(cell.querySelector('input'), { key: 'Tab' }); expect(spiedStopRowEditMode.callCount).to.equal(1); expect(spiedStopRowEditMode.lastCall.args[0].ignoreModifications).to.equal(true); @@ -1055,7 +1150,9 @@ describe(' - Row Editing', () => { const { setProps } = render( , ); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); setProps({ rowModesModel: { 0: { mode: GridRowModes.View, ignoreModifications: true } } }); expect(getCell(0, 1).textContent).to.equal('USDGBP'); }); @@ -1064,7 +1161,9 @@ describe(' - Row Editing', () => { const { setProps } = render( , ); - await apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }); + await act(() => + apiRef.current.setEditCellValue({ id: 0, field: 'currencyPair', value: 'USD GBP' }), + ); setProps({ rowModesModel: { 0: { mode: GridRowModes.View, cellToFocusAfter: 'below', field: 'currencyPair' }, @@ -1077,7 +1176,7 @@ describe(' - Row Editing', () => { it(`should publish 'rowModesModelChange' when the model changes`, () => { render(); const listener = spy(); - apiRef.current.subscribeEvent('rowModesModelChange', listener); + act(() => apiRef.current.subscribeEvent('rowModesModelChange', listener)); const cell = getCell(0, 1); fireEvent.doubleClick(cell); expect(listener.lastCall.args[0]).to.deep.equal({ @@ -1089,7 +1188,7 @@ describe(' - Row Editing', () => { const { setProps } = render(); const listener = spy(); expect(listener.callCount).to.equal(0); - apiRef.current.subscribeEvent('rowModesModelChange', listener); + act(() => apiRef.current.subscribeEvent('rowModesModelChange', listener)); setProps({ rowModesModel: { 0: { currencyPair: { mode: 'edit' } } } }); expect(listener.lastCall.args[0]).to.deep.equal({ 0: { currencyPair: { mode: 'edit' } }, @@ -1099,7 +1198,7 @@ describe(' - Row Editing', () => { it(`should not publish 'rowModesModelChange' when the model changes and rowModesModel is set`, () => { render(); const listener = spy(); - apiRef.current.subscribeEvent('rowModesModelChange', listener); + act(() => apiRef.current.subscribeEvent('rowModesModelChange', listener)); const cell = getCell(0, 1); fireEvent.doubleClick(cell); expect(listener.callCount).to.equal(0); diff --git a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx index 1e80994d7cb4..17020ae4099a 100644 --- a/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/rowEditing.DataGridPro.old.test.tsx @@ -7,7 +7,7 @@ import { GridColDef, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, waitFor } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, waitFor, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { getCell, getRow } from 'test/utils/helperFn'; import { spy } from 'sinon'; @@ -126,7 +126,12 @@ describe(' - Row Editing', () => { fireEvent.change(input, { target: { value: 'ADIDAS' } }); clock.tick(500); expect(input!.value).to.equal('ADIDAS'); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(cell).to.have.text('ADIDAS'); }); @@ -139,7 +144,12 @@ describe(' - Row Editing', () => { const input = cell.querySelector('input'); fireEvent.change(input, { target: { value: 'ADIDAS' } }); expect(input!.value).to.equal('ADIDAS'); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await waitFor(() => { expect(getCell(2, 0)).toHaveFocus(); }); @@ -153,8 +163,14 @@ describe(' - Row Editing', () => { fireEvent.change(input, { target: { value: 'ADIDAS' } }); clock.tick(500); expect(input!.value).to.equal('ADIDAS'); - fireClickEvent(getCell(2, 0)); - clock.tick(0); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireClickEvent(getCell(2, 0)); + }); + + await act(async () => clock.tick(0)); + await waitFor(() => { // Wait for promise expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -169,7 +185,7 @@ describe(' - Row Editing', () => { expect(getCell(1, 0).querySelector('input')).toHaveFocus(); }); - it('should call the valueSetter on each column', () => { + it('should call the valueSetter on each column', async () => { const valueSetter = spy(({ row }) => row); render( - Row Editing', () => { const input = firstCell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Peter Smith' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + expect(valueSetter.callCount).to.equal(1); expect(valueSetter.lastCall.args[0]).to.deep.equal({ row: { id: 0, firstName: 'John', lastName: 'Doe' }, @@ -230,8 +251,14 @@ describe(' - Row Editing', () => { fireEvent.doubleClick(firstCell); const secondInput = secondCell.querySelector('input'); const firstInput = firstCell.querySelector('input'); - fireEvent.change(firstInput, { target: { value: 'ADIDAS' } }); - clock.tick(500); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.change(firstInput, { target: { value: 'ADIDAS' } }); + }); + + await act(async () => clock.tick(500)); + await waitFor(() => { expect(firstInput).to.have.attribute('aria-invalid', 'true'); expect(secondInput).to.have.attribute('aria-invalid', 'true'); @@ -255,8 +282,14 @@ describe(' - Row Editing', () => { fireEvent.doubleClick(firstCell); const firstInput = firstCell.querySelector('input'); const secondInput = secondCell.querySelector('input'); - fireEvent.change(firstInput, { target: { value: 'ADIDAS' } }); - clock.tick(500); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.change(firstInput, { target: { value: 'ADIDAS' } }); + }); + + await act(async () => clock.tick(500)); + await waitFor(() => { expect(firstInput).to.have.attribute('aria-invalid', 'true'); expect(secondInput).to.have.attribute('aria-invalid', 'true'); @@ -281,11 +314,22 @@ describe(' - Row Editing', () => { fireEvent.mouseUp(cell); fireEvent.doubleClick(cell); const input = cell.querySelector('input')!; - fireEvent.change(input, { target: { value: 'Adidas' } }); - clock.runToLast(); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.change(input, { target: { value: 'Adidas' } }); + }); + + await act(async () => clock.runToLast()); + await new Promise((resolve) => nativeSetTimeout(resolve)); expect(apiRef.current.getEditRowsModel()[0].brand.value).to.equal('Adidas'); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); + await new Promise((resolve) => nativeSetTimeout(resolve)); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); expect(cell).to.have.text('Adidas'); @@ -322,7 +366,11 @@ describe(' - Row Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -367,7 +415,11 @@ describe(' - Row Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -409,7 +461,11 @@ describe(' - Row Editing', () => { const input = cell.querySelector('input')!; fireEvent.change(input, { target: { value: 'Adidas' } }); clock.tick(500); - fireEvent.keyDown(input, { key: 'Enter' }); + + // Wrap in `act` to flush updates after the promise has resolved + await act(async () => { + fireEvent.keyDown(input, { key: 'Enter' }); + }); await new Promise((resolve) => nativeSetTimeout(resolve)); // Wait for promise @@ -448,7 +504,7 @@ describe(' - Row Editing', () => { expect(getRow(1)).not.to.have.class('MuiDataGrid-row--editing'); }); - it(`should ignore keydown event until the IME is confirmed`, () => { + it(`should ignore keydown event until the IME is confirmed`, async () => { const valueSetter = spy(({ row }) => row); render( - Row Editing', () => { fireEvent.keyDown(input, { key: 'Enter', keyCode: 229 }); expect(valueSetter.callCount).to.equal(0); fireEvent.keyDown(input, { key: 'Enter', keyCode: 13 }); + await act(() => new Promise((resolve) => nativeSetTimeout(resolve))); expect(valueSetter.callCount).to.equal(1); expect(input!.value).to.equal('あ'); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx index 7bfc1c598258..1fc840328334 100644 --- a/packages/grid/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, act } from '@mui/monorepo/test/utils'; import { spy } from 'sinon'; import { expect } from 'chai'; import { @@ -79,13 +79,13 @@ describe(' - Rows', () => { ); }; render(); - apiRef!.current.setCellMode('c2', 'first', 'edit'); + act(() => apiRef!.current.setCellMode('c2', 'first', 'edit')); const cell = getCell(1, 1); expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).to.have.class('MuiDataGrid-cell--editing'); expect(cell.querySelector('input')!.value).to.equal('Jack'); - apiRef!.current.setCellMode('c2', 'first', 'view'); + act(() => apiRef!.current.setCellMode('c2', 'first', 'view')); expect(cell).to.have.class('MuiDataGrid-cell--editable'); expect(cell).not.to.have.class('MuiDataGrid-cell--editing'); @@ -168,14 +168,14 @@ describe(' - Rows', () => { it('should not throttle by default', () => { render(); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Fila', 'Puma']); }); it('should allow to enable throttle', () => { render(); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); clock.tick(50); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); clock.tick(50); @@ -184,49 +184,53 @@ describe(' - Rows', () => { it('should allow to update row data', () => { render(); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); - apiRef.current.updateRows([{ id: 0, brand: 'Pata' }]); - apiRef.current.updateRows([{ id: 2, brand: 'Pum' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); + act(() => apiRef.current.updateRows([{ id: 0, brand: 'Pata' }])); + act(() => apiRef.current.updateRows([{ id: 2, brand: 'Pum' }])); expect(getColumnValues(0)).to.deep.equal(['Pata', 'Fila', 'Pum']); }); it('update row data can also add rows', () => { render(); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); - apiRef.current.updateRows([{ id: 0, brand: 'Pata' }]); - apiRef.current.updateRows([{ id: 2, brand: 'Pum' }]); - apiRef.current.updateRows([{ id: 3, brand: 'Jordan' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); + act(() => apiRef.current.updateRows([{ id: 0, brand: 'Pata' }])); + act(() => apiRef.current.updateRows([{ id: 2, brand: 'Pum' }])); + act(() => apiRef.current.updateRows([{ id: 3, brand: 'Jordan' }])); expect(getColumnValues(0)).to.deep.equal(['Pata', 'Fila', 'Pum', 'Jordan']); }); it('update row data can also add rows in bulk', () => { render(); - apiRef.current.updateRows([ - { id: 1, brand: 'Fila' }, - { id: 0, brand: 'Pata' }, - { id: 2, brand: 'Pum' }, - { id: 3, brand: 'Jordan' }, - ]); + act(() => + apiRef.current.updateRows([ + { id: 1, brand: 'Fila' }, + { id: 0, brand: 'Pata' }, + { id: 2, brand: 'Pum' }, + { id: 3, brand: 'Jordan' }, + ]), + ); expect(getColumnValues(0)).to.deep.equal(['Pata', 'Fila', 'Pum', 'Jordan']); }); it('update row data can also delete rows', () => { render(); - apiRef.current.updateRows([{ id: 1, _action: 'delete' }]); - apiRef.current.updateRows([{ id: 0, brand: 'Apple' }]); - apiRef.current.updateRows([{ id: 2, _action: 'delete' }]); - apiRef.current.updateRows([{ id: 5, brand: 'Atari' }]); + act(() => apiRef.current.updateRows([{ id: 1, _action: 'delete' }])); + act(() => apiRef.current.updateRows([{ id: 0, brand: 'Apple' }])); + act(() => apiRef.current.updateRows([{ id: 2, _action: 'delete' }])); + act(() => apiRef.current.updateRows([{ id: 5, brand: 'Atari' }])); expect(getColumnValues(0)).to.deep.equal(['Apple', 'Atari']); }); it('update row data can also delete rows in bulk', () => { render(); - apiRef.current.updateRows([ - { id: 1, _action: 'delete' }, - { id: 0, brand: 'Apple' }, - { id: 2, _action: 'delete' }, - { id: 5, brand: 'Atari' }, - ]); + act(() => + apiRef.current.updateRows([ + { id: 1, _action: 'delete' }, + { id: 0, brand: 'Apple' }, + { id: 2, _action: 'delete' }, + { id: 5, brand: 'Atari' }, + ]), + ); expect(getColumnValues(0)).to.deep.equal(['Apple', 'Atari']); }); @@ -248,33 +252,16 @@ describe(' - Rows', () => { render(); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); - apiRef.current.updateRows([ - { idField: 1, _action: 'delete' }, - { idField: 0, brand: 'Apple' }, - { idField: 2, _action: 'delete' }, - { idField: 5, brand: 'Atari' }, - ]); + act(() => + apiRef.current.updateRows([ + { idField: 1, _action: 'delete' }, + { idField: 0, brand: 'Apple' }, + { idField: 2, _action: 'delete' }, + { idField: 5, brand: 'Atari' }, + ]), + ); expect(getColumnValues(0)).to.deep.equal(['Apple', 'Atari']); }); - - it('should not loose partial updates after a props.loading switch', () => { - const Test = (props: Partial) => { - apiRef = useGridApiRef(); - return ( -
- -
- ); - }; - - const { setProps } = render(); - expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); - - setProps({ loading: true }); - apiRef.current.updateRows([{ id: 0, brand: 'Nike 2' }]); - setProps({ loading: false }); - expect(getColumnValues(0)).to.deep.equal(['Nike 2', 'Adidas', 'Puma']); - }); }); describe('apiRef: setRows', () => { @@ -319,7 +306,7 @@ describe(' - Rows', () => { brand: 'Asics', }, ]; - apiRef.current.setRows(newRows); + act(() => apiRef.current.setRows(newRows)); expect(getColumnValues(0)).to.deep.equal(['Asics']); }); @@ -333,7 +320,7 @@ describe(' - Rows', () => { brand: 'Asics', }, ]; - apiRef.current.setRows(newRows); + act(() => apiRef.current.setRows(newRows)); clock.tick(50); expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']); @@ -390,7 +377,7 @@ describe(' - Rows', () => { '.MuiDataGrid-virtualScrollerRenderZone', )!; virtualScroller.scrollTop = 10e6; // scroll to the bottom - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); const lastCell = document.querySelector('[role="row"]:last-child [role="cell"]:first-child')!; expect(lastCell).to.have.text('995'); @@ -424,7 +411,7 @@ describe(' - Rows', () => { expect(firstRow.children).to.have.length(Math.floor(width / columnWidth) + columnBuffer); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; virtualScroller.scrollLeft = 301; - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); expect(firstRow.children).to.have.length( columnBuffer + Math.floor(width / columnWidth) + columnBuffer, ); @@ -441,7 +428,7 @@ describe(' - Rows', () => { let firstRow = renderingZone.firstChild; expect(firstRow).to.have.attr('data-rowindex', '0'); virtualScroller.scrollTop = rowThreshold * rowHeight; - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); firstRow = renderingZone.firstChild; expect(firstRow).to.have.attr('data-rowindex', '3'); }); @@ -458,7 +445,7 @@ describe(' - Rows', () => { let firstColumn = firstRow.firstChild!; expect(firstColumn).to.have.attr('data-colindex', '0'); virtualScroller.scrollLeft = columnThreshold * columnWidth; - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); firstRow = renderingZone.querySelector('[role="row"]:first-child')!; firstColumn = firstRow.firstChild!; expect(firstColumn).to.have.attr('data-colindex', '3'); @@ -478,7 +465,7 @@ describe(' - Rows', () => { ); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; virtualScroller.scrollTop = 10e6; // scroll to the bottom - virtualScroller.dispatchEvent(new Event('scroll')); + act(() => virtualScroller.dispatchEvent(new Event('scroll'))); const lastCell = document.querySelector( '[role="row"]:last-child [role="cell"]:first-child', @@ -549,7 +536,7 @@ describe(' - Rows', () => { />, ); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; - apiRef.current.scrollToIndexes({ rowIndex: 4, colIndex: 0 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 4, colIndex: 0 })); expect(virtualScroller.scrollTop).to.equal(rowHeight - offset); }); @@ -570,11 +557,11 @@ describe(' - Rows', () => { const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; virtualScroller.scrollTop = offset; virtualScroller.dispatchEvent(new Event('scroll')); // Simulate browser behavior - apiRef.current.scrollToIndexes({ rowIndex: 2, colIndex: 0 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 2, colIndex: 0 })); expect(virtualScroller.scrollTop).to.equal(offset); - apiRef.current.scrollToIndexes({ rowIndex: 1, colIndex: 0 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 1, colIndex: 0 })); expect(virtualScroller.scrollTop).to.equal(offset); - apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 0 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 0 })); expect(virtualScroller.scrollTop).to.equal(0); }); @@ -592,7 +579,7 @@ describe(' - Rows', () => { render(); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; expect(virtualScroller.scrollLeft).to.equal(0); - apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 2 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 2 })); expect(virtualScroller.scrollLeft).to.equal(columnWidth * 3 - width); }); @@ -610,10 +597,10 @@ describe(' - Rows', () => { render(); const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!; expect(virtualScroller.scrollLeft).to.equal(0); - apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 2 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 2 })); virtualScroller.dispatchEvent(new Event('scroll')); // Simulate browser behavior expect(virtualScroller.scrollLeft).to.equal(columnWidth * 3 - width); - apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 1 }); + act(() => apiRef.current.scrollToIndexes({ rowIndex: 0, colIndex: 1 })); expect(virtualScroller.scrollLeft).to.equal(columnWidth * 3 - width); }); }); @@ -647,7 +634,7 @@ describe(' - Rows', () => { it('should render the correct rows when changing pages', () => { render(); expect(document.querySelectorAll('[role="row"][data-rowindex]')).to.have.length(6); - apiRef.current.setPage(1); + act(() => apiRef.current.setPage(1)); expect(document.querySelectorAll('[role="row"][data-rowindex]')).to.have.length(4); }); }); @@ -789,6 +776,7 @@ describe(' - Rows', () => { const cell = getCell(0, 0); fireEvent.mouseUp(cell); fireEvent.click(cell); + act(() => apiRef.current.updateRows([{ id: 1, _action: 'delete' }])); }).not.to.throw(); }); @@ -797,7 +785,7 @@ describe(' - Rows', () => { render(); const cell = getCell(0, 0); fireEvent.mouseEnter(cell); - apiRef.current.updateRows([{ id: 1, _action: 'delete' }]); + act(() => apiRef.current.updateRows([{ id: 1, _action: 'delete' }])); fireEvent.mouseLeave(cell); }).not.to.throw(); }); @@ -850,7 +838,7 @@ describe(' - Rows', () => { expect(getRow(1).clientHeight).to.equal(ROW_HEIGHT); - apiRef.current.unstable_setRowHeight(resizedRowId, 100); + act(() => apiRef.current.unstable_setRowHeight(resizedRowId, 100)); expect(getRow(resizedRowId).clientHeight).to.equal(100); }); @@ -863,7 +851,7 @@ describe(' - Rows', () => { expect(row.clientHeight).to.equal(ROW_HEIGHT); getRowHeight.resetHistory(); - apiRef.current.unstable_setRowHeight(resizedRowId, 100); + act(() => apiRef.current.unstable_setRowHeight(resizedRowId, 100)); expect(row.clientHeight).to.equal(100); // sort diff --git a/packages/grid/x-data-grid-pro/src/tests/selection.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/selection.DataGridPro.test.tsx index c2688a60ebaa..1f442abfa88f 100644 --- a/packages/grid/x-data-grid-pro/src/tests/selection.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/selection.DataGridPro.test.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { getCell, getColumnValues, getRows } from 'test/utils/helperFn'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import { GridApi, useGridApiRef, @@ -211,7 +211,7 @@ describe(' - Selection', () => { />, ); expect(apiRef.current.getSelectedRows()).to.have.length(0); - apiRef.current.selectRow(1); + act(() => apiRef.current.selectRow(1)); expect(apiRef.current.getSelectedRows().get(1)).to.deep.equal({ id: 1, currencyPair: 'USDEUR', @@ -241,15 +241,15 @@ describe(' - Selection', () => { it('should call onSelectionModelChange with the ids selected', () => { const handleSelectionModelChange = spy(); render(); - apiRef.current.selectRow(1); + act(() => apiRef.current.selectRow(1)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([1]); // Reset old selection - apiRef.current.selectRow(2, true, true); + act(() => apiRef.current.selectRow(2, true, true)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([2]); // Keep old selection - apiRef.current.selectRow(3); + act(() => apiRef.current.selectRow(3)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([2, 3]); - apiRef.current.selectRow(3, false); + act(() => apiRef.current.selectRow(3, false)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([2]); }); @@ -261,9 +261,9 @@ describe(' - Selection', () => { onSelectionModelChange={handleSelectionModelChange} />, ); - apiRef.current.selectRow(0); + act(() => apiRef.current.selectRow(0)); expect(handleSelectionModelChange.callCount).to.equal(0); - apiRef.current.selectRow(1); + act(() => apiRef.current.selectRow(1)); expect(handleSelectionModelChange.callCount).to.equal(1); }); }); @@ -273,17 +273,17 @@ describe(' - Selection', () => { const handleSelectionModelChange = spy(); render(); - apiRef.current.selectRows([1, 2]); + act(() => apiRef.current.selectRows([1, 2])); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2]); - apiRef.current.selectRows([3]); + act(() => apiRef.current.selectRows([3])); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2, 3]); - apiRef.current.selectRows([1, 2], false); + act(() => apiRef.current.selectRows([1, 2], false)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([3]); // Deselect others - apiRef.current.selectRows([4, 5], true, true); + act(() => apiRef.current.selectRows([4, 5], true, true)); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([4, 5]); }); @@ -295,14 +295,14 @@ describe(' - Selection', () => { onSelectionModelChange={handleSelectionModelChange} />, ); - apiRef.current.selectRows([0, 1, 2]); + act(() => apiRef.current.selectRows([0, 1, 2])); expect(handleSelectionModelChange.lastCall.args[0]).to.deep.equal([1, 2]); }); it('should not select a range of several elements when disableMultipleSelection = true', () => { render(); - apiRef.current.selectRows([0, 1, 2], true); + act(() => apiRef.current.selectRows([0, 1, 2], true)); expect(getSelectedRowIds()).to.deep.equal([]); }); }); @@ -311,54 +311,60 @@ describe(' - Selection', () => { it('should select all the rows in the range', () => { render(); - apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); + act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); }); it('should unselect all the rows in the range', () => { render(); - apiRef.current.setSelectionModel([2, 3]); + act(() => apiRef.current.setSelectionModel([2, 3])); expect(getSelectedRowIds()).to.deep.equal([2, 3]); - apiRef.current.selectRowRange({ startId: 0, endId: 3 }, false); + act(() => apiRef.current.selectRowRange({ startId: 0, endId: 3 }, false)); expect(getSelectedRowIds()).to.deep.equal([]); }); it('should not unselect the selected elements if the range is to be selected', () => { render(); - apiRef.current.setSelectionModel([2]); - apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); + act(() => { + apiRef.current.setSelectionModel([2]); + apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); + }); expect(getSelectedRowIds()).to.deep.equal([1, 2, 3]); }); it('should not reset the other selections when resetSelection = false', () => { render(); - apiRef.current.setSelectionModel([0]); - apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, false); + act(() => { + apiRef.current.setSelectionModel([0]); + apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, false); + }); expect(getSelectedRowIds()).to.deep.equal([0, 2, 3]); }); it('should reset the other selections when resetSelection = true', () => { render(); - apiRef.current.setSelectionModel([0]); - apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, true); + act(() => { + apiRef.current.setSelectionModel([0]); + apiRef.current.selectRowRange({ startId: 2, endId: 3 }, true, true); + }); expect(getSelectedRowIds()).to.deep.equal([2, 3]); }); it('should not select unselectable rows inside the range', () => { render( Number(params.id) % 2 === 1} />); - apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); + act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([1, 3]); }); it('should not select a range of several elements when disableMultipleSelection = true', () => { render(); - apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true); + act(() => apiRef.current.selectRowRange({ startId: 1, endId: 3 }, true)); expect(getSelectedRowIds()).to.deep.equal([]); }); @@ -368,7 +374,7 @@ describe(' - Selection', () => { filterModel={{ items: [{ columnField: 'id', value: 1, operatorValue: '!=' }] }} />, ); - apiRef.current.selectRowRange({ startId: 0, endId: 2 }, true); + act(() => apiRef.current.selectRowRange({ startId: 0, endId: 2 }, true)); expect(getSelectedRowIds()).to.deep.equal([0, 2]); }); }); @@ -378,15 +384,17 @@ describe(' - Selection', () => { const selectAll = screen.getByRole('checkbox', { name: /select all rows/i, }); - apiRef.current.setFilterModel({ - items: [ - { - columnField: 'currencyPair', - value: 'usd', - operatorValue: 'startsWith', - }, - ], - }); + act(() => + apiRef.current.setFilterModel({ + items: [ + { + columnField: 'currencyPair', + value: 'usd', + operatorValue: 'startsWith', + }, + ], + }), + ); expect(getColumnValues(1)).to.deep.equal(['0', '1']); fireEvent.click(selectAll); expect(getSelectedRowIds()).to.deep.equal([0, 1]); diff --git a/packages/grid/x-data-grid-pro/src/tests/sorting.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/sorting.DataGridPro.test.tsx index 501a6268d2ac..06efe9145a60 100644 --- a/packages/grid/x-data-grid-pro/src/tests/sorting.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/sorting.DataGridPro.test.tsx @@ -8,7 +8,7 @@ import { GridColumns, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { getColumnValues, getCell, getColumnHeaderCell } from 'test/utils/helperFn'; @@ -38,7 +38,7 @@ describe(' - Sorting', () => { columns: [{ field: 'brand' }, { field: 'year', type: 'number' }], }; - const { render } = createRenderer(); + const { render } = createRenderer({ clock: 'fake' }); let apiRef: React.MutableRefObject; @@ -84,21 +84,21 @@ describe(' - Sorting', () => { brand: 'Hugo', }, ]; - apiRef.current.setRows(newRows); + act(() => apiRef.current.setRows(newRows)); expect(getColumnValues(0)).to.deep.equal(['Asics', 'Hugo', 'RedBull']); }); it('should apply the sortModel prop correctly on GridApiRef update row data', () => { renderBrandSortedAsc(); - apiRef.current.updateRows([{ id: 1, brand: 'Fila' }]); - apiRef.current.updateRows([{ id: 0, brand: 'Patagonia' }]); + act(() => apiRef.current.updateRows([{ id: 1, brand: 'Fila' }])); + act(() => apiRef.current.updateRows([{ id: 0, brand: 'Patagonia' }])); expect(getColumnValues(0)).to.deep.equal(['Fila', 'Patagonia', 'Puma']); }); it('should allow apiRef to setSortModel', () => { render(); - apiRef.current.setSortModel([{ field: 'brand', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'brand', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); }); @@ -119,7 +119,7 @@ describe(' - Sorting', () => { { field: 'brand', sort: 'asc' }, ]; - apiRef.current.setSortModel(sortModel); + act(() => apiRef.current.setSortModel(sortModel)); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Adidas', 'Nike']); }); @@ -127,7 +127,7 @@ describe(' - Sorting', () => { ['shiftKey', 'metaKey', 'ctrlKey'].forEach((key) => { it(`should do a multi-sorting when clicking the header cell while ${key} is pressed`, () => { render(); - apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); fireEvent.click(getColumnHeaderCell(0), { [key]: true }); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Adidas', 'Nike']); @@ -137,9 +137,9 @@ describe(' - Sorting', () => { ['metaKey', 'ctrlKey'].forEach((key) => { it(`should do nothing when pressing Enter while ${key} is pressed`, () => { render(); - apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); - getColumnHeaderCell(1).focus(); + act(() => getColumnHeaderCell(1).focus()); fireEvent.keyDown(getColumnHeaderCell(1), { key: 'Enter', [key]: true }); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); }); @@ -147,16 +147,16 @@ describe(' - Sorting', () => { it('should do a multi-sorting pressing Enter while shiftKey is pressed', () => { render(); - apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); - getColumnHeaderCell(0).focus(); + act(() => getColumnHeaderCell(0).focus()); fireEvent.keyDown(getColumnHeaderCell(0), { key: 'Enter', shiftKey: true }); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Adidas', 'Nike']); }); it(`should not do a multi-sorting if no multiple key is pressed`, () => { render(); - apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); fireEvent.click(getColumnHeaderCell(0)); expect(getColumnValues(0)).to.deep.equal(['Adidas', 'Nike', 'Puma']); @@ -164,7 +164,7 @@ describe(' - Sorting', () => { it('should not do a multi-sorting if disableMultipleColumnsSorting is true', () => { render(); - apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }]); + act(() => apiRef.current.setSortModel([{ field: 'year', sort: 'desc' }])); expect(getColumnValues(0)).to.deep.equal(['Puma', 'Nike', 'Adidas']); fireEvent.click(getColumnHeaderCell(0), { shiftKey: true }); expect(getColumnValues(0)).to.deep.equal(['Adidas', 'Nike', 'Puma']); diff --git a/packages/grid/x-data-grid-pro/src/tests/statePersistence.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/statePersistence.DataGridPro.test.tsx index 0e5cc193a243..e0829dbfaaea 100644 --- a/packages/grid/x-data-grid-pro/src/tests/statePersistence.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/statePersistence.DataGridPro.test.tsx @@ -11,7 +11,7 @@ import { useGridApiRef, } from '@mui/x-data-grid-pro'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, screen, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { getColumnHeaderCell, @@ -206,17 +206,19 @@ describe(' - State Persistence', () => { it('should export the current version of the exportable state', () => { render(); - apiRef.current.setPageSize(2); - apiRef.current.setPage(1); - apiRef.current.setPinnedColumns({ left: ['id'] }); - apiRef.current.showPreferences(GridPreferencePanelsValue.filters); - apiRef.current.setSortModel([{ field: 'id', sort: 'desc' }]); - apiRef.current.setFilterModel({ - items: [{ columnField: 'id', operatorValue: '<', value: '5' }], + act(() => { + apiRef.current.setPageSize(2); + apiRef.current.setPage(1); + apiRef.current.setPinnedColumns({ left: ['id'] }); + apiRef.current.showPreferences(GridPreferencePanelsValue.filters); + apiRef.current.setSortModel([{ field: 'id', sort: 'desc' }]); + apiRef.current.setFilterModel({ + items: [{ columnField: 'id', operatorValue: '<', value: '5' }], + }); + apiRef.current.setColumnIndex('category', 1); + apiRef.current.setColumnWidth('category', 75); + apiRef.current.setColumnVisibilityModel({ idBis: false }); }); - apiRef.current.setColumnIndex('category', 1); - apiRef.current.setColumnWidth('category', 75); - apiRef.current.setColumnVisibilityModel({ idBis: false }); expect(apiRef.current.exportState()).to.deep.equal(FULL_INITIAL_STATE); }); }); @@ -225,7 +227,7 @@ describe(' - State Persistence', () => { it('should restore the whole exportable state', () => { render(); - apiRef.current.restoreState(FULL_INITIAL_STATE); + act(() => apiRef.current.restoreState(FULL_INITIAL_STATE)); // Pinning, pagination, sorting and filtering expect(getColumnValues(0)).to.deep.equal(['2', '1']); @@ -243,12 +245,14 @@ describe(' - State Persistence', () => { it('should restore partial exportable state', () => { render(); - apiRef.current.restoreState({ - pagination: { - page: 1, - pageSize: 2, - }, - }); + act(() => + apiRef.current.restoreState({ + pagination: { + page: 1, + pageSize: 2, + }, + }), + ); expect(getColumnValues(0)).to.deep.equal(['2', '3']); }); @@ -268,12 +272,14 @@ describe(' - State Persistence', () => { }; render(); - apiRef.current.restoreState({ - pagination: { - page: 1, - pageSize: 2, - }, - }); + act(() => + apiRef.current.restoreState({ + pagination: { + page: 1, + pageSize: 2, + }, + }), + ); clock.runToLast(); expect(getColumnValues(0)).to.deep.equal(['2', '3']); }); @@ -305,13 +311,15 @@ describe(' - State Persistence', () => { render(); - apiRef.current.restoreState({ - columns: { - columnVisibilityModel: { - category: false, + act(() => + apiRef.current.restoreState({ + columns: { + columnVisibilityModel: { + category: false, + }, }, - }, - }); + }), + ); expect(getColumnHeadersTextContent()).to.deep.equal(['category']); }); diff --git a/packages/grid/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx b/packages/grid/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx index aab2a3f38b78..a301a4359aa1 100644 --- a/packages/grid/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx +++ b/packages/grid/x-data-grid-pro/src/tests/treeData.DataGridPro.test.tsx @@ -118,7 +118,7 @@ describe(' - Tree Data', () => { 'B.B.A.A', 'C', ]); - apiRef.current.updateRows([{ name: 'A.A', _action: 'delete' }]); + act(() => apiRef.current.updateRows([{ name: 'A.A', _action: 'delete' }])); expect(getColumnValues(0)).to.deep.equal([ 'A', 'A.B', @@ -171,7 +171,7 @@ describe(' - Tree Data', () => { , ); expect(getColumnValues(1)).to.deep.equal(['A']); - apiRef.current.setRowChildrenExpansion('A', true); + act(() => apiRef.current.setRowChildrenExpansion('A', true)); clock.runToLast(); expect(getColumnValues(1)).to.deep.equal(['A', 'A.A']); setProps({ @@ -276,9 +276,7 @@ describe(' - Tree Data', () => { it('should not re-apply default expansion on rerender after expansion manually toggled', () => { const { setProps } = render(); expect(getColumnValues(1)).to.deep.equal(['A', 'B', 'C']); - act(() => { - apiRef.current.setRowChildrenExpansion('B', true); - }); + act(() => apiRef.current.setRowChildrenExpansion('B', true)); expect(getColumnValues(1)).to.deep.equal(['A', 'B', 'B.A', 'B.B', 'C']); setProps({ sortModel: [{ field: 'name', sort: 'desc' }] }); expect(getColumnValues(1)).to.deep.equal(['C', 'B', 'B.B', 'B.A', 'A']); @@ -399,14 +397,18 @@ describe(' - Tree Data', () => { it('should keep the grouping column width between generations', () => { render(); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '200px' }); - apiRef.current.updateColumns([{ field: GRID_TREE_DATA_GROUPING_FIELD, width: 100 }]); + act(() => + apiRef.current.updateColumns([{ field: GRID_TREE_DATA_GROUPING_FIELD, width: 100 }]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); - apiRef.current.updateColumns([ - { - field: 'name', - headerName: 'New name', - }, - ]); + act(() => + apiRef.current.updateColumns([ + { + field: 'name', + headerName: 'New name', + }, + ]), + ); expect(getColumnHeaderCell(0)).toHaveInlineStyle({ width: '100px' }); }); }); diff --git a/packages/grid/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx b/packages/grid/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx index f41cc64e6d3e..7dd5829bb0b7 100644 --- a/packages/grid/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx +++ b/packages/grid/x-data-grid/src/hooks/utils/useGridApiEventHandler.test.tsx @@ -47,14 +47,14 @@ describe('useGridApiEventHandler', () => { // which makes 2 event listeners to be registered. Since the second render is never // committed (to simulate a trashed render in React 18), the effects also don't run, so we're // unable to unsubscribe the last listener using the cleanup function. - expect(apiRef.current.subscribeEvent.callCount).to.equal(2); + expect(apiRef.current.subscribeEvent.callCount).to.equal(3); unmount(); global.gc!(); // Triggers garbage collector await sleep(50); // Ensure that both event listeners were unsubscribed - expect(unsubscribe.callCount).to.equal(2); + expect(unsubscribe.callCount).to.equal(3); }); }); @@ -79,13 +79,13 @@ describe('useGridApiEventHandler', () => { // which makes 2 event listeners to be registered. Since the second render is never // committed (to simulate a trashed render in React 18), the effects also don't run, so we're // unable to unsubscribe the last listener using the cleanup function. - expect(apiRef.current.subscribeEvent.callCount).to.equal(2); + expect(apiRef.current.subscribeEvent.callCount).to.equal(3); unmount(); await sleep(60); // Ensure that both event listeners were unsubscribed - expect(unsubscribe.callCount).to.equal(2); + expect(unsubscribe.callCount).to.equal(3); }); }); }); diff --git a/packages/grid/x-data-grid/src/tests/components.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/components.DataGrid.test.tsx index b39369fd9652..a53915210b23 100644 --- a/packages/grid/x-data-grid/src/tests/components.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/components.DataGrid.test.tsx @@ -1,6 +1,11 @@ import * as React from 'react'; -// @ts-ignore Remove once the test utils are typed -import { createRenderer, ErrorBoundary, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { + createRenderer, + ErrorBoundary, + fireEvent, + screen, + // @ts-ignore Remove once the test utils are typed +} from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { DataGrid, GridOverlay } from '@mui/x-data-grid'; @@ -149,6 +154,7 @@ describe(' - Components', () => { , ); }).toErrorDev([ + 'MUI: useGridRootProps should only be used inside the DataGrid, DataGridPro or DataGridPremium component.', 'MUI: useGridRootProps should only be used inside the DataGrid, DataGridPro or DataGridPremium component.', 'The above error occurred in the component', ]); diff --git a/packages/grid/x-data-grid-pro/src/tests/export.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/export.DataGrid.test.tsx similarity index 99% rename from packages/grid/x-data-grid-pro/src/tests/export.DataGrid.test.tsx rename to packages/grid/x-data-grid/src/tests/export.DataGrid.test.tsx index 1dd14d50ba0d..e76e9bdc9f88 100644 --- a/packages/grid/x-data-grid-pro/src/tests/export.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/export.DataGrid.test.tsx @@ -6,7 +6,7 @@ import { useData } from 'storybook/src/hooks/useData'; import { expect } from 'chai'; import { spy, SinonSpy } from 'sinon'; -describe(' - Export', () => { +describe(' - Export', () => { const { render, clock } = createRenderer({ clock: 'fake' }); const TestCase = (props: Omit) => { diff --git a/packages/grid/x-data-grid/src/tests/filterPanel.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/filterPanel.DataGrid.test.tsx index 367bde145303..96e92d88031a 100644 --- a/packages/grid/x-data-grid/src/tests/filterPanel.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/filterPanel.DataGrid.test.tsx @@ -9,7 +9,7 @@ import { GridPreferencePanelsValue, } from '@mui/x-data-grid'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, waitFor } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; import { getColumnHeaderCell, getColumnValues } from 'test/utils/helperFn'; function setColumnValue(columnValue: string) { @@ -49,7 +49,7 @@ function CustomInputValue(props: GridFilterInputValueProps) { const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe(' - Filter panel', () => { - const { render } = createRenderer(); + const { render, clock } = createRenderer({ clock: 'fake' }); const baselineProps: DataGridProps = { autoHeight: isJSDOM, @@ -471,9 +471,8 @@ describe(' - Filter panel', () => { expect(onFilterModelChange.lastCall.args[0].items[0].value).to.equal(undefined); deleteFilterForm(); - await waitFor(() => { - expect(screen.queryAllByRole('tooltip').length).to.deep.equal(0); - }); + clock.tick(100); + expect(screen.queryAllByRole('tooltip').length).to.deep.equal(0); }); // See https://github.com/mui/mui-x/issues/5402 diff --git a/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx index c82db972638c..e70746770df5 100644 --- a/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import Portal from '@mui/material/Portal'; import { spy } from 'sinon'; import { expect } from 'chai'; @@ -336,7 +336,7 @@ describe(' - Keyboard', () => { it('should move to the first row when pressing "ArrowDown" on a column header on the 1st page', () => { render(); - getColumnHeaderCell(1).focus(); + act(() => getColumnHeaderCell(1).focus()); expect(getActiveColumnHeader()).to.equal('1'); fireEvent.keyDown(document.activeElement!, { key: 'ArrowDown' }); expect(getActiveCell()).to.equal('0-1'); @@ -344,7 +344,7 @@ describe(' - Keyboard', () => { it('should move to the first row when pressing "ArrowDown" on a column header on the 2nd page', () => { render(); - getColumnHeaderCell(1).focus(); + act(() => getColumnHeaderCell(1).focus()); expect(getActiveColumnHeader()).to.equal('1'); fireEvent.keyDown(document.activeElement!, { key: 'ArrowDown' }); expect(getActiveCell()).to.equal('10-1'); @@ -352,7 +352,7 @@ describe(' - Keyboard', () => { it('should move to the column header right when pressing "ArrowRight" on a column header', () => { render(); - getColumnHeaderCell(1).focus(); + act(() => getColumnHeaderCell(1).focus()); expect(getActiveColumnHeader()).to.equal('1'); fireEvent.keyDown(document.activeElement!, { key: 'ArrowRight' }); expect(getActiveColumnHeader()).to.equal('2'); @@ -362,7 +362,7 @@ describe(' - Keyboard', () => { it('should move to the column header left when pressing "ArrowLeft" on a column header', () => { render(); - getColumnHeaderCell(1).focus(); + act(() => getColumnHeaderCell(1).focus()); expect(getActiveColumnHeader()).to.equal('1'); fireEvent.keyDown(document.activeElement!, { key: 'ArrowLeft' }); expect(getActiveColumnHeader()).to.equal('0'); @@ -514,7 +514,7 @@ describe(' - Keyboard', () => { , ); - getColumnHeaderCell(0).focus(); + act(() => getColumnHeaderCell(0).focus()); expect(getActiveColumnHeader()).to.equal('0'); expect(getColumnValues(1)).to.deep.equal(['John', 'Doe']); fireEvent.keyDown(getColumnHeaderCell(0), { key: 'Enter' }); diff --git a/packages/grid/x-data-grid/src/tests/layout.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/layout.DataGrid.test.tsx index 55f6579e4aad..c67b29329943 100644 --- a/packages/grid/x-data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/layout.DataGrid.test.tsx @@ -17,7 +17,7 @@ import { createTheme, ThemeProvider } from '@mui/material/styles'; import { getColumnHeaderCell, getColumnValues, getCell, getRow } from 'test/utils/helperFn'; describe(' - Layout & Warnings', () => { - const { clock, render } = createRenderer({ clock: 'real' }); + const { clock, render } = createRenderer(); const baselineProps = { rows: [ @@ -987,6 +987,7 @@ describe(' - Layout & Warnings', () => { , ); }).toErrorDev([ + 'The data grid component requires all rows to have a unique `id` property', 'The data grid component requires all rows to have a unique `id` property', 'The above error occurred in the component', ]); diff --git a/packages/grid/x-data-grid/src/tests/pagination.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/pagination.DataGrid.test.tsx index 4d17cefcf6f4..6922dabd4798 100644 --- a/packages/grid/x-data-grid/src/tests/pagination.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/pagination.DataGrid.test.tsx @@ -1,6 +1,11 @@ import * as React from 'react'; -// @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen, waitFor } from '@mui/monorepo/test/utils'; +import { + createRenderer, + fireEvent, + screen, + waitFor, + // @ts-ignore Remove once the test utils are typed +} from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { DataGrid, @@ -359,9 +364,12 @@ describe(' - Pagination', () => { expect(() => { render(); - }).toWarnDev([ - `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, - ]); + }).toWarnDev( + [ + `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, + `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, + ].filter((message): message is string => typeof message === 'string'), + ); }); it('should display a warning if the prop pageSize is not in the default rowsPerPageOptions', () => { @@ -369,15 +377,23 @@ describe(' - Pagination', () => { expect(() => { render(); - }).toWarnDev([ - `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, - ]); + }).toWarnDev( + [ + `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, + `MUI: The page size \`${pageSize}\` is not preset in the \`rowsPerPageOptions\``, + ].filter((message): message is string => typeof message === 'string'), + ); }); it('should display a warning if the default pageSize given as props is not in the prop rowsPerPageOptions', () => { expect(() => { render(); - }).toWarnDev([`MUI: The page size \`100\` is not preset in the \`rowsPerPageOptions\``]); + }).toWarnDev( + [ + `MUI: The page size \`100\` is not preset in the \`rowsPerPageOptions\``, + `MUI: The page size \`100\` is not preset in the \`rowsPerPageOptions\``, + ].filter((message): message is string => typeof message === 'string'), + ); }); it('should update the pageCount state when updating the pageSize prop with a lower value', () => { diff --git a/packages/grid/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/rows.DataGrid.test.tsx index f8eeb5acf46f..c535d2e42da2 100644 --- a/packages/grid/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -1,6 +1,10 @@ import * as React from 'react'; -// @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { + createRenderer, + fireEvent, + screen, + // @ts-ignore Remove once the test utils are typed +} from '@mui/monorepo/test/utils'; import clsx from 'clsx'; import { expect } from 'chai'; import { spy, stub } from 'sinon'; @@ -182,11 +186,14 @@ describe(' - Rows', () => { } expect(() => { render(); - }).toErrorDev([ - 'MUI: Missing the `getActions` property in the `GridColDef`.', - 'The above error occurred in the component', - 'MUI: GridErrorHandler - An unexpected error occurred.', - ]); + }).toErrorDev( + [ + 'MUI: Missing the `getActions` property in the `GridColDef`.', + 'MUI: Missing the `getActions` property in the `GridColDef`.', + 'The above error occurred in the component', + 'MUI: GridErrorHandler - An unexpected error occurred.', + ].filter((message): message is string => typeof message === 'string'), + ); }); it('should call getActions with the row params', () => { diff --git a/packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx index 1163cb8fff21..1cbd3ffb9e18 100644 --- a/packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/selection.DataGrid.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-expect-error Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { DataGrid, DataGridProps, GridInputSelectionModel, GridRowId } from '@mui/x-data-grid'; import { @@ -456,7 +456,7 @@ describe(' - Selection', () => { const selectAllCell = document.querySelector( '[role="columnheader"][data-field="__check__"] input', )!; - selectAllCell.focus(); + act(() => selectAllCell.focus()); fireEvent.keyDown(selectAllCell, { key: ' ', diff --git a/packages/grid/x-data-grid/src/tests/toolbar.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/toolbar.DataGrid.test.tsx index 911f2f512edb..ebae45838daf 100644 --- a/packages/grid/x-data-grid/src/tests/toolbar.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/toolbar.DataGrid.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // @ts-ignore Remove once the test utils are typed -import { createRenderer, fireEvent, screen } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; import { getColumnHeadersTextContent } from 'test/utils/helperFn'; import { expect } from 'chai'; import { DataGrid, DataGridProps, GridToolbar, gridClasses } from '@mui/x-data-grid'; @@ -12,7 +12,7 @@ import { const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe(' - Toolbar', () => { - const { render } = createRenderer(); + const { render, clock } = createRenderer({ clock: 'fake' }); const baselineProps = { autoHeight: isJSDOM, @@ -56,6 +56,7 @@ describe(' - Toolbar', () => { ); fireEvent.click(getByText('Density')); + clock.tick(100); fireEvent.click(getByText('Compact')); expect(screen.getAllByRole('row')[1]).toHaveInlineStyle({ @@ -259,11 +260,11 @@ describe(' - Toolbar', () => { ); const button = screen.getByRole('button', { name: 'Select columns' }); - button.focus(); + act(() => button.focus()); fireEvent.click(button); const column: HTMLElement | null = document.querySelector('[role="tooltip"] [name="id"]'); - column!.focus(); + act(() => column!.focus()); fireEvent.click(column); expect(column).toHaveFocus(); diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 7ddad0ea9e10..b21abf734333 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -25,8 +25,8 @@ "@mui/x-license-pro": "5.14.0", "@storybook/builder-webpack5": "^6.5.9", "@storybook/manager-webpack5": "^6.5.9", - "react": "^17.0.2", - "react-is": "^17.0.2", + "react": "^18.2.0", + "react-is": "^18.2.0", "rxjs": "^7.5.6", "webpack": "^5.73.0" }, diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.test.tsx index e446a2e937ab..18985b67acb2 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { describeConformance, screen, fireEvent, userEvent } from '@mui/monorepo/test/utils'; +import { describeConformance, screen, fireEvent, userEvent, act } from '@mui/monorepo/test/utils'; import TextField from '@mui/material/TextField'; import { createTheme, ThemeProvider } from '@mui/material/styles'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; @@ -424,7 +424,7 @@ describe('', () => { render(); const startInput = screen.getAllByRole('textbox')[0]; - startInput.focus(); + act(() => startInput.focus()); fireEvent.keyDown(startInput, { key }); expect(onOpen.callCount).to.equal(1); @@ -439,7 +439,7 @@ describe('', () => { render(); const endInput = screen.getAllByRole('textbox')[1]; - endInput.focus(); + act(() => endInput.focus()); fireEvent.keyDown(endInput, { key }); expect(onOpen.callCount).to.equal(1); diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.test.tsx index 86bbb9b1cb8e..54dff8560526 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.test.tsx @@ -24,7 +24,7 @@ const WrappedMobileDateRangePicker = withPickerControls(MobileDateRangePicker)({ }); describe('', () => { - const { render } = createPickerRenderer(); + const { render } = createPickerRenderer({ clock: 'fake' }); describeConformance(