- 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>
107 lines
3.8 KiB
JavaScript
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);
|
|
})();
|