Skip to content

Commit 6021e3c

Browse files
Rewrite some tests to reduce flakiness: part 3 (#3880)
* -1 * -1 * eslint * Add `testLength` util * Add `getRowByCellName` util * Revert accidental change * -1 * Remove unused * Export * Rename * Add missing import * -1 * -1 * Rename * Rename helper * Pin eslint? * Update test/browser/utils.tsx Co-authored-by: Nicolas Stepien <[email protected]> * Fix types --------- Co-authored-by: Nicolas Stepien <[email protected]>
1 parent 574f28c commit 6021e3c

15 files changed

+354
-315
lines changed

test/browser/TreeDataGrid.test.tsx

Lines changed: 130 additions & 120 deletions
Large diffs are not rendered by default.

test/browser/column/grouping.test.ts

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

33
import type { ColumnOrColumnGroup } from '../../../src';
4-
import { getSelectedCell, setup, tabIntoGrid, validateCellPosition } from '../utils';
4+
import {
5+
getGrid,
6+
getSelectedCell,
7+
setup,
8+
tabIntoGrid,
9+
testCount,
10+
validateCellPosition
11+
} from '../utils';
512

613
const columns: readonly ColumnOrColumnGroup<NonNullable<unknown>>[] = [
714
{ key: 'col1', name: 'col 1' },
@@ -90,31 +97,29 @@ const columns: readonly ColumnOrColumnGroup<NonNullable<unknown>>[] = [
9097
test('grouping', async () => {
9198
setup({ columns, rows: [{}] });
9299

93-
const grid = page.getByRole('grid');
100+
const grid = getGrid();
94101
await expect.element(grid).toHaveAttribute('aria-colcount', '12');
95102
await expect.element(grid).toHaveAttribute('aria-rowcount', '5');
96103

97-
const rows = page.getByRole('row').all();
98-
expect(rows).toHaveLength(5);
104+
const rows = page.getByRole('row');
105+
await testCount(rows, 5);
99106

100-
await expect.element(rows[0]).toHaveAttribute('aria-rowindex', '1');
101-
await expect.element(rows[1]).toHaveAttribute('aria-rowindex', '2');
102-
await expect.element(rows[2]).toHaveAttribute('aria-rowindex', '3');
103-
await expect.element(rows[3]).toHaveAttribute('aria-rowindex', '4');
104-
await expect.element(rows[4]).toHaveAttribute('aria-rowindex', '5');
107+
await expect.element(rows.nth(0)).toHaveAttribute('aria-rowindex', '1');
108+
await expect.element(rows.nth(1)).toHaveAttribute('aria-rowindex', '2');
109+
await expect.element(rows.nth(2)).toHaveAttribute('aria-rowindex', '3');
110+
await expect.element(rows.nth(3)).toHaveAttribute('aria-rowindex', '4');
111+
await expect.element(rows.nth(4)).toHaveAttribute('aria-rowindex', '5');
105112

106-
expect(rows[0].getByRole('columnheader').all()).toHaveLength(2);
107-
expect(rows[1].getByRole('columnheader').all()).toHaveLength(2);
108-
expect(rows[2].getByRole('columnheader').all()).toHaveLength(4);
109-
expect(rows[3].getByRole('columnheader').all()).toHaveLength(12);
110-
expect(rows[4].getByRole('columnheader').all()).toHaveLength(0);
113+
await testCount(rows.nth(0).getByRole('columnheader'), 2);
114+
await testCount(rows.nth(1).getByRole('columnheader'), 2);
115+
await testCount(rows.nth(2).getByRole('columnheader'), 4);
116+
await testCount(rows.nth(3).getByRole('columnheader'), 12);
117+
await testCount(rows.nth(4).getByRole('columnheader'), 0);
111118

112-
const headerCells = page.getByRole('columnheader').all();
113-
expect(headerCells).toHaveLength(20);
114-
115-
const headerCellDetails = headerCells.map((cellLocator) => {
116-
const cell = cellLocator.element();
119+
const headerCells = page.getByRole('columnheader');
120+
await testCount(headerCells, 20);
117121

122+
const headerCellDetails = headerCells.elements().map((cell) => {
118123
return {
119124
text: cell.textContent,
120125
colIndex: cell.getAttribute('aria-colindex'),

test/browser/column/renderEditCell.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { commands, page, userEvent } from '@vitest/browser/context';
44

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

99
interface Row {
1010
col1: number;
@@ -98,15 +98,15 @@ describe('Editor', () => {
9898
.getByRole('row')
9999
.filter({ has: getSelectedCell() })
100100
.getByRole('gridcell');
101-
await expect.poll(() => selectedRowCells.elements().length).toBe(2);
101+
await testCount(selectedRowCells, 2);
102102
await commands.scrollGrid({ scrollTop: 2000 });
103-
await expect.poll(() => selectedRowCells.elements().length).toBe(1);
103+
await testCount(selectedRowCells, 1);
104104
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
105105
await expect.element(editor).not.toBeInTheDocument();
106106
expect(getGrid().element().scrollTop).toBe(2000);
107107
// TODO: await userEvent.keyboard('123'); fails in FF
108108
await userEvent.keyboard('{enter}123');
109-
await expect.poll(() => selectedRowCells.elements().length).toBe(2);
109+
await testCount(selectedRowCells, 2);
110110
await expect.element(editor).toHaveValue(123);
111111
expect(getGrid().element().scrollTop).toBe(0);
112112
});

test/browser/column/resizable.test.tsx

Lines changed: 30 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,25 @@ import { useState } from 'react';
22
import { commands, page, userEvent } from '@vitest/browser/context';
33

44
import { DataGrid, type Column, type ColumnWidth, type ColumnWidths } from '../../../src';
5-
import { getGrid, getHeaderCells, setup } from '../utils';
5+
import { getGrid, getHeaderCell, setup } from '../utils';
66

77
interface Row {
88
readonly col1: number;
99
readonly col2: string;
1010
}
1111

12-
function queryResizeHandle(column: Element) {
13-
return column.querySelector('.rdg-resize-handle');
12+
function getResizeHandle(name: string) {
13+
return getHeaderCell(name).getBySelector('.rdg-resize-handle');
1414
}
1515

16-
function getResizeHandle(column: Element) {
17-
const resizeHandle = queryResizeHandle(column);
16+
async function resize(columnName: string, resizeBy: number | readonly number[]) {
17+
await expect.element(getResizeHandle(columnName)).toBeInTheDocument();
1818

19-
if (resizeHandle === null) {
20-
throw new Error('Resize handle not found');
21-
}
22-
23-
return resizeHandle;
24-
}
25-
26-
interface ResizeArgs {
27-
readonly column: Element;
28-
readonly resizeBy: number | readonly number[];
29-
}
30-
31-
async function resize({ column, resizeBy }: ResizeArgs) {
32-
expect(getResizeHandle(column)).toBeInTheDocument();
33-
34-
await commands.resizeColumn(resizeBy);
19+
await commands.resizeColumn('col2', resizeBy);
3520
}
3621

37-
async function autoResize(column: Element) {
38-
const resizeHandle = getResizeHandle(column);
22+
async function autoResize(columnName: string) {
23+
const resizeHandle = getResizeHandle(columnName);
3924

4025
await userEvent.dblClick(resizeHandle);
4126
}
@@ -56,10 +41,9 @@ const columns: readonly Column<Row>[] = [
5641
}
5742
];
5843

59-
test('cannot resize or auto resize column when resizable is not specified', () => {
44+
test('cannot resize or auto resize column when resizable is not specified', async () => {
6045
setup<Row, unknown>({ columns, rows: [] });
61-
const [col1] = getHeaderCells();
62-
expect(queryResizeHandle(col1)).not.toBeInTheDocument();
46+
await expect.element(getResizeHandle('col1')).not.toBeInTheDocument();
6347
});
6448

6549
test('should resize column when dragging the handle', async () => {
@@ -68,8 +52,7 @@ test('should resize column when dragging the handle', async () => {
6852
const grid = getGrid();
6953
expect(onColumnResize).not.toHaveBeenCalled();
7054
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
71-
const [, col2] = getHeaderCells();
72-
await resize({ column: col2, resizeBy: -50 });
55+
await resize('col2', -50);
7356
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 150px' });
7457
expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(expect.objectContaining(columns[1]), 150);
7558
});
@@ -78,17 +61,15 @@ test('should use the maxWidth if specified when dragging the handle', async () =
7861
setup<Row, unknown>({ columns, rows: [] });
7962
const grid = getGrid();
8063
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
81-
const [, col2] = getHeaderCells();
82-
await resize({ column: col2, resizeBy: 1000 });
64+
await resize('col2', 1000);
8365
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
8466
});
8567

8668
test('should use the minWidth if specified when dragging the handle', async () => {
8769
setup<Row, unknown>({ columns, rows: [] });
8870
const grid = getGrid();
8971
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
90-
const [, col2] = getHeaderCells();
91-
await resize({ column: col2, resizeBy: -150 });
72+
await resize('col2', -150);
9273
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 100px' });
9374
});
9475

@@ -98,7 +79,7 @@ test('should resize column using keboard', async () => {
9879
const grid = getGrid();
9980
expect(onColumnResize).not.toHaveBeenCalled();
10081
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
101-
const [, col2] = getHeaderCells();
82+
const col2 = getHeaderCell('col2');
10283
await userEvent.click(col2);
10384

10485
await userEvent.keyboard('{Control>}{ArrowRight}{/Control}');
@@ -116,7 +97,7 @@ test('should use the maxWidth if specified when resizing using keyboard', async
11697
setup<Row, unknown>({ columns, rows: [], onColumnResize });
11798
const grid = getGrid();
11899
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
119-
const [, col2] = getHeaderCells();
100+
const col2 = getHeaderCell('col2');
120101
await userEvent.click(col2);
121102
await userEvent.keyboard(`{Control>}${'{ArrowRight}'.repeat(22)}{/Control}`);
122103
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
@@ -128,7 +109,7 @@ test('should use the minWidth if specified resizing using keyboard', async () =>
128109
setup<Row, unknown>({ columns, rows: [], onColumnResize });
129110
const grid = getGrid();
130111
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
131-
const [, col2] = getHeaderCells();
112+
const col2 = getHeaderCell('col2');
132113
await userEvent.click(col2);
133114
await userEvent.keyboard(`{Control>}${'{ArrowLeft}'.repeat(12)}{/Control}`);
134115
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 100px' });
@@ -149,8 +130,7 @@ test('should auto resize column when resize handle is double clicked', async ()
149130
});
150131
const grid = getGrid();
151132
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
152-
const [, col2] = getHeaderCells();
153-
await autoResize(col2);
133+
await autoResize('col2');
154134
await testGridTemplateColumns('100px 327.703px', '100px 327.833px', '100px 400px');
155135
expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(
156136
expect.objectContaining(columns[1]),
@@ -177,8 +157,7 @@ test('should use the maxWidth if specified on auto resize', async () => {
177157
});
178158
const grid = getGrid();
179159
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
180-
const [, col2] = getHeaderCells();
181-
await autoResize(col2);
160+
await autoResize('col2');
182161
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
183162
});
184163

@@ -194,8 +173,7 @@ test('should use the minWidth if specified on auto resize', async () => {
194173
});
195174
const grid = getGrid();
196175
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
197-
const [, col2] = getHeaderCells();
198-
await autoResize(col2);
176+
await autoResize('col2');
199177
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 100px' });
200178
});
201179

@@ -237,16 +215,15 @@ test('should remeasure flex columns when resizing a column', async () => {
237215
});
238216

239217
await testGridTemplateColumns('639.328px 639.328px 639.344px', '639.333px 639.333px 639.333px');
240-
const [col1] = getHeaderCells();
241-
await autoResize(col1);
218+
await autoResize('col1');
242219
await testGridTemplateColumns(
243220
'79.1406px 919.422px 919.438px',
244221
'79.1667px 919.417px 919.417px',
245222
'100.5px 908.75px 908.75px'
246223
);
247224
expect(onColumnResize).toHaveBeenCalledOnce();
248225
// onColumnResize is not called if width is not changed
249-
await autoResize(col1);
226+
await autoResize('col1');
250227
await testGridTemplateColumns(
251228
'79.1406px 919.422px 919.438px',
252229
'79.1667px 919.417px 919.417px',
@@ -302,8 +279,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
302279

303280
const grid = getGrid();
304281
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '101px 201px' });
305-
const [, col2] = getHeaderCells();
306-
await autoResize(col2);
282+
await autoResize('col2');
307283
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
308284
new Map([
309285
['col1', { width: 101, type: 'measured' }],
@@ -317,7 +293,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
317293
onColumnWidthsChangeSpy.mockClear();
318294
onColumnResizeSpy.mockClear();
319295

320-
await resize({ column: col2, resizeBy: [5, 5, 5] });
296+
await resize('col2', [5, 5, 5]);
321297
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
322298
new Map([
323299
['col1', { width: 101, type: 'measured' }],
@@ -335,7 +311,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
335311
expect(onColumnWidthsChangeSpy).not.toHaveBeenCalled();
336312
expect(onColumnResizeSpy).not.toHaveBeenCalled();
337313
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '120px 120px' });
338-
await resize({ column: col2, resizeBy: [5, 5] });
314+
await resize('col2', [5, 5]);
339315
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
340316
new Map([
341317
['col1', { width: 120, type: 'measured' }],
@@ -349,9 +325,11 @@ async function testGridTemplateColumns(chrome: string, firefox: string, firefoxC
349325
if (navigator.userAgent.includes('Chrome')) {
350326
await expect.element(grid).toHaveStyle({ gridTemplateColumns: chrome });
351327
} else {
352-
expect((grid.element() as HTMLDivElement).style.gridTemplateColumns).toBeOneOf([
353-
firefox,
354-
firefoxCI
355-
]);
328+
await vi.waitFor(() => {
329+
expect((grid.element() as HTMLDivElement).style.gridTemplateColumns).toBeOneOf([
330+
firefox,
331+
firefoxCI
332+
]);
333+
});
356334
}
357335
}

test/browser/columnOrder.test.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { page } from '@vitest/browser/context';
22

33
import { DataGrid, SelectColumn, TreeDataGrid } from '../../src';
44
import type { Column } from '../../src';
5-
import { getHeaderCells } from './utils';
5+
import { testCount } from './utils';
66

77
const frozen1: Column<unknown> = {
88
key: 'f1',
@@ -26,10 +26,10 @@ const standard2: Column<unknown> = {
2626
name: 'std2'
2727
};
2828

29-
test('column order', () => {
29+
test('column order', async () => {
3030
const rows: readonly unknown[] = [];
3131

32-
function run(columns: readonly Column<unknown>[]) {
32+
async function run(columns: readonly Column<unknown>[]) {
3333
let unmount;
3434
if (groupBy === undefined) {
3535
({ unmount } = page.render(<DataGrid columns={columns} rows={rows} />));
@@ -46,31 +46,33 @@ test('column order', () => {
4646
));
4747
}
4848

49-
expect(getHeaderCells().map((c) => c.textContent)).toStrictEqual(expected);
49+
const headerCells = page.getByRole('columnheader');
50+
await testCount(headerCells, expected.length);
51+
expect(headerCells.elements().map((c) => c.textContent)).toStrictEqual(expected);
5052
unmount();
5153
}
5254

5355
let expected: readonly string[] = ['', 'frz1', 'frz2', 'std1', 'std2'];
5456
let groupBy: readonly string[] | undefined;
5557

56-
run([SelectColumn, frozen1, frozen2, standard1, standard2]);
57-
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
58-
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
59-
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
58+
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
59+
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
60+
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
61+
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);
6062

6163
expected = ['', 'std1', 'frz1', 'frz2', 'std2'];
6264
groupBy = ['s1'];
6365

64-
run([SelectColumn, frozen1, frozen2, standard1, standard2]);
65-
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
66-
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
67-
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
66+
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
67+
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
68+
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
69+
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);
6870

6971
expected = ['', 'std1', 'frz2', 'frz1', 'std2'];
7072
groupBy = ['s1', 'f2'];
7173

72-
run([SelectColumn, frozen1, frozen2, standard1, standard2]);
73-
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
74-
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
75-
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
74+
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
75+
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
76+
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
77+
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);
7678
});

0 commit comments

Comments
 (0)