131 lines
4.8 KiB
TypeScript
131 lines
4.8 KiB
TypeScript
|
|
/**
|
||
|
|
* 화면 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<string, any>
|
||
|
|
) {
|
||
|
|
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<string, any> = { 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();
|