import { test, expect } from "@playwright/test"; /** * Full-stack integration tests against the real backend (http://localhost:8000). * These tests do NOT mock API routes — they exercise the real API + frontend. * * Prerequisites: * - Backend running on port 8000 * - Frontend dev server running on port 5173 * - Admin account with username "admin" / password "admin123" * - A3Master server record exists */ const REAL_API = "http://localhost:8000"; test.describe("Full Stack Integration", () => { test("should login and see A3Master server on dashboard", async ({ page }) => { // Navigate to login page await page.goto("/login"); await expect(page.locator('[data-testid="login-card"]')).toBeVisible(); // Fill in real credentials await page.locator('[data-testid="login-username"]').fill("admin"); await page.locator('[data-testid="login-password"]').fill("admin123"); await page.locator('[data-testid="login-submit"]').click(); // Should navigate to dashboard await page.waitForURL("/", { timeout: 10_000 }); // Dashboard should render await expect(page.locator('[data-testid="dashboard-content"]')).toBeVisible({ timeout: 10_000, }); // Should show at least one server (A3Master) — use .first() to avoid strict mode await expect(page.locator("text=A3Master").first()).toBeVisible({ timeout: 10_000 }); // Should show server count const serverCount = await page.locator("[data-testid^='server-card-']").count(); expect(serverCount).toBeGreaterThanOrEqual(1); }); test("should show A3Master server details in card", async ({ page }) => { // Login via API and set auth state const loginRes = await page.request.post(`${REAL_API}/api/auth/login`, { data: { username: "admin", password: "admin123" }, }); expect(loginRes.ok()).toBe(true); const loginData = await loginRes.json(); const token = loginData.data.access_token; const user = loginData.data.user; // Set auth state in localStorage await page.addInitScript( ({ token, user }) => { localStorage.setItem("languard_token", token); localStorage.setItem( "languard-auth", JSON.stringify({ state: { token, user }, version: 0 }), ); }, { token, user }, ); await page.goto("/"); await expect(page.locator('[data-testid="dashboard-content"]')).toBeVisible({ timeout: 10_000, }); // Server card should show the A3Master name await expect(page.locator("text=A3Master").first()).toBeVisible({ timeout: 10_000 }); // Server card should show arma3 game type await expect(page.locator("text=arma3").first()).toBeVisible({ timeout: 5_000 }); }); test("should navigate to server detail page", async ({ page }) => { // Login via API const loginRes = await page.request.post(`${REAL_API}/api/auth/login`, { data: { username: "admin", password: "admin123" }, }); const loginData = await loginRes.json(); const token = loginData.data.access_token; const user = loginData.data.user; await page.addInitScript( ({ token, user }) => { localStorage.setItem("languard_token", token); localStorage.setItem( "languard-auth", JSON.stringify({ state: { token, user }, version: 0 }), ); }, { token, user }, ); await page.goto("/"); await expect(page.locator('[data-testid="dashboard-content"]')).toBeVisible({ timeout: 10_000, }); // Click the A3Master server card link in the dashboard content area const serverLink = page.locator('[data-testid="dashboard-content"] a[href="/servers/1"]'); await serverLink.click(); // Should navigate to server detail await expect(page).toHaveURL(/\/servers\/1/, { timeout: 5_000 }); }); test("should redirect to login when unauthenticated", async ({ page }) => { // Navigate to dashboard without auth — should redirect to login await page.goto("/"); await expect(page).toHaveURL(/\/login/, { timeout: 10_000 }); await expect(page.locator('[data-testid="login-card"]')).toBeVisible(); }); test("should authenticate and check server API response shape", async ({ page }) => { // Login via API to verify backend response format const loginRes = await page.request.post(`${REAL_API}/api/auth/login`, { data: { username: "admin", password: "admin123" }, }); expect(loginRes.ok()).toBe(true); const loginData = await loginRes.json(); expect(loginData.success).toBe(true); expect(loginData.data.access_token).toBeDefined(); expect(loginData.data.user.username).toBe("admin"); expect(loginData.data.user.role).toBe("admin"); // Fetch servers via API const token = loginData.data.access_token; const serversRes = await page.request.get(`${REAL_API}/api/servers`, { headers: { Authorization: `Bearer ${token}` }, }); expect(serversRes.ok()).toBe(true); const serversData = await serversRes.json(); expect(serversData.success).toBe(true); expect(Array.isArray(serversData.data)).toBe(true); expect(serversData.data.length).toBeGreaterThanOrEqual(1); // Verify A3Master server has expected fields const a3master = serversData.data.find((s: { name: string }) => s.name === "A3Master"); expect(a3master).toBeDefined(); expect(a3master.game_type).toBe("arma3"); expect(a3master.exe_path).toContain("A3Master"); }); });