/** * 화면 156, 4155, 1053 검증: 버튼 레이아웃 및 가시성 */ import { chromium } from "playwright"; import * as path from "path"; import * as fs from "fs"; const BASE_URL = "http://localhost:9771"; const SCREENSHOT_DIR = path.join(__dirname, "../verification-screenshots"); async function loginIfNeeded(page: any) { if (page.url().includes("/login")) { await page.fill("#userId", "wace"); await page.fill("#password", "qlalfqjsgh11"); await page.locator('button[type="submit"]').first().click(); await page.waitForURL((u: URL) => !u.includes("/login"), { timeout: 15000 }).catch(() => {}); await page.waitForTimeout(2000); } } async function verifyScreen( page: any, screenId: number, report: Record ) { await page.goto(`${BASE_URL}/screens/${screenId}`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(2000); if (page.url().includes("/login")) { await loginIfNeeded(page); await page.goto(`${BASE_URL}/screens/${screenId}`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(2000); } await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {}); await page.waitForTimeout(1500); const info = await page.evaluate(() => { const buttons = Array.from(document.querySelectorAll("button")); const buttonDetails = buttons.slice(0, 20).map((btn) => { const text = (btn as HTMLElement).innerText?.trim() || ""; const rect = (btn as HTMLElement).getBoundingClientRect(); const style = window.getComputedStyle(btn); return { text: text.substring(0, 50), hasText: text.length > 0, width: rect.width, height: rect.height, visible: rect.width > 0 && rect.height > 0, }; }); const buttonsWithText = buttonDetails.filter((b) => b.hasText); const table = document.querySelector("table"); const pagination = document.body.innerText.includes("표시") || document.body.innerText.includes("1/"); const splitPanel = document.querySelector("[class*='split'], [class*='Split'], [class*='border-r']"); return { pageLoadsWithoutErrors: !document.body.innerText.includes("화면을 찾을 수 없습니다"), totalButtons: buttons.length, buttonsWithTextCount: buttonsWithText.length, buttonsVisibleWithText: buttonsWithText.length > 0, buttonDetails: buttonDetails.slice(0, 10), tableVisible: !!table, paginationVisible: !!pagination, splitPanelVisible: !!splitPanel, bodyScrollWidth: document.body.scrollWidth, viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, hasHorizontalOverflow: document.body.scrollWidth > window.innerWidth, layoutFitsViewport: document.body.scrollWidth <= window.innerWidth, }; }); report.pageLoadsWithoutErrors = info.pageLoadsWithoutErrors; report.buttonsVisibleWithText = info.buttonsVisibleWithText; report.buttonsWithTextCount = info.buttonsWithTextCount; report.buttonDetails = info.buttonDetails; report.tableVisible = info.tableVisible; report.paginationVisible = info.paginationVisible; report.splitPanelVisible = info.splitPanelVisible; report.layoutFitsViewport = info.layoutFitsViewport; report.hasHorizontalOverflow = info.hasHorizontalOverflow; report.details = { bodyScrollWidth: info.bodyScrollWidth, viewportWidth: info.viewportWidth, viewportHeight: info.viewportHeight, }; await page.screenshot({ path: path.join(SCREENSHOT_DIR, `screen-${screenId}-buttons.png`), fullPage: true, }); console.log(`screen-${screenId}-buttons.png saved`); } async function main() { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1280, height: 900 } }); const page = await context.newPage(); const report: Record = { screen156: {}, screen4155: {}, screen1053: {} }; try { await page.goto(`${BASE_URL}/login`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(1000); await loginIfNeeded(page); await page.waitForTimeout(2000); await verifyScreen(page, 156, report.screen156); await verifyScreen(page, 4155, report.screen4155); await verifyScreen(page, 1053, report.screen1053); console.log("\n=== Report ==="); console.log(JSON.stringify(report, null, 2)); fs.writeFileSync( path.join(SCREENSHOT_DIR, "button-layout-screens-report.json"), JSON.stringify(report, null, 2) ); } catch (error: any) { console.error("Error:", error.message); report.error = error.message; await page.screenshot({ path: path.join(SCREENSHOT_DIR, "button-layout-error.png"), fullPage: true, }).catch(() => {}); } finally { await browser.close(); } } main();