Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 131 additions & 118 deletions test/browser/TreeDataGrid.test.tsx

Large diffs are not rendered by default.

43 changes: 24 additions & 19 deletions test/browser/column/grouping.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { page, userEvent } from '@vitest/browser/context';

import type { ColumnOrColumnGroup } from '../../../src';
import { getSelectedCell, setup, tabIntoGrid, validateCellPosition } from '../utils';
import {
getGrid,
getSelectedCell,
setup,
tabIntoGrid,
testCount,
validateCellPosition
} from '../utils';

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

const grid = page.getByRole('grid');
const grid = getGrid();
await expect.element(grid).toHaveAttribute('aria-colcount', '12');
await expect.element(grid).toHaveAttribute('aria-rowcount', '5');

const rows = page.getByRole('row').all();
expect(rows).toHaveLength(5);
const rows = page.getByRole('row');
await testCount(rows, 5);

await expect.element(rows[0]).toHaveAttribute('aria-rowindex', '1');
await expect.element(rows[1]).toHaveAttribute('aria-rowindex', '2');
await expect.element(rows[2]).toHaveAttribute('aria-rowindex', '3');
await expect.element(rows[3]).toHaveAttribute('aria-rowindex', '4');
await expect.element(rows[4]).toHaveAttribute('aria-rowindex', '5');
await expect.element(rows.nth(0)).toHaveAttribute('aria-rowindex', '1');
await expect.element(rows.nth(1)).toHaveAttribute('aria-rowindex', '2');
await expect.element(rows.nth(2)).toHaveAttribute('aria-rowindex', '3');
await expect.element(rows.nth(3)).toHaveAttribute('aria-rowindex', '4');
await expect.element(rows.nth(4)).toHaveAttribute('aria-rowindex', '5');

expect(rows[0].getByRole('columnheader').all()).toHaveLength(2);
expect(rows[1].getByRole('columnheader').all()).toHaveLength(2);
expect(rows[2].getByRole('columnheader').all()).toHaveLength(4);
expect(rows[3].getByRole('columnheader').all()).toHaveLength(12);
expect(rows[4].getByRole('columnheader').all()).toHaveLength(0);
await testCount(rows.nth(0).getByRole('columnheader'), 2);
await testCount(rows.nth(1).getByRole('columnheader'), 2);
await testCount(rows.nth(2).getByRole('columnheader'), 4);
await testCount(rows.nth(3).getByRole('columnheader'), 12);
await testCount(rows.nth(4).getByRole('columnheader'), 0);

const headerCells = page.getByRole('columnheader').all();
expect(headerCells).toHaveLength(20);

