feat: přidání testů – Jest unit testy + Playwright E2E + CI pipeline
Server: - Jest unit testy (88 testů): auth, utils, restaurants, service, voting, pizza - in-memory storage mock pro izolaci testů - oprava race condition při inicializaci Redis (storageReady promise) - dev route dostupná i pro NODE_ENV=test - getStatsMock deterministický (nahrazení Math.random) - exporty interních helperů pro testovatelnost - /api/health endpoint pro Playwright readiness check - tsconfig vylučuje test soubory z produkčního buildu E2E (e2e/): - Playwright s Firefoxem + Chromiem - testy: login, menu, výběr jídla, pizza day životní cyklus, QR/nastavení - trusted-header auth bypass pro testy, video + trace při selhání CI (Woodpecker): - pipeline spouštěna na všech větvích a PR (nejen master) - redis-stack-server service pro E2E – čistý Redis per větev automaticky - kroky: unit testy, build, E2E testy (parallel kde možné) - Docker build zůstává pouze pro master Co-Authored-By: Claude Opus (extra usage) 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
import path from 'path';
|
||||
|
||||
// Use 127.0.0.1 explicitly — on Node.js 18+/Windows, `localhost` may resolve to ::1
|
||||
// (IPv6) while the HTTP server only binds to 0.0.0.0 (IPv4), causing the webServer
|
||||
// readiness poll to time out even though the server is listening.
|
||||
const BASE_URL = process.env.E2E_BASE_URL ?? 'http://127.0.0.1:3001';
|
||||
|
||||
// Server env vars injected for local runs. In CI these are set at the step level.
|
||||
const serverEnv: Record<string, string> = {
|
||||
NODE_ENV: 'test',
|
||||
MOCK_DATA: 'true',
|
||||
STORAGE: process.env.STORAGE ?? 'json',
|
||||
JWT_SECRET: process.env.JWT_SECRET ?? 'e2e-test-secret-min-32-chars-aaaa',
|
||||
HTTP_REMOTE_USER_ENABLED: 'true',
|
||||
HTTP_REMOTE_USER_HEADER_NAME: 'remote-user',
|
||||
HTTP_REMOTE_TRUSTED_IPS: process.env.HTTP_REMOTE_TRUSTED_IPS ?? '127.0.0.1,::1,::ffff:127.0.0.1',
|
||||
};
|
||||
if (process.env.REDIS_HOST) {
|
||||
serverEnv.REDIS_HOST = process.env.REDIS_HOST;
|
||||
serverEnv.REDIS_PORT = process.env.REDIS_PORT ?? '6379';
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
timeout: 30_000,
|
||||
retries: process.env.CI ? 1 : 0,
|
||||
workers: 1,
|
||||
reporter: [['list'], ['html', { open: 'never' }]],
|
||||
use: {
|
||||
baseURL: BASE_URL,
|
||||
// Default: every test authenticates as e2e-user via trusted header.
|
||||
// Tests that need the real login form should override this in their own context.
|
||||
extraHTTPHeaders: {
|
||||
'remote-user': 'e2e-user',
|
||||
},
|
||||
trace: 'retain-on-failure',
|
||||
video: 'retain-on-failure',
|
||||
},
|
||||
projects: [
|
||||
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
||||
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
|
||||
],
|
||||
// Pre-built server must be started before tests. In CI the step does this
|
||||
// explicitly. Locally: build types+server+client, cp -r client/dist server/public,
|
||||
// then `cd e2e && yarn test` OR let webServer below do it if reuseExistingServer=true
|
||||
// is set and the server is already running.
|
||||
webServer: {
|
||||
command: 'node dist/server/src/index.js',
|
||||
cwd: path.resolve(__dirname, '../server'),
|
||||
// Poll a dedicated health endpoint — polling '/' can stall in Express 5 when
|
||||
// server/public/ doesn't exist in the working directory (no finalhandler match).
|
||||
url: `http://127.0.0.1:3001/api/health`,
|
||||
timeout: 15_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
env: serverEnv,
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user