ERP-node/frontend/scripts/screen-approval-modal-test.ts

102 lines
4.6 KiB
TypeScript
Raw Normal View History

/**
* 테스트: 버튼 vs CustomEvent
* 실행: npx tsx frontend/scripts/screen-approval-modal-test.ts
*/
import { chromium } from "playwright";
import { writeFileSync } from "fs";
const BASE_URL = "http://localhost:9771";
const LOGIN_ID = "wace";
const LOGIN_PW = "qlalfqjsgh11";
const SCREEN_URL = `${BASE_URL}/screen/COMPANY_7_064`;
const results: string[] = [];
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();
try {
// 1. 로그인
results.push("=== 1. 로그인 ===");
await page.goto(`${BASE_URL}/login`, { waitUntil: "networkidle", timeout: 15000 });
await page.getByPlaceholder("사용자 ID를 입력하세요").or(page.locator('#userId, input[name="userId"]')).first().fill(LOGIN_ID);
await page.getByPlaceholder("비밀번호를 입력하세요").or(page.locator('#password, input[name="password"]')).first().fill(LOGIN_PW);
await page.getByRole("button", { name: "로그인" }).or(page.locator('button[type="submit"]')).first().click();
await page.waitForURL((url) => !url.toString().includes("/login"), { timeout: 30000 });
await page.waitForLoadState("networkidle");
results.push("OK: 로그인 성공");
// 2. 화면 이동 및 대기
results.push("\n=== 2. 화면 COMPANY_7_064 이동 ===");
await page.goto(SCREEN_URL, { waitUntil: "networkidle", timeout: 20000 });
await page.waitForTimeout(3000);
results.push("OK: 페이지 로드 완료");
// 3. 전체 페이지 스크린샷
results.push("\n=== 3. 전체 페이지 스크린샷 ===");
await page.screenshot({ path: "/Users/gbpark/ERP-node/approval-test-1-full-page.png", fullPage: true });
results.push("OK: approval-test-1-full-page.png 저장");
// 4. "결재 요청" 버튼 클릭
results.push("\n=== 4. 결재 요청 버튼 클릭 ===");
const approvalBtn = page.getByRole("button", { name: "결재 요청" }).or(page.locator('button:has-text("결재 요청")'));
await approvalBtn.first().click({ force: true });
await page.waitForTimeout(2000);
// 5. 클릭 후 스크린샷
results.push("\n=== 5. 클릭 후 스크린샷 ===");
await page.screenshot({ path: "/Users/gbpark/ERP-node/approval-test-2-after-button-click.png", fullPage: true });
results.push("OK: approval-test-2-after-button-click.png 저장");
// 6. 모달 등장 여부 확인
results.push("\n=== 6. 버튼 클릭 후 모달 확인 ===");
const modalAfterClick = page.locator('[role="dialog"]');
const modalVisibleAfterClick = (await modalAfterClick.count()) > 0;
results.push(modalVisibleAfterClick ? "OK: 버튼 클릭으로 모달 열림" : "FAIL: 버튼 클릭 후 모달 없음");
// 7. CustomEvent 직접 발송 (모달이 없었을 때)
results.push("\n=== 7. CustomEvent 직접 발송 ===");
await page.evaluate(() => {
window.dispatchEvent(
new CustomEvent("open-approval-modal", {
detail: { targetTable: "purchase_order_mng", targetRecordId: "test-123" },
})
);
});
await page.waitForTimeout(2000);
// 8. CustomEvent 발송 후 스크린샷
results.push("\n=== 8. CustomEvent 발송 후 스크린샷 ===");
await page.screenshot({ path: "/Users/gbpark/ERP-node/approval-test-3-after-customevent.png", fullPage: true });
results.push("OK: approval-test-3-after-customevent.png 저장");
// 9. CustomEvent 발송 후 모달 확인
results.push("\n=== 9. CustomEvent 발송 후 모달 확인 ===");
const modalAfterEvent = page.locator('[role="dialog"]');
const modalVisibleAfterEvent = (await modalAfterEvent.count()) > 0;
results.push(modalVisibleAfterEvent ? "OK: CustomEvent 발송으로 모달 열림" : "FAIL: CustomEvent 발송 후에도 모달 없음");
// 10. 최종 요약
results.push("\n=== 10. 최종 요약 ===");
results.push(`버튼 클릭 → 모달: ${modalVisibleAfterClick ? "YES" : "NO"}`);
results.push(`CustomEvent 발송 → 모달: ${modalVisibleAfterEvent ? "YES" : "NO"}`);
} catch (err: any) {
results.push(`\nERROR: ${err.message}`);
await page.screenshot({ path: "/Users/gbpark/ERP-node/approval-test-error.png", fullPage: true }).catch(() => {});
} finally {
await browser.close();
}
const output = results.join("\n");
console.log("\n" + "=".repeat(60));
console.log("결재 모달 테스트 결과");
console.log("=".repeat(60));
console.log(output);
console.log("=".repeat(60));
writeFileSync("/Users/gbpark/ERP-node/approval-modal-test-result.txt", output);
}
main();