All checks were successful
build-and-push / build (push) Successful in 36s
- playwright.config.ts: 로컬 스택(5380/8380) 대상 headless chromium - e2e/spin.spec.ts: 대시보드·네비·쪽지함·캘린더 일정 생성·프로젝트 생성 모달·검증, 구성원 역할(관리자 메뉴 숨김·관리 라우트 리다이렉트·프로필) - e2e/project-flow.spec.ts: 프로젝트 상세 개요/작업자/메일 탭, 타임라인 작업 추가→상세 모달→칸반 카드 - e2e/member-domains.spec.ts: 근무·휴가 신청 검증, 인센티브 게이지, 대시보드 내 이슈 - ?as=user 로 역할 전환(api.ts 포워딩 활용), afterAll API 정리 - npm run test:e2e 스크립트, test-results/·playwright-report/ gitignore Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.9 KiB
TypeScript
62 lines
2.9 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
// 실제 프로젝트 상세 워크플로(개요/작업자/타임라인 칸반/메일 탭 + 작업 생성→상세 모달).
|
|
const API = "http://localhost:8380/api";
|
|
const stamp = Date.now().toString().slice(-6);
|
|
let projectId = "";
|
|
|
|
test.beforeAll(async () => {
|
|
const r = await fetch(`${API}/projects`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ name: `E2E흐름-${stamp}`, clientDomain: "meditech.com" }),
|
|
});
|
|
const p = await r.json();
|
|
projectId = p.id;
|
|
// 작업자 1명 추가(담당자 옵션)
|
|
await fetch(`${API}/projects/${projectId}/members`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ memberEmail: "park@special-partners.com", portion: 100, role: "작업자" }),
|
|
});
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
if (projectId) await fetch(`${API}/projects/${projectId}`, { method: "DELETE" }).catch(() => {});
|
|
});
|
|
|
|
test("프로젝트 상세 — 개요 렌더", async ({ page }) => {
|
|
await page.goto(`/projects/${projectId}`);
|
|
await expect(page.getByRole("heading", { name: new RegExp(`E2E흐름-${stamp}`) })).toBeVisible();
|
|
await expect(page.getByText("컨설팅 종류")).toBeVisible();
|
|
await expect(page.getByPlaceholder(/주의할 점/)).toBeVisible();
|
|
});
|
|
|
|
test("탭 이동 — 작업자/메일", async ({ page }) => {
|
|
await page.goto(`/projects/${projectId}`);
|
|
await page.getByRole("button", { name: "작업자", exact: true }).click();
|
|
await expect(page.getByText(/기여도\(portion\)/)).toBeVisible();
|
|
await expect(page.getByText("park@special-partners.com")).toBeVisible();
|
|
await page.getByRole("button", { name: "메일", exact: true }).click();
|
|
// 로컬은 Google Workspace 연동 미설정 → 안내 empty state가 정상
|
|
await expect(page.getByText("메일 연동이 설정되지 않았습니다")).toBeVisible();
|
|
});
|
|
|
|
test("타임라인 — 작업 추가 → 상세 모달 → 칸반 카드", async ({ page }) => {
|
|
const errs: string[] = [];
|
|
page.on("pageerror", (e) => errs.push(e.message));
|
|
await page.goto(`/projects/${projectId}`);
|
|
await page.getByRole("button", { name: "타임라인", exact: true }).click();
|
|
await page.getByRole("button", { name: "작업 추가" }).click();
|
|
const title = `E2E작업-${stamp}`;
|
|
await page.getByPlaceholder("예: 기술문서 초안 작성").fill(title);
|
|
await page.getByRole("button", { name: "추가", exact: true }).click();
|
|
// 생성 후 상세 모달이 열림(댓글 입력창으로 확인)
|
|
await expect(page.getByPlaceholder("댓글 입력…")).toBeVisible();
|
|
// 모달 닫기 → 칸반 카드에 작업명 표시
|
|
await page.keyboard.press("Escape");
|
|
await expect(page.getByPlaceholder("댓글 입력…")).toBeHidden();
|
|
await expect(page.getByText(title).first()).toBeVisible();
|
|
expect(errs, errs.join("\n")).toHaveLength(0);
|
|
});
|