/** * 화면 156, 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 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: {}, screen1053: {} }; try { // 1-2: Ensure logged in - goto login first, then login await page.goto(`${BASE_URL}/login`, { waitUntil: "domcontentloaded", timeout: 45000 }); await page.waitForTimeout(2000); 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: 20000 }).catch(() => {}); await page.waitForTimeout(3000); await page.goto(`${BASE_URL}/screens/156`, { waitUntil: "domcontentloaded", timeout: 45000 }); 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: URL) => !u.includes("/login"), { timeout: 20000 }).catch(() => {}); await page.waitForTimeout(3000); } // 3: Company selection if present const companyBtn = page.getByText("회사 선택").first(); if ((await companyBtn.count()) > 0) { await companyBtn.click(); await page.waitForTimeout(1500); const companyOption = page.getByText("company7", { exact: true }).first(); if ((await companyOption.count()) > 0) { await companyOption.click(); } else { const anyOption = page.locator("[role='menuitem'], [role='option'], button").filter({ hasText: /회사|company/i }).first(); if ((await anyOption.count()) > 0) await anyOption.click(); } await page.waitForTimeout(2000); } // 4: Screen 156 with menuObjid await page.goto(`${BASE_URL}/screens/156?menuObjid=1762421920156`, { waitUntil: "domcontentloaded", timeout: 45000 }); await page.waitForTimeout(3000); 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); await page.goto(`${BASE_URL}/screens/156?menuObjid=1762421920156`, { waitUntil: "domcontentloaded", timeout: 45000 }); await page.waitForTimeout(3000); } await page.getByText("화면을 불러오는 중", { exact: false }).waitFor({ state: "hidden", timeout: 35000 }).catch(() => {}); await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 15000 }).catch(() => {}); await page.waitForTimeout(30000); const table156 = page.locator("table tbody tr"); await table156.first().waitFor({ state: "visible", timeout: 15000 }).catch(() => {}); await page.waitForTimeout(3000); const info156 = await page.evaluate(() => { const table = document.querySelector("table"); const tbody = document.querySelector("tbody"); const rows = document.querySelectorAll("tbody tr"); const buttons = Array.from(document.querySelectorAll("button")).filter((b) => (b as HTMLElement).innerText?.trim().length > 2); const pagination = document.body.innerText.includes("표시") || document.body.innerText.includes("1/"); return { tableVisible: !!table && !!tbody, dataRowCount: rows.length, buttonsWithText: buttons.length, paginationVisible: !!pagination, buttonLabels: buttons.slice(0, 8).map((b) => (b as HTMLElement).innerText?.trim().substring(0, 20)), }; }); report.screen156 = info156; await page.screenshot({ path: path.join(SCREENSHOT_DIR, "responsive-156-v2.png"), fullPage: true }); console.log("responsive-156-v2.png saved"); // 5: Screen 1053 with menuObjid await page.goto(`${BASE_URL}/screens/1053?menuObjid=1762421920304`, { waitUntil: "domcontentloaded", timeout: 45000 }); await page.waitForTimeout(3000); await page.getByText("화면을 불러오는 중", { exact: false }).waitFor({ state: "hidden", timeout: 35000 }).catch(() => {}); await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 15000 }).catch(() => {}); await page.waitForTimeout(30000); const splitPanel = page.locator("[class*='border-r'], [class*='split']").first(); await splitPanel.waitFor({ state: "visible", timeout: 15000 }).catch(() => {}); await page.waitForTimeout(3000); const info1053 = await page.evaluate(() => { const leftPanel = document.querySelector("[class*='border-r']"); const rightPanel = document.querySelector("main")?.querySelectorAll("div") || []; const buttons = Array.from(document.querySelectorAll("button")).filter((b) => (b as HTMLElement).innerText?.trim().length > 2); const table = document.querySelector("table"); const bodyText = document.body.innerText; const hasSplitContent = bodyText.includes("좌측에서") || bodyText.includes("공급처") || bodyText.includes("품목"); return { splitPanelVisible: !!leftPanel || hasSplitContent, buttonsWithText: buttons.length, tableVisible: !!table, buttonLabels: buttons.slice(0, 8).map((b) => (b as HTMLElement).innerText?.trim().substring(0, 25)), }; }); report.screen1053 = info1053; await page.screenshot({ path: path.join(SCREENSHOT_DIR, "responsive-1053-v2.png"), fullPage: true }); console.log("responsive-1053-v2.png saved"); fs.writeFileSync( path.join(SCREENSHOT_DIR, "verify-156-1053-v2-report.json"), JSON.stringify(report, null, 2) ); console.log("\n=== Report ==="); console.log(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, "verify-v2-error.png"), fullPage: true }).catch(() => {}); } finally { await browser.close(); } } main();