ERP-node/frontend/scripts/verify-screen-150-tapseal.ts

163 lines
6.6 KiB
TypeScript

/**
* 화면 150 검증 - 탑씰 영업 거래처관리
*/
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<string, any> = {};
try {
await page.goto(`${BASE_URL}/login`, { waitUntil: "load", timeout: 90000 });
await page.waitForTimeout(2000);
await page.fill("#userId", "admin");
await page.fill("#password", "1234");
await page.locator('button[type="submit"]').first().click();
await page.waitForURL((u: URL) => !u.includes("/login"), { timeout: 20000 }).catch(() => {});
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: 20000 }).catch(() => {});
await page.waitForTimeout(3000);
}
const companyBtn = page.getByText("회사 선택").first();
if ((await companyBtn.count()) > 0) {
const currentCompany = await page.getByText("현재 관리 회사").locator("..").textContent().catch(() => "");
if (!currentCompany?.includes("탑씰") && !currentCompany?.includes("COMPANY_7")) {
await companyBtn.click();
await page.waitForTimeout(1500);
const tapseal = page.getByText("탑씰", { exact: true }).first();
const company7 = page.getByText("COMPANY_7", { exact: true }).first();
if ((await tapseal.count()) > 0) {
await tapseal.click();
} else if ((await company7.count()) > 0) {
await company7.click();
}
await page.waitForTimeout(2000);
}
}
await page.goto(`${BASE_URL}/screens/150`, { waitUntil: "domcontentloaded", timeout: 60000 });
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: 20000 }).catch(() => {});
await page.waitForTimeout(3000);
await page.goto(`${BASE_URL}/screens/150`, { waitUntil: "domcontentloaded", timeout: 60000 });
await page.waitForTimeout(3000);
}
await page.getByText("화면을 불러오는 중", { exact: false }).waitFor({ state: "hidden", timeout: 25000 }).catch(() => {});
await page.waitForTimeout(8000);
const info = await page.evaluate(() => {
const buttons = Array.from(document.querySelectorAll("button")).filter((b) => {
const t = (b as HTMLElement).innerText?.trim() || "";
const r = (b as HTMLElement).getBoundingClientRect();
return t.length > 1 && r.x > 250 && r.width > 0;
});
const viewportWidth = window.innerWidth;
const leftThird = viewportWidth * 0.33;
const rightThird = viewportWidth * 0.66;
const btnDetails = buttons.map((b) => {
const r = (b as HTMLElement).getBoundingClientRect();
const text = (b as HTMLElement).innerText?.trim().substring(0, 40);
let group = "center";
if (r.x < leftThird) group = "left";
else if (r.x > rightThird) group = "right";
return {
text,
x: Math.round(r.x),
y: Math.round(r.y),
width: Math.round(r.width),
height: Math.round(r.height),
right: Math.round(r.right),
group,
};
});
const leftPanel = document.querySelector("[class*='border-r']");
const tables = document.querySelectorAll("table");
const rightPanel = document.querySelector("main")?.querySelectorAll("[class*='overflow'], [style*='overflow']");
const leftRect = leftPanel ? (leftPanel as HTMLElement).getBoundingClientRect() : null;
const mainRect = document.querySelector("main")?.getBoundingClientRect();
const contentWidth = mainRect ? mainRect.width : viewportWidth;
const leftWidthPercent = leftRect && contentWidth > 0 ? (leftRect.width / contentWidth) * 100 : null;
let overlaps = false;
for (let i = 0; i < btnDetails.length; i++) {
for (let j = i + 1; j < btnDetails.length; j++) {
const a = btnDetails[i];
const b = btnDetails[j];
if (Math.abs(a.y - b.y) < 30 && !(a.right < b.x || b.right < a.x)) overlaps = true;
}
}
const rightTable = tables.length > 1 ? tables[1] : tables[0];
const rightTableRect = rightTable ? (rightTable as HTMLElement).getBoundingClientRect() : null;
const rightTableScrollable = rightTable
? (() => {
let el: Element | null = rightTable;
while (el) {
const s = window.getComputedStyle(el);
if (s.overflowY === "auto" || s.overflowY === "scroll" || s.overflow === "auto") return true;
el = el.parentElement;
}
return false;
})()
: null;
return {
buttonCount: buttons.length,
buttonDetails: btnDetails,
leftGroup: btnDetails.filter((b) => b.group === "left"),
centerGroup: btnDetails.filter((b) => b.group === "center"),
rightGroup: btnDetails.filter((b) => b.group === "right"),
splitPanelVisible: !!leftPanel,
leftWidthPercent: leftWidthPercent ? Math.round(leftWidthPercent) : null,
rightWidthPercent: leftWidthPercent ? Math.round(100 - leftWidthPercent) : null,
tableCount: tables.length,
rightPanelHasTable: !!rightTable,
rightTableScrollable,
buttonsOverlap: overlaps,
};
});
report.screen150 = info;
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "screen-150-tapseal.png"), fullPage: true });
console.log("screen-150-tapseal.png saved");
fs.writeFileSync(
path.join(SCREENSHOT_DIR, "screen-150-tapseal-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, "screen-150-tapseal-error.png"), fullPage: true }).catch(() => {});
} finally {
await browser.close();
}
}
main();