import { test, expect } from "@playwright/test"; import { LoginPage } from "../pages/LoginPage"; test.describe("Login Flow", () => { let loginPage: LoginPage; test.beforeEach(async ({ page }) => { loginPage = new LoginPage(page); await loginPage.goto(); }); test("should display login form", async () => { await expect(loginPage.card).toBeVisible(); await expect(loginPage.usernameInput).toBeVisible(); await expect(loginPage.passwordInput).toBeVisible(); await expect(loginPage.submitButton).toBeVisible(); await expect(loginPage.submitButton).toContainText("Sign In"); }); test("should show Languard branding", async () => { await expect(loginPage.card.locator("h1")).toContainText("Languard"); await expect(loginPage.card.locator("p")).toContainText("Server Manager"); }); test("should show validation errors on empty submit", async ({ page }) => { await loginPage.submitButton.click(); await expect(page.locator("text=Username is required")).toBeVisible(); await expect(page.locator("text=Password is required")).toBeVisible(); }); test("should show error on invalid credentials", async ({ page }) => { // Mock the backend to return 401 for invalid login await page.route("**/api/auth/login", (route) => route.fulfill({ status: 401, contentType: "application/json", body: JSON.stringify({ detail: "Invalid credentials", }), }), ); await loginPage.login("invalid", "credentials"); await expect(loginPage.errorMessage).toBeVisible({ timeout: 10_000 }); }); test("should navigate to dashboard on successful login", async ({ page }) => { await page.route("**/api/auth/login", (route) => route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ success: true, data: { access_token: "mock-jwt-token", user: { id: 1, username: "admin", role: "admin" }, }, }), }), ); // Mock auth/me and servers so the dashboard loads await page.route("**/api/auth/me", (route) => route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ success: true, data: { id: 1, username: "admin", role: "admin" }, error: null }), }), ); await page.route("**/api/servers**", (route) => route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ success: true, data: [] }), }), ); await loginPage.login("admin", "password"); await page.waitForURL("/", { timeout: 10_000 }); await expect(page.locator("text=Dashboard")).toBeVisible(); }); test("should show loading state while submitting", async ({ page }) => { let resolveLogin: (value: unknown) => void; const loginPromise = new Promise((resolve) => { resolveLogin = resolve; }); await page.route("**/api/auth/login", async (route) => { await loginPromise; await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ success: true, data: { access_token: "mock-jwt-token", user: { id: 1, username: "admin", role: "admin" }, }, }), }); }); await loginPage.usernameInput.fill("admin"); await loginPage.passwordInput.fill("password"); // Click submit and immediately check for loading state await loginPage.submitButton.click(); // The button should show "Signing in..." while the request is pending await expect(loginPage.submitButton).toContainText("Signing in...", { timeout: 5_000 }); // Resolve the login to let the test finish resolveLogin!("done"); }); });