Skip to content
Merged
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ website/ # demo site (Vite + TanStack Router)
- Browser tests use `vite-plus/test/browser` + Playwright. `test/setupBrowser.ts` configures `page.render()` via `vitest-browser-react` and registers custom locators via `locators.extend()` — prefer `page.getGrid()`, `page.getCell({ name })`, `page.getRow()`, `page.getHeaderCell()`, `page.getActiveCell()`, etc. over raw `page.getByRole()`.
- Test helpers in `test/browser/utils.tsx`: `setup()`, `getRowWithCell()`, `getCellsAtRowIndex()`, `validateCellPosition()`, `scrollGrid()`, `safeTab()`, `testCount()`, `testRowCount()`.
- `test/failOnConsole.ts` fails tests on unexpected console warnings/errors.
- Firefox runs test files in parallel. Firefox sends the mouse events of all its pages with the same pointer ID, so each test file that drags a resize or drag-fill handle, which captures the pointer, runs in a separate Firefox instance with a browser of its own: add such test files to `firefoxPointerCaptureTests` in `vite.config.ts`. Use `--project "*firefox*"` to run all the Firefox instances.
- **Never run visual regression tests** — screenshots are environment-dependent, so visual regression tests must run in CI only.

## Tooling
Expand Down
65 changes: 42 additions & 23 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { basename } from 'node:path';
import react from '@vitejs/plugin-react';
import { ecij } from 'ecij/plugin';
import { Features } from 'lightningcss';
import { defineConfig, lazyPlugins } from 'vite-plus';
import { playwright, type PlaywrightProviderOptions } from 'vite-plus/test/browser-playwright';
import type { BrowserCommandContext } from 'vite-plus/test/node';
import type { BrowserCommandContext, BrowserInstanceOption } from 'vite-plus/test/node';

import pkg from './package.json' with { type: 'json' };

const isCI = process.env.CI === 'true';
const isCIWorkflow = process.env.GITHUB_WORKFLOW === 'CI';
const isTest = process.env.VITEST === 'true';
const isAgent = process.env.AI_AGENT !== undefined;
const isWindows = process.platform === 'win32';

// TODO: remove when `userEvent.pointer` is supported
async function resizeColumn(
Expand All @@ -34,21 +36,14 @@ async function resizeColumn(
}

// TODO: remove when `userEvent.pointer` is supported
async function dragFill(
{ page, iframe, project }: BrowserCommandContext,
from: string,
to: string
) {
async function dragFill({ page, iframe }: BrowserCommandContext, from: string, to: string) {
await iframe.getByRole('gridcell', { name: from, exact: true }).click();
await iframe.locator('.rdg-cell-drag-handle').hover();
await page.mouse.down();
await iframe.getByRole('gridcell', { name: to, exact: true }).hover();
if (project.name.includes('webkit')) {
// let React re-render after handleDragHandlePointerMove calls setDraggedOverRowIdx()
await new Promise((resolve) => {
setTimeout(resolve, 20);
});
}
const target = iframe.getByRole('gridcell', { name: to, exact: true });
await target.hover();
// the grid fills the cells it rendered as dragged over, so wait for it to render the drag
await target.and(iframe.locator('.rdg-cell-dragged-over')).waitFor();
await page.mouse.up();
}

Expand All @@ -66,6 +61,23 @@ const playwrightOptions: PlaywrightProviderOptions = {
viewport
}
};
const firefoxProvider = playwright({
...playwrightOptions,
launchOptions: {
firefoxUserPrefs: {
'accessibility.force_disabled': 1
}
}
});
// Firefox sends the mouse events of all its pages with the same pointer ID,
// so a page that captures the pointer also receives the other pages' mouse events.
// These tests drag a resize or drag-fill handle, which captures the pointer,
// so each of them runs in a browser of its own.
// https://github.com/microsoft/playwright/issues/43631
const firefoxPointerCaptureTests = [
'browser/dragFill.test.tsx',
'browser/column/resizable.test.tsx'
];

export default defineConfig({
staged: {
Expand Down Expand Up @@ -264,6 +276,13 @@ export default defineConfig({
}
},
slowTestThreshold: 1000,
// On Windows, WebKit slows down the mouse events of Playwright's Firefox,
// which dispatches those of all its pages one after the other,
// so with all cores but one as workers, Firefox's clicks time out.
// In a terminal, the browser instances get half the cores anyway, as in watch mode,
// since they don't inherit the `watch: false` of `vitest run`.
// https://github.com/vitest-dev/vitest/issues/11721
...(isWindows && { maxWorkers: '50%' }),
browser: {
headless: true,
ui: false,
Expand All @@ -290,17 +309,17 @@ export default defineConfig({
},
{
browser: 'firefox',
provider: playwright({
...playwrightOptions,
launchOptions: {
firefoxUserPrefs: {
'accessibility.force_disabled': 1
}
}
}),
// TODO: remove when FF tests are stable
fileParallelism: false
exclude: firefoxPointerCaptureTests,
provider: firefoxProvider
},
// the names sort after `browser (webkit)`, so with few workers, as in CI,
// WebKit's tests start before these
...firefoxPointerCaptureTests.map((test): BrowserInstanceOption => ({
name: `firefox (${basename(test).split('.')[0]})`,
browser: 'firefox',
include: [test],
provider: firefoxProvider
})),
{
browser: 'webkit',
provider: playwright(playwrightOptions)
Expand Down
Loading