141 lines
5.1 KiB
TypeScript
141 lines
5.1 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
// 대시보드 E2E TDD
|
|
// - 비로그인 사용자는 /dashboard 접근 시 /login 으로 리다이렉트되어야 한다.
|
|
// - 로그인 사용자는 /dashboard 에서 요약 지표 + 프로젝트 카드 리스트를 볼 수 있어야 한다.
|
|
// - 백엔드/DB 에 의존하지 않도록 /api/dashboard/overview 를 Playwright 라우팅으로 목킹한다.
|
|
|
|
test("비로그인 사용자가 /dashboard 에 접근하면 /login 으로 리다이렉트되어야 한다", async ({ page }) => {
|
|
await page.route("**/api/dashboard/overview", async (route) => {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ message: "로그인이 필요합니다." }),
|
|
});
|
|
});
|
|
|
|
await page.goto("/dashboard");
|
|
|
|
await expect(page.getByRole("heading", { name: "Log in" })).toBeVisible();
|
|
});
|
|
|
|
test("로그인 사용자가 /dashboard 에 접근하면 요약 지표와 프로젝트 카드 리스트, 일별 그래프를 볼 수 있어야 한다", async ({ page }) => {
|
|
await page.route("**/api/dashboard/overview", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
summaryStats: {
|
|
totalProjects: 2,
|
|
totalSubmissions: 3,
|
|
todaySubmissions: 1,
|
|
last7DaysSubmissions: 3,
|
|
},
|
|
projectStats: [
|
|
{
|
|
projectId: "proj-1",
|
|
title: "테스트 프로젝트 A",
|
|
slug: "test-project-a",
|
|
status: "DRAFT",
|
|
totalSubmissions: 2,
|
|
lastSubmissionAt: "2025-01-02T12:00:00.000Z",
|
|
},
|
|
{
|
|
projectId: "proj-2",
|
|
title: "테스트 프로젝트 B",
|
|
slug: "test-project-b",
|
|
status: "PUBLISHED",
|
|
totalSubmissions: 1,
|
|
lastSubmissionAt: "2025-01-03T09:30:00.000Z",
|
|
},
|
|
],
|
|
dailySubmissions: [
|
|
{ date: "2024-12-26", count: 1 },
|
|
{ date: "2025-01-02", count: 1 },
|
|
{ date: "2025-01-03", count: 1 },
|
|
],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.goto("/dashboard");
|
|
|
|
// 대시보드 헤더가 보여야 한다.
|
|
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
|
|
|
|
// 상단 헤더 내비게이션이 보여야 한다.
|
|
const dashboardLink = page.getByRole("link", { name: "Dashboard" });
|
|
await expect(dashboardLink).toBeVisible();
|
|
|
|
const projectsLink = page.getByRole("link", { name: "Projects" });
|
|
await expect(projectsLink).toBeVisible();
|
|
|
|
const submissionsLink = page.getByRole("link", { name: "All submissions" });
|
|
await expect(submissionsLink).toBeVisible();
|
|
|
|
const menuButton = page.getByRole("button", { name: "Menu" });
|
|
await expect(menuButton).toBeVisible();
|
|
|
|
// 상단 요약 위젯의 지표들이 기대 값으로 렌더되어야 한다.
|
|
const totalProjects = page.getByTestId("dashboard-summary-total-projects");
|
|
await expect(totalProjects).toContainText("2");
|
|
|
|
const totalSubmissions = page.getByTestId("dashboard-summary-total-submissions");
|
|
await expect(totalSubmissions).toContainText("3");
|
|
|
|
const todaySubmissions = page.getByTestId("dashboard-summary-today-submissions");
|
|
await expect(todaySubmissions).toContainText("1");
|
|
|
|
const last7DaysSubmissions = page.getByTestId(
|
|
"dashboard-summary-last7days-submissions",
|
|
);
|
|
await expect(last7DaysSubmissions).toContainText("3");
|
|
|
|
// 프로젝트 카드 리스트가 2개 렌더링되어야 한다.
|
|
const projectCards = page.getByTestId("dashboard-project-card");
|
|
await expect(projectCards).toHaveCount(2);
|
|
|
|
await expect(projectCards.nth(0)).toContainText("테스트 프로젝트 A");
|
|
await expect(projectCards.nth(0)).toContainText("test-project-a");
|
|
await expect(projectCards.nth(0)).toContainText("2");
|
|
|
|
await expect(projectCards.nth(1)).toContainText("테스트 프로젝트 B");
|
|
await expect(projectCards.nth(1)).toContainText("test-project-b");
|
|
await expect(projectCards.nth(1)).toContainText("1");
|
|
|
|
// 일별 제출 수 그래프가 렌더링되어야 한다.
|
|
const dailyChart = page.getByTestId("dashboard-daily-chart");
|
|
await expect(dailyChart).toBeVisible();
|
|
|
|
const dailyBars = page.getByTestId("dashboard-daily-chart-bar");
|
|
await expect(dailyBars).toHaveCount(3);
|
|
|
|
// 메뉴 버튼을 클릭하면 로그아웃 항목이 보여야 한다.
|
|
await menuButton.click();
|
|
await expect(page.getByRole("button", { name: "Log out" })).toBeVisible();
|
|
});
|
|
|
|
test("로그인 사용자가 / 에 접속하면 대시보드로 진입해야 한다", async ({ page }) => {
|
|
await page.route("**/api/dashboard/overview", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
summaryStats: {
|
|
totalProjects: 1,
|
|
totalSubmissions: 0,
|
|
todaySubmissions: 0,
|
|
last7DaysSubmissions: 0,
|
|
},
|
|
projectStats: [],
|
|
dailySubmissions: [],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.goto("/");
|
|
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
|
|
});
|