ERP-node/scripts/run-e2e-test.js

152 lines
5.1 KiB
JavaScript

/**
* 결재 템플릿 관리 및 결재함 E2E 테스트
* 실행: node scripts/run-e2e-test.js
*/
const { chromium } = require("playwright");
const BASE_URL = "http://localhost:9771";
const SCREENSHOT_DIR = ".agent-pipeline/browser-tests";
async function runTest() {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
});
const page = await context.newPage();
const results = [];
let allPassed = true;
function pass(name) {
results.push({ name, status: "PASS" });
console.log(`PASS: ${name}`);
}
function fail(name, reason) {
results.push({ name, status: "FAIL", reason });
console.log(`FAIL: ${name} - ${reason}`);
allPassed = false;
}
try {
// 로그인
await page.goto(`${BASE_URL}/login`);
await page.waitForLoadState("networkidle");
await page.getByPlaceholder("사용자 ID를 입력하세요").fill("wace");
await page.getByPlaceholder("비밀번호를 입력하세요").fill("qlalfqjsgh11");
await Promise.all([
page.waitForURL(url => !url.toString().includes("/login"), { timeout: 30000 }),
page.getByRole("button", { name: "로그인" }).click(),
]);
await page.waitForLoadState("networkidle");
pass("로그인");
// =========================================================
// 결재 템플릿 관리 페이지
// =========================================================
await page.goto(`${BASE_URL}/admin/approvalTemplate`);
await page.waitForLoadState("domcontentloaded");
await page.waitForTimeout(3000);
// 1. "결재 템플릿 관리" 제목 확인
try {
await page.locator("h1").filter({ hasText: "결재 템플릿 관리" }).waitFor({ timeout: 10000 });
pass("결재 템플릿 관리 - 제목 확인");
} catch (e) {
fail("결재 템플릿 관리 - 제목 확인", e.message);
}
// 2. "신규 등록" 버튼 확인
try {
await page.getByRole("button", { name: "신규 등록" }).waitFor({ timeout: 10000 });
pass("결재 템플릿 관리 - 신규 등록 버튼 확인");
} catch (e) {
fail("결재 템플릿 관리 - 신규 등록 버튼 확인", e.message);
}
// 3. 검색 입력란 확인
try {
await page.getByPlaceholder("템플릿명 또는 설명 검색...").waitFor({ timeout: 10000 });
pass("결재 템플릿 관리 - 검색 입력란 확인");
} catch (e) {
// placeholder가 다를 수 있으므로 input으로 재시도
try {
await page.locator("input[type='text']").first().waitFor({ timeout: 5000 });
pass("결재 템플릿 관리 - 검색 입력란 확인 (input fallback)");
} catch (e2) {
fail("결재 템플릿 관리 - 검색 입력란 확인", e.message);
}
}
// 4. JS 에러 오버레이 확인
const hasError1 = await page.locator('[id="__next"] .nextjs-container-errors-body').isVisible().catch(() => false);
if (!hasError1) {
pass("결재 템플릿 관리 - JS 에러 없음");
} else {
fail("결재 템플릿 관리 - JS 에러 없음", "에러 오버레이 감지됨");
}
await page.screenshot({ path: `${SCREENSHOT_DIR}/result-template.png`, fullPage: true });
// =========================================================
// 결재함 페이지
// =========================================================
await page.goto(`${BASE_URL}/admin/approvalBox`);
await page.waitForLoadState("domcontentloaded");
await page.waitForTimeout(3000);
// 1. 탭 확인
try {
await page.getByRole("tab", { name: /수신함/ }).waitFor({ timeout: 10000 });
pass("결재함 - 수신함 탭 확인");
} catch (e) {
fail("결재함 - 수신함 탭 확인", e.message);
}
try {
await page.getByRole("tab", { name: /상신함/ }).waitFor({ timeout: 10000 });
pass("결재함 - 상신함 탭 확인");
} catch (e) {
fail("결재함 - 상신함 탭 확인", e.message);
}
// 2. JS 에러 오버레이 확인
const hasError2 = await page.locator('[id="__next"] .nextjs-container-errors-body').isVisible().catch(() => false);
if (!hasError2) {
pass("결재함 - JS 에러 없음");
} else {
fail("결재함 - JS 에러 없음", "에러 오버레이 감지됨");
}
await page.screenshot({ path: `${SCREENSHOT_DIR}/result-box.png`, fullPage: true });
} catch (e) {
fail("테스트 실행", e.message);
} finally {
await browser.close();
}
console.log("\n=== 테스트 결과 ===");
results.forEach(r => {
const status = r.status === "PASS" ? "✓" : "✗";
console.log(`${status} ${r.name}${r.reason ? `: ${r.reason}` : ""}`);
});
if (allPassed) {
console.log("\nBROWSER_TEST_RESULT: PASS");
process.exit(0);
} else {
const failed = results.filter(r => r.status === "FAIL").map(r => r.name).join(", ");
console.log(`\nBROWSER_TEST_RESULT: FAIL - ${failed}`);
process.exit(1);
}
}
runTest().catch(e => {
console.error("치명적 오류:", e);
console.log("BROWSER_TEST_RESULT: FAIL - 치명적 오류: " + e.message);
process.exit(1);
});