import { defineConfig, devices } from '@playwright/test'; import { randomBytes } from 'node:crypto'; import { execFileSync } from 'node:child_process'; import { existsSync, mkdirSync, mkdtempSync } from 'node:fs'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; process.env.TEST_TLS_DIR ??= mkdtempSync(join(tmpdir(), 'hamham-tls-')); mkdirSync(process.env.TEST_TLS_DIR, { recursive: true }); const testCert = join(process.env.TEST_TLS_DIR, 'cert.pem'); if (!existsSync(testCert)) execFileSync( 'openssl', [ 'req', '-x509', '-newkey', 'rsa:2048', '-nodes', '-days', '1', '-keyout', join(process.env.TEST_TLS_DIR, 'key.pem'), '-out', testCert, '-subj', '/CN=localhost', '-addext', 'subjectAltName=DNS:localhost,IP:127.0.0.1', ], { stdio: 'ignore' }, ); process.env.TEST_PASSWORD ??= randomBytes(24).toString('base64url'); process.env.TEST_DATABASE_URL ??= `postgres://${process.env.USER ?? 'postgres'}@localhost:5432/hamham_test`; export default defineConfig({ testDir: './tests/e2e', fullyParallel: false, workers: 1, retries: 0, timeout: 45000, globalSetup: './tests/setup.ts', reporter: [['list'], ['html', { open: 'never' }]], use: { baseURL: 'http://localhost:3100', trace: 'retain-on-failure', screenshot: 'only-on-failure', }, webServer: { command: 'npm run start -- --port 3100', url: 'http://localhost:3100/api/health', reuseExistingServer: false, timeout: 60000, env: { DATABASE_URL: process.env.TEST_DATABASE_URL, APP_ORIGIN: 'http://localhost:3100', COOKIE_SECURE: 'false', AUTH_ENCRYPTION_KEY: '12'.repeat(32), ADMIN_EMAIL: 'admin@example.org', NODE_EXTRA_CA_CERTS: testCert, UPLOAD_DIR: './test-results/uploads', NEXT_TELEMETRY_DISABLED: '1', }, }, projects: [ { name: 'desktop', use: { ...devices['Desktop Chrome'], viewport: { width: 1440, height: 1000 } }, }, { name: 'mobile', testMatch: /public.spec.ts/, use: { ...devices['iPhone 13'], defaultBrowserType: 'chromium' }, }, { name: 'tablet', testMatch: /public.spec.ts/, use: { ...devices['iPad Mini'], defaultBrowserType: 'chromium' }, }, ], });