// frontend/playwright/dashboard.spec.ts import { expect, test } from "@playwright/test"; import { resetSeed } from "./fixtures/seed-reset"; test.describe.configure({ mode: "serial" }); // 깨끗한 시드에서 시작(앞선 spec 의 변경과 격리). test.beforeAll(resetSeed); test("로드 → 집계가 시드 기준으로 표시", async ({ page }) => { await page.goto("/dashboard"); await expect(page.getByText("아리 브리핑")).toBeVisible(); await expect(page.locator(".brief b")).toHaveText("분기 리포트"); await expect(page.getByText("아리 결재함")).toBeVisible(); await expect(page.getByText("대기 4건")).toBeVisible(); // +심부름 게이트(phase-14) await expect(page.getByText("현우님께 회신 초안이 준비됐어요")).toBeVisible(); await expect(page.locator(".ev")).toHaveCount(4); await expect(page.getByText("곧", { exact: true })).toBeVisible(); await expect(page.getByRole("progressbar")).toHaveCount(3); }); test("인박스 카드 '새로 적기' → /inbox", async ({ page }) => { await page.goto("/dashboard"); await page.getByRole("link", { name: /새로 적기/ }).click(); await expect(page).toHaveURL(/\/inbox$/); }); test("결재함 카드 CTA → /approvals 실제 페이지(phase-7)", async ({ page }) => { await page.goto("/dashboard"); await page.getByRole("link", { name: /결재함에서 승인하기/ }).click(); await expect(page).toHaveURL(/\/approvals$/); await expect(page.getByRole("heading", { level: 1, name: /아리 결재함/ })).toBeVisible(); }); // phase-16+: 작업 시드 제거 → 작업 요약 딥링크 테스트는 빈 상태라 제외. test("자연어 명령 입력 → 캡처 후 /inbox 이동", async ({ page }) => { test.setTimeout(150_000); // 실 Ollama 콜드스타트 여유 await page.goto("/dashboard"); const input = page.getByLabel("아리에게 명령 입력"); await input.fill("수요일 11시 자전거 수리 맡기기"); await page.getByLabel("보내기").click(); // 실 Ollama 분류(수초) 후 이동 → 넉넉한 타임아웃 await expect(page).toHaveURL(/\/inbox$/, { timeout: 30000 }); await expect( page.locator(".sb-raw", { hasText: "수요일 11시 자전거 수리 맡기기" }).first(), ).toBeVisible({ timeout: 30000 }); }); test("다크 테마 토글 후에도 렌더 정상", async ({ page }) => { await page.goto("/dashboard"); await page.getByLabel("테마 전환").click(); await expect(page.locator("html")).toHaveAttribute("data-theme", "dark"); await expect(page.getByText("아리 브리핑")).toBeVisible(); });