@saas-maker/test-config
v0.2.0
Published
Foundry-standard Playwright + Vitest config factories with a11y + smoke baked in.
Readme
@saas-maker/test-config
Factory functions for Playwright + Vitest with Foundry defaults baked in. Stops every Fleet repo from re-deciding timeout, retries, viewport matrix, etc.
Install
pnpm add -D @saas-maker/test-config @playwright/test @axe-core/playwright vitestPlaywright
// playwright.config.ts
import { definePlaywrightConfig } from '@saas-maker/test-config/playwright';
export default definePlaywrightConfig({
baseURL: 'http://localhost:3000',
webServer: {
command: 'pnpm dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});Defaults:
testDir=./tests/e2etimeout= 30s,expect.timeout= 5sretries= 2 in CI, 0 locally- Reporter:
listlocally;[list, html, junit]in CI trace: 'on-first-retry',screenshot: 'only-on-failure',video: retain-on-failurein CI- 5 projects:
smoke,mobile(Pixel 7),tablet(iPad Pro 11),desktop(Chrome),wide(1920x1080)
Vitest
// vitest.config.ts
import { defineVitestConfig } from '@saas-maker/test-config/vitest';
export default defineVitestConfig({
environment: 'happy-dom', // for React tests
setupFiles: ['./src/test-setup.ts'],
});Defaults:
globals: trueenvironment: 'node'include: ['src/**/__tests__/**/*.test.ts', 'src/**/*.test.ts']testTimeout: 15_000- v8 coverage with sensible excludes (off by default)
Plugins, aliases, and arbitrary test.* overrides
defineVitestConfig is a passthrough of Vite's UserConfig. Any top-level
Vite key (plugins, resolve, define, server, …) and any test.* field
is shallow-merged on top of the foundry defaults — no escape hatch needed.
import { defineVitestConfig } from '@saas-maker/test-config/vitest';
import react from '@vitejs/plugin-react';
import path from 'node:path';
export default defineVitestConfig({
environment: 'happy-dom',
plugins: [react()],
resolve: {
alias: { '@': path.resolve(__dirname, 'src') },
},
test: {
// Anything from Vitest's `test` block — merged with foundry defaults.
pool: 'forks',
sequence: { shuffle: true },
server: { deps: { inline: ['react-markdown'] } },
},
});a11y
import { test, expect } from '@playwright/test';
import { runA11y } from '@saas-maker/test-config/a11y';
test('home is a11y-clean', async ({ page }) => {
await page.goto('/');
const r = await runA11y(page, { exclude: ['#third-party-widget'] });
expect(r.violations, JSON.stringify(r.violations, null, 2)).toHaveLength(0);
});runA11y runs axe-core scoped to wcag2a/aa + wcag21a/aa tags by default.
Smoke
Place smoke tests in any *.smoke.spec.ts file — they're picked up by the dedicated smoke Playwright project so you can run only the fast happy path:
pnpm exec playwright test --project=smoke