Files
vexplor/frontend/scripts/test-formdata-logs.ts
kjs 4f6d9a689d feat: Implement process work standard routes and controller
- Added a new controller for managing process work standards, including CRUD operations for work items and routing processes.
- Introduced routes for fetching items with routing, retrieving routings with processes, and managing work items.
- Integrated the new process work standard routes into the main application file for API accessibility.
- Created a migration script for exporting data related to the new process work standard feature.
- Updated frontend components to support the new process work standard functionality, enhancing the overall user experience.
2026-02-24 12:37:33 +09:00

136 lines
5.1 KiB
TypeScript

/**
* formData 로그 테스트 스크립트
* - http://localhost:9771/screens/1599 접속
* - P003 행 선택 → 추가 버튼 클릭 → 장비 선택 → 저장 전/후 콘솔 로그 수집
*
* 실행: npx tsx scripts/test-formdata-logs.ts
* (Playwright 필요: npx playwright install chromium)
*/
import { chromium } from "playwright";
const TARGET_URL = "http://localhost:9771/screens/1599?menuObjid=1762422235300";
const LOGIN = { userId: "topseal_admin", password: "1234" };
const TARGET_LOGS = ["🔵", "🟡", "🔴", "process_code", "splitPanelParentData"];
async function main() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
const consoleLogs: string[] = [];
const errors: string[] = [];
page.on("console", (msg) => {
const text = msg.text();
const type = msg.type();
if (type === "error") {
errors.push(`[CONSOLE ERROR] ${text}`);
}
const hasTarget = TARGET_LOGS.some((t) => text.includes(t));
if (hasTarget || type === "error") {
consoleLogs.push(`[${type}] ${text}`);
}
});
console.log("1. 페이지 이동:", TARGET_URL);
await page.goto(TARGET_URL, { waitUntil: "domcontentloaded", timeout: 20000 });
// 로그인 필요 여부 확인
const userIdInput = page.locator('input[name="userId"]').first();
if (await userIdInput.isVisible().catch(() => false)) {
console.log("2. 로그인 페이지 감지 - 로그인 진행");
await page.fill('input[name="userId"]', LOGIN.userId);
await page.fill('input[name="password"]', LOGIN.password);
await page.click('button[type="submit"]').catch(() => page.click('button:has-text("로그인")'));
await page.waitForTimeout(4000);
}
console.log("3. 5초 대기 (페이지 로드)");
await page.waitForTimeout(5000);
// 탭 확인 - 공정 마스터 (첫 번째 탭)
const firstTab = page.getByRole("tab", { name: /공정 마스터/i }).or(page.locator('button:has-text("공정 마스터")')).first();
if (await firstTab.isVisible().catch(() => false)) {
console.log("4. '공정 마스터' 탭 클릭");
await firstTab.click();
await page.waitForTimeout(1500);
}
// 좌측 패널 테이블 데이터 로드 대기
console.log("5. 좌측 패널 데이터 로드 대기");
await page.locator("table tbody tr").first().waitFor({ state: "visible", timeout: 25000 }).catch(() => {
throw new Error("좌측 테이블에 데이터가 없습니다. process_mng에 P003 등 데이터가 있는지 확인하세요.");
});
// P003 행 또는 첫 번째 행 클릭
let rowToClick = page.locator('table tbody tr:has(td:has-text("P003"))').first();
const hasP003 = await rowToClick.isVisible().catch(() => false);
if (!hasP003) {
console.log(" P003 미발견 - 첫 번째 행 클릭");
rowToClick = page.locator("table tbody tr").first();
}
await rowToClick.click();
await page.waitForTimeout(800);
// 우측 패널에서 '추가' 버튼 클릭 (모달 열기)
console.log("6. '추가' 버튼 클릭");
const addBtn = page.locator('button:has-text("추가")').first();
await addBtn.click();
await page.waitForTimeout(2000);
// 모달이 열렸는지 확인
const modal = page.locator('[role="dialog"], [data-state="open"]').first();
await modal.waitFor({ state: "visible", timeout: 5000 }).catch(() => {});
// 모달 내 설비 드롭다운/콤보박스 선택 (v2-select, entity-search-input 등)
console.log("7. 모달 내 설비 선택");
const trigger = page.locator('[role="combobox"], button:has-text("선택"), button:has-text("설비")').first();
if (await trigger.isVisible().catch(() => false)) {
await trigger.click();
await page.waitForTimeout(500);
const option = page.locator('[role="option"], li[role="option"]').first();
if (await option.isVisible().catch(() => false)) {
await option.click();
}
} else {
// select 태그인 경우
const selectEl = page.locator('select').first();
if (await selectEl.isVisible().catch(() => false)) {
await selectEl.selectOption({ index: 1 });
}
}
await page.waitForTimeout(800);
// 저장 전 콘솔 스냅샷
console.log("\n=== 저장 전 콘솔 로그 (formData 관련) ===");
consoleLogs.forEach((l) => console.log(l));
if (errors.length) {
console.log("\n=== 에러 ===");
errors.forEach((e) => console.log(e));
}
// 저장 버튼 클릭 (모달 내부의 저장 버튼)
console.log("\n8. '저장' 버튼 클릭");
const saveBtn = page.locator('[role="dialog"] button:has-text("저장"), [data-state="open"] button:has-text("저장")').first();
await saveBtn.click();
await page.waitForTimeout(3000);
// 저장 후 로그 수집
console.log("\n=== 저장 후 콘솔 로그 (formData 관련) ===");
consoleLogs.forEach((l) => console.log(l));
if (errors.length) {
console.log("\n=== 에러 ===");
errors.forEach((e) => console.log(e));
}
await page.waitForTimeout(2000);
await browser.close();
}
main().catch((e) => {
console.error("테스트 실패:", e);
process.exit(1);
});