Files
vexplor/frontend/scripts/test-card-list-e2e.ts
shin 8cfd4024e1 feat(pop-card-list): PopCardList 컴포넌트 구현
- PopCardList 컴포넌트 추가 (NumberInputModal, PackageUnitModal 포함)
- ComponentEditorPanel, PopRenderer 충돌 해결 (modals + onRequestResize 통합)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 15:54:57 +09:00

95 lines
3.7 KiB
TypeScript

/**
* 카드 목록 컴포넌트 E2E 테스트
* 실행: npx tsx scripts/test-card-list-e2e.ts
*/
import { chromium } from "playwright";
import path from "path";
import fs from "fs";
const BASE_URL = "http://localhost:9771";
const SCREEN_URL = "/pop/screens/4114";
const SCREENSHOT_DIR = path.join(process.cwd(), "test-screenshots");
async function ensureDir(dir: string) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
async function main() {
console.log("카드 목록 컴포넌트 E2E 테스트 시작...");
await ensureDir(SCREENSHOT_DIR);
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({ viewport: { width: 1280, height: 800 } });
const page = await context.newPage();
const results: string[] = [];
try {
// 1. 페이지 로드
console.log("1. 페이지 로드 중...");
await page.goto(`${BASE_URL}${SCREEN_URL}`, { waitUntil: "networkidle", timeout: 15000 });
await page.waitForTimeout(2000);
// 카드 목록 컴포넌트 확인
const cardContainer = await page.locator('[class*="grid"]').first();
const cardCount = await page.locator(".rounded-lg.border.bg-card").count();
const hasCards = cardCount > 0;
results.push(`1. 카드 목록 표시: ${hasCards ? "OK" : "FAIL"} (카드 ${cardCount}개)`);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "01-loaded.png") });
// 2. "더보기" 버튼 클릭
const moreBtn = page.getByRole("button", { name: /더보기/ });
const moreBtnCount = await moreBtn.count();
if (moreBtnCount > 0) {
console.log("2. 더보기 버튼 클릭...");
await moreBtn.first().click();
await page.waitForTimeout(1500);
const cardCountAfter = await page.locator(".rounded-lg.border.bg-card").count();
const expanded = cardCountAfter > cardCount;
results.push(`2. 더보기 클릭 후 확장: ${expanded ? "OK" : "카드 수 변화 없음"} (${cardCount} -> ${cardCountAfter})`);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "02-expanded.png") });
// 3. 페이지네이션 확인
const prevBtn = page.getByRole("button", { name: /이전/ });
const nextBtn = page.getByRole("button", { name: /다음/ });
const hasPagination = (await prevBtn.count() > 0) || (await nextBtn.count() > 0);
results.push(`3. 페이지네이션 버튼: ${hasPagination ? "OK" : "없음 (데이터 적음 시 정상)"}`);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "03-pagination.png") });
// 4. 접기 버튼 클릭
const collapseBtn = page.getByRole("button", { name: /접기/ });
if (await collapseBtn.count() > 0) {
console.log("4. 접기 버튼 클릭...");
await collapseBtn.first().click();
await page.waitForTimeout(1000);
const cardCountCollapsed = await page.locator(".rounded-lg.border.bg-card").count();
results.push(`4. 접기 후: OK (카드 ${cardCountCollapsed}개로 복원)`);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "04-collapsed.png") });
} else {
results.push("4. 접기 버튼: 없음 (확장 안됐을 수 있음)");
}
} else {
results.push("2. 더보기 버튼: 없음 (카드가 적거나 모두 표시됨)");
results.push("3. 페이지네이션: N/A");
results.push("4. 접기: N/A");
}
// 결과 출력
console.log("\n=== 테스트 결과 ===");
results.forEach((r) => console.log(r));
console.log(`\n스크린샷 저장: ${SCREENSHOT_DIR}`);
} catch (err) {
console.error("테스트 실패:", err);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "error.png") });
process.exit(1);
} finally {
await browser.close();
}
}
main();