136 lines
4.9 KiB
TypeScript
136 lines
4.9 KiB
TypeScript
|
|
/**
|
||
|
|
* 수주관리 화면(68) 검증 스크립트
|
||
|
|
* - 로그인 상태 확인 후 필요시 로그인
|
||
|
|
* - /screens/68 접속
|
||
|
|
* - 테이블, 검색 필터, 버튼 확인
|
||
|
|
*/
|
||
|
|
|
||
|
|
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 },
|
||
|
|
storageState: undefined, // 새 세션 (쿠키 유지 안 함 - 이전 세션 로그인 상태 확인용)
|
||
|
|
});
|
||
|
|
const page = await context.newPage();
|
||
|
|
|
||
|
|
const steps: { step: string; success: boolean; message?: string }[] = [];
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Step 1: 로그인 페이지 접속 및 로그인 (Playwright는 매번 새 브라우저이므로 항상 로그인 필요)
|
||
|
|
console.log("Step 1: 로그인...");
|
||
|
|
await page.goto(`${BASE_URL}/login`, { waitUntil: "domcontentloaded", timeout: 15000 });
|
||
|
|
await page.waitForTimeout(1000);
|
||
|
|
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s68-01-login-page.png"), fullPage: true });
|
||
|
|
|
||
|
|
await page.fill("#userId", "wace");
|
||
|
|
await page.fill("#password", "qlalfqjsgh11");
|
||
|
|
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s68-02-login-filled.png"), fullPage: true });
|
||
|
|
await page.locator('button[type="submit"]').first().click();
|
||
|
|
await page.waitForTimeout(3000);
|
||
|
|
steps.push({ step: "로그인", success: true });
|
||
|
|
|
||
|
|
// Step 2: /screens/68 접속
|
||
|
|
console.log("Step 2: /screens/68 접속...");
|
||
|
|
await page.goto(`${BASE_URL}/screens/68`, { waitUntil: "domcontentloaded", timeout: 15000 });
|
||
|
|
|
||
|
|
// 5초 대기 (페이지 완전 로드)
|
||
|
|
console.log("Step 3: 5초 대기 (페이지 완전 로드)...");
|
||
|
|
await page.waitForTimeout(5000);
|
||
|
|
|
||
|
|
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s68-03-screen-loaded.png"), fullPage: true });
|
||
|
|
steps.push({ step: "/screens/68 접속 및 5초 대기", success: true });
|
||
|
|
|
||
|
|
// Step 3: 요소 검증
|
||
|
|
console.log("Step 3: 요소 검증...");
|
||
|
|
|
||
|
|
const hasError = await page.locator('text="화면을 찾을 수 없습니다"').count() > 0;
|
||
|
|
if (hasError) {
|
||
|
|
steps.push({ step: "화면 로드", success: false, message: "404 - 화면을 찾을 수 없습니다" });
|
||
|
|
} else {
|
||
|
|
// 테이블 (TableListComponent: role=grid, table, thead/tbody)
|
||
|
|
const tableSelectors = [
|
||
|
|
"table",
|
||
|
|
"[role='grid']",
|
||
|
|
"[role='table']",
|
||
|
|
"thead",
|
||
|
|
"tbody",
|
||
|
|
".table-mobile-fixed",
|
||
|
|
"[class*='ag-']",
|
||
|
|
"[class*='table-list']",
|
||
|
|
];
|
||
|
|
let tableFound = false;
|
||
|
|
for (const sel of tableSelectors) {
|
||
|
|
if ((await page.locator(sel).count()) > 0) {
|
||
|
|
tableFound = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 검색/필터 (input, select, 테이블 툴바 검색/필터 버튼)
|
||
|
|
const filterSelectors = [
|
||
|
|
"input",
|
||
|
|
"select",
|
||
|
|
'input[type="text"]',
|
||
|
|
'input[type="search"]',
|
||
|
|
'input[placeholder*="검색"]',
|
||
|
|
"button:has-text('검색')",
|
||
|
|
"button:has-text('필터')",
|
||
|
|
"[class*='filter']",
|
||
|
|
"[class*='search']",
|
||
|
|
];
|
||
|
|
let filterFound = false;
|
||
|
|
for (const sel of filterSelectors) {
|
||
|
|
if ((await page.locator(sel).count()) > 0) {
|
||
|
|
filterFound = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 버튼
|
||
|
|
const buttonCount = await page.locator("button, [role='button'], input[type='submit']").count();
|
||
|
|
const buttonsFound = buttonCount > 0;
|
||
|
|
|
||
|
|
steps.push({
|
||
|
|
step: "화면 요소 검증",
|
||
|
|
success: tableFound && filterFound && buttonsFound,
|
||
|
|
message: `테이블: ${tableFound ? "O" : "X"}, 검색: ${filterFound ? "O" : "X"}, 버튼: ${buttonsFound ? "O" : "X"}`,
|
||
|
|
});
|
||
|
|
|
||
|
|
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s68-04-verified.png"), fullPage: true });
|
||
|
|
|
||
|
|
const finalSuccess = tableFound && filterFound && buttonsFound && !hasError;
|
||
|
|
console.log("\n=== 검증 결과 ===");
|
||
|
|
steps.forEach((s) => console.log(`${s.step}: ${s.success ? "성공" : "실패"}${s.message ? ` - ${s.message}` : ""}`));
|
||
|
|
console.log(`\n최종 판정: ${finalSuccess ? "성공" : "실패"}`);
|
||
|
|
|
||
|
|
fs.writeFileSync(
|
||
|
|
path.join(SCREENSHOT_DIR, "s68-result.json"),
|
||
|
|
JSON.stringify(
|
||
|
|
{
|
||
|
|
steps,
|
||
|
|
checks: { table: tableFound, filter: filterFound, buttons: buttonsFound },
|
||
|
|
finalSuccess: finalSuccess ? "성공" : "실패",
|
||
|
|
},
|
||
|
|
null,
|
||
|
|
2
|
||
|
|
)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("오류:", error.message);
|
||
|
|
await page.screenshot({ path: path.join(SCREENSHOT_DIR, "s68-99-error.png"), fullPage: true }).catch(() => {});
|
||
|
|
steps.push({ step: "오류", success: false, message: error.message });
|
||
|
|
} finally {
|
||
|
|
await browser.close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
main();
|