import { test as setup, expect } from '@playwright/test'; import path from 'path'; const authFile = path.join(__dirname, '../playwright/.auth/user.json'); /** * Authentication setup - logs in once and saves storage state * All tests will reuse this authenticated session */ setup('authenticate', async ({ page }) => { // Navigate to app (will redirect to Keycloak) await page.goto('/'); // Wait for page to settle await page.waitForLoadState('networkidle'); // Check if we're on a login page (Keycloak at port 18280 or has login form) const hasLoginForm = await page.locator('input[name="username"], input[id="username"]').isVisible().catch(() => false); const isKeycloakUrl = page.url().includes(':18280'); if (hasLoginForm || isKeycloakUrl) { console.log('Login page detected, filling credentials...'); // Fill in login credentials const testEmail = process.env.TEST_USER_EMAIL || 'admin@local.dev'; const testPassword = process.env.TEST_USER_PASSWORD || 'admin'; // Try different input selectors for username/email const usernameInput = page.locator('input[name="username"], input[id="username"], input[type="email"]').first(); await usernameInput.fill(testEmail); // Fill password const passwordInput = page.locator('input[name="password"], input[id="password"], input[type="password"]').first(); await passwordInput.fill(testPassword); // Click sign in button await page.locator('button[type="submit"], input[type="submit"], button:has-text("Sign In")').first().click(); // Wait for redirect back to app await page.waitForURL('http://localhost:13003/**', { timeout: 30000 }); } // Wait for app to be fully loaded await page.waitForLoadState('networkidle'); // Verify we're authenticated by checking for dashboard content // Look for "Service Monitor" text which appears in the header await expect(page.locator('text=Service Monitor').first()).toBeVisible({ timeout: 15000 }); console.log('Authentication successful, saving storage state...'); // Save storage state (cookies, localStorage) await page.context().storageState({ path: authFile }); });