/** * 화면 1556 검증: tabs-widget 레이아웃 */ 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/1556`, { 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/1556`, { waitUntil: "load", timeout: 30000 }); await page.waitForTimeout(2000); } await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {}); await page.waitForTimeout(2000); report.pageLoadsWithoutErrors = (await page.locator('text="화면을 찾을 수 없습니다"').count()) === 0; const tabInfo = await page.evaluate(() => { const tabs = document.querySelectorAll("[role='tab'], [data-state='active'], [class*='TabsTrigger'], [class*='tab']"); const tabList = document.querySelector("[role='tablist']"); const loading = document.body.innerText.includes("로딩중") || document.body.innerText.includes("로딩 중"); return { tabCount: tabs.length, hasTabList: !!tabList, tabHeadersVisible: tabs.length > 0 || !!tabList, stuckOnLoading: loading, }; }); report.tabHeadersVisible = tabInfo.tabHeadersVisible; report.tabCount = tabInfo.tabCount; report.tabContentLoadsProperly = !tabInfo.stuckOnLoading; const loadingText = await page.getByText("로딩중", { exact: false }).count(); report.stuckOnLoading = loadingText > 0; 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-1556-snapshot.png"), fullPage: true }); console.log("screen-1556-snapshot.png saved"); console.log("\n=== Report ==="); console.log(JSON.stringify(report, null, 2)); fs.writeFileSync( path.join(SCREENSHOT_DIR, "screen-1556-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-1556-error.png"), fullPage: true }).catch(() => {}); } finally { await browser.close(); } } main();