Remove obsolete end-to-end test scripts and related files for screen and table components in the agent pipeline.
This commit is contained in:
@@ -1,249 +0,0 @@
|
||||
/**
|
||||
* screens/29 및 screen-management E2E 테스트
|
||||
* 실행: node scripts/run-screen-e2e-test.js
|
||||
*/
|
||||
const { chromium } = require('playwright');
|
||||
const { writeFileSync } = require('fs');
|
||||
|
||||
const BASE_URL = 'http://localhost:9771';
|
||||
const SCREENSHOT_PATH = '.agent-pipeline/browser-tests/result.png';
|
||||
|
||||
const results = [];
|
||||
let passed = true;
|
||||
let failReason = '';
|
||||
|
||||
function pass(name) {
|
||||
results.push(`PASS: ${name}`);
|
||||
}
|
||||
|
||||
function fail(name, reason) {
|
||||
passed = false;
|
||||
if (!failReason) failReason = `${name}: ${reason}`;
|
||||
results.push(`FAIL: ${name} - ${reason}`);
|
||||
}
|
||||
|
||||
async function login(page) {
|
||||
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('로그인 성공');
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
|
||||
// ===== 테스트 1: /screens/29 컴포넌트 렌더링 =====
|
||||
{
|
||||
const context = await browser.newContext({ viewport: { width: 1280, height: 720 } });
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
await login(page);
|
||||
|
||||
await page.goto(`${BASE_URL}/screens/29`);
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await page.waitForTimeout(5000);
|
||||
pass('/screens/29 접속 성공');
|
||||
|
||||
// 에러 오버레이 확인
|
||||
const hasError = await page.locator('[id="__next"] .nextjs-container-errors-body').isVisible().catch(() => false);
|
||||
if (hasError) {
|
||||
fail('/screens/29 에러 체크', '에러 오버레이 발견');
|
||||
} else {
|
||||
pass('/screens/29 에러 오버레이 없음');
|
||||
}
|
||||
|
||||
// body 렌더링 확인
|
||||
const bodyVisible = await page.locator('body').isVisible();
|
||||
if (bodyVisible) {
|
||||
pass('/screens/29 body 렌더링 확인');
|
||||
} else {
|
||||
fail('/screens/29 body 확인', 'body가 보이지 않음');
|
||||
}
|
||||
|
||||
// 컴포넌트 렌더링 확인 - 절대 좌표 배치 포함
|
||||
const selectors = [
|
||||
'[style*="position: absolute"]',
|
||||
'[style*="position:absolute"]',
|
||||
'[data-screen-id]',
|
||||
'[data-widget-id]',
|
||||
'[data-component-id]',
|
||||
'.screen-container',
|
||||
'[class*="widget"]',
|
||||
'[class*="component"]',
|
||||
'[class*="screen"]',
|
||||
];
|
||||
|
||||
let componentFound = false;
|
||||
let foundInfo = '';
|
||||
for (const sel of selectors) {
|
||||
const count = await page.locator(sel).count();
|
||||
if (count > 0) {
|
||||
componentFound = true;
|
||||
foundInfo = `${sel} (${count}개)`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (componentFound) {
|
||||
pass(`/screens/29 컴포넌트 발견: ${foundInfo}`);
|
||||
} else {
|
||||
const pageContent = await page.locator('body').innerText().catch(() => '');
|
||||
pass(`/screens/29 페이지 로드됨 (내용길이: ${pageContent.trim().length}, 컴포넌트 셀렉터 미매칭)`);
|
||||
}
|
||||
|
||||
// 현재 URL 확인 - 로그인 페이지로 리다이렉트되지 않았는지
|
||||
const currentUrl = page.url();
|
||||
if (currentUrl.includes('/login')) {
|
||||
fail('/screens/29 URL 확인', '로그인 페이지로 리다이렉트됨');
|
||||
} else {
|
||||
pass(`/screens/29 URL 정상 (${currentUrl})`);
|
||||
}
|
||||
|
||||
await page.screenshot({ path: '.agent-pipeline/browser-tests/result-screens29.png', fullPage: true });
|
||||
pass('/screens/29 스크린샷 저장');
|
||||
|
||||
} catch (err) {
|
||||
fail('/screens/29 테스트', err.message);
|
||||
await page.screenshot({ path: '.agent-pipeline/browser-tests/result-screens29-fail.png', fullPage: true }).catch(() => {});
|
||||
} finally {
|
||||
await context.close();
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 테스트 2: /admin/screen-management 화면 디자이너 =====
|
||||
{
|
||||
const context = await browser.newContext({ viewport: { width: 1280, height: 720 } });
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
await login(page);
|
||||
|
||||
await page.goto(`${BASE_URL}/admin/screen-management`);
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await page.waitForTimeout(5000);
|
||||
pass('/admin/screen-management 접속 성공');
|
||||
|
||||
// 에러 오버레이 확인
|
||||
const hasError = await page.locator('[id="__next"] .nextjs-container-errors-body').isVisible().catch(() => false);
|
||||
if (hasError) {
|
||||
fail('/admin/screen-management 에러 체크', '에러 오버레이 발견');
|
||||
} else {
|
||||
pass('/admin/screen-management 에러 오버레이 없음');
|
||||
}
|
||||
|
||||
// 화면 목록 확인
|
||||
const tableRows = page.locator('table tbody tr');
|
||||
const rowCount = await tableRows.count();
|
||||
pass(`화면 목록 행 수: ${rowCount}개`);
|
||||
|
||||
if (rowCount > 0) {
|
||||
// 편집 가능한 화면 선택 - 다양한 셀렉터 시도
|
||||
const editSelectors = [
|
||||
'button:has-text("편집")',
|
||||
'button:has-text("수정")',
|
||||
'button:has-text("열기")',
|
||||
'[data-action="edit"]',
|
||||
'[title="편집"]',
|
||||
'td button:first-child',
|
||||
];
|
||||
|
||||
let editFound = false;
|
||||
for (const sel of editSelectors) {
|
||||
const editBtn = page.locator(sel).first();
|
||||
const isVisible = await editBtn.isVisible({ timeout: 2000 }).catch(() => false);
|
||||
if (isVisible) {
|
||||
await editBtn.click();
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await page.waitForTimeout(5000);
|
||||
editFound = true;
|
||||
pass(`편집 버튼 클릭 성공 (${sel})`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!editFound) {
|
||||
// 첫 행 클릭 시도
|
||||
await tableRows.first().click().catch(() => {});
|
||||
await page.waitForTimeout(3000);
|
||||
pass('테이블 첫 행 클릭 (편집 버튼 미발견)');
|
||||
}
|
||||
|
||||
// 편집 후 에러 오버레이 재확인
|
||||
const hasErrorAfterEdit = await page.locator('[id="__next"] .nextjs-container-errors-body').isVisible().catch(() => false);
|
||||
if (hasErrorAfterEdit) {
|
||||
fail('편집 후 에러 체크', '에러 오버레이 발견');
|
||||
} else {
|
||||
pass('편집 후 에러 오버레이 없음');
|
||||
}
|
||||
|
||||
// 절대 좌표 배치 컴포넌트 확인
|
||||
const absoluteCount = await page.locator('[style*="position: absolute"], [style*="position:absolute"]').count();
|
||||
pass(`절대 좌표 요소 수: ${absoluteCount}개`);
|
||||
|
||||
// 디자이너 UI 확인
|
||||
const designerSelectors = [
|
||||
'[class*="canvas"]',
|
||||
'[class*="designer"]',
|
||||
'[class*="editor"]',
|
||||
'[data-designer]',
|
||||
'[class*="drag"]',
|
||||
'[class*="palette"]',
|
||||
];
|
||||
|
||||
let designerFound = false;
|
||||
for (const sel of designerSelectors) {
|
||||
const count = await page.locator(sel).count();
|
||||
if (count > 0) {
|
||||
pass(`디자이너 UI 발견: ${sel} (${count}개)`);
|
||||
designerFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!designerFound) {
|
||||
pass('디자이너 UI 셀렉터 미매칭 (다른 레이아웃일 수 있음)');
|
||||
}
|
||||
|
||||
} else {
|
||||
const pageText = await page.locator('body').innerText().catch(() => '');
|
||||
pass(`/admin/screen-management 로드됨 (내용길이: ${pageText.trim().length})`);
|
||||
}
|
||||
|
||||
await page.screenshot({ path: SCREENSHOT_PATH, fullPage: true });
|
||||
pass('/admin/screen-management 스크린샷 저장');
|
||||
|
||||
} catch (err) {
|
||||
fail('/admin/screen-management 테스트', err.message);
|
||||
await page.screenshot({ path: '.agent-pipeline/browser-tests/result-screen-mgmt-fail.png', fullPage: true }).catch(() => {});
|
||||
} finally {
|
||||
await context.close();
|
||||
}
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
runTest()
|
||||
.then(() => {
|
||||
const output = results.join('\n');
|
||||
console.log(output);
|
||||
const resultLine = passed ? 'RESULT: PASS' : `RESULT: FAIL - ${failReason}`;
|
||||
writeFileSync('/tmp/screen-e2e-result.txt', output + '\n' + resultLine);
|
||||
console.log(resultLine);
|
||||
process.exit(passed ? 0 : 1);
|
||||
})
|
||||
.catch(err => {
|
||||
const msg = `치명적 오류: ${err.message}`;
|
||||
console.error(msg);
|
||||
writeFileSync('/tmp/screen-e2e-result.txt', msg + '\nRESULT: FAIL - ' + err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,298 +0,0 @@
|
||||
/**
|
||||
* /screens/29 전체 E2E 테스트
|
||||
* - 테이블 데이터 표시 확인
|
||||
* - 컬럼 정렬 클릭 확인
|
||||
* - 375px 모바일에서 가로 스크롤 확인
|
||||
*/
|
||||
const { chromium } = require("playwright");
|
||||
|
||||
const BASE_URL = "http://localhost:9771";
|
||||
const SCREENSHOT_DESKTOP = ".agent-pipeline/browser-tests/result-desktop.png";
|
||||
const SCREENSHOT_MOBILE = ".agent-pipeline/browser-tests/result.png";
|
||||
|
||||
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;
|
||||
const failReasons = [];
|
||||
|
||||
function pass(name) {
|
||||
results.push(`PASS: ${name}`);
|
||||
console.log(`PASS: ${name}`);
|
||||
}
|
||||
|
||||
function fail(name, reason) {
|
||||
allPassed = false;
|
||||
const msg = `FAIL: ${name} - ${reason}`;
|
||||
results.push(msg);
|
||||
failReasons.push(msg);
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
results.push(`INFO: ${msg}`);
|
||||
console.log(`INFO: ${msg}`);
|
||||
}
|
||||
|
||||
try {
|
||||
// ===== 1. 로그인 =====
|
||||
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");
|
||||
|
||||
const loginUrl = page.url();
|
||||
if (loginUrl.includes("/login")) {
|
||||
fail("로그인", "/login 페이지에 머무름");
|
||||
throw new Error("로그인 실패");
|
||||
} else {
|
||||
pass(`로그인 성공 (URL: ${loginUrl})`);
|
||||
}
|
||||
|
||||
// ===== 2. /screens/29 접속 =====
|
||||
await page.goto(`${BASE_URL}/screens/29`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
info(`screens/29 접속 URL = ${page.url()}`);
|
||||
|
||||
// 에러 오버레이 체크
|
||||
const hasError = await page
|
||||
.locator('[id="__next"] .nextjs-container-errors-body')
|
||||
.isVisible()
|
||||
.catch(() => false);
|
||||
if (hasError) {
|
||||
fail("에러 오버레이 확인", "에러 오버레이가 표시됨");
|
||||
} else {
|
||||
pass("에러 오버레이 없음");
|
||||
}
|
||||
|
||||
// ===== 3. 테이블 데이터 표시 확인 =====
|
||||
// 다양한 테이블 셀렉터 시도
|
||||
let tableFound = false;
|
||||
let tableSelector = "";
|
||||
|
||||
// table 태그 시도
|
||||
const tableCount = await page.locator("table").count();
|
||||
if (tableCount > 0) {
|
||||
tableFound = true;
|
||||
tableSelector = "table";
|
||||
pass(`테이블 발견 (table 태그, ${tableCount}개)`);
|
||||
}
|
||||
|
||||
// role=grid 시도
|
||||
if (!tableFound) {
|
||||
const gridCount = await page.locator('[role="grid"]').count();
|
||||
if (gridCount > 0) {
|
||||
tableFound = true;
|
||||
tableSelector = '[role="grid"]';
|
||||
pass(`테이블 발견 (role=grid, ${gridCount}개)`);
|
||||
}
|
||||
}
|
||||
|
||||
// class 기반 시도
|
||||
if (!tableFound) {
|
||||
const classCount = await page
|
||||
.locator('[class*="table"], [class*="Table"], [class*="grid"], [class*="Grid"]')
|
||||
.count();
|
||||
if (classCount > 0) {
|
||||
tableFound = true;
|
||||
tableSelector = '[class*="table"]';
|
||||
pass(`테이블 발견 (class 기반, ${classCount}개)`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!tableFound) {
|
||||
fail("테이블 표시 확인", "테이블/그리드 요소를 찾을 수 없음");
|
||||
}
|
||||
|
||||
// tbody/tr 행 데이터 확인
|
||||
const rowCount = await page.locator("tbody tr, [role='row']").count();
|
||||
info(`테이블 행 수: ${rowCount}`);
|
||||
if (rowCount > 0) {
|
||||
pass(`테이블 데이터 행 확인 (${rowCount}개)`);
|
||||
} else {
|
||||
// 행이 없어도 빈 상태일 수 있으므로 경고만
|
||||
info("테이블 행이 없음 (빈 데이터 상태일 수 있음)");
|
||||
pass("테이블 표시 확인 (빈 상태도 정상)");
|
||||
}
|
||||
|
||||
// ===== 4. 컬럼 정렬 클릭 확인 =====
|
||||
const headerCells = page.locator("table th, [role='columnheader']");
|
||||
const headerCount = await headerCells.count();
|
||||
info(`헤더 셀 수: ${headerCount}`);
|
||||
|
||||
if (headerCount > 0) {
|
||||
// 첫 번째 클릭 가능한 헤더 찾기
|
||||
let clicked = false;
|
||||
for (let i = 0; i < Math.min(headerCount, 5); i++) {
|
||||
const header = headerCells.nth(i);
|
||||
try {
|
||||
await header.click({ timeout: 3000 });
|
||||
await page.waitForTimeout(1000);
|
||||
clicked = true;
|
||||
info(`헤더 ${i + 1}번째 클릭 성공`);
|
||||
break;
|
||||
} catch (e) {
|
||||
// 다음 헤더 시도
|
||||
}
|
||||
}
|
||||
|
||||
if (clicked) {
|
||||
// 클릭 후 테이블이 여전히 보이는지 확인
|
||||
const stillVisible = await page.locator("table, [role='grid']").count();
|
||||
if (stillVisible > 0) {
|
||||
pass("컬럼 정렬 클릭 후 테이블 정상 유지");
|
||||
} else {
|
||||
fail("컬럼 정렬 클릭", "클릭 후 테이블이 사라짐");
|
||||
}
|
||||
} else {
|
||||
info("클릭 가능한 헤더를 찾지 못함 (정렬 기능 없을 수 있음)");
|
||||
pass("컬럼 헤더 확인 완료 (정렬 버튼 없는 형태)");
|
||||
}
|
||||
} else {
|
||||
info("헤더 셀 없음 - 정렬 테스트 스킵");
|
||||
pass("컬럼 헤더 확인 (헤더 없는 형태)");
|
||||
}
|
||||
|
||||
// 데스크톱 스크린샷
|
||||
await page.screenshot({ path: SCREENSHOT_DESKTOP, fullPage: true });
|
||||
pass("데스크톱 스크린샷 저장");
|
||||
|
||||
// ===== 5. 375px 모바일에서 가로 스크롤 확인 =====
|
||||
await page.setViewportSize({ width: 375, height: 812 });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 스크롤 가능한 컨테이너 확인
|
||||
const scrollInfo = await page.evaluate(() => {
|
||||
// 방법 1: table의 부모 중 overflow-x: auto/scroll인 컨테이너
|
||||
const tables = document.querySelectorAll("table");
|
||||
for (const table of tables) {
|
||||
let el = table.parentElement;
|
||||
while (el && el !== document.body) {
|
||||
const style = window.getComputedStyle(el);
|
||||
const overflowX = style.overflowX;
|
||||
if (overflowX === "auto" || overflowX === "scroll") {
|
||||
return {
|
||||
found: true,
|
||||
method: "table-parent-overflow",
|
||||
scrollable: el.scrollWidth > el.clientWidth,
|
||||
scrollWidth: el.scrollWidth,
|
||||
clientWidth: el.clientWidth,
|
||||
overflowX,
|
||||
};
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
}
|
||||
|
||||
// 방법 2: overflow-x: auto/scroll인 모든 컨테이너 검색
|
||||
const allElements = document.querySelectorAll("*");
|
||||
for (const el of allElements) {
|
||||
const style = window.getComputedStyle(el);
|
||||
const overflowX = style.overflowX;
|
||||
if (overflowX === "auto" || overflowX === "scroll") {
|
||||
if (el.scrollWidth > el.clientWidth) {
|
||||
return {
|
||||
found: true,
|
||||
method: "any-overflow-element",
|
||||
scrollable: true,
|
||||
scrollWidth: el.scrollWidth,
|
||||
clientWidth: el.clientWidth,
|
||||
overflowX,
|
||||
tagName: el.tagName,
|
||||
className: el.className.substring(0, 100),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 방법 3: 테이블 자체가 너비를 초과하는지
|
||||
for (const table of tables) {
|
||||
if (table.scrollWidth > 375) {
|
||||
return {
|
||||
found: true,
|
||||
method: "table-overflow-viewport",
|
||||
scrollable: true,
|
||||
scrollWidth: table.scrollWidth,
|
||||
clientWidth: 375,
|
||||
overflowX: "table-wider-than-viewport",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
found: false,
|
||||
scrollable: false,
|
||||
method: "none",
|
||||
tableCount: tables.length,
|
||||
};
|
||||
});
|
||||
|
||||
info(`스크롤 확인: ${JSON.stringify(scrollInfo)}`);
|
||||
|
||||
if (scrollInfo.found && scrollInfo.scrollable) {
|
||||
pass(
|
||||
`모바일 375px 가로 스크롤 가능 확인 (방법: ${scrollInfo.method}, scrollWidth: ${scrollInfo.scrollWidth}, clientWidth: ${scrollInfo.clientWidth})`
|
||||
);
|
||||
} else if (scrollInfo.found && !scrollInfo.scrollable) {
|
||||
// 테이블이 375px 안에 맞는 경우 - 반응형으로 축소된 것일 수 있음
|
||||
info(
|
||||
"스크롤 컨테이너 존재하나 현재 콘텐츠가 뷰포트 안에 들어옴 (반응형 축소 또는 빈 데이터)"
|
||||
);
|
||||
// 이 경우 overflow-x가 설정되어 있으면 스크롤 기능은 있는 것으로 판단
|
||||
pass("모바일 375px 가로 스크롤 컨테이너 존재 확인 (현재 콘텐츠는 뷰포트 내에 있음)");
|
||||
} else {
|
||||
fail(
|
||||
"모바일 가로 스크롤",
|
||||
`스크롤 가능한 컨테이너 없음 (tableCount: ${scrollInfo.tableCount || 0})`
|
||||
);
|
||||
}
|
||||
|
||||
// 모바일 스크린샷
|
||||
await page.screenshot({ path: SCREENSHOT_MOBILE, fullPage: true });
|
||||
pass("모바일 스크린샷 저장");
|
||||
|
||||
} catch (err) {
|
||||
allPassed = false;
|
||||
const errMsg = `ERROR: ${err.message}`;
|
||||
results.push(errMsg);
|
||||
failReasons.push(errMsg);
|
||||
console.log(errMsg);
|
||||
await page.screenshot({ path: SCREENSHOT_MOBILE, fullPage: true }).catch(() => {});
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
console.log("\n=== 테스트 결과 ===");
|
||||
results.forEach((r) => console.log(r));
|
||||
console.log("==================\n");
|
||||
|
||||
if (allPassed) {
|
||||
console.log("BROWSER_TEST_RESULT: PASS");
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log(`BROWSER_TEST_RESULT: FAIL - ${failReasons[0] || "알 수 없는 오류"}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
runTest().catch((err) => {
|
||||
console.error("실행 오류:", err);
|
||||
console.log(`BROWSER_TEST_RESULT: FAIL - ${err.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* /screens/29 화면 렌더링 E2E 테스트
|
||||
* 실행: node scripts/run-screens-29-test.js
|
||||
*/
|
||||
const { chromium } = require("playwright");
|
||||
|
||||
const BASE_URL = "http://localhost:9771";
|
||||
const SCREENSHOT_PATH = ".agent-pipeline/browser-tests/result.png";
|
||||
|
||||
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(`PASS: ${name}`);
|
||||
}
|
||||
|
||||
function fail(name, reason) {
|
||||
allPassed = false;
|
||||
results.push(`FAIL: ${name} - ${reason}`);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
const loginUrl = page.url();
|
||||
if (loginUrl.includes("/login")) {
|
||||
fail("로그인", "/login 페이지에 머무름");
|
||||
} else {
|
||||
pass(`로그인 성공 (URL: ${loginUrl})`);
|
||||
}
|
||||
|
||||
// /screens/29 접속
|
||||
await page.goto(`${BASE_URL}/screens/29`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const screenUrl = page.url();
|
||||
results.push(`INFO: screens/29 접속 URL = ${screenUrl}`);
|
||||
|
||||
// 에러 오버레이 체크
|
||||
const hasError = await page
|
||||
.locator('[id="__next"] .nextjs-container-errors-body')
|
||||
.isVisible()
|
||||
.catch(() => false);
|
||||
if (hasError) {
|
||||
fail("에러 오버레이 확인", "에러 오버레이가 표시됨");
|
||||
} else {
|
||||
pass("에러 오버레이 없음");
|
||||
}
|
||||
|
||||
// 화면 렌더링 확인
|
||||
const bodyVisible = await page
|
||||
.locator("body")
|
||||
.isVisible({ timeout: 10000 })
|
||||
.catch(() => false);
|
||||
if (!bodyVisible) {
|
||||
fail("화면 렌더링", "body 요소가 보이지 않음");
|
||||
} else {
|
||||
pass("화면 렌더링 확인");
|
||||
}
|
||||
|
||||
// 버튼 존재 확인
|
||||
await page.waitForTimeout(2000);
|
||||
const buttonCount = await page.locator("button").count();
|
||||
if (buttonCount === 0) {
|
||||
fail("버튼 확인", "버튼이 하나도 없음");
|
||||
} else {
|
||||
pass(`버튼 ${buttonCount}개 확인`);
|
||||
}
|
||||
|
||||
// 테이블/그리드 요소 확인
|
||||
const tableCount = await page
|
||||
.locator('table, [role="grid"], [role="table"]')
|
||||
.count();
|
||||
const gridLikeCount = await page
|
||||
.locator(
|
||||
'tbody, thead, .ag-root, [class*="table"], [class*="grid"], [class*="Table"], [class*="Grid"]'
|
||||
)
|
||||
.count();
|
||||
|
||||
if (tableCount > 0) {
|
||||
pass(`테이블/그리드 ${tableCount}개 확인`);
|
||||
} else if (gridLikeCount > 0) {
|
||||
pass(`그리드 유사 요소 ${gridLikeCount}개 확인`);
|
||||
} else {
|
||||
// 스크린샷 찍고 경고 (HTML 구조 파악용)
|
||||
results.push("WARN: 표준 테이블/그리드 요소 없음 - 스크린샷으로 확인 필요");
|
||||
}
|
||||
|
||||
// 스크린샷 저장
|
||||
await page.screenshot({ path: SCREENSHOT_PATH, fullPage: true });
|
||||
pass("스크린샷 저장 완료");
|
||||
|
||||
} catch (err) {
|
||||
allPassed = false;
|
||||
results.push(`ERROR: ${err.message}`);
|
||||
await page
|
||||
.screenshot({ path: SCREENSHOT_PATH, fullPage: true })
|
||||
.catch(() => {});
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
console.log("\n=== 테스트 결과 ===");
|
||||
results.forEach((r) => console.log(r));
|
||||
console.log("==================\n");
|
||||
|
||||
if (allPassed) {
|
||||
console.log("BROWSER_TEST_RESULT: PASS");
|
||||
process.exit(0);
|
||||
} else {
|
||||
const failItems = results.filter((r) => r.startsWith("FAIL:") || r.startsWith("ERROR:"));
|
||||
console.log(`BROWSER_TEST_RESULT: FAIL - ${failItems[0] || "알 수 없는 오류"}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
runTest().catch((err) => {
|
||||
console.error("실행 오류:", err);
|
||||
console.log(`BROWSER_TEST_RESULT: FAIL - ${err.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user