/** * 브라우저 검증 스크립트 * 1. 로그인 페이지 접속 * 2. 로그인 * 3. /screens/29 접속 * 4. 화면 렌더링 검증 (버튼, 테이블, 검색 필터) */ import { chromium } from "playwright"; import * as path from "path"; const BASE_URL = "http://localhost:9771"; const SCREENSHOT_DIR = path.join(__dirname, "../verification-screenshots"); async function main() { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1280, height: 800 } }); const page = await context.newPage(); const results: { step: string; success: boolean; message?: string }[] = []; try { // Step 1: 로그인 페이지 접속 console.log("Step 1: 로그인 페이지 접속..."); await page.goto(`${BASE_URL}/login`, { waitUntil: "networkidle", timeout: 10000 }); await page.screenshot({ path: path.join(SCREENSHOT_DIR, "01-login-page.png"), fullPage: true }); results.push({ step: "1. 로그인 페이지 접속", success: true }); // Step 2: 로그인 console.log("Step 2: 로그인..."); await page.fill('#userId', "wace"); await page.fill('#password', "qlalfqjsgh11"); await page.screenshot({ path: path.join(SCREENSHOT_DIR, "02-login-filled.png"), fullPage: true }); const loginButton = page.locator('button[type="submit"]').first(); await loginButton.click(); await page.waitForURL((url) => !url.pathname.includes("/login") || url.pathname === "/", { timeout: 10000 }).catch(() => {}); await page.waitForTimeout(2000); const currentUrl = page.url(); if (currentUrl.includes("/login") && !currentUrl.includes("/screens")) { await page.screenshot({ path: path.join(SCREENSHOT_DIR, "02-login-result.png"), fullPage: true }); const errorText = await page.locator('[role="alert"], .error, .text-destructive, [class*="error"]').first().textContent().catch(() => ""); results.push({ step: "2. 로그인", success: false, message: errorText || "로그인 실패 - 여전히 로그인 페이지에 있음" }); } else { results.push({ step: "2. 로그인", success: true }); } // Step 3: /screens/29 접속 console.log("Step 3: /screens/29 접속..."); await page.goto(`${BASE_URL}/screens/29`, { waitUntil: "networkidle", timeout: 15000 }); await page.waitForTimeout(3000); await page.screenshot({ path: path.join(SCREENSHOT_DIR, "03-screen-29.png"), fullPage: true }); results.push({ step: "3. /screens/29 접속", success: true }); // Step 4: 화면 렌더링 검증 console.log("Step 4: 화면 렌더링 검증..."); const checks: { name: string; selector: string; found: boolean }[] = []; // 버튼 확인 const buttons = page.locator("button, [role='button'], input[type='submit'], input[type='button']"); const buttonCount = await buttons.count(); checks.push({ name: "버튼", selector: "button, [role='button']", found: buttonCount > 0 }); // 테이블 확인 const tables = page.locator("table, [role='grid'], [role='table'], .ag-root"); const tableCount = await tables.count(); checks.push({ name: "테이블", selector: "table, [role='grid']", found: tableCount > 0 }); // 검색 필터 확인 (input, select 등) const searchFilters = page.locator('input[type="text"], input[type="search"], input[placeholder*="검색"], input[placeholder*="Search"], select, [class*="filter"], [class*="search"]'); const filterCount = await searchFilters.count(); checks.push({ name: "검색/필터", selector: "input, select, filter", found: filterCount > 0 }); await page.screenshot({ path: path.join(SCREENSHOT_DIR, "04-screen-29-verified.png"), fullPage: true }); const allPassed = checks.every((c) => c.found); results.push({ step: "4. 화면 렌더링 검증", success: allPassed, message: checks.map((c) => `${c.name}: ${c.found ? "O" : "X"}`).join(", "), }); // 결과 출력 console.log("\n=== 검증 결과 ==="); results.forEach((r) => { console.log(`${r.step}: ${r.success ? "성공" : "실패"}${r.message ? ` - ${r.message}` : ""}`); }); checks.forEach((c) => { console.log(` - ${c.name}: ${c.found ? "보임" : "없음"}`); }); const finalSuccess = results.every((r) => r.success); console.log(`\n최종 판정: ${finalSuccess ? "성공" : "실패"}`); // 결과를 JSON 파일로 저장 const fs = await import("fs"); fs.writeFileSync( path.join(SCREENSHOT_DIR, "verification-result.json"), JSON.stringify({ results, checks, finalSuccess: finalSuccess ? "성공" : "실패" }, null, 2) ); } catch (error: any) { console.error("오류 발생:", error.message); await page.screenshot({ path: path.join(SCREENSHOT_DIR, "99-error.png"), fullPage: true }).catch(() => {}); results.push({ step: "오류", success: false, message: error.message }); } finally { await browser.close(); } } main();