/** * 결재 모달 테스트: 버튼 클릭 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();