import { defineConfig, devices } from '@playwright/test'; import { execSync } from 'child_process'; /** * Playwright configuration for website smoke tests * * Purpose: Verify all website pages load without runtime errors * Scope: Page rendering, console errors, React hydration * * Critical Detection: * - Console errors during page load * - React hydration mismatches * - Navigation failures * - Missing content * * IMPORTANT: This test requires Docker to run against real TypeORM/PostgreSQL */ // Enforce Docker usage function validateDockerEnvironment(): void { // Skip validation if explicitly requested (for CI or advanced users) if (process.env.PLAYWRIGHT_SKIP_DOCKER_CHECK === 'true') { console.warn('⚠️ Skipping Docker validation - assuming services are running'); return; } try { // Check if Docker is running execSync('docker info', { stdio: 'pipe' }); // Check if the required Docker services are running const services = execSync('docker ps --format "{{.Names}}"', { encoding: 'utf8' }); // Look for services that match our test pattern const testServices = services.split('\n').filter(s => s.includes('gridpilot-test')); if (testServices.length === 0) { console.error('❌ No test Docker services found running'); console.error('💡 Please run: docker-compose -f docker-compose.test.yml up -d'); console.error(' This will start:'); console.error(' - PostgreSQL database'); console.error(' - API server with TypeORM/PostgreSQL'); console.error(' - Website server'); process.exit(1); } // Check for specific required services (website runs locally, not in Docker) const hasApi = testServices.some(s => s.includes('api')); const hasDb = testServices.some(s => s.includes('db')); if (!hasApi || !hasDb) { console.error('❌ Missing required Docker services'); console.error(' Found:', testServices.join(', ')); console.error(' Required: api, db'); console.error('💡 Please run: docker-compose -f docker-compose.test.yml up -d'); process.exit(1); } console.log('✅ Docker environment validated'); } catch (error) { console.error('❌ Docker is not available or not running'); console.error('💡 Please ensure Docker is installed and running, then run:'); console.error(' docker-compose -f docker-compose.test.yml up -d'); console.error(''); console.error(' Or skip this check with: PLAYWRIGHT_SKIP_DOCKER_CHECK=true npx playwright test'); process.exit(1); } } // Run validation before config (unless in CI or explicitly skipped) if (!process.env.CI && !process.env.PLAYWRIGHT_SKIP_DOCKER_CHECK) { validateDockerEnvironment(); } export default defineConfig({ testDir: './tests/e2e/website', testMatch: ['**/website-pages.test.ts'], testIgnore: ['**/electron-build.smoke.test.ts'], // Serial execution for consistent results fullyParallel: false, workers: 1, // Continue on errors to see all failures maxFailures: undefined, // Timeout: Pages should load quickly timeout: 30_000, // Base URL for the website (local dev server) use: { baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000', // Local website dev server screenshot: 'only-on-failure', video: 'retain-on-failure', trace: 'retain-on-failure', }, // Reporter: verbose for debugging reporter: [ ['list'], ['html', { open: 'never' }] ], // No retry - smoke tests must pass on first run retries: 0, // Web server configuration // Start local Next.js dev server that connects to Docker API webServer: { command: 'npm run dev -w @gridpilot/website', url: 'http://localhost:3000', timeout: 120_000, reuseExistingServer: !process.env.CI, env: { NEXT_PUBLIC_API_BASE_URL: 'http://localhost:3101', API_BASE_URL: 'http://localhost:3101', }, }, // Browser projects projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, ], });