// Drive headless Edge on the LOCAL test server's chat host (chat.localhost:8080). import fs from 'node:fs'; const [, , outPrefix, ...steps] = process.argv; const list = await (await fetch('http://127.0.0.1:9333/json')).json(); const page = list.find(t => t.type === 'page'); const ws = new WebSocket(page.webSocketDebuggerUrl); await new Promise(r => ws.onopen = r); let id = 0; const pend = {}; const logs = []; ws.onmessage = ev => { const m = JSON.parse(ev.data); if (m.id && pend[m.id]) { pend[m.id](m.result || m.error); delete pend[m.id]; } if (m.method === 'Runtime.exceptionThrown') logs.push('EXC: ' + JSON.stringify(m.params.exceptionDetails.exception?.description || m.params.exceptionDetails.text)); if (m.method === 'Runtime.consoleAPICalled' && ['error'].includes(m.params.type)) logs.push(m.params.type + ': ' + m.params.args.map(a => a.value ?? a.description).join(' ')); if (m.method === 'Page.javascriptDialogOpening') { logs.push('DIALOG: ' + m.params.message); send('Page.handleJavaScriptDialog', { accept: true }); } }; const send = (method, params = {}) => new Promise(r => { const i = ++id; pend[i] = r; ws.send(JSON.stringify({ id: i, method, params })); }); const sleep = ms => new Promise(r => setTimeout(r, ms)); const ev = async expr => (await send('Runtime.evaluate', { expression: expr, awaitPromise: true, returnByValue: true })).result?.value; await send('Runtime.enable'); await send('Page.enable'); await send('Emulation.setDeviceMetricsOverride', { width: Number(process.env.W || 1100), height: Number(process.env.H || 800), deviceScaleFactor: 1, mobile: false }); await send('Page.navigate', { url: 'http://chat.localhost:8080/' }); await sleep(2000); console.log('login:', await ev(`fetch('/chat/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:'testpw123'})}).then(r=>r.status)`)); await send('Page.navigate', { url: 'http://chat.localhost:8080/' }); await sleep(2500); for (const step of steps.join(' ').split('||')) { const s = step.trim(); if (!s) continue; if (s.startsWith('wait:')) { await sleep(Number(s.slice(5))); continue; } if (s.startsWith('shot:')) { const img = await send('Page.captureScreenshot', { format: 'png' }); const f = `${outPrefix}-${s.slice(5)}.png`; fs.writeFileSync(f, Buffer.from(img.data, 'base64')); console.log('saved', f); continue; } console.log('eval:', JSON.stringify(await ev(s))); } console.log('console problems:', logs.length ? logs : 'none'); ws.close();