diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d500bd3134..15cf151811 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,21 +38,18 @@ jobs: run: npx playwright install chromium firefox - name: Test - run: node --run test + run: node --run test:ci timeout-minutes: 4 - - name: Visual regression test - run: node --run visual - - name: Upload test failure artifacts if: failure() uses: actions/upload-artifact@v7 with: name: test-artifacts path: | - test/browser/**/__screenshots__/** - test/browser/**/__traces__/** - .vitest-attachments/test/**/* + test/**/__screenshots__/** + test/**/__traces__/** + .vitest-attachments/test/** if-no-files-found: ignore - name: Upload coverage diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5861d171bd..46dc044da7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -49,12 +49,9 @@ jobs: run: npx playwright install chromium firefox - name: Test - run: node --run test + run: node --run test:ci timeout-minutes: 4 - - name: Visual regression test - run: node --run visual - - name: Update version run: | git config user.name "${{ github.actor }}" diff --git a/.github/workflows/update-screenshots.yml b/.github/workflows/update-screenshots.yml index f7f0e9d6d9..1908f54a93 100644 --- a/.github/workflows/update-screenshots.yml +++ b/.github/workflows/update-screenshots.yml @@ -5,14 +5,6 @@ on: types: [labeled] workflow_dispatch: -env: - AUTHOR_NAME: 'github-actions[bot]' - AUTHOR_EMAIL: '41898282+github-actions[bot]@users.noreply.github.com' - COMMIT_MESSAGE: | - Update screenshots - - Co-authored-by: ${{ github.actor }} - jobs: update-screenshots: if: ${{ github.event.label.name == 'Update Screenshots' || github.event_name == 'workflow_dispatch' }} @@ -46,12 +38,12 @@ jobs: run: npx playwright install chromium firefox - name: Update screenshots run: | - rm -r test/visual/__screenshots__ - node --run visual:update + rm -r test/**/screenshots/** + node --run test:ci:update - name: Push new screenshots run: | - git config --global user.name "${{ env.AUTHOR_NAME }}" - git config --global user.email "${{ env.AUTHOR_EMAIL }}" - git add test/visual/__screenshots__/. - git diff-index --quiet HEAD || git commit -m "${{ env.COMMIT_MESSAGE }}" + git config user.name "${{ github.actor }}" + git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com" + git add "test/**/screenshots/**" + git diff-index --quiet HEAD || git commit -m "Update screenshots" git push diff --git a/.gitignore b/.gitignore index b8bd53aef4..3d25e31c3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,17 @@ /.cache /.claude -/coverage /dist /lib /node_modules /package-lock.json -test/browser/**/__screenshots__ npm-debug.log **.orig .idea -.vitest-attachments -__traces__ +# Vitest +/.vitest-attachments +/coverage +/test/**/__screenshots__ +/test/**/__traces__ +/test/**/screenshots/**/*-win32.png diff --git a/AGENTS.md b/AGENTS.md index e6775ffa51..b64555fe1a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,7 +55,7 @@ website/ # demo site (Vite + TanStack Router) - Browser tests use `vitest/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.getSelectedCell()`, etc. over raw `page.getByRole()`. - Test helpers in `test/browser/utils.tsx`: `setup()`, `getRowWithCell()`, `getCellsAtRowIndex()`, `validateCellPosition()`, `scrollGrid()`, `tabIntoGrid()`, `testCount()`, `testRowCount()`. - `test/failOnConsole.ts` fails tests on unexpected console warnings/errors. -- **Never run visual regression tests locally** — screenshots are CI-only and environment-dependent. +- **Never run visual regression tests** — screenshots are environment-dependent so visual regression tests must run in CI only. ## Validation diff --git a/package.json b/package.json index 9125d14218..fa0c3e274a 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,10 @@ "preview": "vite preview", "build:website": "vite build", "build": "rolldown -c", - "test": "vitest run --project browser --project node --coverage.reportsDirectory='./coverage/test'", + "test": "vitest run --project browser --project node", "test:watch": "vitest watch --project browser --project node", - "visual": "vitest run --project visual --coverage.reportsDirectory='./coverage/visual'", - "visual:update": "vitest run --project visual --update", + "test:ci": "vitest run", + "test:ci:update": "vitest run --project visual --update", "format": "oxfmt", "format:check": "oxfmt --check", "eslint": "eslint --max-warnings 0 --cache --cache-location .cache/eslint --cache-strategy content", diff --git a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png b/test/visual/screenshots/basicGrid.test.tsx/basic-grid-chromium-linux.png similarity index 100% rename from test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png rename to test/visual/screenshots/basicGrid.test.tsx/basic-grid-chromium-linux.png diff --git a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png b/test/visual/screenshots/basicGrid.test.tsx/basic-grid-firefox-linux.png similarity index 100% rename from test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png rename to test/visual/screenshots/basicGrid.test.tsx/basic-grid-firefox-linux.png diff --git a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png b/test/visual/screenshots/treeGrid.test.tsx/tree-grid-chromium-linux.png similarity index 100% rename from test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png rename to test/visual/screenshots/treeGrid.test.tsx/tree-grid-chromium-linux.png diff --git a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png b/test/visual/screenshots/treeGrid.test.tsx/tree-grid-firefox-linux.png similarity index 100% rename from test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png rename to test/visual/screenshots/treeGrid.test.tsx/tree-grid-firefox-linux.png diff --git a/vite.config.ts b/vite.config.ts index 32d77852ba..a1dc692fdc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -39,22 +39,23 @@ const dragFill: BrowserCommand<[from: string, to: string]> = async ({ page, ifra await page.mouse.up(); }; +const actionTimeout = 2000; const viewport = { width: 1920, height: 1080 } as const; +const playwrightOptions: PlaywrightProviderOptions = { + actionTimeout, + contextOptions: { + viewport + } +}; // vitest modifies the instance objects, so we cannot rely on static objects +// https://github.com/vitest-dev/vitest/issues/9877 function getInstances(): BrowserInstanceOption[] { - const opts: PlaywrightProviderOptions = { - actionTimeout: 2000, - contextOptions: { - viewport - } - }; - return [ { browser: 'chromium', provider: playwright({ - ...opts, + ...playwrightOptions, launchOptions: { channel: 'chromium' } @@ -62,7 +63,7 @@ function getInstances(): BrowserInstanceOption[] { }, { browser: 'firefox', - provider: playwright(opts), + provider: playwright(playwrightOptions), // TODO: remove when FF tests are stable fileParallelism: false } @@ -74,6 +75,7 @@ export default defineConfig( base: '/react-data-grid/', cacheDir: '.cache/vite', clearScreen: false, + define: isTest ? { __IS_CI__: JSON.stringify(isCI) } : {}, build: { modulePreload: { polyfill: false }, sourcemap: true, @@ -107,15 +109,20 @@ export default defineConfig( }, restoreMocks: true, sequence: { - shuffle: true + shuffle: { + files: false, + tests: true + } + }, + expect: { + poll: { + timeout: actionTimeout + } }, slowTestThreshold: 1000, projects: [ { extends: true, - define: { - __IS_CI__: JSON.stringify(isCI) - }, test: { name: 'browser', include: ['browser/**/*.test.*'], @@ -141,7 +148,21 @@ export default defineConfig( viewport, headless: true, ui: false, - screenshotFailures: false + expect: { + toMatchScreenshot: { + resolveScreenshotPath({ + root, + testFileDirectory, + testFileName, + arg, + browserName, + platform, + ext + }) { + return `${root}/${testFileDirectory}/screenshots/${testFileName}/${arg}-${browserName}-${platform}${ext}`; + } + } + } }, setupFiles: ['test/setupBrowser.ts', 'test/failOnConsole.ts'] }