const headerCellDetails = headerCells.map((cellLocator) => {
const cell = cellLocator.element();
const headerCells = page.getByRole('columnheader');
await testCount(headerCells, 20);

const headerCellDetails = headerCells.elements().map((cell) => {
return {
text: cell.textContent,
colIndex: cell.getAttribute('aria-colindex'),
Expand Down
8 changes: 4 additions & 4 deletions test/browser/column/renderEditCell.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { commands, page, userEvent } from '@vitest/browser/context';

import { DataGrid } from '../../../src';
import type { Column, DataGridProps } from '../../../src';
import { getCell, getCellsAtRowIndex, getGrid, getSelectedCell } from '../utils';
import { getCell, getCellsAtRowIndex, getGrid, getSelectedCell, testCount } from '../utils';

interface Row {
col1: number;
Expand Down Expand Up @@ -98,15 +98,15 @@ describe('Editor', () => {
.getByRole('row')
.filter({ has: getSelectedCell() })
.getByRole('gridcell');
await expect.poll(() => selectedRowCells.elements().length).toBe(2);
await testCount(selectedRowCells, 2);
await commands.scrollGrid({ scrollTop: 2000 });
await expect.poll(() => selectedRowCells.elements().length).toBe(1);
await testCount(selectedRowCells, 1);
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await expect.element(editor).not.toBeInTheDocument();
expect(getGrid().element().scrollTop).toBe(2000);
// TODO: await userEvent.keyboard('123'); fails in FF
await userEvent.keyboard('{enter}123');
await expect.poll(() => selectedRowCells.elements().length).toBe(2);
await testCount(selectedRowCells, 2);
await expect.element(editor).toHaveValue(123);
expect(getGrid().element().scrollTop).toBe(0);
});
Expand Down
82 changes: 30 additions & 52 deletions test/browser/column/resizable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,25 @@ import { useState } from 'react';
import { commands, page, userEvent } from '@vitest/browser/context';

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

interface Row {
readonly col1: number;
readonly col2: string;
}

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

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

if (resizeHandle === null) {
throw new Error('Resize handle not found');
}

return resizeHandle;
}

interface ResizeArgs {
readonly column: Element;
readonly resizeBy: number | readonly number[];
}

async function resize({ column, resizeBy }: ResizeArgs) {
expect(getResizeHandle(column)).toBeInTheDocument();

await commands.resizeColumn(resizeBy);
await commands.resizeColumn('col2', resizeBy);
}

async function autoResize(column: Element) {
const resizeHandle = getResizeHandle(column);
async function autoResize(columnName: string) {
const resizeHandle = getResizeHandle(columnName);

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

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

test('should resize column when dragging the handle', async () => {
Expand All @@ -68,8 +52,7 @@ test('should resize column when dragging the handle', async () => {
const grid = getGrid();
expect(onColumnResize).not.toHaveBeenCalled();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
const [, col2] = getHeaderCells();
await resize({ column: col2, resizeBy: -50 });
await resize('col2', -50);
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 150px' });
expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(expect.objectContaining(columns[1]), 150);
});
Expand All @@ -78,17 +61,15 @@ test('should use the maxWidth if specified when dragging the handle', async () =
setup<Row, unknown>({ columns, rows: [] });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
const [, col2] = getHeaderCells();
await resize({ column: col2, resizeBy: 1000 });
await resize('col2', 1000);
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
});

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

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

await userEvent.keyboard('{Control>}{ArrowRight}{/Control}');
Expand All @@ -116,7 +97,7 @@ test('should use the maxWidth if specified when resizing using keyboard', async
setup<Row, unknown>({ columns, rows: [], onColumnResize });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
const [, col2] = getHeaderCells();
const col2 = getHeaderCell('col2');
await userEvent.click(col2);
await userEvent.keyboard(`{Control>}${'{ArrowRight}'.repeat(22)}{/Control}`);
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
Expand All @@ -128,7 +109,7 @@ test('should use the minWidth if specified resizing using keyboard', async () =>
setup<Row, unknown>({ columns, rows: [], onColumnResize });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
const [, col2] = getHeaderCells();
const col2 = getHeaderCell('col2');
await userEvent.click(col2);
await userEvent.keyboard(`{Control>}${'{ArrowLeft}'.repeat(12)}{/Control}`);
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 100px' });
Expand All @@ -149,8 +130,7 @@ test('should auto resize column when resize handle is double clicked', async ()
});
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
const [, col2] = getHeaderCells();
await autoResize(col2);
await autoResize('col2');
await testGridTemplateColumns('100px 327.703px', '100px 327.833px', '100px 400px');
expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining(columns[1]),
Expand All @@ -177,8 +157,7 @@ test('should use the maxWidth if specified on auto resize', async () => {
});
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
const [, col2] = getHeaderCells();
await autoResize(col2);
await autoResize('col2');
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 400px' });
});

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

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

await testGridTemplateColumns('639.328px 639.328px 639.344px', '639.333px 639.333px 639.333px');
const [col1] = getHeaderCells();
await autoResize(col1);
await autoResize('col1');
await testGridTemplateColumns(
'79.1406px 919.422px 919.438px',
'79.1667px 919.417px 919.417px',
'100.5px 908.75px 908.75px'
);
expect(onColumnResize).toHaveBeenCalledOnce();
// onColumnResize is not called if width is not changed
await autoResize(col1);
await autoResize('col1');
await testGridTemplateColumns(
'79.1406px 919.422px 919.438px',
'79.1667px 919.417px 919.417px',
Expand Down Expand Up @@ -302,8 +279,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy

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

await resize({ column: col2, resizeBy: [5, 5, 5] });
await resize('col2', [5, 5, 5]);
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
new Map([
['col1', { width: 101, type: 'measured' }],
Expand All @@ -335,7 +311,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
expect(onColumnWidthsChangeSpy).not.toHaveBeenCalled();
expect(onColumnResizeSpy).not.toHaveBeenCalled();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '120px 120px' });
await resize({ column: col2, resizeBy: [5, 5] });
await resize('col2', [5, 5]);
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
new Map([
['col1', { width: 120, type: 'measured' }],
Expand All @@ -349,9 +325,11 @@ async function testGridTemplateColumns(chrome: string, firefox: string, firefoxC
if (navigator.userAgent.includes('Chrome')) {
await expect.element(grid).toHaveStyle({ gridTemplateColumns: chrome });
} else {
expect((grid.element() as HTMLDivElement).style.gridTemplateColumns).toBeOneOf([
firefox,
firefoxCI
]);
await vi.waitFor(() => {
Copy link
Collaborator Author

@amanmahajan7 amanmahajan7 Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expect((grid.element() as HTMLDivElement).style.gridTemplateColumns).toBeOneOf([
firefox,
firefoxCI
]);
});
}
}
34 changes: 18 additions & 16 deletions test/browser/columnOrder.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { page } from '@vitest/browser/context';

import { DataGrid, SelectColumn, TreeDataGrid } from '../../src';
import type { Column } from '../../src';
import { getHeaderCells } from './utils';
import { testCount } from './utils';

const frozen1: Column<unknown> = {
key: 'f1',
Expand All @@ -26,10 +26,10 @@ const standard2: Column<unknown> = {
name: 'std2'
};

test('column order', () => {
test('column order', async () => {
const rows: readonly unknown[] = [];

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

expect(getHeaderCells().map((c) => c.textContent)).toStrictEqual(expected);
const headerCells = page.getByRole('columnheader');
await testCount(headerCells, expected.length);
expect(headerCells.elements().map((c) => c.textContent)).toStrictEqual(expected);
unmount();
}

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

run([SelectColumn, frozen1, frozen2, standard1, standard2]);
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);

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

run([SelectColumn, frozen1, frozen2, standard1, standard2]);
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);

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

run([SelectColumn, frozen1, frozen2, standard1, standard2]);
run([standard1, standard2, SelectColumn, frozen1, frozen2]);
run([standard1, standard2, frozen1, SelectColumn, frozen2]);
run([standard1, frozen1, standard2, frozen2, SelectColumn]);
await run([SelectColumn, frozen1, frozen2, standard1, standard2]);
await run([standard1, standard2, SelectColumn, frozen1, frozen2]);
await run([standard1, standard2, frozen1, SelectColumn, frozen2]);
await run([standard1, frozen1, standard2, frozen2, SelectColumn]);
});
Loading