import { chromium } from 'playwright'; import fs from 'fs'; const OUT = 'C:/GUARDiA/workspace/zioinfo-web/frontend/public/screenshots'; fs.mkdirSync(OUT, { recursive: true }); const log = (...a) => console.log('[capture]', ...a); async function run() { const browser = await chromium.launch({ headless: true, args: ['--ignore-certificate-errors'] }); const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1440, height: 900 } }); const page = await ctx.newPage(); const results = []; async function shot(name) { try { await page.waitForTimeout(2500); await page.screenshot({ path: `${OUT}/${name}.png`, fullPage: false }); log('OK', name); results.push({ name, ok: true }); } catch (e) { log('FAIL shot', name, e.message); results.push({ name, ok: false, err: e.message }); } } // ── ITSM ── try { await page.goto('https://itsm.zioinfo.co.kr', { waitUntil: 'networkidle', timeout: 30000 }); await page.waitForTimeout(1500); // try login try { const userSel = 'input[type="text"], input[name="username"], input[id*="user"], input[placeholder*="아이디"], input[placeholder*="ID"]'; const passSel = 'input[type="password"]'; if (await page.locator(passSel).count()) { await page.locator(userSel).first().fill('admin'); await page.locator(passSel).first().fill('1111'); await shot('cap_itsm_login'); const btn = page.locator('button[type="submit"], button:has-text("로그인"), button:has-text("Login")').first(); await btn.click(); await page.waitForTimeout(4000); } } catch (e) { log('itsm login skip', e.message); } await shot('cap_itsm_dashboard'); // SR list for (const path of ['/sr', '/tasks', '/#/sr', '/#/tasks']) { try { await page.goto('https://itsm.zioinfo.co.kr' + path, { waitUntil: 'networkidle', timeout: 15000 }); break; } catch {} } await shot('cap_itsm_sr'); // CMDB for (const path of ['/cmdb', '/servers', '/#/cmdb', '/#/servers']) { try { await page.goto('https://itsm.zioinfo.co.kr' + path, { waitUntil: 'networkidle', timeout: 15000 }); break; } catch {} } await shot('cap_itsm_cmdb'); // anomaly / AI for (const path of ['/anomaly', '/ai', '/#/anomaly', '/#/ai-insights']) { try { await page.goto('https://itsm.zioinfo.co.kr' + path, { waitUntil: 'networkidle', timeout: 15000 }); break; } catch {} } await shot('cap_itsm_anomaly'); } catch (e) { log('ITSM block fail', e.message); } // ── Manager ── try { const mctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1440, height: 900 } }); const mpage = await mctx.newPage(); await mpage.goto('https://manager.zioinfo.co.kr', { waitUntil: 'networkidle', timeout: 30000 }); await mpage.waitForTimeout(1500); try { const passSel = 'input[type="password"]'; if (await mpage.locator(passSel).count()) { const userSel = 'input[type="text"], input[name="username"], input[placeholder*="아이디"], input[placeholder*="ID"]'; await mpage.locator(userSel).first().fill('admin'); await mpage.locator(passSel).first().fill('Admin@zioinfo2026!'); const btn = mpage.locator('button[type="submit"], button:has-text("로그인"), button:has-text("Login")').first(); await btn.click(); await mpage.waitForTimeout(4000); } } catch (e) { log('manager login skip', e.message); } await mpage.waitForTimeout(2500); await mpage.screenshot({ path: `${OUT}/cap_manager_dashboard.png` }); log('OK cap_manager_dashboard'); results.push({ name: 'cap_manager_dashboard', ok: true }); } catch (e) { log('Manager block fail', e.message); results.push({ name: 'cap_manager_dashboard', ok: false, err: e.message }); } fs.writeFileSync(`${OUT}/cap_result.json`, JSON.stringify(results, null, 2)); await browser.close(); log('DONE'); } run().catch(e => { console.error('FATAL', e); process.exit(1); });