diff --git a/.gitignore b/.gitignore
index 9ad8d4c877..202fe72c65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ __screenshots__
npm-debug.log
**.orig
.idea
+.vitest-attachments
+
+__traces__
diff --git a/README.md b/README.md
index bde3617286..767c603769 100644
--- a/README.md
+++ b/README.md
@@ -579,8 +579,8 @@ function MyGrid() {
return ;
}
-test('grid', () => {
- render();
+test('grid', async () => {
+ await render();
const grid = screen.getByRole('grid', { name: 'my-grid' });
});
```
diff --git a/package.json b/package.json
index 2e7867fa8b..62d695689e 100644
--- a/package.json
+++ b/package.json
@@ -64,8 +64,8 @@
"@typescript-eslint/eslint-plugin": "^8.39.1",
"@typescript-eslint/parser": "^8.39.1",
"@vitejs/plugin-react": "5.0.2",
- "@vitest/browser": "^3.2.4",
- "@vitest/coverage-istanbul": "^3.2.4",
+ "@vitest/browser-playwright": "^4.0.1",
+ "@vitest/coverage-istanbul": "^4.0.1",
"@vitest/eslint-plugin": "^1.3.4",
"@wyw-in-js/rollup": "^0.7.0",
"@wyw-in-js/vite": "^0.7.0",
@@ -78,7 +78,7 @@
"eslint-plugin-testing-library": "^7.10.0",
"jspdf": "^3.0.1",
"jspdf-autotable": "^5.0.2",
- "playwright": "^1.54.2",
+ "playwright": "^1.56.1",
"postcss": "^8.5.2",
"prettier": "3.6.2",
"react": "^19.2.0",
@@ -87,8 +87,8 @@
"rolldown-plugin-dts": "^0.16.1",
"typescript": "~5.9.2",
"vite": "npm:rolldown-vite@^7.1.3",
- "vitest": "^3.2.4",
- "vitest-browser-react": "^1.0.1"
+ "vitest": "^4.0.1",
+ "vitest-browser-react": "^2.0.0"
},
"peerDependencies": {
"react": "^19.2",
diff --git a/test/browser/TextEditor.test.tsx b/test/browser/TextEditor.test.tsx
index 2afa699dc0..81161b45b2 100644
--- a/test/browser/TextEditor.test.tsx
+++ b/test/browser/TextEditor.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid, textEditor } from '../../src';
import type { Column } from '../../src';
@@ -27,7 +27,7 @@ function Test() {
}
test('TextEditor', async () => {
- page.render();
+ await page.render();
const cell = page.getByRole('gridcell');
await expect.element(cell).toHaveTextContent(/^Tacitus Kilgore$/);
await userEvent.dblClick(cell);
diff --git a/test/browser/TreeDataGrid.test.tsx b/test/browser/TreeDataGrid.test.tsx
index d303bcff03..160d577e84 100644
--- a/test/browser/TreeDataGrid.test.tsx
+++ b/test/browser/TreeDataGrid.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import type { Column } from '../../src';
import { SelectColumn, textEditor, TreeDataGrid } from '../../src';
@@ -136,7 +136,7 @@ function rowGrouper(rows: readonly Row[], columnKey: string) {
}
function setup(groupBy: string[], groupIdGetter?: (groupKey: string, parentId?: string) => string) {
- page.render();
+ return page.render();
}
async function testHeaderCellsContent(expected: readonly string[]) {
@@ -147,27 +147,27 @@ async function testHeaderCellsContent(expected: readonly string[]) {
}
test('should not group if groupBy is empty', async () => {
- setup([]);
+ await setup([]);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '7');
await testHeaderCellsContent(['', 'Sport', 'Country', 'Year', 'Id']);
await testRowCount(7);
});
test('should not group if column does not exist', async () => {
- setup(['abc']);
+ await setup(['abc']);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '7');
await testRowCount(7);
});
test('should group by single column', async () => {
- setup(['country']);
+ await setup(['country']);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '9');
await testHeaderCellsContent(['', 'Country', 'Sport', 'Year', 'Id']);
await testRowCount(5);
});
test('should group by multiple columns', async () => {
- setup(['country', 'year']);
+ await setup(['country', 'year']);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '13');
await testHeaderCellsContent(['', 'Country', 'Year', 'Sport', 'Id']);
await testRowCount(5);
@@ -177,7 +177,7 @@ test('should use groupIdGetter when provided', async () => {
const groupIdGetter = vi.fn((groupKey: string, parentId?: string) =>
parentId !== undefined ? `${groupKey}#${parentId}` : groupKey
);
- setup(['country', 'year'], groupIdGetter);
+ await setup(['country', 'year'], groupIdGetter);
expect(groupIdGetter).toHaveBeenCalled();
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '13');
await testHeaderCellsContent(['', 'Country', 'Year', 'Sport', 'Id']);
@@ -193,20 +193,20 @@ test('should use groupIdGetter when provided', async () => {
});
test('should ignore duplicate groupBy columns', async () => {
- setup(['year', 'year', 'year']);
+ await setup(['year', 'year', 'year']);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '10');
await testRowCount(6);
});
test('should use groupBy order while grouping', async () => {
- setup(['year', 'country']);
+ await setup(['year', 'country']);
await expect.element(getTreeGrid()).toHaveAttribute('aria-rowcount', '14');
await testHeaderCellsContent(['', 'Year', 'Country', 'Sport', 'Id']);
await testRowCount(6);
});
test('should toggle group when group cell is clicked', async () => {
- setup(['year']);
+ await setup(['year']);
await testRowCount(6);
const groupCell = getCell('2021');
await userEvent.click(groupCell);
@@ -216,7 +216,7 @@ test('should toggle group when group cell is clicked', async () => {
});
test('should toggle group using keyboard', async () => {
- setup(['year']);
+ await setup(['year']);
await testRowCount(6);
const groupCell = getCell('2021');
await userEvent.click(groupCell);
@@ -231,7 +231,7 @@ test('should toggle group using keyboard', async () => {
});
test('should set aria-attributes', async () => {
- setup(['year', 'country']);
+ await setup(['year', 'country']);
const groupRow1 = getRowByCellName('2020');
await expect.element(groupRow1).toHaveAttribute('aria-level', '1');
@@ -264,7 +264,7 @@ test('should set aria-attributes', async () => {
});
test('should select rows in a group', async () => {
- setup(['year', 'country']);
+ await setup(['year', 'country']);
const headerCheckbox = getSelectAllCheckbox();
await expect.element(headerCheckbox).not.toBeChecked();
@@ -316,7 +316,7 @@ test('should select rows in a group', async () => {
});
test('cell navigation in a treegrid', async () => {
- setup(['country', 'year']);
+ await setup(['country', 'year']);
await testRowCount(5);
const focusSink = page.getBySelector(`.${focusSinkClassname}`);
@@ -399,7 +399,7 @@ test('cell navigation in a treegrid', async () => {
});
test('copy/paste when grouping is enabled', async () => {
- setup(['year']);
+ await setup(['year']);
await userEvent.click(getCell('2021'));
await userEvent.copy();
expect(onCellCopySpy).not.toHaveBeenCalled();
@@ -434,7 +434,7 @@ test('copy/paste when grouping is enabled', async () => {
});
test('update row using cell renderer', async () => {
- setup(['year']);
+ await setup(['year']);
await userEvent.click(getCell('2021'));
await userEvent.click(getCell('USA'));
await userEvent.keyboard('{arrowright}{arrowright}');
@@ -444,7 +444,7 @@ test('update row using cell renderer', async () => {
});
test('custom renderGroupCell', async () => {
- setup(['country']);
+ await setup(['country']);
await expect.element(getRowByCellName('USA').getByRole('gridcell').nth(4)).toHaveTextContent('1');
await expect
.element(getRowByCellName('Canada').getByRole('gridcell').nth(4))
diff --git a/test/browser/column/cellClass.test.ts b/test/browser/column/cellClass.test.ts
index d86d3c98ca..811e774ed4 100644
--- a/test/browser/column/cellClass.test.ts
+++ b/test/browser/column/cellClass.test.ts
@@ -15,7 +15,7 @@ test('cellClass is undefined', async () => {
name: 'ID'
}
];
- setup({ columns, rows });
+ await setup({ columns, rows });
const [cell1, cell2] = getCellsNew('0', '1');
await expect.element(cell1).toHaveClass(cellClassname, { exact: true });
await expect.element(cell2).toHaveClass(cellClassname, { exact: true });
@@ -29,7 +29,7 @@ test('cellClass is a string', async () => {
cellClass: 'my-cell'
}
];
- setup({ columns, rows });
+ await setup({ columns, rows });
const [cell1, cell2] = getCellsNew('0', '1');
await expect.element(cell1).toHaveClass(`${cellClassname} my-cell`, { exact: true });
await expect.element(cell2).toHaveClass(`${cellClassname} my-cell`, { exact: true });
@@ -43,7 +43,7 @@ test('cellClass returns a string', async () => {
cellClass: (row) => `my-cell-${row.id}`
}
];
- setup({ columns, rows });
+ await setup({ columns, rows });
const [cell1, cell2] = getCellsNew('0', '1');
await expect.element(cell1).toHaveClass(`${cellClassname} my-cell-0`, { exact: true });
await expect.element(cell2).toHaveClass(`${cellClassname} my-cell-1`, { exact: true });
@@ -57,7 +57,7 @@ test('cellClass returns undefined', async () => {
cellClass: () => undefined
}
];
- setup({ columns, rows });
+ await setup({ columns, rows });
const [cell1, cell2] = getCellsNew('0', '1');
await expect.element(cell1).toHaveClass(cellClassname, { exact: true });
await expect.element(cell2).toHaveClass(cellClassname, { exact: true });
diff --git a/test/browser/column/colSpan.test.ts b/test/browser/column/colSpan.test.ts
index 0e487cd0f0..4b93ca1889 100644
--- a/test/browser/column/colSpan.test.ts
+++ b/test/browser/column/colSpan.test.ts
@@ -1,10 +1,10 @@
-import { userEvent } from '@vitest/browser/context';
+import { userEvent } from 'vitest/browser';
import type { Column } from '../../../src';
import { getCellsAtRowIndex, getHeaderCells, setup, validateCellPosition } from '../utils';
describe('colSpan', () => {
- function setupColSpanGrid(colCount = 15) {
+ function setupColSpan(colCount = 15) {
type Row = number;
const columns: Column[] = [];
const rows: readonly Row[] = Array.from({ length: 10 }, (_, i) => i);
@@ -34,11 +34,11 @@ describe('colSpan', () => {
}
});
}
- setup({ columns, rows, bottomSummaryRows: [1, 2], topSummaryRows: [1, 2] });
+ return setup({ columns, rows, bottomSummaryRows: [1, 2], topSummaryRows: [1, 2] });
}
- it('should merges cells', () => {
- setupColSpanGrid();
+ it('should merges cells', async () => {
+ await setupColSpan();
// header
expect(getHeaderCells()).toHaveLength(13);
@@ -93,7 +93,7 @@ describe('colSpan', () => {
});
it('should navigate between merged cells', async () => {
- setupColSpanGrid();
+ await setupColSpan();
// header row
await userEvent.click(getHeaderCells()[7]);
await validateCellPosition(7, 0);
@@ -171,7 +171,7 @@ describe('colSpan', () => {
});
it('should scroll to the merged cell when selected', async () => {
- setupColSpanGrid(30);
+ await setupColSpan(30);
await userEvent.click(getCellsAtRowIndex(10)[23]); // last visible cell (1920/80)
const spy = vi.spyOn(window.HTMLElement.prototype, 'scrollIntoView');
const testScrollIntoView = () => {
diff --git a/test/browser/column/draggable.test.ts b/test/browser/column/draggable.test.ts
index e32e0a9e23..0c8cf43eed 100644
--- a/test/browser/column/draggable.test.ts
+++ b/test/browser/column/draggable.test.ts
@@ -1,4 +1,4 @@
-import { userEvent } from '@vitest/browser/context';
+import { userEvent } from 'vitest/browser';
import type { Column } from '../../../src';
import { getHeaderCellsNew, setup } from '../utils';
@@ -27,7 +27,7 @@ const columns: readonly Column[] = [
test('draggable columns', async () => {
const onColumnsReorder = vi.fn();
- setup({ columns, rows: [], onColumnsReorder });
+ await setup({ columns, rows: [], onColumnsReorder });
const [cell1, cell2, cell3, cell4] = getHeaderCellsNew('col1', 'col2', 'col3', 'col4');
await expect.element(cell1).not.toHaveAttribute('draggable');
diff --git a/test/browser/column/frozen.test.ts b/test/browser/column/frozen.test.ts
index 4223a06a4e..7776be7ce1 100644
--- a/test/browser/column/frozen.test.ts
+++ b/test/browser/column/frozen.test.ts
@@ -1,4 +1,4 @@
-import { page } from '@vitest/browser/context';
+import { page } from 'vitest/browser';
import type { Column } from '../../../src';
import { cellClassname, cellFrozenClassname } from '../../../src/style/cell';
@@ -27,7 +27,7 @@ test('frozen column have a specific class, and are stable-sorted before non-froz
}
];
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
await expect.element(page.getByRole('row')).toHaveTextContent('col1col3col2col4');
const [cell1, cell2, cell3, cell4] = getHeaderCellsNew('col1', 'col2', 'col3', 'col4');
diff --git a/test/browser/column/grouping.test.ts b/test/browser/column/grouping.test.ts
index 9234755ba5..cb0b3fb9d2 100644
--- a/test/browser/column/grouping.test.ts
+++ b/test/browser/column/grouping.test.ts
@@ -1,4 +1,4 @@
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import type { ColumnOrColumnGroup } from '../../../src';
import {
@@ -95,7 +95,7 @@ const columns: readonly ColumnOrColumnGroup>[] = [
];
test('grouping', async () => {
- setup({ columns, rows: [{}] });
+ await setup({ columns, rows: [{}] });
const grid = getGrid();
await expect.element(grid).toHaveAttribute('aria-colcount', '12');
@@ -253,7 +253,7 @@ test('grouping', async () => {
});
test('keyboard navigation', async () => {
- setup({ columns, rows: [{}] }, true);
+ await setup({ columns, rows: [{}] }, true);
// no initial selection
await expect.element(getSelectedCell()).not.toBeInTheDocument();
diff --git a/test/browser/column/headerCellClass.test.ts b/test/browser/column/headerCellClass.test.ts
index 8b292c626f..b31f00c4df 100644
--- a/test/browser/column/headerCellClass.test.ts
+++ b/test/browser/column/headerCellClass.test.ts
@@ -2,7 +2,7 @@ import type { Column, ColumnGroup } from '../../../src';
import { cellClassname } from '../../../src/style/cell';
import { getHeaderCells, setup } from '../utils';
-test('headerCellClass is either nullish or a string', () => {
+test('headerCellClass is either nullish or a string', async () => {
const columns: readonly Column[] = [
{
key: 'id',
@@ -15,13 +15,13 @@ test('headerCellClass is either nullish or a string', () => {
}
];
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const [cell1, cell2] = getHeaderCells();
expect(cell1).toHaveClass(cellClassname, { exact: true });
expect(cell2).toHaveClass(`${cellClassname} my-header`, { exact: true });
});
-test('columnGroup.headerCellClass is either nullish or a string', () => {
+test('columnGroup.headerCellClass is either nullish or a string', async () => {
const columns: readonly ColumnGroup[] = [
{
name: 'Group 1',
@@ -34,7 +34,7 @@ test('columnGroup.headerCellClass is either nullish or a string', () => {
}
];
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const [cell1, cell2] = getHeaderCells();
expect(cell1).toHaveClass(cellClassname, { exact: true });
expect(cell2).toHaveClass(`${cellClassname} my-header`, { exact: true });
diff --git a/test/browser/column/key.test.ts b/test/browser/column/key.test.ts
index 497b48b224..07ef5b4fe4 100644
--- a/test/browser/column/key.test.ts
+++ b/test/browser/column/key.test.ts
@@ -9,7 +9,7 @@ test('key is escaped in query selectors', () => {
}
];
- expect(() => {
- setup({ columns, rows: [] });
+ expect(async () => {
+ await setup({ columns, rows: [] });
}).not.toThrow();
});
diff --git a/test/browser/column/name.test.tsx b/test/browser/column/name.test.tsx
index 73b681120d..21bf572fbd 100644
--- a/test/browser/column/name.test.tsx
+++ b/test/browser/column/name.test.tsx
@@ -17,7 +17,7 @@ test('name is either a string or an element', async () => {
}
];
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const [cell1, cell2] = getHeaderCellsNew('ID', 'Fancy');
await expect.element(cell1).toBeVisible();
await expect.element(cell2).toBeVisible();
diff --git a/test/browser/column/renderCell.test.tsx b/test/browser/column/renderCell.test.tsx
index ffd7f8d649..e62903ce20 100644
--- a/test/browser/column/renderCell.test.tsx
+++ b/test/browser/column/renderCell.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../../src';
import type { Column } from '../../../src';
@@ -18,15 +18,15 @@ describe('renderValue', () => {
const rows: readonly Row[] = [{ id: 101 }];
- it('should be used by default', () => {
- setup({ columns, rows });
+ it('should be used by default', async () => {
+ await setup({ columns, rows });
const [cell1, cell2] = getCells();
expect(cell1).toHaveTextContent('101');
expect(cell2).toBeEmptyDOMElement();
});
- it('should handle non-object values', () => {
- setup({ columns, rows: [null] });
+ it('should handle non-object values', async () => {
+ await setup({ columns, rows: [null] });
const [cell1, cell2] = getCells();
expect(cell1).toBeEmptyDOMElement();
expect(cell2).toBeEmptyDOMElement();
@@ -49,8 +49,8 @@ describe('Custom cell renderer', () => {
const rows: readonly Row[] = [{ id: 101 }];
- it('should replace the default cell renderer', () => {
- setup({ columns, rows });
+ it('should replace the default cell renderer', async () => {
+ await setup({ columns, rows });
const [cell1, cell2] = getCells();
expect(cell1).toHaveTextContent('#101');
expect(cell2).toHaveTextContent('No name');
@@ -90,7 +90,7 @@ describe('Custom cell renderer', () => {
);
}
- page.render();
+ await page.render();
const [cell] = getCells();
expect(cell).toHaveTextContent('value: 1');
@@ -135,7 +135,7 @@ test('Focus child if it sets tabIndex', async () => {
}
};
- page.render();
+ await page.render();
const button1 = page.getByRole('button', { name: 'Button 1' });
const button2 = page.getByRole('button', { name: 'Button 2' });
@@ -190,7 +190,7 @@ test('Cell should not steal focus when the focus is outside the grid and cell is
);
}
- page.render();
+ await page.render();
await userEvent.click(getCellsAtRowIndex(0)[0]);
expect(getCellsAtRowIndex(0)[0]).toHaveFocus();
diff --git a/test/browser/column/renderEditCell.test.tsx b/test/browser/column/renderEditCell.test.tsx
index 95f358d861..dedd460149 100644
--- a/test/browser/column/renderEditCell.test.tsx
+++ b/test/browser/column/renderEditCell.test.tsx
@@ -1,6 +1,6 @@
import { useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
-import { commands, page, userEvent } from '@vitest/browser/context';
+import { commands, page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../../src';
import type { Column, DataGridProps } from '../../../src';
@@ -13,7 +13,7 @@ interface Row {
describe('Editor', () => {
it('should open editor on double click', async () => {
- page.render();
+ await page.render();
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await userEvent.click(getCellsAtRowIndex(0)[0]);
await expect.element(editor).not.toBeInTheDocument();
@@ -26,7 +26,7 @@ describe('Editor', () => {
});
it('should open and commit changes on enter', async () => {
- page.render();
+ await page.render();
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await userEvent.click(getCellsAtRowIndex(0)[0]);
await expect.element(editor).not.toBeInTheDocument();
@@ -39,7 +39,7 @@ describe('Editor', () => {
});
it('should open editor when user types', async () => {
- page.render();
+ await page.render();
await userEvent.click(getCellsAtRowIndex(0)[0]);
// TODO: await userEvent.keyboard('123{enter}'); fails in FF
await userEvent.keyboard('{enter}123{enter}');
@@ -47,7 +47,7 @@ describe('Editor', () => {
});
it('should close editor and discard changes on escape', async () => {
- page.render();
+ await page.render();
await userEvent.dblClick(getCellsAtRowIndex(0)[0]);
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await expect.element(editor).toHaveValue(1);
@@ -58,7 +58,7 @@ describe('Editor', () => {
});
it('should commit changes and close editor when clicked outside', async () => {
- page.render();
+ await page.render();
await userEvent.dblClick(getCellsAtRowIndex(0)[0]);
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await expect.element(editor).toHaveValue(1);
@@ -70,7 +70,7 @@ describe('Editor', () => {
it('should commit quickly enough on outside clicks so click event handlers access the latest rows state', async () => {
const onSave = vi.fn();
- page.render();
+ await page.render();
await userEvent.dblClick(getCellsAtRowIndex(0)[0]);
await userEvent.keyboard('234');
expect(onSave).not.toHaveBeenCalled();
@@ -92,18 +92,18 @@ describe('Editor', () => {
rows.push({ col1: i, col2: `${i}` });
}
- page.render();
+ await page.render();
await userEvent.click(getCellsAtRowIndex(0)[0]);
const selectedRowCells = page
.getByRole('row')
.filter({ has: getSelectedCell() })
.getByRole('gridcell');
await testCount(selectedRowCells, 2);
- await commands.scrollGrid({ scrollTop: 2000 });
+ await commands.scrollGrid({ scrollTop: 2001 });
await testCount(selectedRowCells, 1);
const editor = page.getByRole('spinbutton', { name: 'col1-editor' });
await expect.element(editor).not.toBeInTheDocument();
- expect(getGrid().element().scrollTop).toBe(2000);
+ expect(getGrid().element().scrollTop).toBe(2001);
// TODO: await userEvent.keyboard('123'); fails in FF
await userEvent.keyboard('{enter}123');
await testCount(selectedRowCells, 2);
@@ -113,7 +113,7 @@ describe('Editor', () => {
describe('editable', () => {
it('should be editable if an editor is specified and editable is undefined/null', async () => {
- page.render();
+ await page.render();
const cell = getCellsAtRowIndex(0)[1];
expect(cell).not.toHaveAttribute('aria-readonly');
await userEvent.dblClick(cell);
@@ -121,13 +121,13 @@ describe('Editor', () => {
});
it('should be editable if an editor is specified and editable is set to true', async () => {
- page.render();
+ await page.render();
await userEvent.dblClick(getCellsAtRowIndex(0)[1]);
await expect.element(page.getByRole('textbox', { name: 'col2-editor' })).toBeInTheDocument();
});
it('should not be editable if editable is false', async () => {
- page.render();
+ await page.render();
const cell = getCellsAtRowIndex(0)[1];
expect(cell).toHaveAttribute('aria-readonly', 'true');
await userEvent.dblClick(cell);
@@ -138,7 +138,7 @@ describe('Editor', () => {
});
it('should not be editable if editable function returns false', async () => {
- page.render( row.col1 === 2} />);
+ await page.render( row.col1 === 2} />);
await userEvent.dblClick(getCellsAtRowIndex(0)[1]);
const editor = page.getByRole('textbox', { name: 'col2-editor' });
await expect.element(editor).not.toBeInTheDocument();
@@ -150,7 +150,9 @@ describe('Editor', () => {
describe('editorOptions', () => {
it('should detect outside click if editor is rendered in a portal', async () => {
- page.render();
+ await page.render(
+
+ );
await userEvent.dblClick(getCellsAtRowIndex(0)[1]);
const editor1 = page.getByRole('textbox', { name: 'col2-editor' });
await expect.element(editor1).toHaveValue('a1');
@@ -172,7 +174,7 @@ describe('Editor', () => {
});
it('should not commit on outside click if commitOnOutsideClick is false', async () => {
- page.render(
+ await page.render(
{
});
it('should not open editor if onCellKeyDown prevents the default event', async () => {
- page.render(
+ await page.render(
{
if (args.mode === 'SELECT' && event.key === 'x') {
@@ -210,7 +212,7 @@ describe('Editor', () => {
});
it('should prevent navigation if onCellKeyDown prevents the default event', async () => {
- page.render(
+ await page.render(
{
if (args.mode === 'EDIT' && event.key === 'ArrowDown') {
@@ -226,7 +228,7 @@ describe('Editor', () => {
});
it('should close the editor when closeOnExternalRowChange is true or undefined and row is changed from outside', async () => {
- page.render(
+ await page.render(
{
});
it('should not close the editor when closeOnExternalRowChange is false and row is changed from outside', async () => {
- page.render(
+ await page.render(
{
rows.push({ col1: i, col2: `name${i}` });
}
- page.render();
+ await page.render();
await userEvent.dblClick(getCell('name0'));
await userEvent.keyboard('abc');
@@ -308,7 +310,7 @@ describe('Editor', () => {
}
];
- page.render(
+ await page.render(
<>
diff --git a/test/browser/column/renderHeaderCell.test.tsx b/test/browser/column/renderHeaderCell.test.tsx
index 030efedb33..e7ad327e99 100644
--- a/test/browser/column/renderHeaderCell.test.tsx
+++ b/test/browser/column/renderHeaderCell.test.tsx
@@ -1,7 +1,7 @@
import type { Column } from '../../../src';
import { getHeaderCells, setup } from '../utils';
-test('renderHeaderCell is either undefined or a component', () => {
+test('renderHeaderCell is either undefined or a component', async () => {
const columns: readonly Column[] = [
{
key: 'id',
@@ -14,7 +14,7 @@ test('renderHeaderCell is either undefined or a component', () => {
}
];
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const [cell1, cell2] = getHeaderCells();
expect(cell1).toHaveTextContent('ID');
expect(cell2).toHaveTextContent('Fancy! Name');
diff --git a/test/browser/column/renderSummaryCell.test.tsx b/test/browser/column/renderSummaryCell.test.tsx
index 50b471a789..ed40ce23bd 100644
--- a/test/browser/column/renderSummaryCell.test.tsx
+++ b/test/browser/column/renderSummaryCell.test.tsx
@@ -21,8 +21,8 @@ const columns: readonly Column[] = [
}
];
-test('renderSummaryCell', () => {
- setup({
+test('renderSummaryCell', async () => {
+ await setup({
columns,
rows: [],
topSummaryRows: [
diff --git a/test/browser/column/resizable.test.tsx b/test/browser/column/resizable.test.tsx
index f17eb1b286..e6d85a0b8f 100644
--- a/test/browser/column/resizable.test.tsx
+++ b/test/browser/column/resizable.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { commands, page, userEvent } from '@vitest/browser/context';
+import { commands, page, userEvent } from 'vitest/browser';
import { DataGrid, type Column, type ColumnWidth, type ColumnWidths } from '../../../src';
import { getGrid, getHeaderCell, setup } from '../utils';
@@ -10,6 +10,7 @@ interface Row {
}
function getResizeHandle(name: string) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
return getHeaderCell(name).getBySelector('.rdg-resize-handle');
}
@@ -42,23 +43,26 @@ const columns: readonly Column[] = [
];
test('cannot resize or auto resize column when resizable is not specified', async () => {
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
await expect.element(getResizeHandle('col1')).not.toBeInTheDocument();
});
test('should resize column when dragging the handle', async () => {
const onColumnResize = vi.fn();
- setup({ columns, rows: [], onColumnResize });
+ await setup({ columns, rows: [], onColumnResize });
const grid = getGrid();
expect(onColumnResize).not.toHaveBeenCalled();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
await resize('col2', -50);
- await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 150px' });
- expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(expect.objectContaining(columns[1]), 150);
+ await testGridTemplateColumns('100px 150px', '100px 150.5px');
+ expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(
+ expect.objectContaining(columns[1]),
+ satisfyRange(150)
+ );
});
test('should use the maxWidth if specified when dragging the handle', async () => {
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
await resize('col2', 1000);
@@ -66,7 +70,7 @@ test('should use the maxWidth if specified when dragging the handle', async () =
});
test('should use the minWidth if specified when dragging the handle', async () => {
- setup({ columns, rows: [] });
+ await setup({ columns, rows: [] });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
await resize('col2', -150);
@@ -75,7 +79,7 @@ test('should use the minWidth if specified when dragging the handle', async () =
test('should resize column using keboard', async () => {
const onColumnResize = vi.fn();
- setup({ columns, rows: [], onColumnResize });
+ await setup({ columns, rows: [], onColumnResize });
const grid = getGrid();
expect(onColumnResize).not.toHaveBeenCalled();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
@@ -94,7 +98,7 @@ test('should resize column using keboard', async () => {
test('should use the maxWidth if specified when resizing using keyboard', async () => {
const onColumnResize = vi.fn();
- setup({ columns, rows: [], onColumnResize });
+ await setup({ columns, rows: [], onColumnResize });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px ' });
const col2 = getHeaderCell('col2');
@@ -106,7 +110,7 @@ test('should use the maxWidth if specified when resizing using keyboard', async
test('should use the minWidth if specified resizing using keyboard', async () => {
const onColumnResize = vi.fn();
- setup({ columns, rows: [], onColumnResize });
+ await setup({ columns, rows: [], onColumnResize });
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' });
const col2 = getHeaderCell('col2');
@@ -118,7 +122,7 @@ test('should use the minWidth if specified resizing using keyboard', async () =>
test('should auto resize column when resize handle is double clicked', async () => {
const onColumnResize = vi.fn();
- setup({
+ await setup({
columns,
rows: [
{
@@ -146,7 +150,7 @@ test('should auto resize column when resize handle is double clicked', async ()
});
test('should use the maxWidth if specified on auto resize', async () => {
- setup({
+ await setup({
columns,
rows: [
{
@@ -162,7 +166,7 @@ test('should use the maxWidth if specified on auto resize', async () => {
});
test('should use the minWidth if specified on auto resize', async () => {
- setup({
+ await setup({
columns,
rows: [
{
@@ -179,7 +183,7 @@ test('should use the minWidth if specified on auto resize', async () => {
test('should remeasure flex columns when resizing a column', async () => {
const onColumnResize = vi.fn();
- setup<
+ await setup<
{
readonly col1: string;
readonly col2: string;
@@ -275,7 +279,7 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
);
}
- page.render();
+ await page.render();
const grid = getGrid();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '101px 201px' });
@@ -301,8 +305,16 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
])
);
expect(onColumnResizeSpy).toHaveBeenCalledTimes(3);
- expect(onColumnResizeSpy).toHaveBeenNthCalledWith(1, expect.objectContaining(columns[1]), 105);
- expect(onColumnResizeSpy).toHaveBeenNthCalledWith(2, expect.objectContaining(columns[1]), 110);
+ expect(onColumnResizeSpy).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining(columns[1]),
+ satisfyRange(105)
+ );
+ expect(onColumnResizeSpy).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining(columns[1]),
+ satisfyRange(110)
+ );
expect(onColumnResizeSpy).toHaveBeenNthCalledWith(3, expect.objectContaining(columns[1]), 115);
onColumnWidthsChangeSpy.mockClear();
onColumnResizeSpy.mockClear();
@@ -312,10 +324,11 @@ test('should use columnWidths and onColumnWidthsChange props when provided', asy
expect(onColumnResizeSpy).not.toHaveBeenCalled();
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '120px 120px' });
await resize('col2', [5, 5]);
+ const col2Width = navigator.userAgent.includes('Chrome') ? 130 : 130.5;
expect(onColumnWidthsChangeSpy).toHaveBeenCalledExactlyOnceWith(
new Map([
['col1', { width: 120, type: 'measured' }],
- ['col2', { width: 130, type: 'resized' }]
+ ['col2', { width: col2Width, type: 'resized' }]
])
);
});
@@ -333,3 +346,9 @@ async function testGridTemplateColumns(chrome: string, firefox: string, firefoxC
});
}
}
+
+// TODO: remove once scale is set to 1
+function satisfyRange(value: number) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
+ return expect.toSatisfy((v: number) => v >= value - 1 && v <= value + 1);
+}
diff --git a/test/browser/column/summaryCellClass.test.ts b/test/browser/column/summaryCellClass.test.ts
index cc51c8cae3..cab3d9e7cb 100644
--- a/test/browser/column/summaryCellClass.test.ts
+++ b/test/browser/column/summaryCellClass.test.ts
@@ -11,20 +11,20 @@ const cellClassname = `${cellClass} ${summaryCellClassname}`;
const topSummaryRows: readonly SummaryRow[] = [{ id: 0 }, { id: 1 }];
const bottomSummaryRows: readonly SummaryRow[] = [{ id: 2 }, { id: 3 }];
-test('summaryCellClass is undefined', () => {
+test('summaryCellClass is undefined', async () => {
const columns: readonly Column[] = [
{
key: 'id',
name: 'ID'
}
];
- setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
+ await setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
const [cell1, cell2] = getCells();
expect(cell1).toHaveClass(cellClassname, { exact: true });
expect(cell2).toHaveClass(cellClassname, { exact: true });
});
-test('summaryCellClass is a string', () => {
+test('summaryCellClass is a string', async () => {
const columns: readonly Column[] = [
{
key: 'id',
@@ -32,14 +32,14 @@ test('summaryCellClass is a string', () => {
summaryCellClass: 'my-cell'
}
];
- setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
+ await setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
const cells = getCells();
for (const cell of cells) {
expect(cell).toHaveClass(`${cellClassname} my-cell`, { exact: true });
}
});
-test('summaryCellClass returns a string', () => {
+test('summaryCellClass returns a string', async () => {
const columns: readonly Column[] = [
{
key: 'id',
@@ -47,7 +47,7 @@ test('summaryCellClass returns a string', () => {
summaryCellClass: (row) => `my-cell-${row.id}`
}
];
- setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
+ await setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
const [cell1, cell2, cell3, cell4] = getCells();
expect(cell1).toHaveClass(`${cellClassname} my-cell-0`, { exact: true });
expect(cell2).toHaveClass(`${cellClassname} my-cell-1`, { exact: true });
@@ -55,7 +55,7 @@ test('summaryCellClass returns a string', () => {
expect(cell4).toHaveClass(`${cellClassname} my-cell-3`, { exact: true });
});
-test('summaryCellClass returns undefined', () => {
+test('summaryCellClass returns undefined', async () => {
const columns: readonly Column[] = [
{
key: 'id',
@@ -63,7 +63,7 @@ test('summaryCellClass returns undefined', () => {
summaryCellClass: () => undefined
}
];
- setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
+ await setup({ columns, topSummaryRows, bottomSummaryRows, rows: [] });
const cells = getCells();
for (const cell of cells) {
expect(cell).toHaveClass(cellClassname, { exact: true });
diff --git a/test/browser/columnOrder.test.tsx b/test/browser/columnOrder.test.tsx
index fcdfe4f9de..2e58efe31d 100644
--- a/test/browser/columnOrder.test.tsx
+++ b/test/browser/columnOrder.test.tsx
@@ -1,4 +1,4 @@
-import { page } from '@vitest/browser/context';
+import { page } from 'vitest/browser';
import { DataGrid, SelectColumn, TreeDataGrid } from '../../src';
import type { Column } from '../../src';
@@ -32,9 +32,9 @@ test('column order', async () => {
async function run(columns: readonly Column[]) {
let unmount;
if (groupBy === undefined) {
- ({ unmount } = page.render());
+ ({ unmount } = await page.render());
} else {
- ({ unmount } = page.render(
+ ({ unmount } = await page.render(
{
const headerCells = page.getByRole('columnheader');
await testCount(headerCells, expected.length);
expect(headerCells.elements().map((c) => c.textContent)).toStrictEqual(expected);
- unmount();
+ await unmount();
}
let expected: readonly string[] = ['', 'frz1', 'frz2', 'std1', 'std2'];
diff --git a/test/browser/copyPaste.test.tsx b/test/browser/copyPaste.test.tsx
index d71b7227a1..c0fe2c30b6 100644
--- a/test/browser/copyPaste.test.tsx
+++ b/test/browser/copyPaste.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../src';
import type { CellPasteArgs, Column } from '../../src';
@@ -65,11 +65,11 @@ function CopyPasteTest() {
function setup() {
onCellCopySpy.mockClear();
onCellPasteSpy.mockClear();
- page.render();
+ return page.render();
}
test('should call onCellCopy on cell copy', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(0)[0]);
await userEvent.copy();
expect(onCellCopySpy).toHaveBeenCalledExactlyOnceWith(
@@ -82,7 +82,7 @@ test('should call onCellCopy on cell copy', async () => {
});
test('should call onCellPaste on cell paste', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(0)[0]);
await userEvent.paste();
expect(onCellPasteSpy).toHaveBeenCalledExactlyOnceWith(
@@ -95,14 +95,14 @@ test('should call onCellPaste on cell paste', async () => {
});
test('should not allow paste on readonly cells', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(2)[0]);
await userEvent.paste();
expect(onCellPasteSpy).not.toHaveBeenCalled();
});
test('should allow copying a readonly cell', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(2)[0]);
await userEvent.copy();
expect(onCellCopySpy).toHaveBeenCalledExactlyOnceWith(
@@ -115,7 +115,7 @@ test('should allow copying a readonly cell', async () => {
});
test('should not allow copy/paste on header or summary cells', async () => {
- setup();
+ await setup();
await userEvent.tab();
await userEvent.copy();
expect(onCellCopySpy).not.toHaveBeenCalled();
@@ -130,7 +130,7 @@ test('should not allow copy/paste on header or summary cells', async () => {
});
test('should not start editing when pressing ctrl+', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(1)[0]);
await userEvent.keyboard('{Control>}b');
await expect.element(getSelectedCell()).not.toHaveClass('rdg-editor-container');
diff --git a/test/browser/direction.test.ts b/test/browser/direction.test.ts
index f77b9529fa..b6c57b491a 100644
--- a/test/browser/direction.test.ts
+++ b/test/browser/direction.test.ts
@@ -1,4 +1,4 @@
-import { userEvent } from '@vitest/browser/context';
+import { userEvent } from 'vitest/browser';
import type { Column } from '../../src';
import { getGrid, getSelectedCell, setup, tabIntoGrid } from './utils';
@@ -22,7 +22,7 @@ const columns: readonly Column[] = [
const rows: readonly Row[] = [];
test('should use left to right direction by default', async () => {
- setup({ rows, columns }, true);
+ await setup({ rows, columns }, true);
await expect.element(getGrid()).toHaveAttribute('dir', 'ltr');
await tabIntoGrid();
await expect.element(getSelectedCell()).toHaveTextContent('ID');
@@ -31,7 +31,7 @@ test('should use left to right direction by default', async () => {
});
test('should use left to right direction if direction prop is set to ltr', async () => {
- setup({ rows, columns, direction: 'ltr' }, true);
+ await setup({ rows, columns, direction: 'ltr' }, true);
await expect.element(getGrid()).toHaveAttribute('dir', 'ltr');
await tabIntoGrid();
await expect.element(getSelectedCell()).toHaveTextContent('ID');
@@ -40,7 +40,7 @@ test('should use left to right direction if direction prop is set to ltr', async
});
test('should use right to left direction if direction prop is set to rtl', async () => {
- setup({ rows, columns, direction: 'rtl' }, true);
+ await setup({ rows, columns, direction: 'rtl' }, true);
await expect.element(getGrid()).toHaveAttribute('dir', 'rtl');
await tabIntoGrid();
await expect.element(getSelectedCell()).toHaveTextContent('ID');
diff --git a/test/browser/dragFill.test.tsx b/test/browser/dragFill.test.tsx
index 43eaaf95c7..6562d2a430 100644
--- a/test/browser/dragFill.test.tsx
+++ b/test/browser/dragFill.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { commands, page, userEvent } from '@vitest/browser/context';
+import { commands, page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../src';
import type { Column, FillEvent } from '../../src';
@@ -23,7 +23,7 @@ const columns: readonly Column[] = [
const initialRows: readonly Row[] = [{ col: 'a1' }, { col: 'a2' }, { col: 'a3' }, { col: 'a4' }];
function setup(allowDragFill = true) {
- page.render();
+ return page.render();
}
function DragFillTest({ allowDragFill = true }: { allowDragFill?: boolean }) {
@@ -48,13 +48,13 @@ function getDragHandle() {
}
test('should not allow dragFill if onFill is undefined', async () => {
- setup(false);
+ await setup(false);
await userEvent.click(getCellsAtRowIndex(0)[0]);
expect(getDragHandle()).not.toBeInTheDocument();
});
test('should allow dragFill if onFill is specified', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(0)[0]);
await expect.element(getCellsAtRowIndex(0)[0]).toHaveFocus();
await userEvent.dblClick(getDragHandle()!);
@@ -65,7 +65,7 @@ test('should allow dragFill if onFill is specified', async () => {
});
test('should update single row using mouse', async () => {
- setup();
+ await setup();
await commands.dragFill('a1', 'a2');
await expect.element(getCellsAtRowIndex(1)[0]).toHaveTextContent('a1');
await expect.element(getCellsAtRowIndex(2)[0]).toHaveTextContent('a3');
@@ -73,7 +73,7 @@ test('should update single row using mouse', async () => {
});
test('should update multiple rows using mouse', async () => {
- setup();
+ await setup();
await commands.dragFill('a1', 'a4');
await expect.element(getCellsAtRowIndex(1)[0]).toHaveTextContent('a1');
await expect.element(getCellsAtRowIndex(2)[0]).toHaveTextContent('a1');
@@ -81,7 +81,7 @@ test('should update multiple rows using mouse', async () => {
});
test('should allow drag up using mouse', async () => {
- setup();
+ await setup();
await commands.dragFill('a4', 'a1');
await expect.element(getCellsAtRowIndex(0)[0]).toHaveTextContent('a4');
await expect.element(getCellsAtRowIndex(1)[0]).toHaveTextContent('a4');
@@ -89,7 +89,7 @@ test('should allow drag up using mouse', async () => {
});
test('should focus the cell when drag handle is clicked', async () => {
- setup();
+ await setup();
await userEvent.click(getCellsAtRowIndex(0)[0]);
await userEvent.click(document.body);
expect(document.body).toHaveFocus();
diff --git a/test/browser/events.test.tsx b/test/browser/events.test.tsx
index 39e19598a6..cb99f34f67 100644
--- a/test/browser/events.test.tsx
+++ b/test/browser/events.test.tsx
@@ -1,4 +1,4 @@
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../src';
import type { Column, DataGridProps } from '../../src';
@@ -54,7 +54,7 @@ const rows: readonly Row[] = [
describe('Events', () => {
it('should not select cell if onCellMouseDown prevents grid default', async () => {
- page.render(
+ await page.render(
{
if (args.column.key === 'col1') {
@@ -70,7 +70,7 @@ describe('Events', () => {
});
it('should be able to open editor editor on single click using onCellClick', async () => {
- page.render(
+ await page.render(
{
if (args.column.key === 'col2') {
@@ -87,7 +87,7 @@ describe('Events', () => {
});
it('should not open editor editor on double click if onCellDoubleClick prevents default', async () => {
- page.render(
+ await page.render(
{
if (args.column.key === 'col1') {
@@ -104,7 +104,7 @@ describe('Events', () => {
it('should call onCellContextMenu when cell is right clicked', async () => {
const onCellContextMenu = vi.fn();
- page.render();
+ await page.render();
expect(onCellContextMenu).not.toHaveBeenCalled();
await userEvent.click(getCell('1'), { button: 'right' });
expect(onCellContextMenu).toHaveBeenCalledExactlyOnceWith(
@@ -122,7 +122,7 @@ describe('Events', () => {
it('should call onSelectedCellChange when cell selection is changed', async () => {
const onSelectedCellChange = vi.fn();
- page.render();
+ await page.render();
expect(onSelectedCellChange).not.toHaveBeenCalled();
diff --git a/test/browser/headerRowClass.test.ts b/test/browser/headerRowClass.test.ts
index 10d1e816c9..9c88e9508a 100644
--- a/test/browser/headerRowClass.test.ts
+++ b/test/browser/headerRowClass.test.ts
@@ -1,4 +1,4 @@
-import { page } from '@vitest/browser/context';
+import { page } from 'vitest/browser';
import type { Column } from '../../src';
import { headerRowClassname } from '../../src/HeaderRow';
@@ -12,7 +12,7 @@ const columns: readonly Column[] = [{ key: 'id', name: 'ID' }];
const rows: readonly Row[] = [];
test('headerRowClass is undefined', async () => {
- setup({
+ await setup({
columns,
rows,
headerRowClass: undefined
@@ -22,7 +22,7 @@ test('headerRowClass is undefined', async () => {
});
test('headerRowClass is a string', async () => {
- setup({
+ await setup({
columns,
rows,
headerRowClass: 'my-header-row'
diff --git a/test/browser/keyboardNavigation.test.tsx b/test/browser/keyboardNavigation.test.tsx
index c7aee2ec7f..777bb0e280 100644
--- a/test/browser/keyboardNavigation.test.tsx
+++ b/test/browser/keyboardNavigation.test.tsx
@@ -1,4 +1,4 @@
-import { commands, page, userEvent } from '@vitest/browser/context';
+import { commands, page, userEvent } from 'vitest/browser';
import { DataGrid, SelectColumn } from '../../src';
import type { Column } from '../../src';
@@ -21,7 +21,7 @@ const columns = [
] as const satisfies Column[];
test('keyboard navigation', async () => {
- setup({ columns, rows, topSummaryRows, bottomSummaryRows }, true);
+ await setup({ columns, rows, topSummaryRows, bottomSummaryRows }, true);
// no initial selection
await expect.element(getSelectedCell()).not.toBeInTheDocument();
@@ -97,7 +97,7 @@ test('keyboard navigation', async () => {
});
test('arrow and tab navigation', async () => {
- setup({ columns, rows, bottomSummaryRows }, true);
+ await setup({ columns, rows, bottomSummaryRows }, true);
// pressing arrowleft on the leftmost cell does nothing
await tabIntoGrid();
@@ -122,7 +122,7 @@ test('arrow and tab navigation', async () => {
});
test('grid enter/exit', async () => {
- setup({ columns, rows: new Array(5), bottomSummaryRows }, true);
+ await setup({ columns, rows: new Array(5), bottomSummaryRows }, true);
const beforeButton = page.getByRole('button', { name: 'Before' });
const afterButton = page.getByRole('button', { name: 'After' });
@@ -164,7 +164,7 @@ test('grid enter/exit', async () => {
});
test('navigation with focusable cell renderer', async () => {
- setup({ columns, rows: new Array(1), bottomSummaryRows }, true);
+ await setup({ columns, rows: new Array(1), bottomSummaryRows }, true);
await tabIntoGrid();
await userEvent.keyboard('{arrowdown}');
await validateCellPosition(0, 1);
@@ -205,7 +205,7 @@ test('navigation when header and summary rows have focusable elements', async ()
}
];
- setup({ columns, rows: new Array(2), bottomSummaryRows: [1, 2] }, true);
+ await setup({ columns, rows: new Array(2), bottomSummaryRows: [1, 2] }, true);
await tabIntoGrid();
// should set focus on the header filter
@@ -249,7 +249,7 @@ 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 });
}
- setup({ columns, rows, bottomSummaryRows }, true);
+ await setup({ columns, rows, bottomSummaryRows }, true);
await tabIntoGrid();
await validateCellPosition(0, 0);
@@ -287,13 +287,13 @@ test('reset selected cell when column is removed', async () => {
return ;
}
- const { rerender } = page.render();
+ const { rerender } = await page.render();
await userEvent.tab();
await userEvent.keyboard('{arrowdown}{arrowright}');
await validateCellPosition(1, 1);
- rerender();
+ await rerender();
await expect.element(getSelectedCell()).not.toBeInTheDocument();
});
@@ -309,19 +309,19 @@ test('reset selected cell when row is removed', async () => {
return ;
}
- const { rerender } = page.render();
+ const { rerender } = await page.render();
await userEvent.tab();
await userEvent.keyboard('{arrowdown}{arrowdown}{arrowright}');
await validateCellPosition(1, 2);
- rerender();
+ await rerender();
await expect.element(getSelectedCell()).not.toBeInTheDocument();
});
test('should not change the left and right arrow behavior for right to left languages', async () => {
- setup({ rows, columns, direction: 'rtl' }, true);
+ await setup({ rows, columns, direction: 'rtl' }, true);
await tabIntoGrid();
await validateCellPosition(0, 0);
await userEvent.tab();
diff --git a/test/browser/label.test.ts b/test/browser/label.test.ts
index aa077c0715..7d006928c1 100644
--- a/test/browser/label.test.ts
+++ b/test/browser/label.test.ts
@@ -1,7 +1,7 @@
import { getGrid, setup } from './utils';
test('should set label and description', async () => {
- setup({
+ await setup({
rows: [],
columns: [],
'aria-label': 'label',
diff --git a/test/browser/renderers.test.tsx b/test/browser/renderers.test.tsx
index fcf7d65b0e..aa6b200a41 100644
--- a/test/browser/renderers.test.tsx
+++ b/test/browser/renderers.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import {
Cell,
@@ -114,28 +114,28 @@ function setupContext(props: DataGridProps
}
test('fallback defined using renderers prop with no rows', async () => {
- setup({ columns, rows: noRows, renderers: { noRowsFallback: } });
+ await setup({ columns, rows: noRows, renderers: { noRowsFallback: } });
await testRowCount(1);
await expect.element(page.getByText('Local no rows fallback')).toBeInTheDocument();
});
test('fallback defined using context with no rows', async () => {
- setupContext({ columns, rows: noRows });
+ await setupContext({ columns, rows: noRows });
await testRowCount(1);
await expect.element(page.getByText('Global no rows fallback')).toBeInTheDocument();
});
test('fallback defined using both context and renderers with no rows', async () => {
- setupContext({ columns, rows: noRows, renderers: { noRowsFallback: } });
+ await setupContext({ columns, rows: noRows, renderers: { noRowsFallback: } });
await testRowCount(1);
await expect.element(page.getByText('Local no rows fallback')).toBeInTheDocument();
});
test('fallback defined using renderers prop with a row', async () => {
- setup({
+ await setup({
columns,
rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }],
renderers: { noRowsFallback: }
@@ -146,14 +146,14 @@ test('fallback defined using renderers prop with a row', async () => {
});
test('fallback defined using context with a row', async () => {
- setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
+ await setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
await testRowCount(2);
await expect.element(page.getByText('Global no rows fallback')).not.toBeInTheDocument();
});
test('fallback defined using both context and renderers with a row', async () => {
- setupContext({
+ await setupContext({
columns,
rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }],
renderers: { noRowsFallback: }
@@ -165,21 +165,21 @@ test('fallback defined using both context and renderers with a row', async () =>
});
test('checkbox defined using renderers prop', async () => {
- setup({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } });
+ await setup({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } });
await testRowCount(1);
await expect.element(page.getByText('Local checkbox')).toBeInTheDocument();
});
test('checkbox defined using context', async () => {
- setupContext({ columns, rows: noRows });
+ await setupContext({ columns, rows: noRows });
await testRowCount(1);
await expect.element(page.getByText('Global checkbox')).toBeInTheDocument();
});
test('checkbox defined using both context and renderers', async () => {
- setupContext({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } });
+ await setupContext({ columns, rows: noRows, renderers: { renderCheckbox: renderLocalCheckbox } });
await testRowCount(1);
await expect.element(page.getByText('Local checkbox')).toBeInTheDocument();
@@ -187,7 +187,7 @@ test('checkbox defined using both context and renderers', async () => {
});
test('sortPriority defined using both contexts', async () => {
- setupContext({ columns, rows: noRows });
+ await setupContext({ columns, rows: noRows });
const column1 = getHeaderCell('Column1');
const column2 = getHeaderCell('Column2');
@@ -204,7 +204,11 @@ test('sortPriority defined using both contexts', async () => {
});
test('sortPriority defined using both contexts and renderers', async () => {
- setupContext({ columns, rows: noRows, renderers: { renderSortStatus: renderLocalSortStatus } });
+ await setupContext({
+ columns,
+ rows: noRows,
+ renderers: { renderSortStatus: renderLocalSortStatus }
+ });
const column1 = getHeaderCell('Column1');
const column2 = getHeaderCell('Column2');
@@ -221,7 +225,7 @@ test('sortPriority defined using both contexts and renderers', async () => {
});
test('renderCell defined using context', async () => {
- setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
+ await setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
const cell1 = getCell('value 1');
const cell2 = getCell('value 2');
@@ -235,7 +239,7 @@ test('renderCell defined using context', async () => {
});
test('renderCell defined using both contexts and renderers', async () => {
- setupContext({
+ await setupContext({
columns,
rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }],
renderers: { renderCell: renderLocalCell }
@@ -253,7 +257,7 @@ test('renderCell defined using both contexts and renderers', async () => {
});
test('renderRow defined using context', async () => {
- setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
+ await setupContext({ columns, rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }] });
const row = getRowByCellName('value 1');
await expect.element(row).toHaveClass('global');
@@ -261,7 +265,7 @@ test('renderRow defined using context', async () => {
});
test('renderRow defined using both contexts and renderers', async () => {
- setupContext({
+ await setupContext({
columns,
rows: [{ id: 1, col1: 'value 1', col2: 'value 2' }],
renderers: { renderRow: renderLocalRow }
diff --git a/test/browser/rowClass.test.ts b/test/browser/rowClass.test.ts
index 2a0206929b..4742a95e50 100644
--- a/test/browser/rowClass.test.ts
+++ b/test/browser/rowClass.test.ts
@@ -10,7 +10,7 @@ const columns: readonly Column[] = [{ key: 'id', name: 'ID' }];
const rows: readonly Row[] = [{ id: 0 }, { id: 1 }, { id: 2 }];
test('rowClass is undefined', async () => {
- setup({
+ await setup({
columns,
rows,
rowClass: undefined
@@ -27,7 +27,7 @@ test('rowClass is undefined', async () => {
});
test('rowClass returns a string', async () => {
- setup({
+ await setup({
columns,
rows,
rowClass: (row) => `my-row-${row.id}`
@@ -44,7 +44,7 @@ test('rowClass returns a string', async () => {
});
test('rowClass returns undefined', async () => {
- setup({
+ await setup({
columns,
rows,
rowClass: () => undefined
diff --git a/test/browser/rowHeight.test.ts b/test/browser/rowHeight.test.ts
index 3c3cf52438..829e25d07e 100644
--- a/test/browser/rowHeight.test.ts
+++ b/test/browser/rowHeight.test.ts
@@ -1,4 +1,4 @@
-import { userEvent } from '@vitest/browser/context';
+import { userEvent } from 'vitest/browser';
import type { Column, DataGridProps } from '../../src';
import { getGrid, setup, tabIntoGrid, testRowCount } from './utils';
@@ -17,11 +17,11 @@ function setupGrid(rowHeight: DataGridProps['rowHeight']) {
width: 80
});
}
- setup({ columns, rows, rowHeight }, true);
+ return setup({ columns, rows, rowHeight }, true);
}
-function expectGridRows(rowHeightFn: (row: number) => number, expected: string) {
- setupGrid(rowHeightFn);
+async function expectGridRows(rowHeightFn: (row: number) => number, expected: string) {
+ await setupGrid(rowHeightFn);
const grid = getGrid().element() as HTMLDivElement;
const gridTemplateRows = grid.style.gridTemplateRows;
@@ -30,7 +30,7 @@ function expectGridRows(rowHeightFn: (row: number) => number, expected: string)
}
test('rowHeight is number', async () => {
- setupGrid(40);
+ await setupGrid(40);
const grid = getGrid();
await expect.element(grid).toHaveStyle({
@@ -46,7 +46,7 @@ test('rowHeight is number', async () => {
});
test('rowHeight is function', async () => {
- setupGrid((row) => [40, 60, 80][row % 3]);
+ await setupGrid((row) => [40, 60, 80][row % 3]);
const grid = getGrid();
await expect.element(grid).toHaveStyle({
@@ -62,26 +62,26 @@ test('rowHeight is function', async () => {
expect(gridEl.scrollTop + gridEl.clientHeight).toBe(gridEl.scrollHeight);
});
-test('rowHeight with repeat pattern - multiple identical heights', () => {
- expectGridRows(() => 40, 'repeat(1, 35px) repeat(50, 40px)');
+test('rowHeight with repeat pattern - multiple identical heights', async () => {
+ await expectGridRows(() => 40, 'repeat(1, 35px) repeat(50, 40px)');
});
-test('rowHeight with mixed heights - one unique in middle', () => {
- expectGridRows(
+test('rowHeight with mixed heights - one unique in middle', async () => {
+ await expectGridRows(
(row) => (row === 25 ? 40 : 50),
'repeat(1, 35px) repeat(25, 50px) 40px repeat(24, 50px)'
);
});
-test('rowHeight with unique heights', () => {
- expectGridRows(
+test('rowHeight with unique heights', async () => {
+ await expectGridRows(
(row) => row + 1,
'repeat(1, 35px) 1px 2px 3px 4px 5px 6px 7px 8px 9px 10px 11px 12px 13px 14px 15px 16px 17px 18px 19px 20px 21px 22px 23px 24px 25px 26px 27px 28px 29px 30px 31px 32px 33px 34px 35px 36px 37px 38px 39px 40px 41px 42px 43px 44px 45px 46px 47px 48px 49px 50px'
);
});
-test('rowHeight with unique first and unique last heights', () => {
- expectGridRows((row) => {
+test('rowHeight with unique first and unique last heights', async () => {
+ await expectGridRows((row) => {
if (row === 0) {
return 10;
}
@@ -94,14 +94,14 @@ test('rowHeight with unique first and unique last heights', () => {
}, 'repeat(1, 35px) 10px repeat(48, 50px) 20px');
});
-test('rowHeight with unique last height', () => {
- expectGridRows((row) => {
+test('rowHeight with unique last height', async () => {
+ await expectGridRows((row) => {
return row === 49 ? 50 : 20;
}, 'repeat(1, 35px) repeat(49, 20px) 50px');
});
-test('rowHeight with unique first height', () => {
- expectGridRows((row) => {
+test('rowHeight with unique first height', async () => {
+ await expectGridRows((row) => {
return row === 0 ? 45 : 50;
}, 'repeat(1, 35px) 45px repeat(49, 50px)');
});
diff --git a/test/browser/rowSelection.test.tsx b/test/browser/rowSelection.test.tsx
index b7b6990d2d..6065c47e50 100644
--- a/test/browser/rowSelection.test.tsx
+++ b/test/browser/rowSelection.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid, SelectColumn } from '../../src';
import type { Column } from '../../src';
@@ -45,7 +45,7 @@ function RowSelectionTest({
}
function setup(initialRows = defaultRows) {
- page.render();
+ return page.render();
}
function getRowByText(rowIdx: number) {
@@ -66,7 +66,7 @@ async function toggleSelection(rowIdx: number, shift = false, force = false) {
}
test('toggle selection when checkbox is clicked', async () => {
- setup();
+ await setup();
await toggleSelection(0);
await testSelection(0, true);
await toggleSelection(1);
@@ -79,7 +79,7 @@ test('toggle selection when checkbox is clicked', async () => {
});
test('toggle selection using keyboard', async () => {
- setup();
+ await setup();
await testSelection(0, false);
await userEvent.click(getRowByText(0).getByRole('checkbox', { name: 'Select' }));
await testSelection(0, true);
@@ -94,7 +94,7 @@ test('toggle selection using keyboard', async () => {
});
test('should partially select header checkbox', async () => {
- setup();
+ await setup();
const headerCheckbox = getSelectAllCheckbox();
await expect.element(headerCheckbox).not.toBeChecked();
await expect.element(headerCheckbox).not.toBePartiallyChecked();
@@ -127,7 +127,7 @@ test('should partially select header checkbox', async () => {
});
test('should not select row when isRowSelectionDisabled returns true', async () => {
- page.render(
+ await page.render(
row.id === 2} />
);
await toggleSelection(0);
@@ -146,7 +146,7 @@ test('should not select row when isRowSelectionDisabled returns true', async ()
});
test('select/deselect all rows when header checkbox is clicked', async () => {
- setup();
+ await setup();
const headerCheckbox = getSelectAllCheckbox();
await expect.element(headerCheckbox).not.toBeChecked();
await userEvent.click(headerCheckbox);
@@ -167,12 +167,12 @@ test('select/deselect all rows when header checkbox is clicked', async () => {
});
test('header checkbox is not checked when there are no rows', async () => {
- setup([]);
+ await setup([]);
await expect.element(getSelectAllCheckbox()).not.toBeChecked();
});
test('header checkbox is not necessarily checked when selectedRows.size === rows.length', async () => {
- page.render(
+ await page.render(
rows.length', async () => {
- page.render(
+ await page.render(
);
}
- page.render();
+ await page.render();
const headerCheckbox = getSelectAllCheckbox();
@@ -244,7 +244,7 @@ test('extra keys are preserved when updating the selectedRows Set', async () =>
});
test('select/deselect rows using shift click', async () => {
- setup();
+ await setup();
await toggleSelection(0);
await toggleSelection(2, true);
await testSelection(0, true);
@@ -258,7 +258,7 @@ test('select/deselect rows using shift click', async () => {
});
test('select rows using shift space', async () => {
- setup();
+ await setup();
await userEvent.click(getCell('1'));
await userEvent.keyboard('{Shift>} {/Shift}');
await testSelection(0, true);
diff --git a/test/browser/scrollToCell.test.tsx b/test/browser/scrollToCell.test.tsx
index 3a58c416c5..192266fdc4 100644
--- a/test/browser/scrollToCell.test.tsx
+++ b/test/browser/scrollToCell.test.tsx
@@ -1,5 +1,5 @@
import { useRef } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../src';
import type { Column, DataGridHandle } from '../../src';
@@ -55,7 +55,7 @@ async function testScroll(p: PartialPosition) {
}
test('scrollToCell', async () => {
- page.render();
+ await page.render();
await validateCellVisibility('0×0', true);
await validateCellVisibility('40×30', false);
await validateCellVisibility('0×51', true);
diff --git a/test/browser/sorting.test.tsx b/test/browser/sorting.test.tsx
index 5bb6ba1b8e..31eb775a3d 100644
--- a/test/browser/sorting.test.tsx
+++ b/test/browser/sorting.test.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { page, userEvent } from '@vitest/browser/context';
+import { page, userEvent } from 'vitest/browser';
import { DataGrid } from '../../src';
import type { Column, SortColumn } from '../../src/types';
@@ -30,7 +30,7 @@ function TestGrid() {
}
function setup() {
- page.render();
+ return page.render();
}
function testSortColumns(expectedValue: readonly SortColumn[]) {
@@ -40,7 +40,7 @@ function testSortColumns(expectedValue: readonly SortColumn[]) {
}
test('should not sort if sortable is false', async () => {
- setup();
+ await setup();
const headerCell = getHeaderCell('colD');
await userEvent.click(headerCell);
await expect.element(headerCell).not.toHaveAttribute('aria-sort');
@@ -48,7 +48,7 @@ test('should not sort if sortable is false', async () => {
});
test('single column sort', async () => {
- setup();
+ await setup();
const headerCell = getHeaderCell('colA');
await userEvent.click(headerCell);
await expect.element(headerCell).toHaveAttribute('aria-sort', 'ascending');
@@ -64,7 +64,7 @@ test('single column sort', async () => {
});
test('multi column sort', async () => {
- setup();
+ await setup();
const headerCell1 = getHeaderCell('colA', false);
const headerCell2 = getHeaderCell('colB', false);
const headerCell3 = getHeaderCell('colC', false);
@@ -108,7 +108,7 @@ test('multi column sort', async () => {
});
test('multi column sort with metakey', async () => {
- setup();
+ await setup();
const [headerCell1, headerCell2] = getHeaderCellsNew('colA', 'colB');
await userEvent.click(headerCell1);
await userEvent.keyboard('{Meta>}');
@@ -120,7 +120,7 @@ test('multi column sort with metakey', async () => {
});
test('multi column sort with keyboard', async () => {
- setup();
+ await setup();
const headerCell1 = getHeaderCell('colA');
await userEvent.click(headerCell1);
await userEvent.keyboard(' {arrowright}{Control>}{enter}');
diff --git a/test/browser/utils.tsx b/test/browser/utils.tsx
index 2ba02b6314..3f10c007d2 100644
--- a/test/browser/utils.tsx
+++ b/test/browser/utils.tsx
@@ -1,4 +1,4 @@
-import { page, userEvent, type Locator } from '@vitest/browser/context';
+import { page, userEvent, type Locator } from 'vitest/browser';
import { css } from '@linaria/core';
import { DataGrid } from '../../src';
@@ -19,7 +19,7 @@ export function setup(
);
if (renderBeforeAfterButtons) {
- page.render(
+ return page.render(
<>
{grid}
@@ -27,9 +27,8 @@ export function setup(
>
);
- } else {
- page.render(grid);
}
+ return page.render(grid);
}
export function getGrid() {
diff --git a/test/browser/virtualization.test.ts b/test/browser/virtualization.test.ts
index 458e07b5ea..da5ab670c4 100644
--- a/test/browser/virtualization.test.ts
+++ b/test/browser/virtualization.test.ts
@@ -25,7 +25,7 @@ function setupGrid(
});
}
- setup({
+ return setup({
columns,
rows,
topSummaryRows,
@@ -84,7 +84,7 @@ function assertCellIndexes(rowIdx: number, indexes: number[]) {
}
test('virtualization is enabled', async () => {
- setupGrid(true, 30, 100);
+ await setupGrid(true, 30, 100);
assertHeaderCells(18, 0, 17);
assertRows(34, 0, 33);
@@ -138,7 +138,7 @@ test('virtualization is enabled', async () => {
});
test('virtualization is enabled with 4 frozen columns', async () => {
- setupGrid(true, 30, 30, 4);
+ await setupGrid(true, 30, 30, 4);
let indexes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
assertHeaderCellIndexes(indexes);
@@ -157,7 +157,7 @@ test('virtualization is enabled with 4 frozen columns', async () => {
});
test('virtualization is enabled with all columns frozen', async () => {
- setupGrid(true, 30, 30, 30);
+ await setupGrid(true, 30, 30, 30);
const indexes = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
@@ -177,7 +177,7 @@ test('virtualization is enabled with all columns frozen', async () => {
});
test('virtualization is enabled with 2 summary rows', async () => {
- setupGrid(true, 1, 100, 0, 2);
+ await setupGrid(true, 1, 100, 0, 2);
assertRowIndexes([
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
@@ -191,24 +191,24 @@ test('virtualization is enabled with 2 summary rows', async () => {
]);
});
-test('zero columns', () => {
- setupGrid(true, 0, 100);
+test('zero columns', async () => {
+ await setupGrid(true, 0, 100);
expect(getHeaderCells()).toHaveLength(0);
expect(getCells()).toHaveLength(0);
expect(getRows()).toHaveLength(0);
});
-test('zero rows', () => {
- setupGrid(true, 20, 0);
+test('zero rows', async () => {
+ await setupGrid(true, 20, 0);
expect(getHeaderCells()).toHaveLength(18);
expect(getCells()).toHaveLength(0);
expect(getRows()).toHaveLength(0);
});
-test('virtualization is enable with not enough columns or rows to virtualize', () => {
- setupGrid(true, 5, 5);
+test('virtualization is enable with not enough columns or rows to virtualize', async () => {
+ await setupGrid(true, 5, 5);
assertHeaderCells(5, 0, 4);
assertRows(5, 0, 4);
@@ -217,8 +217,8 @@ test('virtualization is enable with not enough columns or rows to virtualize', (
expect(cells).toHaveLength(5 * 5);
});
-test('enableVirtualization is disabled', () => {
- setupGrid(false, 40, 100);
+test('enableVirtualization is disabled', async () => {
+ await setupGrid(false, 40, 100);
assertHeaderCells(40, 0, 39);
assertRows(100, 0, 99);
diff --git a/test/globals.d.ts b/test/globals.d.ts
index acec8e74f0..cd36ff8344 100644
--- a/test/globals.d.ts
+++ b/test/globals.d.ts
@@ -1,4 +1,4 @@
-declare module '@vitest/browser/context' {
+declare module 'vitest/browser' {
interface BrowserCommands {
dragFill: (from: string, to: string) => Promise;
resizeColumn: (name: string, resizeBy: number | readonly number[]) => Promise;
diff --git a/test/setupBrowser.ts b/test/setupBrowser.ts
index ca6d1777fa..5218c269a8 100644
--- a/test/setupBrowser.ts
+++ b/test/setupBrowser.ts
@@ -1,5 +1,5 @@
-import { locators } from '@vitest/browser/context';
import { configure } from 'vitest-browser-react/pure';
+import { locators } from 'vitest/browser';
// vitest-browser-react also automatically injects render method on the page
// need to import it so TypeScript can pick up types
diff --git a/tsconfig.test.json b/tsconfig.test.json
index 25138a3a15..f116d1e433 100644
--- a/tsconfig.test.json
+++ b/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"skipLibCheck": true,
"lib": ["ESNext", "DOM", "DOM.Iterable", "DOM.AsyncIterable"],
- "types": ["vitest/globals", "@vitest/browser/providers/playwright"]
+ "types": ["vitest/globals"]
},
"include": ["test/**/*"],
"references": [{ "path": "tsconfig.src.json" }]
diff --git a/tsconfig.vite.json b/tsconfig.vite.json
index 57d8db9414..5f753ecfa3 100644
--- a/tsconfig.vite.json
+++ b/tsconfig.vite.json
@@ -2,8 +2,7 @@
"extends": "./tsconfig.base.json",
"compilerOptions": {
"skipLibCheck": true,
- "lib": ["ESNext", "DOM"],
- "types": ["@vitest/browser/providers/playwright"]
+ "lib": ["ESNext", "DOM"]
},
"include": ["package.json", "rolldown.config.ts", "vite.config.ts"]
}
diff --git a/vite.config.ts b/vite.config.ts
index 920ad89a0c..705994beb0 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,8 @@
import { tanstackRouter } from '@tanstack/router-plugin/vite';
import react from '@vitejs/plugin-react';
+import { playwright } from '@vitest/browser-playwright';
import wyw from '@wyw-in-js/vite';
-import { defineConfig } from 'vite';
+import { defineConfig, type ViteUserConfig } from 'vitest/config';
import type { BrowserCommand } from 'vitest/node';
const isCI = process.env.CI === 'true';
@@ -19,15 +20,15 @@ const resizeColumn: BrowserCommand<[name: string, resizeBy: number | readonly nu
.getByRole('columnheader', { name, exact: true })
.locator('.rdg-resize-handle');
const { x, y } = (await resizeHandle.boundingBox())!;
- await resizeHandle.hover({
- position: { x: 5, y: 5 }
- });
+ await page.mouse.move(x + 5, y + 5);
await page.mouse.down();
resizeBy = Array.isArray(resizeBy) ? resizeBy : [resizeBy];
+ // https://github.com/vitest-dev/vitest/issues/8099#issuecomment-2959674792
+ const frameScale = Number((await page.locator('#vitest-tester').getAttribute('data-scale')) ?? 1);
let newX = x + 5;
for (const value of resizeBy) {
- newX += value;
- await page.mouse.move(newX, y);
+ newX += value * frameScale;
+ await page.mouse.move(newX, y + 5);
}
await page.mouse.up();
};
@@ -64,88 +65,94 @@ const scrollGrid: BrowserCommand<[{ scrollLeft?: number; scrollTop?: number }]>
const viewport = { width: 1920, height: 1080 } as const;
-export default defineConfig(({ command, isPreview }) => ({
- base: '/react-data-grid/',
- cacheDir: '.cache/vite',
- clearScreen: false,
- build: {
- modulePreload: { polyfill: false },
- sourcemap: true,
- reportCompressedSize: false,
- // https://github.com/parcel-bundler/lightningcss/issues/873
- cssMinify: 'esbuild'
- },
- plugins: [
- (!isTest || isPreview) &&
- tanstackRouter({
- target: 'react',
- generatedRouteTree: 'website/routeTree.gen.ts',
- routesDirectory: 'website/routes',
- autoCodeSplitting: true,
- verboseFileRoutes: false
- }),
- react({
- exclude: ['./.cache/**/*']
- }),
- wyw({
- exclude: ['./.cache/**/*', '**/*.d.ts', '**/*.gen.ts'],
- preprocessor: 'none',
- displayName: command === 'serve'
- })
- ],
- server: {
- open: true
- },
- test: {
- globals: true,
- coverage: {
- provider: 'istanbul',
- enabled: isCI,
- include: ['src/**/*.{ts,tsx}'],
- reporter: ['json']
+export default defineConfig(
+ ({ command, isPreview }): ViteUserConfig => ({
+ base: '/react-data-grid/',
+ cacheDir: '.cache/vite',
+ clearScreen: false,
+ build: {
+ modulePreload: { polyfill: false },
+ sourcemap: true,
+ reportCompressedSize: false,
+ // https://github.com/parcel-bundler/lightningcss/issues/873
+ cssMinify: 'esbuild'
},
- restoreMocks: true,
- sequence: {
- shuffle: true
+ plugins: [
+ (!isTest || isPreview) &&
+ tanstackRouter({
+ target: 'react',
+ generatedRouteTree: 'website/routeTree.gen.ts',
+ routesDirectory: 'website/routes',
+ autoCodeSplitting: true,
+ verboseFileRoutes: false
+ }),
+ react({
+ exclude: ['./.cache/**/*']
+ }),
+ wyw({
+ exclude: ['./.cache/**/*', '**/*.d.ts', '**/*.gen.ts'],
+ preprocessor: 'none',
+ displayName: command === 'serve'
+ })
+ ],
+ server: {
+ open: true
},
- slowTestThreshold: 1000,
- projects: [
- {
- extends: true,
- test: {
- name: 'browser',
- include: ['test/browser/**/*.test.*'],
- browser: {
- // TODO: remove when FF tests are stable
- fileParallelism: false,
- enabled: true,
- provider: 'playwright',
- instances: [
- {
- browser: 'chromium',
- context: { viewport }
- },
- {
- browser: 'firefox',
- context: { viewport }
- }
- ],
- commands: { resizeColumn, dragFill, scrollGrid },
- viewport,
- headless: true,
- screenshotFailures: !isCI
- },
- setupFiles: ['test/setupBrowser.ts']
- }
+ test: {
+ globals: true,
+ coverage: {
+ provider: 'istanbul',
+ enabled: isCI,
+ include: ['src/**/*.{ts,tsx}'],
+ reporter: ['json']
},
- {
- extends: true,
- test: {
- name: 'node',
- include: ['test/node/**/*.test.*'],
- environment: 'node'
+ restoreMocks: true,
+ sequence: {
+ shuffle: true
+ },
+ slowTestThreshold: 1000,
+ projects: [
+ {
+ extends: true,
+ test: {
+ name: 'browser',
+ include: ['test/browser/**/*.test.*'],
+ browser: {
+ ui: false,
+ // TODO: remove when FF tests are stable
+ fileParallelism: false,
+ enabled: true,
+ provider: playwright(),
+ trace: {
+ mode: isCI ? 'off' : 'retain-on-failure'
+ },
+ instances: [
+ {
+ browser: 'chromium',
+ viewport
+ },
+ {
+ browser: 'firefox',
+ viewport
+ }
+ ],
+ commands: { resizeColumn, dragFill, scrollGrid },
+ viewport,
+ headless: true,
+ screenshotFailures: !isCI
+ },
+ setupFiles: ['test/setupBrowser.ts']
+ }
+ },
+ {
+ extends: true,
+ test: {
+ name: 'node',
+ include: ['test/node/**/*.test.*'],
+ environment: 'node'
+ }
}
- }
- ]
- }
-}));
+ ]
+ }
+ })
+);