diff --git a/eslint.config.js b/eslint.config.js index be52560a1d..36e0722ac5 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -706,7 +706,7 @@ export default [ 'testing-library/prefer-explicit-assert': 1, 'testing-library/prefer-find-by': 1, 'testing-library/prefer-implicit-assert': 0, - 'testing-library/prefer-presence-queries': 1, + 'testing-library/prefer-presence-queries': 0, 'testing-library/prefer-query-by-disappearance': 1, 'testing-library/prefer-query-matchers': 0, 'testing-library/prefer-screen-queries': 0, diff --git a/test/browser/TreeDataGrid.test.tsx b/test/browser/TreeDataGrid.test.tsx index c5073b4617..a536da9d7e 100644 --- a/test/browser/TreeDataGrid.test.tsx +++ b/test/browser/TreeDataGrid.test.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; -import { render, screen, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { within } from '@testing-library/react'; +import { page, userEvent } from '@vitest/browser/context'; import type { Column } from '../../src'; import { SelectColumn, textEditor, TreeDataGrid } from '../../src'; @@ -8,13 +8,13 @@ import { focusSinkClassname } from '../../src/style/core'; import { rowSelected } from '../../src/style/row'; import type { PasteEvent } from '../../src/types'; import { - copySelectedCellOld, + copySelectedCell, getCellsAtRowIndexOld, - getHeaderCellsOld, - getRowsOld, - getSelectedCellOld, - getTreeGridOld, - pasteSelectedCellOld + getHeaderCells, + getRows, + getSelectedCell, + getTreeGrid, + pasteSelectedCell } from './utils'; const rowSelectedClassname = 'rdg-row-selected'; @@ -132,82 +132,82 @@ function rowGrouper(rows: readonly Row[], columnKey: string) { } function setup(groupBy: string[]) { - render(); + page.render(); } function getHeaderCellsContent() { - return getHeaderCellsOld().map((cell) => cell.textContent); + return getHeaderCells().map((cell) => cell.element().textContent); } -test('should not group if groupBy is empty', () => { +test('should not group if groupBy is empty', async () => { setup([]); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '7'); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '7'); expect(getHeaderCellsContent()).toStrictEqual(['', 'Sport', 'Country', 'Year', 'Id']); - expect(getRowsOld()).toHaveLength(6); + expect(getRows()).toHaveLength(6); }); -test('should not group if column does not exist', () => { +test('should not group if column does not exist', async () => { setup(['abc']); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '7'); - expect(getRowsOld()).toHaveLength(6); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '7'); + expect(getRows()).toHaveLength(6); }); -test('should group by single column', () => { +test('should group by single column', async () => { setup(['country']); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '9'); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '9'); expect(getHeaderCellsContent()).toStrictEqual(['', 'Country', 'Sport', 'Year', 'Id']); - expect(getRowsOld()).toHaveLength(4); + expect(getRows()).toHaveLength(4); }); -test('should group by multiple columns', () => { +test('should group by multiple columns', async () => { setup(['country', 'year']); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '13'); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '13'); expect(getHeaderCellsContent()).toStrictEqual(['', 'Country', 'Year', 'Sport', 'Id']); - expect(getRowsOld()).toHaveLength(4); + expect(getRows()).toHaveLength(4); }); -test('should ignore duplicate groupBy columns', () => { +test('should ignore duplicate groupBy columns', async () => { setup(['year', 'year', 'year']); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '10'); - expect(getRowsOld()).toHaveLength(5); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '10'); + expect(getRows()).toHaveLength(5); }); -test('should use groupBy order while grouping', () => { +test('should use groupBy order while grouping', async () => { setup(['year', 'country']); - expect(getTreeGridOld()).toHaveAttribute('aria-rowcount', '14'); + await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '14'); expect(getHeaderCellsContent()).toStrictEqual(['', 'Year', 'Country', 'Sport', 'Id']); - expect(getRowsOld()).toHaveLength(5); + expect(getRows()).toHaveLength(5); }); test('should toggle group when group cell is clicked', async () => { setup(['year']); - expect(getRowsOld()).toHaveLength(5); - const groupCell = screen.getByRole('gridcell', { name: '2021' }); + expect(getRows()).toHaveLength(5); + const groupCell = page.getByRole('gridcell', { name: '2021' }); await userEvent.click(groupCell); - expect(getRowsOld()).toHaveLength(7); + expect(getRows()).toHaveLength(7); await userEvent.click(groupCell); - expect(getRowsOld()).toHaveLength(5); + expect(getRows()).toHaveLength(5); }); test('should toggle group using keyboard', async () => { setup(['year']); - expect(getRowsOld()).toHaveLength(5); - const groupCell = screen.getByRole('gridcell', { name: '2021' }); + expect(getRows()).toHaveLength(5); + const groupCell = page.getByRole('gridcell', { name: '2021' }); await userEvent.click(groupCell); - expect(getRowsOld()).toHaveLength(7); + expect(getRows()).toHaveLength(7); // clicking on the group cell selects the row - expect(getSelectedCellOld()).toBeNull(); - expect(getRowsOld()[2]).toHaveClass(rowSelectedClassname); + await expect.element(getSelectedCell()).not.toBeInTheDocument(); + await expect.element(getRows()[2]).toHaveClass(rowSelectedClassname); await userEvent.keyboard('{arrowright}{arrowright}{enter}'); - expect(getRowsOld()).toHaveLength(5); + expect(getRows()).toHaveLength(5); await userEvent.keyboard('{enter}'); - expect(getRowsOld()).toHaveLength(7); + expect(getRows()).toHaveLength(7); }); test('should set aria-attributes', async () => { setup(['year', 'country']); - const groupCell1 = screen.getByRole('gridcell', { name: '2020' }); + const groupCell1 = page.getByRole('gridcell', { name: '2020' }).element(); const groupRow1 = groupCell1.parentElement!; expect(groupRow1).toHaveAttribute('aria-level', '1'); expect(groupRow1).toHaveAttribute('aria-setsize', '3'); @@ -215,7 +215,7 @@ test('should set aria-attributes', async () => { expect(groupRow1).toHaveAttribute('aria-rowindex', '3'); expect(groupRow1).toHaveAttribute('aria-expanded', 'false'); - const groupCell2 = screen.getByRole('gridcell', { name: '2021' }); + const groupCell2 = page.getByRole('gridcell', { name: '2021' }).element(); const groupRow2 = groupCell2.parentElement!; expect(groupRow2).toHaveAttribute('aria-level', '1'); expect(groupRow2).toHaveAttribute('aria-setsize', '3'); @@ -226,7 +226,7 @@ test('should set aria-attributes', async () => { await userEvent.click(groupCell2); expect(groupRow2).toHaveAttribute('aria-expanded', 'true'); - const groupCell3 = screen.getByRole('gridcell', { name: 'Canada' }); + const groupCell3 = page.getByRole('gridcell', { name: 'Canada' }).element(); const groupRow3 = groupCell3.parentElement!; expect(groupRow3).toHaveAttribute('aria-level', '2'); expect(groupRow3).toHaveAttribute('aria-setsize', '2'); @@ -241,67 +241,67 @@ test('should set aria-attributes', async () => { test('should select rows in a group', async () => { setup(['year', 'country']); - const headerCheckbox = screen.getByRole('checkbox', { name: 'Select All' }); - expect(headerCheckbox).not.toBeChecked(); + const headerCheckbox = page.getByRole('checkbox', { name: 'Select All' }); + await expect.element(headerCheckbox).not.toBeChecked(); // expand group - const groupCell1 = screen.getByRole('gridcell', { name: '2021' }); + const groupCell1 = page.getByRole('gridcell', { name: '2021' }).element(); await userEvent.click(groupCell1); - const groupCell2 = screen.getByRole('gridcell', { name: 'Canada' }); + const groupCell2 = page.getByRole('gridcell', { name: 'Canada' }).element(); await userEvent.click(groupCell2); - expect(screen.queryAllByRole('row', { selected: true })).toHaveLength(0); + expect(page.getByRole('row', { selected: true }).all()).toHaveLength(0); // select parent row await userEvent.click( within(groupCell1.parentElement!).getByRole('checkbox', { name: 'Select Group' }) ); - let selectedRows = screen.getAllByRole('row', { selected: true }); + let selectedRows = page.getByRole('row', { selected: true }).all(); expect(selectedRows).toHaveLength(4); - expect(selectedRows[0]).toHaveAttribute('aria-rowindex', '6'); - expect(selectedRows[1]).toHaveAttribute('aria-rowindex', '7'); - expect(selectedRows[2]).toHaveAttribute('aria-rowindex', '9'); - expect(selectedRows[3]).toHaveAttribute('aria-rowindex', '10'); + await expect.element(selectedRows[0]).toHaveAttribute('aria-rowindex', '6'); + await expect.element(selectedRows[1]).toHaveAttribute('aria-rowindex', '7'); + await expect.element(selectedRows[2]).toHaveAttribute('aria-rowindex', '9'); + await expect.element(selectedRows[3]).toHaveAttribute('aria-rowindex', '10'); // unselecting child should unselect the parent row - await userEvent.click(within(selectedRows[3]).getByRole('checkbox', { name: 'Select' })); - selectedRows = screen.getAllByRole('row', { selected: true }); + await userEvent.click(selectedRows[3].getByRole('checkbox', { name: 'Select' })); + selectedRows = page.getByRole('row', { selected: true }).all(); expect(selectedRows).toHaveLength(1); - expect(selectedRows[0]).toHaveAttribute('aria-rowindex', '7'); + await expect.element(selectedRows[0]).toHaveAttribute('aria-rowindex', '7'); // select child group const checkbox = within(groupCell2.parentElement!).getByRole('checkbox', { name: 'Select Group' }); await userEvent.click(checkbox); - selectedRows = screen.getAllByRole('row', { selected: true }); + selectedRows = page.getByRole('row', { selected: true }).all(); expect(selectedRows).toHaveLength(4); // unselect child group await userEvent.click(checkbox); - selectedRows = screen.getAllByRole('row', { selected: true }); + selectedRows = page.getByRole('row', { selected: true }).all(); expect(selectedRows).toHaveLength(1); - await userEvent.click(screen.getByRole('gridcell', { name: '2020' })); - await userEvent.click(screen.getByRole('gridcell', { name: '2022' })); + await userEvent.click(page.getByRole('gridcell', { name: '2020' })); + await userEvent.click(page.getByRole('gridcell', { name: '2022' })); await userEvent.click(headerCheckbox); - expect(screen.queryByRole('row', { selected: true })).not.toBeInTheDocument(); + await expect.element(page.getByRole('row', { selected: true })).not.toBeInTheDocument(); await userEvent.click(headerCheckbox); - expect(screen.getAllByRole('row', { selected: true })).toHaveLength(8); + expect(page.getByRole('row', { selected: true }).all()).toHaveLength(8); await userEvent.click(headerCheckbox); - expect(screen.queryByRole('row', { selected: true })).not.toBeInTheDocument(); + await expect.element(page.getByRole('row', { selected: true })).not.toBeInTheDocument(); }); test('cell navigation in a treegrid', async () => { setup(['country', 'year']); - expect(getRowsOld()).toHaveLength(4); + expect(getRows()).toHaveLength(4); const focusSink = document.querySelector(`.${focusSinkClassname}`); // expand group - const groupCell1 = screen.getByRole('gridcell', { name: 'USA' }); + const groupCell1 = page.getByRole('gridcell', { name: 'USA' }); expect(document.body).toHaveFocus(); expect(focusSink).toHaveAttribute('tabIndex', '-1'); await userEvent.click(groupCell1); @@ -324,7 +324,7 @@ test('cell navigation in a treegrid', async () => { expect(focusSink).toHaveFocus(); expect(focusSink).toHaveStyle('grid-row-start:2'); expect(focusSink).toHaveClass(rowSelected); - const groupCell2 = screen.getByRole('gridcell', { name: '2021' }); + const groupCell2 = page.getByRole('gridcell', { name: '2021' }); await userEvent.click(groupCell2); expect(focusSink).toHaveFocus(); expect(focusSink).toHaveAttribute('tabIndex', '0'); @@ -342,7 +342,7 @@ test('cell navigation in a treegrid', async () => { // if the first cell is selected then arrowleft should select the row await userEvent.keyboard('{arrowleft}'); expect(getCellsAtRowIndexOld(5)[0]).toHaveAttribute('aria-selected', 'false'); - expect(getRowsOld()[4]).toHaveClass(rowSelectedClassname); + await expect.element(getRows()[4]).toHaveClass(rowSelectedClassname); expect(focusSink).toHaveFocus(); // if the row is selected then arrowright should select the first cell on the same row @@ -351,53 +351,53 @@ test('cell navigation in a treegrid', async () => { await userEvent.keyboard('{arrowleft}{arrowup}'); - expect(getRowsOld()).toHaveLength(7); + expect(getRows()).toHaveLength(7); // left arrow should collapse the group await userEvent.keyboard('{arrowleft}'); - expect(getRowsOld()).toHaveLength(6); + expect(getRows()).toHaveLength(6); // right arrow should expand the group await userEvent.keyboard('{arrowright}'); - expect(getRowsOld()).toHaveLength(7); + expect(getRows()).toHaveLength(7); // left arrow on a collapsed group should select the parent group - expect(getRowsOld()[1]).not.toHaveClass(rowSelectedClassname); + await expect.element(getRows()[1]).not.toHaveClass(rowSelectedClassname); await userEvent.keyboard('{arrowleft}{arrowleft}'); - expect(getRowsOld()[1]).toHaveClass(rowSelectedClassname); + await expect.element(getRows()[1]).toHaveClass(rowSelectedClassname); await userEvent.keyboard('{end}'); - expect(getRowsOld()[5]).toHaveClass(rowSelectedClassname); + await expect.element(getRows()[5]).toHaveClass(rowSelectedClassname); await userEvent.keyboard('{home}'); - expect(screen.getAllByRole('row')[0]).toHaveClass(rowSelectedClassname); + await expect.element(page.getByRole('row').all()[0]).toHaveClass(rowSelectedClassname); // collpase parent group await userEvent.keyboard('{arrowdown}{arrowdown}{arrowleft}'); - expect(screen.queryByRole('gridcell', { name: '2021' })).not.toBeInTheDocument(); - expect(getRowsOld()).toHaveLength(4); + await expect.element(page.getByRole('gridcell', { name: '2021' })).not.toBeInTheDocument(); + expect(getRows()).toHaveLength(4); }); test('copy/paste when grouping is enabled', async () => { setup(['year']); - await userEvent.click(screen.getByRole('gridcell', { name: '2021' })); - await userEvent.click(screen.getByRole('gridcell', { name: 'USA' })); - await copySelectedCellOld(); - expect(getSelectedCellOld()).toHaveClass('rdg-cell-copied'); + await userEvent.click(page.getByRole('gridcell', { name: '2021' })); + await userEvent.click(page.getByRole('gridcell', { name: 'USA' })); + await copySelectedCell(); + await expect.element(getSelectedCell()).toHaveClass('rdg-cell-copied'); await userEvent.keyboard('{arrowdown}'); - expect(getSelectedCellOld()).toHaveTextContent('Canada'); - await pasteSelectedCellOld(); - expect(getSelectedCellOld()).toHaveTextContent('USA'); + await expect.element(getSelectedCell()).toHaveTextContent('Canada'); + await pasteSelectedCell(); + await expect.element(getSelectedCell()).toHaveTextContent('USA'); }); test('update row using cell renderer', async () => { setup(['year']); - await userEvent.click(screen.getByRole('gridcell', { name: '2021' })); - await userEvent.click(screen.getByRole('gridcell', { name: 'USA' })); + await userEvent.click(page.getByRole('gridcell', { name: '2021' })); + await userEvent.click(page.getByRole('gridcell', { name: 'USA' })); await userEvent.keyboard('{arrowright}{arrowright}'); - expect(getSelectedCellOld()).toHaveTextContent('value: 2'); - await userEvent.click(screen.getByRole('button', { name: 'value: 2' })); - expect(getSelectedCellOld()).toHaveTextContent('value: 12'); + await expect.element(getSelectedCell()).toHaveTextContent('value: 2'); + await userEvent.click(page.getByRole('button', { name: 'value: 2' })); + await expect.element(getSelectedCell()).toHaveTextContent('value: 12'); }); test('custom renderGroupCell', () => { diff --git a/test/browser/column/colSpan.test.ts b/test/browser/column/colSpan.test.ts index 0dec92c1f9..de5fbc6612 100644 --- a/test/browser/column/colSpan.test.ts +++ b/test/browser/column/colSpan.test.ts @@ -1,7 +1,7 @@ import { userEvent } from '@vitest/browser/context'; import type { Column } from '../../../src'; -import { getCellsAtRowIndexOld, getHeaderCells, setup, validateCellPositionOld } from '../utils'; +import { getCellsAtRowIndexOld, getHeaderCells, setup, validateCellPosition } from '../utils'; describe('colSpan', () => { function setupColSpanGrid(colCount = 15) { @@ -96,78 +96,78 @@ describe('colSpan', () => { setupColSpanGrid(); // header row await userEvent.click(getHeaderCells()[7]); - validateCellPositionOld(7, 0); + validateCellPosition(7, 0); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(8, 0); + validateCellPosition(8, 0); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(11, 0); + validateCellPosition(11, 0); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(12, 0); + validateCellPosition(12, 0); await userEvent.keyboard('{arrowleft}{arrowleft}{arrowleft}'); - validateCellPositionOld(7, 0); + validateCellPosition(7, 0); // top summary rows await userEvent.click(getCellsAtRowIndexOld(0)[6]); - validateCellPositionOld(6, 1); + validateCellPosition(6, 1); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(7, 1); + validateCellPosition(7, 1); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(9, 1); + validateCellPosition(9, 1); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(10, 1); + validateCellPosition(10, 1); await userEvent.keyboard('{arrowleft}{arrowleft}{arrowleft}'); - validateCellPositionOld(6, 1); + validateCellPosition(6, 1); // viewport rows await userEvent.click(getCellsAtRowIndexOld(3)[1]); - validateCellPositionOld(1, 4); + validateCellPosition(1, 4); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(2, 4); + validateCellPosition(2, 4); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(3, 4); + validateCellPosition(3, 4); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(2, 5); + validateCellPosition(2, 5); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(1, 5); + validateCellPosition(1, 5); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(2, 5); + validateCellPosition(2, 5); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(5, 5); + validateCellPosition(5, 5); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(2, 5); + validateCellPosition(2, 5); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(2, 6); + validateCellPosition(2, 6); await userEvent.keyboard('{arrowdown}{arrowdown}'); - validateCellPositionOld(0, 8); + validateCellPosition(0, 8); await userEvent.keyboard('{arrowLeft}'); - validateCellPositionOld(0, 8); + validateCellPosition(0, 8); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(5, 8); + validateCellPosition(5, 8); await userEvent.tab({ shift: true }); await userEvent.tab({ shift: true }); - validateCellPositionOld(14, 7); + validateCellPosition(14, 7); await userEvent.tab(); - validateCellPositionOld(0, 8); + validateCellPosition(0, 8); await userEvent.click(getCellsAtRowIndexOld(10)[11]); - validateCellPositionOld(11, 11); + validateCellPosition(11, 11); await userEvent.tab(); - validateCellPositionOld(12, 11); + validateCellPosition(12, 11); await userEvent.tab(); - validateCellPositionOld(0, 12); + validateCellPosition(0, 12); await userEvent.tab({ shift: true }); - validateCellPositionOld(12, 11); + validateCellPosition(12, 11); // bottom summary rows await userEvent.click(getCellsAtRowIndexOld(12)[6]); - validateCellPositionOld(6, 13); + validateCellPosition(6, 13); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(7, 13); + validateCellPosition(7, 13); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(9, 13); + validateCellPosition(9, 13); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(10, 13); + validateCellPosition(10, 13); await userEvent.keyboard('{arrowleft}{arrowleft}{arrowleft}'); - validateCellPositionOld(6, 13); + validateCellPosition(6, 13); }); it('should scroll to the merged cell when selected', async () => { @@ -182,13 +182,13 @@ describe('colSpan', () => { testScrollIntoView(); await navigate(1); testScrollIntoView(); // should bring the merged cell into view - validateCellPositionOld(27, 11); + validateCellPosition(27, 11); await navigate(7); testScrollIntoView(); - validateCellPositionOld(6, 12); // should navigate to the next row + validateCellPosition(6, 12); // should navigate to the next row await navigate(7, true); testScrollIntoView(); - validateCellPositionOld(27, 11); // should navigate to the previous row + validateCellPosition(27, 11); // should navigate to the previous row await navigate(27); testScrollIntoView(); await navigate(1); diff --git a/test/browser/column/renderEditCell.test.tsx b/test/browser/column/renderEditCell.test.tsx index 8345d3d8c7..d5b2d0c970 100644 --- a/test/browser/column/renderEditCell.test.tsx +++ b/test/browser/column/renderEditCell.test.tsx @@ -5,7 +5,7 @@ import { page, userEvent } from '@vitest/browser/context'; import DataGrid from '../../../src'; import type { Column, DataGridProps } from '../../../src'; -import { getCellsAtRowIndexOld, getGridOld, getSelectedCellOld, scrollGrid } from '../utils'; +import { getCellsAtRowIndexOld, getGrid, getSelectedCell, scrollGrid } from '../utils'; interface Row { col1: number; @@ -100,13 +100,13 @@ describe('Editor', () => { expect(getCellsAtRowIndexOld(0)).toHaveLength(1); const editor = page.getByRole('spinbutton', { name: 'col1-editor' }); await expect.element(editor).not.toBeInTheDocument(); - expect(getGridOld().scrollTop).toBe(2000); + expect(getGrid().element().scrollTop).toBe(2000); await userEvent.keyboard('123'); await waitFor(() => { expect(getCellsAtRowIndexOld(0)).toHaveLength(2); }); await expect.element(editor).toHaveValue(123); - expect(getGridOld().scrollTop).toBe(0); + expect(getGrid().element().scrollTop).toBe(0); }); describe('editable', () => { @@ -238,7 +238,7 @@ describe('Editor', () => { await scrollGrid({ scrollTop: 1500 }); expect(getCellsAtRowIndexOld(40)[1]).toHaveTextContent(/^40$/); await userEvent.click(getCellsAtRowIndexOld(40)[1]); - expect(getSelectedCellOld()).toHaveTextContent(/^40$/); + await expect.element(getSelectedCell()).toHaveTextContent(/^40$/); await scrollGrid({ scrollTop: 0 }); expect(getCellsAtRowIndexOld(0)[1]).toHaveTextContent(/^0abc$/); }); diff --git a/test/browser/events.test.tsx b/test/browser/events.test.tsx index 8bc17d3940..bfd6643f86 100644 --- a/test/browser/events.test.tsx +++ b/test/browser/events.test.tsx @@ -1,9 +1,8 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { page, userEvent } from '@vitest/browser/context'; import DataGrid from '../../src'; import type { Column, DataGridProps } from '../../src'; -import { getCellsAtRowIndexOld } from './utils'; +import { getCellsAtRowIndex } from './utils'; interface Row { col1: number; @@ -55,7 +54,7 @@ const rows: readonly Row[] = [ describe('Events', () => { it('should not select cell if onCellClick prevents grid default', async () => { - render( + page.render( { if (args.column.key === 'col1') { @@ -64,14 +63,14 @@ describe('Events', () => { }} /> ); - await userEvent.click(getCellsAtRowIndexOld(0)[0]); - expect(getCellsAtRowIndexOld(0)[0]).toHaveAttribute('aria-selected', 'false'); - await userEvent.click(getCellsAtRowIndexOld(0)[1]); - expect(getCellsAtRowIndexOld(0)[1]).toHaveAttribute('aria-selected', 'true'); + await userEvent.click(getCellsAtRowIndex(0)[0]); + await expect.element(getCellsAtRowIndex(0)[0]).toHaveAttribute('aria-selected', 'false'); + await userEvent.click(getCellsAtRowIndex(0)[1]); + await expect.element(getCellsAtRowIndex(0)[1]).toHaveAttribute('aria-selected', 'true'); }); it('should be able to open editor editor on single click using onCellClick', async () => { - render( + page.render( { if (args.column.key === 'col2') { @@ -81,14 +80,14 @@ describe('Events', () => { }} /> ); - await userEvent.click(getCellsAtRowIndexOld(0)[0]); - expect(screen.queryByLabelText('col1-editor')).not.toBeInTheDocument(); - await userEvent.click(getCellsAtRowIndexOld(0)[1]); - expect(screen.getByRole('textbox', { name: 'col2-editor' })).toBeInTheDocument(); + await userEvent.click(getCellsAtRowIndex(0)[0]); + await expect.element(page.getByLabelText('col1-editor')).not.toBeInTheDocument(); + await userEvent.click(getCellsAtRowIndex(0)[1]); + await expect.element(page.getByRole('textbox', { name: 'col2-editor' })).toBeInTheDocument(); }); it('should not open editor editor on double click if onCellDoubleClick prevents default', async () => { - render( + page.render( { if (args.column.key === 'col1') { @@ -97,14 +96,14 @@ describe('Events', () => { }} /> ); - await userEvent.dblClick(getCellsAtRowIndexOld(0)[0]); - expect(screen.queryByLabelText('col1-editor')).not.toBeInTheDocument(); - await userEvent.dblClick(getCellsAtRowIndexOld(0)[1]); - expect(screen.getByRole('textbox', { name: 'col2-editor' })).toBeInTheDocument(); + await userEvent.dblClick(getCellsAtRowIndex(0)[0]); + await expect.element(page.getByLabelText('col1-editor')).not.toBeInTheDocument(); + await userEvent.dblClick(getCellsAtRowIndex(0)[1]); + await expect.element(page.getByRole('textbox', { name: 'col2-editor' })).toBeInTheDocument(); }); it('should call onCellContextMenu when cell is right clicked', async () => { - render( + page.render( { if (args.column.key === 'col1') { @@ -113,21 +112,21 @@ describe('Events', () => { }} /> ); - await userEvent.pointer({ target: getCellsAtRowIndexOld(0)[0], keys: '[MouseRight]' }); - expect(getCellsAtRowIndexOld(0)[0]).toHaveAttribute('aria-selected', 'false'); - await userEvent.pointer({ target: getCellsAtRowIndexOld(0)[1], keys: '[MouseRight]' }); - expect(getCellsAtRowIndexOld(0)[1]).toHaveAttribute('aria-selected', 'true'); + await userEvent.click(getCellsAtRowIndex(0)[0], { button: 'right' }); + await expect.element(getCellsAtRowIndex(0)[0]).toHaveAttribute('aria-selected', 'false'); + await userEvent.click(getCellsAtRowIndex(0)[1], { button: 'right' }); + await expect.element(getCellsAtRowIndex(0)[1]).toHaveAttribute('aria-selected', 'true'); }); it('should call onSelectedCellChange when cell selection is changed', async () => { const onSelectedCellChange = vi.fn(); - render(); + page.render(); expect(onSelectedCellChange).not.toHaveBeenCalled(); // Selected by click - await userEvent.click(getCellsAtRowIndexOld(0)[1]); + await userEvent.click(getCellsAtRowIndex(0)[1]); expect(onSelectedCellChange).toHaveBeenCalledWith({ column: expect.objectContaining(columns[1]), row: rows[0], @@ -136,7 +135,7 @@ describe('Events', () => { expect(onSelectedCellChange).toHaveBeenCalledTimes(1); // Selected by double click - await userEvent.dblClick(getCellsAtRowIndexOld(0)[0]); + await userEvent.dblClick(getCellsAtRowIndex(0)[0]); expect(onSelectedCellChange).toHaveBeenCalledWith({ column: expect.objectContaining(columns[0]), row: rows[0], @@ -145,7 +144,7 @@ describe('Events', () => { expect(onSelectedCellChange).toHaveBeenCalledTimes(2); // Selected by right-click - await userEvent.pointer({ target: getCellsAtRowIndexOld(1)[0], keys: '[MouseRight]' }); + await userEvent.click(getCellsAtRowIndex(1)[0], { button: 'right' }); expect(onSelectedCellChange).toHaveBeenCalledWith({ column: expect.objectContaining(columns[0]), row: rows[1], diff --git a/test/browser/keyboardNavigation.test.tsx b/test/browser/keyboardNavigation.test.tsx index e1c44be25d..b4956d092e 100644 --- a/test/browser/keyboardNavigation.test.tsx +++ b/test/browser/keyboardNavigation.test.tsx @@ -5,10 +5,10 @@ import type { Column } from '../../src'; import DataGrid, { SelectColumn } from '../../src'; import { getCellsAtRowIndexOld, - getSelectedCellOld, + getSelectedCell, scrollGrid, - setupOld, - validateCellPositionOld + setup, + validateCellPosition } from './utils'; type Row = undefined; @@ -28,138 +28,138 @@ const columns = [ ] as const satisfies Column[]; test('keyboard navigation', async () => { - setupOld({ columns, rows, topSummaryRows, bottomSummaryRows }); + setup({ columns, rows, topSummaryRows, bottomSummaryRows }); // no initial selection - expect(getSelectedCellOld()).not.toBeInTheDocument(); + await expect.element(getSelectedCell()).not.toBeInTheDocument(); // tab into the grid await userEvent.tab(); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); // tab to the next cell await userEvent.tab(); - validateCellPositionOld(1, 0); + validateCellPosition(1, 0); // tab back to the previous cell await userEvent.tab({ shift: true }); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); // arrow navigation await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(1, 1); + validateCellPosition(1, 1); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(1, 2); + validateCellPosition(1, 2); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(0, 2); + validateCellPosition(0, 2); await userEvent.keyboard('{arrowup}'); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); await userEvent.keyboard('{arrowup}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); // page {up,down} await userEvent.keyboard('{PageDown}'); - validateCellPositionOld(0, 26); + validateCellPosition(0, 26); await userEvent.keyboard('{PageDown}'); - validateCellPositionOld(0, 52); + validateCellPosition(0, 52); await userEvent.keyboard('{PageUp}'); - validateCellPositionOld(0, 26); + validateCellPosition(0, 26); // home/end navigation await userEvent.keyboard('{end}'); - validateCellPositionOld(6, 26); + validateCellPosition(6, 26); await userEvent.keyboard('{home}'); - validateCellPositionOld(0, 26); + validateCellPosition(0, 26); await userEvent.keyboard('{Control>}{end}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{end}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{Control>}{end}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{PageDown}'); - validateCellPositionOld(6, 103); + validateCellPosition(6, 103); await userEvent.keyboard('{Control>}{home}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{home}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{Control>}{home}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{PageUp}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); // tab at the end of a row selects the first cell on the next row await userEvent.keyboard('{end}'); await userEvent.tab(); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); // shift tab should select the last cell of the previous row await userEvent.tab({ shift: true }); - validateCellPositionOld(6, 0); + validateCellPosition(6, 0); }); test('arrow and tab navigation', async () => { - setupOld({ columns, rows, bottomSummaryRows }); + setup({ columns, rows, bottomSummaryRows }); // pressing arrowleft on the leftmost cell does nothing await userEvent.tab(); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); // pressing arrowright on the rightmost cell does nothing await userEvent.keyboard('{end}'); - validateCellPositionOld(6, 1); + validateCellPosition(6, 1); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(6, 1); + validateCellPosition(6, 1); // pressing tab on the rightmost cell navigates to the leftmost cell on the next row await userEvent.tab(); - validateCellPositionOld(0, 2); + validateCellPosition(0, 2); // pressing shift+tab on the leftmost cell navigates to the rightmost cell on the previous row await userEvent.tab({ shift: true }); - validateCellPositionOld(6, 1); + validateCellPosition(6, 1); }); test('grid enter/exit', async () => { - setupOld({ columns, rows: new Array(5), bottomSummaryRows }); + setup({ columns, rows: new Array(5), bottomSummaryRows }); // no initial selection - expect(getSelectedCellOld()).not.toBeInTheDocument(); + await expect.element(getSelectedCell()).not.toBeInTheDocument(); // tab into the grid await userEvent.tab(); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); // shift+tab tabs out of the grid if we are at the first cell await userEvent.tab({ shift: true }); expect(document.body).toHaveFocus(); await userEvent.tab(); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{arrowdown}{arrowdown}'); - validateCellPositionOld(0, 2); + validateCellPosition(0, 2); // tab should select the last selected cell // click outside the grid await userEvent.click(document.body); await userEvent.tab(); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(0, 3); + validateCellPosition(0, 3); // shift+tab should select the last selected cell await userEvent.click(document.body); await userEvent.tab({ shift: true }); await userEvent.keyboard('{arrowup}'); - validateCellPositionOld(0, 2); + validateCellPosition(0, 2); // tab tabs out of the grid if we are at the last cell await userEvent.keyboard('{Control>}{end}'); @@ -168,21 +168,21 @@ test('grid enter/exit', async () => { }); test('navigation with focusable cell renderer', async () => { - setupOld({ columns, rows: new Array(1), bottomSummaryRows }); + setup({ columns, rows: new Array(1), bottomSummaryRows }); await userEvent.tab(); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); // cell should not set tabIndex to 0 if it contains a focusable cell renderer - expect(getSelectedCellOld()).toHaveAttribute('tabIndex', '-1'); - const checkbox = getSelectedCellOld()!.querySelector('input'); + await expect.element(getSelectedCell()).toHaveAttribute('tabIndex', '-1'); + const checkbox = getSelectedCell().getByRole('checkbox').element(); expect(checkbox).toHaveFocus(); expect(checkbox).toHaveAttribute('tabIndex', '0'); await userEvent.tab(); - validateCellPositionOld(1, 1); + validateCellPosition(1, 1); // cell should set tabIndex to 0 if it does not have focusable cell renderer - expect(getSelectedCellOld()).toHaveAttribute('tabIndex', '0'); + await expect.element(getSelectedCell()).toHaveAttribute('tabIndex', '0'); }); test('navigation when header and summary rows have focusable elements', async () => { @@ -209,7 +209,7 @@ test('navigation when header and summary rows have focusable elements', async () } ]; - setupOld({ columns, rows: new Array(2), bottomSummaryRows }); + setup({ columns, rows: new Array(2), bottomSummaryRows }); await userEvent.tab(); // should set focus on the header filter @@ -219,7 +219,7 @@ test('navigation when header and summary rows have focusable elements', async () expect(document.getElementById('header-filter2')).toHaveFocus(); await userEvent.tab(); - validateCellPositionOld(0, 1); + validateCellPosition(0, 1); await userEvent.tab({ shift: true }); expect(document.getElementById('header-filter2')).toHaveFocus(); @@ -230,7 +230,7 @@ test('navigation when header and summary rows have focusable elements', async () await userEvent.tab(); await userEvent.tab(); await userEvent.keyboard('{Control>}{end}{arrowup}{arrowup}'); - validateCellPositionOld(1, 2); + validateCellPosition(1, 2); await userEvent.tab(); expect(document.getElementById('summary-1')).toHaveFocus(); @@ -240,8 +240,8 @@ test('navigation when header and summary rows have focusable elements', async () await userEvent.tab({ shift: true }); await userEvent.tab({ shift: true }); - validateCellPositionOld(1, 2); - expect(getSelectedCellOld()).toHaveFocus(); + validateCellPosition(1, 2); + await expect.element(getSelectedCell()).toHaveFocus(); }); test('navigation when selected cell not in the viewport', async () => { @@ -249,31 +249,31 @@ test('navigation when selected cell not in the viewport', async () => { for (let i = 0; i < 99; i++) { columns.push({ key: `col${i}`, name: `col${i}`, frozen: i < 5 }); } - setupOld({ columns, rows, bottomSummaryRows }); + setup({ columns, rows, bottomSummaryRows }); await userEvent.tab(); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{Control>}{end}{arrowup}{arrowup}'); - validateCellPositionOld(99, 100); + validateCellPosition(99, 100); expect(getCellsAtRowIndexOld(100)).not.toHaveLength(1); await scrollGrid({ scrollTop: 0 }); expect(getCellsAtRowIndexOld(99)).toHaveLength(1); await userEvent.keyboard('{arrowup}'); - validateCellPositionOld(99, 99); + validateCellPosition(99, 99); expect(getCellsAtRowIndexOld(99)).not.toHaveLength(1); await scrollGrid({ scrollLeft: 0 }); await userEvent.keyboard('{arrowdown}'); - validateCellPositionOld(99, 100); + validateCellPosition(99, 100); await userEvent.keyboard( '{home}{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}' ); - validateCellPositionOld(7, 100); + validateCellPosition(7, 100); await scrollGrid({ scrollLeft: 2000 }); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(6, 100); + validateCellPosition(6, 100); }); test('reset selected cell when column is removed', async () => { @@ -291,11 +291,11 @@ test('reset selected cell when column is removed', async () => { await userEvent.tab(); await userEvent.keyboard('{arrowdown}{arrowright}'); - validateCellPositionOld(1, 1); + validateCellPosition(1, 1); rerender(); - expect(getSelectedCellOld()).not.toBeInTheDocument(); + await expect.element(getSelectedCell()).not.toBeInTheDocument(); }); test('reset selected cell when row is removed', async () => { @@ -313,25 +313,25 @@ test('reset selected cell when row is removed', async () => { await userEvent.tab(); await userEvent.keyboard('{arrowdown}{arrowdown}{arrowright}'); - validateCellPositionOld(1, 2); + validateCellPosition(1, 2); rerender(); - expect(getSelectedCellOld()).not.toBeInTheDocument(); + await expect.element(getSelectedCell()).not.toBeInTheDocument(); }); test('should not change the left and right arrow behavior for right to left languages', async () => { - setupOld({ rows, columns, direction: 'rtl' }); + setup({ rows, columns, direction: 'rtl' }); await userEvent.tab(); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.tab(); - validateCellPositionOld(1, 0); + validateCellPosition(1, 0); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{arrowright}'); - validateCellPositionOld(0, 0); + validateCellPosition(0, 0); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(1, 0); + validateCellPosition(1, 0); await userEvent.keyboard('{arrowleft}'); - validateCellPositionOld(2, 0); + validateCellPosition(2, 0); }); diff --git a/test/browser/renderers.test.tsx b/test/browser/renderers.test.tsx index 687cbe3d07..70ca9197e1 100644 --- a/test/browser/renderers.test.tsx +++ b/test/browser/renderers.test.tsx @@ -16,7 +16,7 @@ import type { RenderSortStatusProps, SortColumn } from '../../src'; -import { getCells, getHeaderCells, getRowsOld, setup } from './utils'; +import { getCells, getHeaderCells, getRows, setup } from './utils'; interface Row { id: number; @@ -115,21 +115,21 @@ function setupProvider(props: DataGridProps { setup({ columns, rows: noRows, renderers: { noRowsFallback: } }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Local no rows fallback')).toBeInTheDocument(); }); test('fallback defined using provider with no rows', async () => { setupProvider({ columns, rows: noRows }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Global no rows fallback')).toBeInTheDocument(); }); test('fallback defined using both provider and renderers with no rows', async () => { setupProvider({ columns, rows: noRows, renderers: { noRowsFallback: } }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Local no rows fallback')).toBeInTheDocument(); }); @@ -140,14 +140,14 @@ test('fallback defined using renderers prop with a row', async () => { renderers: { noRowsFallback: } }); - expect(getRowsOld()).toHaveLength(1); + expect(getRows()).toHaveLength(1); await expect.element(page.getByText('Local no rows fallback')).not.toBeInTheDocument(); }); test('fallback defined using provider with a row', async () => { setupProvider({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] }); - expect(getRowsOld()).toHaveLength(1); + expect(getRows()).toHaveLength(1); await expect.element(page.getByText('Global no rows fallback')).not.toBeInTheDocument(); }); @@ -158,7 +158,7 @@ test('fallback defined using both provider and renderers with a row', async () = renderers: { noRowsFallback: } }); - expect(getRowsOld()).toHaveLength(1); + expect(getRows()).toHaveLength(1); await expect.element(page.getByText('Global no rows fallback')).not.toBeInTheDocument(); await expect.element(page.getByText('Local no rows fallback')).not.toBeInTheDocument(); }); @@ -166,21 +166,21 @@ test('fallback defined using both provider and renderers with a row', async () = test('checkbox defined using renderers prop', async () => { setup({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Local checkbox')).toBeInTheDocument(); }); test('checkbox defined using provider', async () => { setupProvider({ columns, rows: noRows }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Global checkbox')).toBeInTheDocument(); }); test('checkbox defined using both provider and renderers', async () => { setupProvider({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } }); - expect(getRowsOld()).toHaveLength(0); + expect(getRows()).toHaveLength(0); await expect.element(page.getByText('Local checkbox')).toBeInTheDocument(); await expect.element(page.getByText('Global checkbox')).not.toBeInTheDocument(); }); @@ -252,7 +252,7 @@ test('renderCell defined using both providers and renderers', async () => { test('renderRow defined using provider', () => { setupProvider({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] }); - const [row] = getRowsOld(); + const row = getRows()[0].element(); expect(row).toHaveClass('global'); expect(row).not.toHaveClass('local'); }); @@ -264,7 +264,7 @@ test('renderRow defined using both providers and renderers', () => { renderers: { renderRow: renderLocalRow } }); - const [row] = getRowsOld(); + const row = getRows()[0].element(); expect(row).toHaveClass('local'); expect(row).not.toHaveClass('global'); });