// frontend/playwright/auth.spec.ts — 로그인 플로우 + 보호 라우트 리다이렉트 // 실행: NEXT_PUBLIC_AUTH_ENABLED=true 프론트 + AUTH_ENABLED=true 백엔드(:31800, 시드 자격). // (데모 CI 와 분리된 auth-multiuser 잡 — playwright/auth.config.ts 사용) import { expect, test } from "@playwright/test"; test("미인증 → 보호 라우트 접근 시 /login 리다이렉트", async ({ page }) => { await page.goto("/tasks"); await expect(page).toHaveURL(/\/login\?next=%2Ftasks/); }); test("로그인 → 대시보드, Topbar 아바타에 '지'", async ({ page }) => { await page.goto("/login"); await page.getByPlaceholder("이메일").fill("jiwoo@lumi.co"); await page.getByPlaceholder("비밀번호").fill("demo-1234"); await page.getByRole("button", { name: "로그인" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await expect(page.locator(".t-ava")).toContainText("지"); }); test("잘못된 비밀번호 → 동일 한국어 메시지(계정 열거 방어)", async ({ page }) => { await page.goto("/login"); await page.getByPlaceholder("이메일").fill("jiwoo@lumi.co"); await page.getByPlaceholder("비밀번호").fill("nope"); await page.getByRole("button", { name: "로그인" }).click(); await expect(page.locator(".login-error")).toContainText("이메일 또는 비밀번호가 올바르지 않아요"); await expect(page).toHaveURL(/\/login/); // 페이지 유지 }); test("쿠키 삭제(세션 만료) → 다음 보호 요청 /login", async ({ page, context }) => { await page.goto("/login"); await page.getByPlaceholder("이메일").fill("jiwoo@lumi.co"); await page.getByPlaceholder("비밀번호").fill("demo-1234"); await page.getByRole("button", { name: "로그인" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await context.clearCookies(); await page.goto("/inbox"); await expect(page).toHaveURL(/\/login/); });