리스트/에디터 스타일 정리 및 버그 수정
This commit is contained in:
+82
-64
@@ -8,10 +8,10 @@ test("/editor 페이지가 존재하고 Page Editor 헤더를 보여줘야 한
|
||||
await expect(page.getByRole("heading", { name: "Page Editor" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("텍스트 블록 추가 버튼을 누르면 캔버스에 '새 텍스트' 블록이 보여야 한다", async ({ page }) => {
|
||||
test("텍스트 버튼을 누르면 캔버스에 '새 텍스트' 블록이 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
await expect(canvas.getByText("새 텍스트")).toBeVisible();
|
||||
@@ -75,7 +75,7 @@ test("텍스트 블록을 더블클릭해서 내용을 수정할 수 있어야
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// 1단계: 더블클릭 → Enter 로 커밋
|
||||
// 기존 텍스트 블록을 더블클릭해서 편집 모드로 전환한다.
|
||||
@@ -109,7 +109,7 @@ test("텍스트 블록을 더블클릭해서 내용을 수정할 수 있어야
|
||||
await editor.fill("blur 로 커밋된 텍스트");
|
||||
|
||||
// 포커스를 다른 곳(예: 속성 패널의 버튼 추가 텍스트 입력)을 클릭하여 blur 를 발생시킨다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// blur 이후에는 마지막 입력 값이 캔버스에 반영되어야 한다.
|
||||
canvasAfterEdit = page.getByTestId("editor-canvas");
|
||||
@@ -120,7 +120,7 @@ test("속성 패널에서 선택된 텍스트 블록 내용을 수정하면 캔
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// 캔버스 블록을 클릭해서 선택한다.
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
@@ -140,8 +140,8 @@ test("여러 텍스트 블록 중 선택을 전환하면 속성 패널 내용과
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록 두 개를 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
@@ -172,7 +172,7 @@ test("텍스트 블록의 정렬과 글자 크기를 속성 패널에서 변경
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록을 하나 추가하고 선택한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const block = canvas.getByTestId("editor-block").nth(0);
|
||||
await block.click({ force: true });
|
||||
@@ -196,7 +196,7 @@ test("텍스트 블록 인라인 툴바에서 정렬과 글자 크기를 변경
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const block = canvas.getByTestId("editor-block").nth(0);
|
||||
@@ -226,8 +226,8 @@ test("에디터 상태를 JSON으로 내보내고 다시 불러오면 동일한
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 블록 두 개를 추가하고 각각 다른 내용/스타일을 설정한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const firstBlock = blocks.nth(0);
|
||||
@@ -290,8 +290,8 @@ test("각 캔버스 블록에 드래그 핸들 UI가 표시되고 선택 상태
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 블록 두 개를 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const firstBlock = blocks.nth(0);
|
||||
@@ -318,8 +318,8 @@ test("블록 드래그앤드롭으로 순서를 변경할 수 있어야 한다",
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 블록 두 개를 추가하고 서로 다른 텍스트로 구분한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const firstBlock = blocks.nth(0);
|
||||
@@ -352,8 +352,8 @@ test("리스트 블록에도 드래그 핸들이 있고 선택/드래그가 가
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 텍스트 블록과 리스트 블록을 하나씩 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(2);
|
||||
@@ -387,7 +387,7 @@ test("버튼 블록을 추가하고 라벨과 링크를 수정할 수 있어야
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 버튼 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
// 캔버스에 기본 버튼이 렌더되어야 한다.
|
||||
const button = canvas.getByRole("button", { name: "버튼" });
|
||||
@@ -410,7 +410,7 @@ test("버튼 블록을 추가하면 속성 패널 기본 색상/패딩 값이
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
const button = canvas.getByRole("button", { name: "버튼" });
|
||||
await expect(button).toBeVisible();
|
||||
@@ -437,7 +437,7 @@ test("버튼 가로/세로 패딩 px 값을 변경하면 에디터 버튼에도
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
const button = canvas.getByRole("button", { name: "버튼" }).first();
|
||||
|
||||
@@ -470,7 +470,7 @@ test("버튼 가로/세로 패딩 px 값을 변경하면 에디터 버튼에도
|
||||
test("이미지 블록 고정 너비와 모서리 둥글기 스타일이 에디터에서 적용되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "이미지 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "이미지" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -504,7 +504,7 @@ test("에디터 메뉴에서 페이지 파일로 내보내기 (ZIP)를 클릭하
|
||||
await page.goto("/editor");
|
||||
|
||||
// 최소 한 개의 블록을 추가해 내보낼 데이터가 있도록 한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// 헤더 메뉴를 연다.
|
||||
await page.getByRole("button", { name: "메뉴 ▼" }).click();
|
||||
@@ -528,7 +528,7 @@ test("2컬럼 섹션에서 블록을 다른 컬럼 영역으로 드래그하면
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 섹션을 하나 추가하고 레이아웃을 2컬럼으로 변경한다.
|
||||
await page.getByRole("button", { name: "섹션 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "섹션" }).click();
|
||||
|
||||
// 섹션을 선택한다 (캔버스 첫 블록).
|
||||
const sectionBlock = canvas.getByTestId("editor-block").nth(0);
|
||||
@@ -538,7 +538,7 @@ test("2컬럼 섹션에서 블록을 다른 컬럼 영역으로 드래그하면
|
||||
await layoutSelect.selectOption("2col");
|
||||
|
||||
// 왼쪽 컬럼에 텍스트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const leftColumn = canvas.locator('[data-section-id][data-column-id]').nth(0);
|
||||
const rightColumn = canvas.locator('[data-section-id][data-column-id]').nth(1);
|
||||
@@ -563,7 +563,7 @@ test("Hero 템플릿 버튼을 클릭하면 섹션과 기본 텍스트/버튼
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// Hero 템플릿을 추가한다.
|
||||
await page.getByRole("button", { name: "Hero 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Hero 템플릿" }).click();
|
||||
|
||||
// 섹션/블록이 하나 이상 존재해야 한다.
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
@@ -582,7 +582,7 @@ test("Features 템플릿 버튼을 클릭하면 3개의 Feature 항목(제목/
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Features 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "기능 템플릿" }).click();
|
||||
|
||||
// Feature 제목들이 렌더되어야 한다.
|
||||
await expect(canvas.getByText("Feature 1 제목")).toBeVisible();
|
||||
@@ -595,7 +595,7 @@ test("CTA 템플릿 버튼을 클릭하면 CTA 텍스트와 버튼이 포함된
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "CTA 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "CTA 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("지금 바로 행동을 유도하는 CTA 텍스트를 입력하세요.")).toBeVisible();
|
||||
const ctaButton = canvas.getByRole("button", { name: "CTA 버튼" });
|
||||
@@ -607,7 +607,7 @@ test("FAQ 템플릿 버튼을 클릭하면 질문/답변 텍스트가 세 쌍
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "FAQ 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "FAQ 템플릿" }).click();
|
||||
|
||||
// 기본 FAQ 질문/답변 텍스트들이 렌더되어야 한다.
|
||||
await expect(canvas.getByText("서비스 이용료는 얼마인가요?")).toBeVisible();
|
||||
@@ -621,7 +621,7 @@ test("Pricing 템플릿 버튼을 클릭하면 3개의 요금제 카드가 생
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Pricing 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "상품 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("Basic")).toBeVisible();
|
||||
await expect(canvas.getByText("₩9,900/월")).toBeVisible();
|
||||
@@ -636,7 +636,7 @@ test("Testimonials 템플릿 버튼을 클릭하면 3개의 후기 카드가 생
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Testimonials 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "후기 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("이 서비스 덕분에 랜딩 페이지 제작 시간이 크게 줄었습니다.")).toBeVisible();
|
||||
await expect(canvas.getByText("디자인을 잘 못해도 깔끔한 페이지를 만들 수 있어요.")).toBeVisible();
|
||||
@@ -648,7 +648,7 @@ test("Blog 템플릿 버튼을 클릭하면 3개의 포스트 카드(제목/요
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Blog 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "블로그 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("블로그 포스트 1")).toBeVisible();
|
||||
await expect(canvas.getByText("첫 번째 포스트 요약을 여기에 입력하세요.")).toBeVisible();
|
||||
@@ -661,7 +661,7 @@ test("Team 템플릿 버튼을 클릭하면 3명의 팀 카드가 생성되어
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Team 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Team 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("홍길동")).toBeVisible();
|
||||
await expect(canvas.getByText("Product Designer")).toBeVisible();
|
||||
@@ -675,7 +675,7 @@ test("템플릿 섹션을 삭제한 뒤 텍스트 블록을 추가하면 캔버
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// Hero 템플릿 섹션을 추가한다.
|
||||
await page.getByRole("button", { name: "Hero 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Hero 템플릿" }).click();
|
||||
|
||||
// 섹션 블록을 선택한다 (캔버스의 첫 번째 블록이 섹션이다).
|
||||
const sectionBlock = canvas.getByTestId("editor-block").first();
|
||||
@@ -685,7 +685,7 @@ test("템플릿 섹션을 삭제한 뒤 텍스트 블록을 추가하면 캔버
|
||||
await page.getByRole("button", { name: "블록 삭제" }).click();
|
||||
|
||||
// 텍스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// 새 텍스트 블록이 캔버스에 보여야 한다.
|
||||
await expect(canvas.getByText("새 텍스트")).toBeVisible();
|
||||
@@ -696,7 +696,7 @@ test("Footer 템플릿 버튼을 클릭하면 링크/카피라이트 텍스트
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "Footer 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Footer 템플릿" }).click();
|
||||
|
||||
await expect(canvas.getByText("서비스 소개")).toBeVisible();
|
||||
await expect(canvas.getByText("고객지원")).toBeVisible();
|
||||
@@ -710,7 +710,7 @@ test("Cmd/Ctrl+Z로 블록 추가를 Undo 하고 Cmd/Ctrl+Shift+Z로 Redo 할
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 텍스트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await expect(canvas.getByTestId("editor-block")).toHaveCount(1);
|
||||
|
||||
// Cmd/Ctrl + Z 로 Undo 한다.
|
||||
@@ -728,6 +728,24 @@ test("Cmd/Ctrl+Z로 블록 추가를 Undo 하고 Cmd/Ctrl+Shift+Z로 Redo 할
|
||||
await expect(canvas.getByTestId("editor-block")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("헤더의 실행 취소/다시 실행 버튼으로 블록 추가를 Undo/Redo 할 수 있어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await expect(canvas.getByTestId("editor-block")).toHaveCount(1);
|
||||
|
||||
const undoButton = page.getByRole("button", { name: "실행 취소" });
|
||||
const redoButton = page.getByRole("button", { name: "다시 실행" });
|
||||
|
||||
await undoButton.click();
|
||||
await expect(canvas.getByTestId("editor-block")).toHaveCount(0);
|
||||
|
||||
await redoButton.click();
|
||||
await expect(canvas.getByTestId("editor-block")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("ArrowUp/ArrowDown 키로 선택된 블록을 위/아래로 이동하며 순차적으로 선택할 수 있어야 한다", async ({ page }) => {
|
||||
test.skip(true, "ArrowUp/Down 기반 선택 이동 E2E는 불안정하여 임시 스킵");
|
||||
await page.goto("/editor");
|
||||
@@ -735,9 +753,9 @@ test("ArrowUp/ArrowDown 키로 선택된 블록을 위/아래로 이동하며
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 텍스트 블록을 세 개 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(3);
|
||||
@@ -771,8 +789,8 @@ test("속성 패널의 블록 삭제 버튼으로 선택된 블록을 삭제할
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 텍스트 블록 두 개를 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(2);
|
||||
@@ -793,7 +811,7 @@ test("Cmd/Ctrl+D 단축키로 선택된 블록을 복제할 수 있어야 한다
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 텍스트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
let blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(1);
|
||||
@@ -821,7 +839,7 @@ test("구분선 블록을 추가하면 캔버스에 구분선이 렌더되고
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 구분선 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const dividerBlock = blocks.nth(0);
|
||||
@@ -845,7 +863,7 @@ test("리스트 블록을 추가하고 첫 번째 아이템과 번호 매기기/
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 리스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const listBlock = blocks.nth(0);
|
||||
@@ -873,7 +891,7 @@ test("리스트 아이템을 선택하면 패널에서 아이템 위/아래/들
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 리스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const listBlock = blocks.nth(0);
|
||||
@@ -912,23 +930,23 @@ test("폼 요소 사이드바에서 폼 입력/셀렉트/라디오/체크박스
|
||||
await expect(page.getByRole("heading", { name: "폼 요소" })).toBeVisible();
|
||||
|
||||
// 폼 입력 블록 추가 버튼을 클릭하면 formInput 블록이 캔버스에 생성되어야 한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
let blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(1);
|
||||
|
||||
// 폼 셀렉트 블록 추가 버튼을 클릭하면 formSelect 블록이 추가되어야 한다.
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(2);
|
||||
|
||||
// 폼 라디오 블록 추가 버튼을 클릭하면 formRadio 블록이 추가되어야 한다.
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(3);
|
||||
|
||||
// 폼 체크박스 블록 추가 버튼을 클릭하면 formCheckbox 블록이 추가되어야 한다.
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
blocks = canvas.getByTestId("editor-block");
|
||||
await expect(blocks).toHaveCount(4);
|
||||
});
|
||||
@@ -939,12 +957,12 @@ test("폼 블록을 선택하면 우측 속성 패널에서 폼 필드/버튼
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 요소와 버튼 블록을 몇 개 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
// 폼 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const formBlock = blocks.nth((await blocks.count()) - 1);
|
||||
@@ -984,7 +1002,7 @@ test("폼 입력 블록의 라벨/전송 키/필수 여부를 우측 패널에
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 입력 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const inputBlock = blocks.nth(0);
|
||||
@@ -1013,7 +1031,7 @@ test("폼 셀렉트/라디오/체크박스 블록도 우측 패널에서 기본
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 셀렉트 블록
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
let blocks = canvas.getByTestId("editor-block");
|
||||
const selectBlock = blocks.nth((await blocks.count()) - 1);
|
||||
await selectBlock.click({ force: true });
|
||||
@@ -1031,7 +1049,7 @@ test("폼 셀렉트/라디오/체크박스 블록도 우측 패널에서 기본
|
||||
await requiredCheckbox.check();
|
||||
|
||||
// 폼 라디오 블록
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
blocks = canvas.getByTestId("editor-block");
|
||||
const radioBlock = blocks.nth((await blocks.count()) - 1);
|
||||
await radioBlock.click({ force: true });
|
||||
@@ -1047,7 +1065,7 @@ test("폼 셀렉트/라디오/체크박스 블록도 우측 패널에서 기본
|
||||
// 라디오 그룹 타이틀 텍스트 필드는 그대로 편집 가능해야 한다.
|
||||
|
||||
// 폼 체크박스 블록
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
blocks = canvas.getByTestId("editor-block");
|
||||
const checkboxBlock = blocks.nth((await blocks.count()) - 1);
|
||||
await checkboxBlock.click({ force: true });
|
||||
@@ -1069,7 +1087,7 @@ test("폼 입력 블록을 추가하면 에디터 캔버스에 라벨과 입력
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 입력 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const inputBlock = blocks.nth(0);
|
||||
@@ -1088,7 +1106,7 @@ test("폼 셀렉트 블록을 추가하면 에디터 캔버스에 라벨과 셀
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 셀렉트 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const selectBlock = blocks.nth(0);
|
||||
@@ -1107,7 +1125,7 @@ test("폼 라디오 블록을 추가하면 에디터 캔버스에 그룹 라벨
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 라디오 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const radioBlock = blocks.nth(0);
|
||||
@@ -1126,7 +1144,7 @@ test("폼 체크박스 블록을 추가하면 에디터 캔버스에 체크박
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 체크박스 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const checkboxBlock = blocks.nth(0);
|
||||
@@ -1144,7 +1162,7 @@ test("폼 입력 필드의 타입과 Placeholder 를 우측 패널에서 변경
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const inputBlock = blocks.nth(0);
|
||||
@@ -1167,7 +1185,7 @@ test("폼 셀렉트 블록의 옵션 목록을 우측 패널에서 수정하면
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const selectBlock = blocks.nth(0);
|
||||
@@ -1208,7 +1226,7 @@ test("폼 입력 블록의 스타일(텍스트/배경/모서리)을 우측 패
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 입력 블록을 하나 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
const inputBlock = blocks.nth(0);
|
||||
|
||||
+67
-67
@@ -10,15 +10,15 @@ test("/preview 페이지는 에디터 크롬 없이 컨텐츠만 보여야 한
|
||||
await expect(page.getByRole("heading", { name: "Page Preview" })).toBeVisible();
|
||||
|
||||
// 에디터 좌측 패널용 버튼들은 나타나지 않아야 한다.
|
||||
await expect(page.getByRole("button", { name: "텍스트 블록 추가" })).toHaveCount(0);
|
||||
await expect(page.getByRole("button", { name: "Hero 템플릿 추가" })).toHaveCount(0);
|
||||
await expect(page.getByRole("button", { name: "텍스트" })).toHaveCount(0);
|
||||
await expect(page.getByRole("button", { name: "Hero 템플릿" })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("에디터에서 Hero 템플릿을 추가하면 프리뷰에서 동일한 Hero 콘텐츠가 보여야 한다", async ({ page }) => {
|
||||
// 에디터에서 Hero 템플릿을 추가한다.
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "Hero 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Hero 템플릿" }).click();
|
||||
|
||||
// 헤드라인과 CTA 버튼이 에디터에서 생성되었는지 한 번 확인한다.
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
@@ -36,8 +36,8 @@ test("에디터에서 Hero 템플릿을 추가하면 프리뷰에서 동일한 H
|
||||
// 프리뷰에서는 CTA를 실제 링크(<a>)로 렌더링하므로 텍스트 기준으로만 검증한다.
|
||||
await expect(page.getByText("지금 시작하기")).toBeVisible();
|
||||
|
||||
// 프리뷰 화면에는 에디터용 "텍스트 블록 추가" 버튼이 없어야 한다.
|
||||
await expect(page.getByRole("button", { name: "텍스트 블록 추가" })).toHaveCount(0);
|
||||
// 프리뷰 화면에는 에디터용 "텍스트" 버튼이 없어야 한다.
|
||||
await expect(page.getByRole("button", { name: "텍스트" })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("프리뷰 페이지에서 에디터로 돌아가는 링크가 있어야 한다", async ({ page }) => {
|
||||
@@ -58,7 +58,7 @@ test("프리뷰 페이지에서 에디터로 돌아가는 링크가 있어야
|
||||
test("에디터에서 Features 템플릿을 추가하면 프리뷰에서 3개의 Feature 섹션이 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "Features 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "기능 템플릿" }).click();
|
||||
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
await expect(editorCanvas.getByText("Feature 1 제목")).toBeVisible();
|
||||
@@ -77,7 +77,7 @@ test("에디터에서 Features 템플릿을 추가하면 프리뷰에서 3개의
|
||||
test("에디터에서 CTA 템플릿을 추가하면 프리뷰에서 CTA 텍스트와 버튼이 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "CTA 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "CTA 템플릿" }).click();
|
||||
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
await expect(editorCanvas.getByText("지금 바로 행동을 유도하는 CTA 텍스트를 입력하세요.")).toBeVisible();
|
||||
@@ -95,10 +95,10 @@ test("모바일 뷰에서도 프리뷰 페이지가 깨지지 않고 주요 템
|
||||
// 에디터에서 여러 템플릿을 추가한다.
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "Hero 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Features 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Pricing 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Testimonials 템플릿 추가" }).click();
|
||||
await page.getByRole("button", { name: "Hero 템플릿" }).click();
|
||||
await page.getByRole("button", { name: "기능 템플릿" }).click();
|
||||
await page.getByRole("button", { name: "상품 템플릿" }).click();
|
||||
await page.getByRole("button", { name: "후기 템플릿" }).click();
|
||||
|
||||
// 모바일 뷰포트로 전환한다.
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
@@ -127,7 +127,7 @@ test("텍스트 블록의 정렬/폰트 크기/색상이 프리뷰에도 반영
|
||||
await page.goto("/editor");
|
||||
|
||||
// 텍스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "텍스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "텍스트" }).first().click();
|
||||
|
||||
// 기본 텍스트 대신 프리뷰에서 쉽게 찾을 수 있도록 내용도 함께 수정한다.
|
||||
const textTextarea = page.getByLabel("선택한 텍스트 블록 내용");
|
||||
@@ -175,8 +175,8 @@ test("구분선/리스트 블록도 프리뷰에서 렌더링되어야 한다",
|
||||
// 에디터에서 구분선과 리스트 블록을 추가한다.
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
// 에디터 캔버스에서 리스트 항목 일부가 보이는지 확인해 sanity check 를 한다.
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
@@ -195,7 +195,7 @@ test("리스트 블록 스타일 속성이 프리뷰에도 반영되어야 한
|
||||
await page.goto("/editor");
|
||||
|
||||
// 리스트 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
// 테스트를 위해 리스트 아이템을 2개 이상으로 만든다 (첫 번째 li 에 margin-bottom 이 적용되도록).
|
||||
const itemsTextarea = page.getByLabel("리스트 아이템들");
|
||||
@@ -271,8 +271,8 @@ test("폼 입력/셀렉트 블록도 FormBlock 없이 프리뷰에서 보여야
|
||||
await page.goto("/editor");
|
||||
|
||||
// 폼 입력/셀렉트 블록을 각각 하나씩 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
|
||||
@@ -293,7 +293,7 @@ test("폼 입력/셀렉트 블록도 FormBlock 없이 프리뷰에서 보여야
|
||||
test("폼 체크박스 그룹 라벨 이미지 업로드 후 에디터/프리뷰 모두 /api/image/:id 기반 이미지가 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -323,7 +323,7 @@ test("폼 체크박스 그룹 라벨 이미지 업로드 후 에디터/프리뷰
|
||||
test("폼 라디오 옵션 라벨 이미지 업로드 후 에디터/프리뷰 모두 /api/image/:id 기반 이미지가 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -356,7 +356,7 @@ test("폼 라디오 옵션 라벨 이미지 업로드 후 에디터/프리뷰
|
||||
test("폼 체크박스 옵션 라벨 이미지 업로드 후 에디터/프리뷰 모두 /api/image/:id 기반 이미지가 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -390,7 +390,7 @@ test("폼 체크박스 옵션 라벨 이미지 업로드 후 에디터/프리뷰
|
||||
test("폼 라디오 그룹 라벨 이미지 업로드 후 에디터/프리뷰 모두 /api/image/:id 기반 이미지가 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -423,7 +423,7 @@ test("폼 입력 필드 스타일 속성이 프리뷰에도 반영되어야 한
|
||||
await page.goto("/editor");
|
||||
|
||||
// 폼 입력 블록을 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
// 우측 속성 패널에서 폼 입력 스타일을 설정한다.
|
||||
// 라벨/필드 텍스트 등 기본 값은 그대로 두고, 스타일 속성만 눈에 띄게 변경한다.
|
||||
@@ -483,7 +483,7 @@ test("폼 입력 필드 스타일 속성이 프리뷰에도 반영되어야 한
|
||||
test("폼 입력 고정 너비가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -512,7 +512,7 @@ test("폼 입력 고정 너비가 프리뷰에서도 em 스케일로 반영되
|
||||
test("버튼 타이포 px 입력이 프리뷰에서는 em 스케일로 렌더링되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -554,7 +554,7 @@ test("버튼 타이포 px 입력이 프리뷰에서는 em 스케일로 렌더링
|
||||
test("버튼 고정 너비와 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -603,7 +603,7 @@ test("버튼 고정 너비와 패딩 px 입력이 프리뷰에서도 em 스케
|
||||
test("이미지 고정 너비가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "이미지 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "이미지" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -634,7 +634,7 @@ test("이미지 고정 너비가 프리뷰에서도 em 스케일로 반영되어
|
||||
test("이미지 블록에서 로컬 파일 업로드 후 에디터/프리뷰 모두 /api/image/:id 기반 이미지가 보여야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "이미지 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "이미지" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
@@ -671,7 +671,7 @@ test("이미지 블록에서 로컬 파일 업로드 후 에디터/프리뷰 모
|
||||
test("구분선 고정 길이와 여백 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -718,7 +718,7 @@ test("구분선 고정 길이와 여백 px 입력이 프리뷰에서도 em 스
|
||||
test("섹션 padding/maxWidth/gap px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "섹션 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "섹션" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -780,7 +780,7 @@ test("섹션 padding/maxWidth/gap px 입력이 프리뷰에서도 em 스케일
|
||||
test("구분선 고정 길이 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -809,7 +809,7 @@ test("구분선 고정 길이 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("구분선 상하 여백 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -837,7 +837,7 @@ test("구분선 상하 여백 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("리스트 아이템 간 여백 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -866,7 +866,7 @@ test("리스트 아이템 간 여백 px 입력이 프리뷰에서도 em 스케
|
||||
test("리스트 글자 크기 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "리스트 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "리스트" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -894,7 +894,7 @@ test("리스트 글자 크기 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 입력 줄간격 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -922,7 +922,7 @@ test("폼 입력 줄간격 px 입력이 프리뷰에서도 em 스케일로 반
|
||||
test("폼 입력 자간 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -950,7 +950,7 @@ test("폼 입력 자간 px 입력이 프리뷰에서도 em 스케일로 반영
|
||||
test("폼 입력 가로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const paddingSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -978,7 +978,7 @@ test("폼 입력 가로 패딩 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 입력 세로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const paddingSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1006,7 +1006,7 @@ test("폼 입력 세로 패딩 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 입력 인라인 라벨 간격 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1035,7 +1035,7 @@ test("폼 입력 인라인 라벨 간격 px 입력이 프리뷰에서도 em 스
|
||||
test("폼 체크박스 옵션 간격 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1065,7 +1065,7 @@ test("폼 체크박스 옵션 간격 px 입력이 프리뷰에서도 em 스케
|
||||
test("FormBlock 은 프리뷰에서 별도 폼 컨트롤러 DOM 을 렌더하지 않아야 한다 (고정 너비 설정 시)", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
// 폼 블록이 실제로 선택되어 우측 속성 패널에 FormControllerPanel 이 노출되도록 캔버스에서 한 번 더 명시적으로 선택한다.
|
||||
const editorCanvas = page.getByTestId("editor-canvas");
|
||||
@@ -1087,7 +1087,7 @@ test("FormBlock 은 프리뷰에서 별도 폼 컨트롤러 DOM 을 렌더하지
|
||||
test("FormBlock 은 프리뷰에서 별도 폼 컨트롤러 DOM 을 렌더하지 않아야 한다 (상하 여백 설정 시)", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
// 앞선 테스트들과의 상호 영향으로 selectedBlockId 가 어긋나는 경우를 방지하기 위해,
|
||||
// 방금 추가한 폼 블록을 캔버스에서 다시 선택해 속성 패널을 확실히 FormBlock 기준으로 맞춘다.
|
||||
@@ -1109,7 +1109,7 @@ test("FormBlock 은 프리뷰에서 별도 폼 컨트롤러 DOM 을 렌더하지
|
||||
test("폼 라디오 줄간격 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1137,7 +1137,7 @@ test("폼 라디오 줄간격 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 라디오 자간 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1165,7 +1165,7 @@ test("폼 라디오 자간 px 입력이 프리뷰에서도 em 스케일로 반
|
||||
test("폼 체크박스 가로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1193,7 +1193,7 @@ test("폼 체크박스 가로 패딩 px 입력이 프리뷰에서도 em 스케
|
||||
test("폼 체크박스 세로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1221,7 +1221,7 @@ test("폼 체크박스 세로 패딩 px 입력이 프리뷰에서도 em 스케
|
||||
test("폼 셀렉트 가로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1249,7 +1249,7 @@ test("폼 셀렉트 가로 패딩 px 입력이 프리뷰에서도 em 스케일
|
||||
test("폼 셀렉트 세로 패딩 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1277,7 +1277,7 @@ test("폼 셀렉트 세로 패딩 px 입력이 프리뷰에서도 em 스케일
|
||||
test("폼 셀렉트 글자 크기 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1305,7 +1305,7 @@ test("폼 셀렉트 글자 크기 px 입력이 프리뷰에서도 em 스케일
|
||||
test("폼 셀렉트 줄간격 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1333,7 +1333,7 @@ test("폼 셀렉트 줄간격 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 셀렉트 자간 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1361,7 +1361,7 @@ test("폼 셀렉트 자간 px 입력이 프리뷰에서도 em 스케일로 반
|
||||
test("폼 체크박스 글자 크기 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1389,7 +1389,7 @@ test("폼 체크박스 글자 크기 px 입력이 프리뷰에서도 em 스케
|
||||
test("폼 라디오 글자 크기 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1417,7 +1417,7 @@ test("폼 라디오 글자 크기 px 입력이 프리뷰에서도 em 스케일
|
||||
test("폼 입력 글자 크기 px 입력이 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1445,7 +1445,7 @@ test("폼 입력 글자 크기 px 입력이 프리뷰에서도 em 스케일로
|
||||
test("폼 셀렉트 고정 너비가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 셀렉트 추가" }).click();
|
||||
await page.getByRole("button", { name: "셀렉트(Select)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1474,7 +1474,7 @@ test("폼 셀렉트 고정 너비가 프리뷰에서도 em 스케일로 반영
|
||||
test("폼 라디오 그룹 고정 너비가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 라디오 추가" }).click();
|
||||
await page.getByRole("button", { name: "단일 선택(Radio)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1503,7 +1503,7 @@ test("폼 라디오 그룹 고정 너비가 프리뷰에서도 em 스케일로
|
||||
test("폼 체크박스 그룹 고정 너비가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "폼 체크박스 추가" }).click();
|
||||
await page.getByRole("button", { name: "다중 선택(Checkbox)" }).click();
|
||||
|
||||
const propertiesSidebar = page.getByTestId("properties-sidebar");
|
||||
|
||||
@@ -1536,9 +1536,9 @@ test("폼 컨트롤러에 매핑한 폼 요소와 버튼이 프리뷰에서 함
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
|
||||
// 폼 입력 요소와 버튼, 폼 블록을 순서대로 추가한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
// 방금 추가된 폼 블록을 선택한다.
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
@@ -1585,9 +1585,9 @@ test("여러 폼 블록과 여러 버튼이 있을 때 각 폼이 독립적으
|
||||
const blocks = canvas.getByTestId("editor-block");
|
||||
|
||||
// Form A: 입력 필드 + 버튼 + 폼 블록을 추가한 뒤, 즉시 컨트롤러를 매핑한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
let count = await blocks.count();
|
||||
const formBlockA = blocks.nth(count - 1);
|
||||
@@ -1603,9 +1603,9 @@ test("여러 폼 블록과 여러 버튼이 있을 때 각 폼이 독립적으
|
||||
await submitSelect.selectOption({ index: 1 });
|
||||
|
||||
// Form B: 입력 필드 + 버튼 + 폼 블록을 다시 추가한 뒤, 즉시 컨트롤러를 매핑한다.
|
||||
await page.getByRole("button", { name: "폼 입력 추가" }).click();
|
||||
await page.getByRole("button", { name: "버튼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "폼 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "입력(Input)" }).click();
|
||||
await page.getByRole("button", { name: "버튼" }).first().click();
|
||||
await page.getByRole("button", { name: "폼 컨트롤러" }).click();
|
||||
|
||||
count = await blocks.count();
|
||||
const formBlockB = blocks.nth(count - 1);
|
||||
@@ -1647,7 +1647,7 @@ test("섹션 패딩/컬럼 간격 수치가 프리뷰에서도 em 스케일에
|
||||
await page.goto("/editor");
|
||||
|
||||
// 섹션 블록을 직접 추가한다.
|
||||
await page.getByRole("button", { name: "섹션 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "섹션" }).click();
|
||||
|
||||
// 캔버스에서 첫 번째 섹션 블록을 선택한다.
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
@@ -1705,7 +1705,7 @@ test("섹션 패딩/컬럼 간격 수치가 프리뷰에서도 em 스케일에
|
||||
test("구분선 여백/길이 수치가 프리뷰에서도 em 스케일로 반영되어야 한다", async ({ page }) => {
|
||||
await page.goto("/editor");
|
||||
|
||||
await page.getByRole("button", { name: "구분선 블록 추가" }).click();
|
||||
await page.getByRole("button", { name: "구분선" }).click();
|
||||
|
||||
const canvas = page.getByTestId("editor-canvas");
|
||||
const dividerBlock = canvas.getByTestId("editor-block").first();
|
||||
|
||||
@@ -52,28 +52,25 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
|
||||
Object.values(templateActions).forEach((fn) => fn.mockReset());
|
||||
});
|
||||
|
||||
it("Hero 템플릿 추가 버튼 클릭 시 addHeroTemplateSection 이 호출되어야 한다", () => {
|
||||
it("Hero 템플릿 버튼 클릭 시 addHeroTemplateSection 이 호출되어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
const button = screen.getByRole("button", { name: "Hero 템플릿 추가" });
|
||||
const button = screen.getByRole("button", { name: "Hero 템플릿" });
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(templateActions.addHeroTemplateSection).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("Features 템플릿 추가 버튼 클릭 시 addFeaturesTemplateSection 이 호출되어야 한다", () => {
|
||||
it("Features 템플릿 버튼 클릭 시 addFeaturesTemplateSection 이 호출되어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
const button = screen.getByRole("button", { name: "Features 템플릿 추가" });
|
||||
const button = screen.getByRole("button", { name: "기능 템플릿" });
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(templateActions.addFeaturesTemplateSection).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("CTA 템플릿 추가 버튼 클릭 시 addCtaTemplateSection 이 호출되어야 한다", () => {
|
||||
it("CTA 템플릿 버튼 클릭 시 addCtaTemplateSection 이 호출되어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
const button = screen.getByRole("button", { name: "CTA 템플릿 추가" });
|
||||
const button = screen.getByRole("button", { name: "CTA 템플릿" });
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(templateActions.addCtaTemplateSection).toHaveBeenCalledTimes(1);
|
||||
@@ -81,13 +78,12 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
|
||||
|
||||
it("FAQ/Pricing/Testimonials/Blog/Team/Footer 템플릿 버튼도 각각의 액션을 호출해야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "FAQ 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Pricing 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Testimonials 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Blog 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Team 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Footer 템플릿 추가" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "FAQ 템플릿" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "상품 템플릿" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "후기 템플릿" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "블로그 템플릿" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Team 템플릿" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Footer 템플릿" }));
|
||||
|
||||
expect(templateActions.addFaqTemplateSection).toHaveBeenCalledTimes(1);
|
||||
expect(templateActions.addPricingTemplateSection).toHaveBeenCalledTimes(1);
|
||||
@@ -111,10 +107,9 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
|
||||
expect(screen.getByText("페이지 푸터 섹션"));
|
||||
});
|
||||
|
||||
it("비디오 블록 추가 버튼 클릭 시 addVideoBlock 이 호출되어야 한다", () => {
|
||||
it("비디오 버튼 클릭 시 addVideoBlock 이 호출되어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
const button = screen.getByRole("button", { name: "비디오 블록 추가" });
|
||||
const button = screen.getByRole("button", { name: "비디오" });
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(otherActions.addVideoBlock).toHaveBeenCalledTimes(1);
|
||||
@@ -165,4 +160,55 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
|
||||
expect(pricingThumb.children.length).toBe(3);
|
||||
expect(teamThumb.children.length).toBe(3);
|
||||
});
|
||||
|
||||
it("블록 섹션 타이틀을 클릭하면 블록 버튼들을 접고 펼 수 있어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
// 초기에는 텍스트 버튼이 보여야 한다.
|
||||
expect(screen.getByRole("button", { name: "텍스트" })).toBeDefined();
|
||||
|
||||
const blockToggle = screen.getByRole("button", { name: "블록" });
|
||||
fireEvent.click(blockToggle);
|
||||
|
||||
// 접힌 상태에서는 텍스트 버튼이 보이지 않아야 한다.
|
||||
expect(screen.queryByRole("button", { name: "텍스트" })).toBeNull();
|
||||
|
||||
// 다시 클릭하면 펼쳐져야 한다.
|
||||
fireEvent.click(blockToggle);
|
||||
expect(screen.getByRole("button", { name: "텍스트" })).toBeDefined();
|
||||
});
|
||||
|
||||
it("폼 요소 섹션 타이틀을 클릭하면 폼 관련 버튼들을 접고 펼 수 있어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
// 초기에는 폼 입력 버튼이 보여야 한다.
|
||||
expect(screen.getByRole("button", { name: "입력(Input)" })).toBeDefined();
|
||||
|
||||
const formToggle = screen.getByRole("button", { name: "폼 요소" });
|
||||
fireEvent.click(formToggle);
|
||||
|
||||
// 접힌 상태에서는 폼 입력 버튼이 보이지 않아야 한다.
|
||||
expect(screen.queryByRole("button", { name: "입력(Input)" })).toBeNull();
|
||||
|
||||
// 다시 클릭하면 펼쳐져야 한다.
|
||||
fireEvent.click(formToggle);
|
||||
expect(screen.getByRole("button", { name: "입력(Input)" })).toBeDefined();
|
||||
});
|
||||
|
||||
it("템플릿 섹션 타이틀을 클릭하면 템플릿 카드들을 접고 펼 수 있어야 한다", () => {
|
||||
render(<BlocksSidebar />);
|
||||
|
||||
// 초기에는 Hero 템플릿 버튼이 보여야 한다.
|
||||
expect(screen.getByRole("button", { name: "Hero 템플릿" })).toBeDefined();
|
||||
|
||||
const templateToggle = screen.getByRole("button", { name: "템플릿" });
|
||||
fireEvent.click(templateToggle);
|
||||
|
||||
// 접힌 상태에서는 Hero 템플릿 버튼이 보이지 않아야 한다.
|
||||
expect(screen.queryByRole("button", { name: "Hero 템플릿" })).toBeNull();
|
||||
|
||||
// 다시 클릭하면 펼쳐져야 한다.
|
||||
fireEvent.click(templateToggle);
|
||||
expect(screen.getByRole("button", { name: "Hero 템플릿" })).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,8 @@ import EditorPage from "@/app/editor/page";
|
||||
let mockState: any;
|
||||
|
||||
beforeEach(() => {
|
||||
window.localStorage.clear();
|
||||
|
||||
const baseProjectConfig: ProjectConfig = {
|
||||
title: "멀티 선택 테스트",
|
||||
slug: "multi-select",
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { describe, it, expect, vi, afterEach } from "vitest";
|
||||
import { render, screen, fireEvent, cleanup } from "@testing-library/react";
|
||||
import type { Block } from "@/features/editor/state/editorStore";
|
||||
import { PropertiesSidebar } from "@/app/editor/panels/PropertiesSidebar";
|
||||
|
||||
describe("PropertiesSidebar HELP 튜토리얼 모달", () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
const createTextBlock = (): Block => ({
|
||||
id: "text-1",
|
||||
type: "text",
|
||||
props: {
|
||||
text: "도움말 테스트",
|
||||
align: "left",
|
||||
size: "base",
|
||||
} as any,
|
||||
sectionId: null,
|
||||
columnId: null,
|
||||
});
|
||||
|
||||
const defaultProps = (blocks: Block[], selectedBlockId: string | null) => ({
|
||||
blocks,
|
||||
selectedBlockId,
|
||||
selectedListItemId: null,
|
||||
updateBlock: vi.fn(),
|
||||
removeBlock: vi.fn(),
|
||||
duplicateBlock: vi.fn(),
|
||||
editingBlockId: null,
|
||||
setEditingText: vi.fn(),
|
||||
onMoveSelectedItemUp: vi.fn(),
|
||||
onMoveSelectedItemDown: vi.fn(),
|
||||
onIndentSelectedItem: vi.fn(),
|
||||
onOutdentSelectedItem: vi.fn(),
|
||||
});
|
||||
|
||||
it("텍스트 블록이 선택된 상태에서 HELP 버튼을 노출해야 한다", () => {
|
||||
const textBlock = createTextBlock();
|
||||
|
||||
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
|
||||
|
||||
const helpButton = screen.getByRole("button", { name: "HELP" });
|
||||
expect(helpButton).toBeDefined();
|
||||
});
|
||||
|
||||
it("HELP 버튼 클릭 시 현재 블록 타입에 맞는 튜토리얼 모달이 열려야 한다", () => {
|
||||
const textBlock = createTextBlock();
|
||||
|
||||
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
|
||||
|
||||
const helpButton = screen.getByRole("button", { name: "HELP" });
|
||||
fireEvent.click(helpButton);
|
||||
|
||||
expect(screen.getByText("텍스트 블록 튜토리얼")).toBeDefined();
|
||||
expect(screen.getByText(/제목과 본문 텍스트를 입력할 때 사용하는 기본 블록입니다/)).toBeDefined();
|
||||
});
|
||||
|
||||
it("모달의 닫기 버튼을 클릭하면 튜토리얼 모달이 닫혀야 한다", () => {
|
||||
const textBlock = createTextBlock();
|
||||
|
||||
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
|
||||
|
||||
const helpButton = screen.getByRole("button", { name: "HELP" });
|
||||
fireEvent.click(helpButton);
|
||||
|
||||
const closeButton = screen.getByRole("button", { name: "닫기" });
|
||||
fireEvent.click(closeButton);
|
||||
|
||||
expect(screen.queryByText("텍스트 블록 튜토리얼")).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -221,6 +221,11 @@ describe("formHelpers - editor tokens", () => {
|
||||
widthMode: "fixed",
|
||||
widthPx: 260,
|
||||
borderRadius: "lg",
|
||||
paddingX: 12,
|
||||
paddingY: 6,
|
||||
fontSizeCustom: "14px",
|
||||
lineHeightCustom: "20px",
|
||||
letterSpacingCustom: "1px",
|
||||
} as any);
|
||||
|
||||
expect(tokens.fieldStyle.color).toBe("#ff0000");
|
||||
@@ -228,6 +233,11 @@ describe("formHelpers - editor tokens", () => {
|
||||
expect(tokens.fieldStyle.borderColor).toBe("#654321");
|
||||
expect(tokens.fieldStyle.width).toBe("260px");
|
||||
expect(tokens.fieldStyle.borderRadius).toBe(9999);
|
||||
expect(tokens.fieldStyle.paddingInline).toBe("12px");
|
||||
expect(tokens.fieldStyle.paddingBlock).toBe("6px");
|
||||
expect(tokens.fieldStyle.fontSize).toBe("14px");
|
||||
expect(tokens.fieldStyle.lineHeight).toBe("20px");
|
||||
expect(tokens.fieldStyle.letterSpacing).toBe("1px");
|
||||
});
|
||||
|
||||
it("computeFormOptionGroupEditorTokens: 에디터 라디오/체크박스 그룹 필드 스타일을 계산해야 한다", () => {
|
||||
@@ -239,6 +249,11 @@ describe("formHelpers - editor tokens", () => {
|
||||
widthMode: "fixed",
|
||||
widthPx: 280,
|
||||
borderRadius: "lg",
|
||||
paddingX: 8,
|
||||
paddingY: 4,
|
||||
fontSizeCustom: "15px",
|
||||
lineHeightCustom: "22px",
|
||||
letterSpacingCustom: "0.5px",
|
||||
} as any);
|
||||
|
||||
expect(tokens.fieldStyle.color).toBe("#ff0000");
|
||||
@@ -246,6 +261,11 @@ describe("formHelpers - editor tokens", () => {
|
||||
expect(tokens.fieldStyle.borderColor).toBe("#654321");
|
||||
expect(tokens.fieldStyle.width).toBe("280px");
|
||||
expect(tokens.fieldStyle.borderRadius).toBe(9999);
|
||||
expect(tokens.fieldStyle.paddingInline).toBe("8px");
|
||||
expect(tokens.fieldStyle.paddingBlock).toBe("4px");
|
||||
expect(tokens.fieldStyle.fontSize).toBe("15px");
|
||||
expect(tokens.fieldStyle.lineHeight).toBe("22px");
|
||||
expect(tokens.fieldStyle.letterSpacing).toBe("0.5px");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user