zioinfo-web/test-homepage.js
DESKTOP-TKLFCPRython 1e98f0d04a refactor: 101.79.17.164 → zioinfo.co.kr 전체 도메인 변환 + Manager UI 배포
- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스)
- Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포
- 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:09:17 +09:00

107 lines
3.8 KiB
JavaScript

const { chromium } = require('playwright');
const path = require('path');
const fs = require('fs');
const BASE = 'http://localhost:3000';
const OUT = path.join(__dirname, 'frontend/public/screenshots');
if (!fs.existsSync(OUT)) fs.mkdirSync(OUT, { recursive: true });
const PAGES = [
{ name: '01_home', url: '/', label: '홈' },
{ name: '02_guardia', url: '/solution/guardia', label: 'GUARDiA 소개' },
{ name: '03_company', url: '/company/greeting', label: '회사소개' },
{ name: '04_contact', url: '/support/contact', label: '문의하기' },
{ name: '05_news', url: '/news/press', label: '뉴스' },
];
const RESULTS = [];
(async () => {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
locale: 'ko-KR',
});
for (const pg of PAGES) {
const page = await context.newPage();
const errors = [];
page.on('console', msg => { if (msg.type() === 'error') errors.push(msg.text()); });
page.on('pageerror', err => errors.push(err.message));
const t0 = Date.now();
let status = 'OK';
try {
const resp = await page.goto(BASE + pg.url, { waitUntil: 'networkidle', timeout: 15000 });
const loadTime = Date.now() - t0;
// 메인 컨텐츠 대기
await page.waitForSelector('#root > *', { timeout: 5000 }).catch(() => {});
// 풀페이지 스크린샷
const ssPath = path.join(OUT, pg.name + '.png');
await page.screenshot({ path: ssPath, fullPage: true });
// 뷰포트 스크린샷 (Above-the-fold)
const vpPath = path.join(OUT, pg.name + '_viewport.png');
await page.screenshot({ path: vpPath, fullPage: false });
// 타이틀, 링크 수 확인
const title = await page.title();
const links = await page.$$eval('a[href]', els => els.length);
const images = await page.$$eval('img', els => els.length);
const h1Count = await page.$$eval('h1', els => els.length);
RESULTS.push({
page: pg.label,
url: pg.url,
status: resp ? resp.status() : 'err',
loadMs: loadTime,
title,
links,
images,
h1: h1Count,
errors: errors.length,
errorMsgs: errors.slice(0, 3),
screenshot: ssPath,
});
console.log(`[OK] ${pg.label} (${loadTime}ms) — title: "${title}" links:${links} imgs:${images}`);
} catch (e) {
status = 'FAIL';
RESULTS.push({ page: pg.label, url: pg.url, status: 'FAIL', error: e.message });
console.error(`[FAIL] ${pg.label}: ${e.message}`);
}
await page.close();
}
// 모바일 홈 스크린샷
const mobilePage = await context.newPage();
await mobilePage.setViewportSize({ width: 390, height: 844 });
await mobilePage.goto(BASE + '/', { waitUntil: 'networkidle', timeout: 15000 }).catch(() => {});
await mobilePage.screenshot({ path: path.join(OUT, '06_mobile_home.png'), fullPage: false });
await mobilePage.close();
console.log('[OK] 모바일 홈 스크린샷 완료');
await browser.close();
// 결과 출력
console.log('\n=== 테스트 결과 요약 ===');
const passed = RESULTS.filter(r => r.status !== 'FAIL').length;
console.log(`통과: ${passed}/${RESULTS.length}`);
RESULTS.forEach(r => {
if (r.status === 'FAIL') {
console.log(` FAIL ${r.page}: ${r.error}`);
} else {
const warn = r.errors > 0 ? ` [콘솔오류 ${r.errors}개]` : '';
console.log(` PASS ${r.page} HTTP${r.status} ${r.loadMs}ms${warn}`);
}
});
// JSON 저장
fs.writeFileSync(path.join(OUT, 'test-result.json'), JSON.stringify(RESULTS, null, 2));
console.log(`\n스크린샷 저장 위치: ${OUT}`);
process.exit(passed === RESULTS.length ? 0 : 1);
})();