Skip to content

Commit 20d6730

Browse files
authored
Rewrite some tests to reduce flakiness: part 1 (#3871)
* Rewrite scrollToCell tests * tweak * -1 * -1 * -1 * -1 * -3 * -2 * Revert a few changes * Fix flaky test * Fix types * Add new utils * Fix one test * check focus and selection * Revert 1 change * tweak * Check column order * Check exact text * format * Tweak 1 test
1 parent 8b46566 commit 20d6730

15 files changed

+271
-203
lines changed

test/browser/TextEditor.test.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { page, userEvent } from '@vitest/browser/context';
33

44
import { DataGrid, textEditor } from '../../src';
55
import type { Column } from '../../src';
6-
import { getCells } from './utils';
76

87
interface Row {
98
readonly name: string;
@@ -29,27 +28,27 @@ function Test() {
2928

3029
test('TextEditor', async () => {
3130
page.render(<Test />);
32-
33-
await userEvent.dblClick(getCells()[0]);
34-
let input = page.getByRole('textbox').element() as HTMLInputElement;
35-
expect(input).toHaveClass('rdg-text-editor');
31+
const cell = page.getByRole('gridcell');
32+
await expect.element(cell).toHaveTextContent(/^Tacitus Kilgore$/);
33+
await userEvent.dblClick(cell);
34+
const input = page.getByRole('textbox');
35+
await expect.element(input).toHaveClass('rdg-text-editor');
3636
// input value is row[column.key]
37-
expect(input).toHaveValue(initialRows[0].name);
37+
await expect.element(input).toHaveValue(initialRows[0].name);
3838
// input is focused
39-
expect(input).toHaveFocus();
39+
await expect.element(input).toHaveFocus();
4040
// input value is fully selected
41-
expect(input).toHaveSelection(initialRows[0].name);
41+
await expect.element(input).toHaveSelection(initialRows[0].name);
4242

4343
// pressing escape closes the editor without committing
4444
await userEvent.keyboard('Test{escape}');
45-
expect(input).not.toBeInTheDocument();
46-
await expect.element(getCells()[0]).toHaveTextContent(/^Tacitus Kilgore$/);
45+
await expect.element(input).not.toBeInTheDocument();
46+
await expect.element(cell).toHaveTextContent(/^Tacitus Kilgore$/);
4747

4848
// blurring the input closes and commits the editor
49-
await userEvent.dblClick(getCells()[0]);
50-
input = page.getByRole('textbox').element() as HTMLInputElement;
49+
await userEvent.dblClick(cell);
5150
await userEvent.fill(input, 'Jim Milton');
5251
await userEvent.tab();
53-
expect(input).not.toBeInTheDocument();
54-
await expect.element(getCells()[0]).toHaveTextContent(/^Jim Milton$/);
52+
await expect.element(input).not.toBeInTheDocument();
53+
await expect.element(cell).toHaveTextContent(/^Jim Milton$/);
5554
});
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
import type { Column } from '../../../src';
22
import { cellClassname } from '../../../src/style/cell';
3-
import { getCells, setup } from '../utils';
3+
import { getCellsNew, setup } from '../utils';
44

55
interface Row {
66
id: number;
77
}
88

99
const rows: readonly Row[] = [{ id: 0 }, { id: 1 }];
1010

11-
test('cellClass is undefined', () => {
11+
test('cellClass is undefined', async () => {
1212
const columns: readonly Column<Row>[] = [
1313
{
1414
key: 'id',
1515
name: 'ID'
1616
}
1717
];
1818
setup({ columns, rows });
19-
const [cell1, cell2] = getCells();
20-
expect(cell1).toHaveClass(cellClassname, { exact: true });
21-
expect(cell2).toHaveClass(cellClassname, { exact: true });
19+
const [cell1, cell2] = getCellsNew('0', '1');
20+
await expect.element(cell1).toHaveClass(cellClassname, { exact: true });
21+
await expect.element(cell2).toHaveClass(cellClassname, { exact: true });
2222
});
2323

24-
test('cellClass is a string', () => {
24+
test('cellClass is a string', async () => {
2525
const columns: readonly Column<Row>[] = [
2626
{
2727
key: 'id',
@@ -30,12 +30,12 @@ test('cellClass is a string', () => {
3030
}
3131
];
3232
setup({ columns, rows });
33-
const [cell1, cell2] = getCells();
34-
expect(cell1).toHaveClass(`${cellClassname} my-cell`, { exact: true });
35-
expect(cell2).toHaveClass(`${cellClassname} my-cell`, { exact: true });
33+
const [cell1, cell2] = getCellsNew('0', '1');
34+
await expect.element(cell1).toHaveClass(`${cellClassname} my-cell`, { exact: true });
35+
await expect.element(cell2).toHaveClass(`${cellClassname} my-cell`, { exact: true });
3636
});
3737

38-
test('cellClass returns a string', () => {
38+
test('cellClass returns a string', async () => {
3939
const columns: readonly Column<Row>[] = [
4040
{
4141
key: 'id',
@@ -44,12 +44,12 @@ test('cellClass returns a string', () => {
4444
}
4545
];
4646
setup({ columns, rows });
47-
const [cell1, cell2] = getCells();
48-
expect(cell1).toHaveClass(`${cellClassname} my-cell-0`, { exact: true });
49-
expect(cell2).toHaveClass(`${cellClassname} my-cell-1`, { exact: true });
47+
const [cell1, cell2] = getCellsNew('0', '1');
48+
await expect.element(cell1).toHaveClass(`${cellClassname} my-cell-0`, { exact: true });
49+
await expect.element(cell2).toHaveClass(`${cellClassname} my-cell-1`, { exact: true });
5050
});
5151

52-
test('cellClass returns undefined', () => {
52+
test('cellClass returns undefined', async () => {
5353
const columns: readonly Column<Row>[] = [
5454
{
5555
key: 'id',
@@ -58,7 +58,7 @@ test('cellClass returns undefined', () => {
5858
}
5959
];
6060
setup({ columns, rows });
61-
const [cell1, cell2] = getCells();
62-
expect(cell1).toHaveClass(cellClassname, { exact: true });
63-
expect(cell2).toHaveClass(cellClassname, { exact: true });
61+
const [cell1, cell2] = getCellsNew('0', '1');
62+
await expect.element(cell1).toHaveClass(cellClassname, { exact: true });
63+
await expect.element(cell2).toHaveClass(cellClassname, { exact: true });
6464
});

test/browser/column/draggable.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { userEvent } from '@vitest/browser/context';
22

33
import type { Column } from '../../../src';
4-
import { getHeaderCells, setup } from '../utils';
4+
import { getHeaderCellsNew, setup } from '../utils';
55

66
const columns: readonly Column<never>[] = [
77
{
@@ -28,12 +28,12 @@ const columns: readonly Column<never>[] = [
2828
test('draggable columns', async () => {
2929
const onColumnsReorder = vi.fn();
3030
setup({ columns, rows: [], onColumnsReorder });
31-
const [cell1, cell2, cell3, cell4] = getHeaderCells();
31+
const [cell1, cell2, cell3, cell4] = getHeaderCellsNew('col1', 'col2', 'col3', 'col4');
3232

33-
expect(cell1).not.toHaveAttribute('draggable');
34-
expect(cell2).toHaveAttribute('draggable');
35-
expect(cell3).toHaveAttribute('draggable');
36-
expect(cell4).toHaveAttribute('draggable');
33+
await expect.element(cell1).not.toHaveAttribute('draggable');
34+
await expect.element(cell2).toHaveAttribute('draggable');
35+
await expect.element(cell3).toHaveAttribute('draggable');
36+
await expect.element(cell4).toHaveAttribute('draggable');
3737

3838
expect(onColumnsReorder).not.toHaveBeenCalled();
3939

test/browser/column/frozen.test.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { page } from '@vitest/browser/context';
2+
13
import type { Column } from '../../../src';
24
import { cellClassname, cellFrozenClassname } from '../../../src/style/cell';
3-
import { getHeaderCells, setup } from '../utils';
5+
import { getHeaderCellsNew, setup } from '../utils';
46

5-
test('frozen column have a specific class, and are stable-sorted before non-frozen columns', () => {
7+
test('frozen column have a specific class, and are stable-sorted before non-frozen columns', async () => {
68
const columns: readonly Column<never>[] = [
79
{
810
key: 'col1',
@@ -26,15 +28,15 @@ test('frozen column have a specific class, and are stable-sorted before non-froz
2628
];
2729

2830
setup({ columns, rows: [] });
29-
const [cell1, cell2, cell3, cell4] = getHeaderCells();
30-
31-
expect(cell1).toHaveClass(`${cellClassname} ${cellFrozenClassname}`, { exact: true });
32-
expect(cell2).toHaveClass(`${cellClassname} ${cellFrozenClassname}`, { exact: true });
33-
expect(cell3).toHaveClass(cellClassname, { exact: true });
34-
expect(cell4).toHaveClass(cellClassname, { exact: true });
31+
await expect.element(page.getByRole('row')).toHaveTextContent('col1col3col2col4');
32+
const [cell1, cell2, cell3, cell4] = getHeaderCellsNew('col1', 'col2', 'col3', 'col4');
3533

36-
expect(cell1).toHaveTextContent('col1');
37-
expect(cell2).toHaveTextContent('col3');
38-
expect(cell3).toHaveTextContent('col2');
39-
expect(cell4).toHaveTextContent('col4');
34+
await expect
35+
.element(cell1)
36+
.toHaveClass(`${cellClassname} ${cellFrozenClassname}`, { exact: true });
37+
await expect
38+
.element(cell3)
39+
.toHaveClass(`${cellClassname} ${cellFrozenClassname}`, { exact: true });
40+
await expect.element(cell2).toHaveClass(cellClassname, { exact: true });
41+
await expect.element(cell4).toHaveClass(cellClassname, { exact: true });
4042
});

test/browser/column/renderEditCell.test.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { useMemo, useState } from 'react';
22
import { createPortal } from 'react-dom';
3-
import { page, userEvent } from '@vitest/browser/context';
3+
import { commands, page, userEvent } from '@vitest/browser/context';
44

55
import { DataGrid } from '../../../src';
66
import type { Column, DataGridProps } from '../../../src';
7-
import { getCellsAtRowIndex, getGrid, getSelectedCell, scrollGrid } from '../utils';
7+
import { getCell, getCellsAtRowIndex, getGrid, getSelectedCell, scrollGrid } from '../utils';
88

99
interface Row {
1010
col1: number;
@@ -258,20 +258,19 @@ describe('Editor', () => {
258258
it('should not steal focus back to the cell if the editor is not in the viewport and another cell is clicked', async () => {
259259
const rows: Row[] = [];
260260
for (let i = 0; i < 99; i++) {
261-
rows.push({ col1: i, col2: `${i}` });
261+
rows.push({ col1: i, col2: `name${i}` });
262262
}
263263

264264
page.render(<EditorTest gridRows={rows} />);
265265

266-
await userEvent.dblClick(getCellsAtRowIndex(0)[1]);
266+
await userEvent.dblClick(getCell('name0'));
267267
await userEvent.keyboard('abc');
268268

269-
await scrollGrid({ scrollTop: 1500 });
270-
expect(getCellsAtRowIndex(40)[1]).toHaveTextContent(/^40$/);
271-
await userEvent.click(getCellsAtRowIndex(40)[1]);
272-
await expect.element(getSelectedCell()).toHaveTextContent(/^40$/);
273-
await scrollGrid({ scrollTop: 0 });
274-
expect(getCellsAtRowIndex(0)[1]).toHaveTextContent(/^0abc$/);
269+
await commands.scrollGrid({ scrollTop: 1500 });
270+
await userEvent.click(getCell('name43'));
271+
await expect.element(getSelectedCell()).toHaveTextContent(/^name43$/);
272+
await commands.scrollGrid({ scrollTop: 0 });
273+
await expect.element(getCell('name0abc')).toBeVisible();
275274
});
276275

277276
it('should not steal focus back to the cell after being closed by clicking outside the grid', async () => {

test/browser/headerRowClass.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ interface Row {
99
}
1010

1111
const columns: readonly Column<Row>[] = [{ key: 'id', name: 'ID' }];
12-
const rows: readonly Row[] = [{ id: 0 }];
12+
const rows: readonly Row[] = [];
1313

14-
test('headerRowClass is undefined', () => {
14+
test('headerRowClass is undefined', async () => {
1515
setup({
1616
columns,
1717
rows,
18-
rowClass: undefined
18+
headerRowClass: undefined
1919
});
20-
const header = page.getByRole('row').first();
21-
expect(header).toHaveClass(headerRowClassname, { exact: true });
20+
const header = page.getByRole('row');
21+
await expect.element(header).toHaveClass(headerRowClassname, { exact: true });
2222
});
2323

24-
test('headerRowClass is a string', () => {
24+
test('headerRowClass is a string', async () => {
2525
setup({
2626
columns,
2727
rows,
2828
headerRowClass: 'my-header-row'
2929
});
30-
const header = page.getByRole('row').first();
31-
expect(header).toHaveClass(`${headerRowClassname} my-header-row`, { exact: true });
30+
const header = page.getByRole('row');
31+
await expect.element(header).toHaveClass(`${headerRowClassname} my-header-row`, { exact: true });
3232
});

test/browser/label.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getGrid, setup } from './utils';
22

3-
test('should set label and description', () => {
3+
test('should set label and description', async () => {
44
setup({
55
rows: [],
66
columns: [],
@@ -12,11 +12,11 @@ test('should set label and description', () => {
1212
'data-cy': 'cy'
1313
});
1414

15-
const grid = getGrid().element();
16-
expect(grid).toHaveAttribute('aria-label', 'label');
17-
expect(grid).toHaveAttribute('aria-labelledby', 'labelledby');
18-
expect(grid).toHaveAttribute('aria-description', 'description');
19-
expect(grid).toHaveAttribute('aria-describedby', 'describedby');
20-
expect(grid).toHaveAttribute('data-testid', 'testid');
21-
expect(grid).toHaveAttribute('data-cy', 'cy');
15+
const grid = getGrid();
16+
await expect.element(grid).toHaveAttribute('aria-label', 'label');
17+
await expect.element(grid).toHaveAttribute('aria-labelledby', 'labelledby');
18+
await expect.element(grid).toHaveAttribute('aria-description', 'description');
19+
await expect.element(grid).toHaveAttribute('aria-describedby', 'describedby');
20+
await expect.element(grid).toHaveAttribute('data-testid', 'testid');
21+
await expect.element(grid).toHaveAttribute('data-cy', 'cy');
2222
});

test/browser/rowClass.test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Column } from '../../src';
22
import { rowClassname } from '../../src/style/row';
3-
import { getRows, setup } from './utils';
3+
import { getRowsNew, setup } from './utils';
44

55
interface Row {
66
id: number;
@@ -9,38 +9,38 @@ interface Row {
99
const columns: readonly Column<Row>[] = [{ key: 'id', name: 'ID' }];
1010
const rows: readonly Row[] = [{ id: 0 }, { id: 1 }, { id: 2 }];
1111

12-
test('rowClass is undefined', () => {
12+
test('rowClass is undefined', async () => {
1313
setup({
1414
columns,
1515
rows,
1616
rowClass: undefined
1717
});
18-
const [row1, row2, row3] = getRows();
19-
expect(row1).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
20-
expect(row2).toHaveClass(`${rowClassname} rdg-row-odd`, { exact: true });
21-
expect(row3).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
18+
const [row1, row2, row3] = getRowsNew('0', '1', '2');
19+
await expect.element(row1).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
20+
await expect.element(row2).toHaveClass(`${rowClassname} rdg-row-odd`, { exact: true });
21+
await expect.element(row3).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
2222
});
2323

24-
test('rowClass returns a string', () => {
24+
test('rowClass returns a string', async () => {
2525
setup({
2626
columns,
2727
rows,
2828
rowClass: (row) => `my-row-${row.id}`
2929
});
30-
const [row1, row2, row3] = getRows();
31-
expect(row1).toHaveClass(`${rowClassname} rdg-row-even my-row-0`, { exact: true });
32-
expect(row2).toHaveClass(`${rowClassname} rdg-row-odd my-row-1`, { exact: true });
33-
expect(row3).toHaveClass(`${rowClassname} rdg-row-even my-row-2`, { exact: true });
30+
const [row1, row2, row3] = getRowsNew('0', '1', '2');
31+
await expect.element(row1).toHaveClass(`${rowClassname} rdg-row-even my-row-0`, { exact: true });
32+
await expect.element(row2).toHaveClass(`${rowClassname} rdg-row-odd my-row-1`, { exact: true });
33+
await expect.element(row3).toHaveClass(`${rowClassname} rdg-row-even my-row-2`, { exact: true });
3434
});
3535

36-
test('rowClass returns undefined', () => {
36+
test('rowClass returns undefined', async () => {
3737
setup({
3838
columns,
3939
rows,
4040
rowClass: () => undefined
4141
});
42-
const [row1, row2, row3] = getRows();
43-
expect(row1).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
44-
expect(row2).toHaveClass(`${rowClassname} rdg-row-odd`, { exact: true });
45-
expect(row3).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
42+
const [row1, row2, row3] = getRowsNew('0', '1', '2');
43+
await expect.element(row1).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
44+
await expect.element(row2).toHaveClass(`${rowClassname} rdg-row-odd`, { exact: true });
45+
await expect.element(row3).toHaveClass(`${rowClassname} rdg-row-even`, { exact: true });
4646
});

0 commit comments

Comments
 (0)