127 lines
5.3 KiB
TypeScript
127 lines
5.3 KiB
TypeScript
/**
|
|
* 반응형 렌더링 검증: 화면 1053, 2089, 156, 4155
|
|
* 로그인: admin / wace1234!
|
|
*/
|
|
|
|
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 {
|
|
// 1-3: Login
|
|
await page.goto(`${BASE_URL}/login`, { waitUntil: "load", timeout: 30000 });
|
|
await page.waitForTimeout(1500);
|
|
await page.fill("#userId", "admin");
|
|
await page.fill("#password", "wace1234!");
|
|
await page.locator('button[type="submit"]').first().click();
|
|
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.waitForTimeout(3000);
|
|
}
|
|
await page.waitForURL((u: URL) => !u.includes("/login"), { timeout: 15000 }).catch(() => {});
|
|
await page.waitForTimeout(2000);
|
|
await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {});
|
|
|
|
async function captureAndVerify(screenId: number, screenName: string) {
|
|
await page.goto(`${BASE_URL}/screens/${screenId}`, { 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: 15000 }).catch(() => {});
|
|
await page.waitForTimeout(2000);
|
|
await page.goto(`${BASE_URL}/screens/${screenId}`, { waitUntil: "domcontentloaded", timeout: 45000 });
|
|
await page.waitForTimeout(2000);
|
|
}
|
|
await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {});
|
|
await page.getByText("화면을 불러오는 중", { exact: false }).waitFor({ state: "hidden", timeout: 25000 }).catch(() => {});
|
|
await page.waitForTimeout(2000);
|
|
|
|
const info = await page.evaluate(() => {
|
|
const buttons = Array.from(document.querySelectorAll("button"));
|
|
const btnWithText = buttons.filter((b) => (b as HTMLElement).innerText?.trim().length > 0);
|
|
const splitPanel = document.querySelector("[class*='split'], [class*='Split'], [class*='border-r']");
|
|
const leftPanel = document.querySelector("[class*='border-r']");
|
|
const table = document.querySelector("table");
|
|
const thead = document.querySelector("thead");
|
|
const tbody = document.querySelector("tbody");
|
|
const pagination = document.body.innerText.includes("표시") || document.body.innerText.includes("1/");
|
|
const bodyText = document.body.innerText;
|
|
const hasOverlap = bodyText.includes("화면을 찾을 수 없습니다") ? false : null;
|
|
|
|
const btnDetails = btnWithText.slice(0, 5).map((b) => ({
|
|
text: (b as HTMLElement).innerText?.trim().substring(0, 30),
|
|
rect: (b as HTMLElement).getBoundingClientRect(),
|
|
}));
|
|
|
|
return {
|
|
pageLoadsWithoutErrors: !bodyText.includes("화면을 찾을 수 없습니다"),
|
|
buttonsVisible: btnWithText.length > 0,
|
|
buttonsCount: btnWithText.length,
|
|
buttonDetails: btnDetails,
|
|
splitPanelVisible: !!splitPanel,
|
|
leftPanelVisible: !!leftPanel,
|
|
tableVisible: !!table && !!thead && !!tbody,
|
|
paginationVisible: !!pagination,
|
|
bodyScrollWidth: document.body.scrollWidth,
|
|
viewportWidth: window.innerWidth,
|
|
viewportHeight: window.innerHeight,
|
|
hasHorizontalOverflow: document.body.scrollWidth > window.innerWidth,
|
|
};
|
|
});
|
|
|
|
await page.screenshot({
|
|
path: path.join(SCREENSHOT_DIR, `responsive-${screenId}.png`),
|
|
fullPage: true,
|
|
});
|
|
console.log(`responsive-${screenId}.png saved`);
|
|
|
|
return { screenId, screenName, ...info };
|
|
}
|
|
|
|
// 4: Screen 1053 - 거래처관리
|
|
report.screen1053 = await captureAndVerify(1053, "거래처관리 - split panel custom mode");
|
|
|
|
// 5: Screen 2089 - BOM관리
|
|
report.screen2089 = await captureAndVerify(2089, "BOM관리 - split panel");
|
|
|
|
// 6: Screen 156 - 수주관리
|
|
report.screen156 = await captureAndVerify(156, "수주관리 - regular screen");
|
|
|
|
// 7: Screen 4155 - 작업지시
|
|
report.screen4155 = await captureAndVerify(4155, "작업지시 - buttons at bottom");
|
|
|
|
fs.writeFileSync(
|
|
path.join(SCREENSHOT_DIR, "responsive-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, "responsive-error.png"),
|
|
fullPage: true,
|
|
}).catch(() => {});
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
main();
|