ERP-node/frontend/scripts/company-menu-flow-verificat...

157 lines
7.0 KiB
TypeScript

/**
* 회사 선택 → 메뉴 → 수주/구매관리 화면 검증
* 1. 로그인 (topseal7 또는 wace)
* 2. 회사 선택 → 탑씰
* 3. 영업관리 > 수주관리 또는 구매관리
* 4. 데이터 화면 스크린샷
* 5. 테이블 가로 스크롤 확인
*/
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 steps: string[] = [];
try {
// Step 1: 로그인 페이지
console.log("Step 1: 로그인 페이지 접속...");
await page.goto(`${BASE_URL}/login`, { waitUntil: "domcontentloaded", timeout: 15000 });
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-01-login-page.png"), fullPage: true });
steps.push("01-login-page");
// Step 2: 로그인 시도 (topseal7 먼저)
console.log("Step 2: 로그인 (topseal7 시도)...");
await page.fill("#userId", "topseal7");
await page.fill("#password", "qlalfqjsgh11");
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-02-login-topseal7.png"), fullPage: true });
await page.locator('button[type="submit"]').first().click();
await page.waitForTimeout(3000);
const urlAfterLogin = page.url();
const isStillLogin = urlAfterLogin.includes("/login");
if (isStillLogin) {
console.log("topseal7 로그인 실패, wace 시도...");
await page.fill("#userId", "wace");
await page.fill("#password", "qlalfqjsgh11");
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-02b-login-wace.png"), fullPage: true });
await page.locator('button[type="submit"]').first().click();
await page.waitForTimeout(3000);
}
await page.waitForURL((url) => !url.includes("/login"), { timeout: 15000 }).catch(() => {});
await page.waitForTimeout(3000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-03-after-login.png"), fullPage: true });
steps.push("03-after-login");
// Step 3: 회사 선택 → 탑씰 (SUPER_ADMIN만 보임, 메인 앱 로드 대기)
console.log("Step 3: 회사 선택 클릭...");
await page.getByText("현재 관리 회사").waitFor({ timeout: 8000 }).catch(() => {});
await page.waitForTimeout(1000);
const companyBtn = page.getByText("회사 선택").first();
if ((await companyBtn.count()) > 0) {
await companyBtn.click();
await page.waitForTimeout(1500);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-04-company-dropdown.png"), fullPage: true });
const tapsealOption = page.getByText("탑씰", { exact: true }).first();
if ((await tapsealOption.count()) > 0) {
await tapsealOption.click();
await page.waitForTimeout(2000);
console.log("탑씰 선택됨");
} else {
console.log("탑씰 옵션 없음 - 스킵");
}
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-05-after-company.png"), fullPage: true });
} else {
console.log("회사 선택 버튼 없음");
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-05-no-company-btn.png"), fullPage: true });
}
steps.push("05-after-company");
// Step 4: 영업관리 > 수주관리 또는 구매관리
console.log("Step 4: 메뉴 클릭 (영업관리 > 수주관리)...");
const salesMgmt = page.getByText("영업관리").first();
if ((await salesMgmt.count()) > 0) {
await salesMgmt.click();
await page.waitForTimeout(1000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-06-sales-expanded.png"), fullPage: true });
const orderMgmt = page.getByText("수주관리").first();
if ((await orderMgmt.count()) > 0) {
await orderMgmt.click();
await page.waitForTimeout(3000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-07-order-screen.png"), fullPage: true });
} else {
const purchaseMgmt = page.getByText("구매관리").first();
if ((await purchaseMgmt.count()) > 0) {
await purchaseMgmt.click();
await page.waitForTimeout(3000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-07-purchase-screen.png"), fullPage: true });
}
}
} else {
const purchaseMgmt = page.getByText("구매관리").first();
if ((await purchaseMgmt.count()) > 0) {
await purchaseMgmt.click();
await page.waitForTimeout(3000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-07-purchase-direct.png"), fullPage: true });
}
}
steps.push("07-menu-screen");
// Step 5: /screens/1244 직접 접속 시도
console.log("Step 5: /screens/1244 직접 접속...");
await page.goto(`${BASE_URL}/screens/1244`, { waitUntil: "domcontentloaded", timeout: 15000 });
await page.waitForTimeout(5000);
await page.getByText("로딩중", { exact: false }).waitFor({ state: "hidden", timeout: 10000 }).catch(() => {});
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-08-screen-1244.png"), fullPage: true });
steps.push("08-screen-1244");
// Step 6: 테이블 가로 스크롤 확인
console.log("Step 6: 테이블 가로 스크롤 확인...");
const tableContainer = page.locator("table").locator("..").first();
const table = page.locator("table").first();
if ((await table.count()) > 0) {
const tableBox = await table.boundingBox();
const hasOverflowX = await table.evaluate((el) => {
const parent = el.closest("[style*='overflow'], [class*='overflow']");
return parent ? getComputedStyle(parent as Element).overflowX !== "visible" : false;
}).catch(() => false);
const scrollWidth = await table.evaluate((el) => el.scrollWidth);
const clientWidth = await table.evaluate((el) => el.clientWidth);
const canScroll = scrollWidth > clientWidth;
console.log(`테이블: scrollWidth=${scrollWidth}, clientWidth=${clientWidth}, 가로스크롤가능=${canScroll}`);
}
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-09-table-scroll-check.png"), fullPage: true });
steps.push("09-table-scroll");
// Step 7: 최종 스크린샷
console.log("Step 7: 최종 스크린샷...");
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-10-final.png"), fullPage: true });
steps.push("10-final");
fs.writeFileSync(
path.join(SCREENSHOT_DIR, "flow-result.json"),
JSON.stringify({ steps, timestamp: new Date().toISOString() }, null, 2)
);
console.log("\n완료. 스크린샷:", SCREENSHOT_DIR);
} catch (error: any) {
console.error("오류:", error.message);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "flow-99-error.png"), fullPage: true }).catch(() => {});
} finally {
await browser.close();
}
}
main();