/** * 카드 목록 컴포넌트 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();