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:'home', url:'/', label:'홈' }, { name:'guardia', url:'/solution/guardia', label:'GUARDiA ITSM' }, { name:'solution_erp', url:'/solution/erp', label:'솔루션-ERP' }, { name:'solution_crm', url:'/solution/crm', label:'솔루션-CRM' }, { name:'solution_bi', url:'/solution/bi', label:'솔루션-BI' }, { name:'company_greeting', url:'/company/greeting', label:'회사-CEO인사말' }, { name:'company_history', url:'/company/history', label:'회사-연혁' }, { name:'company_org', url:'/company/organization', label:'회사-조직도' }, { name:'company_ci', url:'/company/ci', label:'회사-CI소개' }, { name:'company_location', url:'/company/location', label:'회사-오시는길' }, { name:'business_ref', url:'/business/reference', label:'사업-레퍼런스' }, { name:'business_partner', url:'/business/partner', label:'사업-파트너' }, { name:'support_notice', url:'/support/notice', label:'지원-공지사항' }, { name:'support_faq', url:'/support/faq', label:'지원-FAQ' }, { name:'support_catalog', url:'/support/catalog', label:'지원-카탈로그' }, { name:'support_contact', url:'/support/contact', label:'지원-문의하기' }, { name:'recruit_jobs', url:'/recruit/jobs', label:'채용-공고' }, { name:'recruit_welfare', url:'/recruit/welfare', label:'채용-복리후생' }, { name:'recruit_apply', url:'/recruit/apply', label:'채용-지원하기' }, { name:'news_newsroom', url:'/news/newsroom', label:'뉴스-뉴스룸' }, { name:'news_blog', url:'/news/blog', label:'뉴스-블로그' }, ]; (async () => { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport:{ width:1440, height:900 }, locale:'ko-KR' }); const results = []; for (const pg of PAGES) { const page = await context.newPage(); const errors = []; page.on('pageerror', e => errors.push(e.message)); const t0 = Date.now(); try { const resp = await page.goto(BASE + pg.url, { waitUntil:'networkidle', timeout:15000 }); await page.waitForSelector('#root > *', { timeout:5000 }).catch(() => {}); const loadMs = Date.now() - t0; await page.screenshot({ path: path.join(OUT, pg.name + '.png'), fullPage:false }); const title = await page.title(); const h1 = await page.$eval('h1', el => el.textContent).catch(() => ''); results.push({ page:pg.label, url:pg.url, http:resp?.status(), loadMs, title, h1:h1.trim(), errors:errors.length, ok:true }); const icon = errors.length ? '⚠️' : '✅'; console.log(`${icon} ${pg.label.padEnd(20)} HTTP${resp?.status()} ${loadMs}ms H1:"${h1.trim().slice(0,30)}"`); } catch(e) { results.push({ page:pg.label, url:pg.url, ok:false, error:e.message.slice(0,80) }); console.log(`❌ ${pg.label.padEnd(20)} FAIL: ${e.message.slice(0,60)}`); } await page.close(); } await browser.close(); const pass = results.filter(r => r.ok).length; const fail = results.filter(r => !r.ok).length; console.log(`\n${'='.repeat(50)}`); console.log(`결과: ${pass}/${results.length} 통과 ${fail > 0 ? `(실패 ${fail}건)` : '— 전체 통과 🎉'}`); fs.writeFileSync(path.join(OUT, 'all-pages-result.json'), JSON.stringify(results, null, 2)); })();