163 lines
6.6 KiB
TypeScript
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();
|