/** * 화면 1053 검증: split-panel 레이아웃 * - 좌/우 패널, 버튼 오버레이, 높이 채움, overflow 확인 */ 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 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 = {}; try { await page.goto(`${BASE_URL}/screens/1053`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(2000); 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) => !u.includes("/login"), { timeout: 15000 }).catch(() => {}); await page.waitForTimeout(2000); await page.goto(`${BASE_URL}/screens/1053`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(2000); } await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {}); await page.waitForTimeout(1500); report.pageLoadsWithoutErrors = (await page.locator('text="화면을 찾을 수 없습니다"').count()) === 0; const splitPanel = await page.evaluate(() => { const leftPanel = document.querySelector("[class*='split'][class*='left'], [data-panel='left'], [class*='left-panel']"); const rightPanel = document.querySelector("[class*='split'][class*='right'], [data-panel='right'], [class*='right-panel']"); const resizable = document.querySelector("[class*='resize'], [class*='ResizablePanel]"); const panels = document.querySelectorAll("[class*='panel'], [data-panel]"); return { hasLeftPanel: !!leftPanel || document.body.innerText.includes("left") || panels.length >= 2, hasRightPanel: !!rightPanel || panels.length >= 2, panelCount: panels.length, resizableCount: document.querySelectorAll("[class*='ResizablePanel'], [class*='resize']").length, }; }); report.splitPanelVisible = splitPanel.panelCount >= 2 || splitPanel.resizableCount > 0; const twoPanels = await page.locator("[class*='panel'], [data-panel], [class*='split']").count(); report.twoPanelsFound = twoPanels >= 2; const buttons = await page.locator("button").count(); const buttonsTopRight = await page.evaluate(() => { const btns = Array.from(document.querySelectorAll("button")); const viewportW = window.innerWidth; return btns.filter((b) => { const r = b.getBoundingClientRect(); return r.right > viewportW * 0.5 && r.top < 200; }).length; }); report.buttonsVisible = buttons > 0; report.buttonsInTopRightArea = buttonsTopRight; const layoutFillsHeight = await page.evaluate(() => { const main = document.querySelector("main") || document.body; const h = (main as HTMLElement).offsetHeight; return h >= window.innerHeight * 0.8; }); report.layoutFillsHeight = layoutFillsHeight; const overflow = await page.evaluate(() => ({ bodyScrollWidth: document.body.scrollWidth, bodyScrollHeight: document.body.scrollHeight, viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, hasHorizontalOverflow: document.body.scrollWidth > window.innerWidth, hasVerticalOverflow: document.body.scrollHeight > window.innerHeight, })); report.noContentOverflowsViewport = !overflow.hasHorizontalOverflow; report.overflowDetails = overflow; await page.screenshot({ path: path.join(SCREENSHOT_DIR, "screen-1053-snapshot.png"), fullPage: true }); console.log("screen-1053-snapshot.png saved"); console.log("\n=== Report ==="); console.log(JSON.stringify(report, null, 2)); fs.writeFileSync( path.join(SCREENSHOT_DIR, "screen-1053-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, "screen-1053-error.png"), fullPage: true }).catch(() => {}); } finally { await browser.close(); } } main();