115 lines
5.2 KiB
TypeScript
115 lines
5.2 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
// E2E: 에디터에서 폼 컨트롤러를 추가해 프로젝트를 저장하고,
|
|
// 프리뷰에서 실제 폼을 제출하면 DB에 저장된 뒤
|
|
// 프로젝트의 "폼 제출 내역" 페이지에서 해당 데이터가 표시되는지 검증한다.
|
|
test("프리뷰 폼 제출 후 제출 내역 페이지에서 데이터가 보여야 한다", async ({ page, request }) => {
|
|
// 고유한 테스트용 이메일/프로젝트 slug 를 생성한다.
|
|
const now = Date.now();
|
|
const email = `form-e2e-${now}@example.com`;
|
|
const password = "form-e2e-password";
|
|
const projectSlug = `form-e2e-project-${now}`;
|
|
|
|
// 1) 실제 /api/auth/signup API 를 호출해 테스트용 유저를 생성하고,
|
|
// 응답 헤더의 Set-Cookie 에서 pb_access 토큰 값을 추출한다.
|
|
const signupRes = await request.post("/api/auth/signup", {
|
|
headers: { "Content-Type": "application/json" },
|
|
data: { email, password },
|
|
});
|
|
|
|
expect(signupRes.status()).toBe(201);
|
|
|
|
const setCookieHeader = signupRes.headers()["set-cookie"];
|
|
expect(setCookieHeader).toBeTruthy();
|
|
|
|
const cookieHeaderString = Array.isArray(setCookieHeader)
|
|
? setCookieHeader.join("; ")
|
|
: (setCookieHeader as string);
|
|
|
|
const match = cookieHeaderString.match(/pb_access=([^;]+)/);
|
|
expect(match).not.toBeNull();
|
|
|
|
const accessToken = match![1];
|
|
|
|
// 브라우저 컨텍스트에 pb_access 쿠키를 직접 주입해
|
|
// /api/auth/me, /api/projects, /api/projects/[slug]/submissions 에서
|
|
// 실제 인증 플로우를 그대로 타도록 한다.
|
|
await page.context().addCookies([
|
|
{
|
|
name: "pb_access",
|
|
value: accessToken,
|
|
domain: "localhost",
|
|
path: "/",
|
|
httpOnly: true,
|
|
secure: false,
|
|
sameSite: "Lax",
|
|
},
|
|
]);
|
|
|
|
// 2) 에디터에서 프로젝트 제목/slug 를 설정하고 폼 컨트롤러 블록을 추가한다.
|
|
await page.goto("/editor");
|
|
|
|
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
|
await propertiesSidebar.getByLabel("프로젝트 제목").fill("E2E 폼 프로젝트");
|
|
await propertiesSidebar.getByLabel("프로젝트 주소 (slug)").fill(projectSlug);
|
|
|
|
// 좌측 블록 사이드바에서 "폼 컨트롤러" 버튼을 눌러 기본 contact 폼을 추가한다.
|
|
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
|
|
|
// 3) "저장 (로컬 + 서버)" 액션으로 프로젝트를 서버에 실제 저장한다.
|
|
await page.getByRole("button", { name: "메뉴 ▼" }).click();
|
|
await page.getByRole("button", { name: "프로젝트 저장/불러오기" }).click();
|
|
await page.getByRole("button", { name: "저장 (로컬 + 서버)" }).click();
|
|
|
|
// 저장 후 /projects 페이지로 리다이렉트 되었는지 확인하고,
|
|
// 방금 저장한 slug 가 목록에 노출되는지 검증한다.
|
|
await expect(page).toHaveURL(/\/_?projects/);
|
|
await expect(page.getByText(projectSlug)).toBeVisible();
|
|
|
|
// 해당 프로젝트 행에서 "편집" 링크를 클릭해 /editor?slug=... 로 이동한다.
|
|
const projectRow = page.locator("tr", { hasText: projectSlug }).first();
|
|
await projectRow.getByRole("link", { name: "편집" }).click();
|
|
|
|
// 에디터 페이지로 이동했는지 확인한다.
|
|
await expect(page).toHaveURL(/\/editor/);
|
|
|
|
// 에디터 헤더의 "프리뷰 열기" 링크를 클릭해 프리뷰 페이지로 이동한다.
|
|
await page.getByRole("link", { name: "프리뷰 열기" }).click();
|
|
|
|
await expect(page).toHaveURL(/\/preview/);
|
|
|
|
// 4) 프리뷰 화면의 폼에 값을 입력하고 제출 버튼("폼 전송")을 클릭한다.
|
|
const nameValue = "홍길동";
|
|
const emailValue = `submitted-${now}@example.com`;
|
|
const messageValue = "E2E 테스트 메시지";
|
|
|
|
await page.getByLabel("이름").fill(nameValue);
|
|
await page.getByLabel("이메일").fill(emailValue);
|
|
await page.getByLabel("메시지").fill(messageValue);
|
|
|
|
await page.getByRole("button", { name: "폼 전송" }).click();
|
|
|
|
// 폼 제출 성공 메시지가 표시되어야 한다.
|
|
await expect(page.getByText("성공적으로 전송되었습니다.")).toBeVisible();
|
|
|
|
// 5) 프리뷰 헤더의 "프로젝트 목록" 링크를 통해 다시 /projects 로 이동한다.
|
|
await page.getByRole("link", { name: "프로젝트 목록" }).click();
|
|
await expect(page).toHaveURL(/\/_?projects/);
|
|
|
|
// 동일한 프로젝트 행에서 "폼 제출 내역" 링크를 클릭해 제출 내역 페이지로 이동한다.
|
|
const submissionsRow = page.locator("tr", { hasText: projectSlug }).first();
|
|
await submissionsRow.getByRole("link", { name: "폼 제출 내역" }).click();
|
|
|
|
// URL 이 /projects/[slug]/submissions 형태인지 확인한다.
|
|
await expect(page).toHaveURL(new RegExp(`/projects/${projectSlug}/submissions`));
|
|
|
|
// 6) 제출 내역 페이지에서 헤더와 slug 가 올바르게 표시되는지 검증한다.
|
|
await expect(page.getByRole("heading", { name: "폼 제출 내역" })).toBeVisible();
|
|
await expect(page.getByText(projectSlug)).toBeVisible();
|
|
|
|
// 테이블에 방금 제출한 값들이 포함되어 있어야 한다.
|
|
await expect(page.getByText(nameValue)).toBeVisible();
|
|
await expect(page.getByText(emailValue)).toBeVisible();
|
|
await expect(page.getByText(`message: ${messageValue}`)).toBeVisible();
|
|
});
|