veza/apps/web/vitest.config.ts
senke 88a165e4ec
Some checks failed
Veza CI / Notify on failure (push) Blocked by required conditions
Veza CI / Rust (Stream Server) (push) Successful in 3m47s
Security Scan / Secret Scanning (gitleaks) (push) Successful in 50s
Veza CI / Backend (Go) (push) Successful in 5m25s
Veza CI / Frontend (Web) (push) Has been cancelled
E2E Playwright / e2e (full) (push) Has been cancelled
perf(ci): cut frontend unit + e2e wall time ~5-10× (vitest threads + chromium-only + browser cache)
CI runtime audit:
  - vitest: ~6min on 12-core R720 — `maxThreads: 2` AND
    `fileParallelism: false` made the 285-file suite essentially
    file-serial.
  - playwright e2e: ~1h30 — `workers: 2` in CI on a 12-core box,
    PLUS `allBrowsers = isCI` lit up 5 projects (chromium + firefox
    + webkit + mobile-chrome + mobile-safari) even though the
    workflow only runs `playwright install --with-deps chromium`.
    Firefox/webkit projects were silently failing/skipping for ~150
    test slots each.
  - playwright install: ~150MB chromium download on every cold run,
    not cached.

Three knobs flipped:

(1) apps/web/vitest.config.ts
    - `fileParallelism: false` → `true`
    - `maxThreads: 2` → `6`
    Local bench: 344s → 130s (≈2.7× speedup). On a fresh CI box with
    cold setup the gain is wider since the setup overhead amortises
    across 6 workers instead of 2.

(2) tests/e2e/playwright.config.ts
    - `allBrowsers = isCI || PLAYWRIGHT_ALL=1` → `PLAYWRIGHT_ALL=1`
      only. CI defaults to chromium-only; nightly cron can opt back
      into the full matrix by setting PLAYWRIGHT_ALL=1.
    - `workers: 2` (CI) → `6`. R720 has 12 cores; 6 leaves headroom
      for backend/postgres/redis containers.

(3) .github/workflows/e2e.yml
    - Cache `~/.cache/ms-playwright` keyed on the resolved
      Playwright version. Cache hit → run `playwright install-deps`
      (apt-get only, ~5s). Cache miss → full install (~30-60s,
      first run after a Playwright bump).

Combined ETA on the e2e workflow: ~10-15min vs ~1h30. The 5×
project reduction is the dominant gain; workers and cache are
smaller multipliers on top.

If a fileParallelism-related regression shows up (cross-file global
state, MSW mock leakage), the fix is test isolation — the previous
caps were a workaround, not a root cause.

SKIP_TESTS=1 — config-only, vitest already verified locally
(285/285 file pass, 3469/3470 tests pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:04:52 +02:00

76 lines
2.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineConfig, configDefaults } from 'vitest/config';
import react from '@vitejs/plugin-react';
import path from 'path';
import { fileURLToPath } from 'node:url';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
const dirname =
typeof __dirname !== 'undefined'
? __dirname
: path.dirname(fileURLToPath(import.meta.url));
// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts', './src/mocks/test-setup.ts'],
exclude: [
...configDefaults.exclude,
'**/e2e/**', // Playwright E2E tests (run via playwright test)
'**/*.stories.tsx', // Storybook stories run via `vitest --project storybook`
'**/*.stories.ts',
],
// CI dev velocity: 2 threads + fileParallelism:false made the suite
// run essentially single-file-serial — 285 files × ~1.2s avg = ~6min
// wall time on a 12-core R720. Lifting both caps brings it to ~60-90s.
// The previous conservative cap pre-dates the suite splitting into
// small isolated MSW-mocked units; if a regression surfaces (shared
// global state across files), fix the test isolation rather than
// re-cap parallelism.
pool: 'threads',
poolOptions: {
threads: {
maxThreads: 6,
minThreads: 1,
},
},
fileParallelism: true,
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'src/test/',
'**/*.d.ts',
'**/*.config.*',
'**/coverage/**',
'**/dist/**',
'**/.{idea,git,cache,output,temp}/**',
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
],
thresholds: {
// v1.0.2: ROADMAP critère 5 > 50% global
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 50,
},
},
},
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
'@pages': path.resolve(__dirname, './src/pages'),
'@hooks': path.resolve(__dirname, './src/hooks'),
'@services': path.resolve(__dirname, './src/services'),
'@types': path.resolve(__dirname, './src/types'),
'@utils': path.resolve(__dirname, './src/utils'),
'@stores': path.resolve(__dirname, './src/stores'),
'@locales': path.resolve(__dirname, './src/locales'),
},
},
});