// Capture screenshots of the OA replica for manual review (saved as PNGs). import { spawn } from 'node:child_process' import { mkdtemp, readFile, rm, writeFile, mkdir } from 'node:fs/promises' import os from 'node:os' import path from 'node:path' import { setTimeout as delay } from 'node:timers/promises' const CHROME = process.env.CHROME_BIN || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' const BASE = process.env.OA_BASE || 'http://localhost:8080/modern/app/' const OUTDIR = '/Users/qiu/Desktop/ERP/ofbiz-framework/plugins/modern-ui/verification/oa-shots' const SHOTS = [ ['portal', '#/oa'], ['collab-todo', '#/oa/collab/todo'], ['collab-create', '#/oa/collab/create'], ['collab-center', '#/oa/collab/center'], ['meeting-mine', '#/oa/meeting/mine'], ['meeting-room', '#/oa/meeting/room'], ['goal-project', '#/oa/goal/project'], ['knowledge-doccenter', '#/oa/knowledge/doccenter'], ['hr-staff', '#/oa/hr/staff'], ['hr-org', '#/oa/hr/org'], ['culture-notice', '#/oa/culture/notice'], ['report-analysis', '#/oa/report/analysis'], ['contacts', '#/oa/contacts'] ] await mkdir(OUTDIR, { recursive: true }) const profile = await mkdtemp(path.join(os.tmpdir(), 'oashots.')) const chrome = spawn(CHROME, ['--headless=new', '--disable-gpu', '--no-first-run', '--remote-debugging-port=0', '--window-size=1440,900', `--user-data-dir=${profile}`, 'about:blank'], { stdio: ['ignore', 'ignore', 'pipe'] }) let port = '' const dl = Date.now() + 15000 while (Date.now() < dl && !port) { try { port = (await readFile(path.join(profile, 'DevToolsActivePort'), 'utf8')).trim().split('\n')[0] } catch { await delay(150) } } const targets = await fetch(`http://127.0.0.1:${port}/json/list`).then((r) => r.json()) const ws = new WebSocket(targets.find((t) => t.type === 'page' && t.webSocketDebuggerUrl).webSocketDebuggerUrl) await new Promise((res) => ws.addEventListener('open', res, { once: true })) let id = 0 const pending = new Map() ws.addEventListener('message', (e) => { const m = JSON.parse(e.data); if (m.id && pending.has(m.id)) { pending.get(m.id)(m.result); pending.delete(m.id) } }) const cmd = (method, params = {}) => new Promise((res) => { const i = ++id; pending.set(i, res); ws.send(JSON.stringify({ id: i, method, params })) }) await cmd('Page.enable') await cmd('Emulation.setDeviceMetricsOverride', { width: 1440, height: 900, deviceScaleFactor: 1, mobile: false }) for (const [name, route] of SHOTS) { await cmd('Page.navigate', { url: BASE + route }) await delay(1900) const shot = await cmd('Page.captureScreenshot', { format: 'png' }) if (shot?.data) { await writeFile(path.join(OUTDIR, `${name}.png`), Buffer.from(shot.data, 'base64')); console.log('saved', name) } else console.log('FAILED', name) } ws.close(); chrome.kill('SIGTERM'); await delay(300); await rm(profile, { recursive: true, force: true }) console.log('OUTDIR', OUTDIR) process.exit(0)