import { WebSocket } from 'ws'; import http from 'http'; const CDP_HOST = 'localhost'; const CDP_PORT = 9222; function httpRequest(method, path) { return new Promise((resolve, reject) => { const req = http.request({ hostname: CDP_HOST, port: CDP_PORT, method, path }, (res) => { let data = ''; res.on('data', (c) => data += c); res.on('end', () => { try { resolve(JSON.parse(data)); } catch(e) { resolve(data); } }); }); req.on('error', reject); req.end(); }); } function cdpCommand(ws, method, params = {}) { const id = Math.floor(Math.random() * 1000000); return new Promise((resolve) => { const handler = (raw) => { try { const msg = JSON.parse(raw.toString()); if (msg.id === id) { ws.off('message', handler); resolve(msg.result || msg); } } catch {} }; ws.on('message', handler); ws.send(JSON.stringify({ id, method, params })); setTimeout(() => { ws.off('message', handler); resolve({ error: 'timeout' }); }, 8000); }); } async function main() { console.log('[1] Creating new tab...'); const newTab = await httpRequest('PUT', '/json/new?about:blank'); console.log(' New tab:', newTab.id, '| WS:', newTab.webSocketDebuggerUrl?.substring(0, 50) + '...'); const ws = new WebSocket(newTab.webSocketDebuggerUrl); await new Promise((resolve) => ws.on('open', resolve)); console.log('[2] CDP connected.'); await cdpCommand(ws, 'Runtime.enable'); await cdpCommand(ws, 'Page.enable'); await cdpCommand(ws, 'Log.enable'); const consoleMessages = []; const errors = []; ws.on('message', (raw) => { try { const msg = JSON.parse(raw.toString()); if (msg.method === 'Runtime.consoleAPICalled') { const p = msg.params; const text = p.args?.map(a => a.value || a.description || '').join(' ') || ''; consoleMessages.push(`[${p.type}] ${text}`); console.log(` CONSOLE [${p.type}]: ${text.substring(0, 200)}`); } if (msg.method === 'Runtime.exceptionThrown') { const ed = msg.params.exceptionDetails; const text = ed.text || ed.exception?.description || JSON.stringify(ed).substring(0, 300); errors.push(text); console.log(` EXCEPTION: ${text.substring(0, 300)}`); if (ed.stackTrace) { ed.stackTrace.callFrames?.forEach((f) => { console.log(` at ${f.functionName || '(anonymous)'} (${f.url}:${f.lineNumber}:${f.columnNumber})`); }); } } if (msg.method === 'Log.entryAdded') { const entry = msg.params.entry; const text = entry.text?.substring(0, 200) || ''; console.log(` LOG [${entry.level}]: ${text}`); if (entry.level === 'error') { errors.push(`[LOG:${entry.level}] ${text}`); consoleMessages.push(`[LOG:${entry.level}] ${text}`); } } } catch {} }); console.log('[3] Navigating to http://localhost:5199/ ...'); await cdpCommand(ws, 'Page.navigate', { url: 'http://localhost:5199/' }); console.log('[4] Waiting 8s for page load...'); await new Promise(r => setTimeout(r, 8000)); console.log('[5] Checking DOM...'); const docNode = await cdpCommand(ws, 'DOM.getDocument', { depth: 2 }); if (docNode && docNode.root) { console.log(' Root:', docNode.root.nodeName, 'children:', docNode.root.childNodeCount); } // Evaluate #root content try { const e1 = await cdpCommand(ws, 'Runtime.evaluate', { expression: ` (() => { const root = document.getElementById('root'); if (!root) return 'NO_ROOT_ELEMENT'; const html = root.innerHTML.trim(); if (!html) return 'ROOT_EMPTY'; return 'ROOT_CONTENT(len=' + html.length + '): ' + html.substring(0, 500); })() `, returnByValue: true, }); console.log(' #root:', e1?.result?.value || JSON.stringify(e1).substring(0, 300)); } catch(e) { console.log(' Eval error:', e.message); } // Check body try { const e2 = await cdpCommand(ws, 'Runtime.evaluate', { expression: `document.body ? document.body.children.length + ' body children, innerHTML len=' + document.body.innerHTML.length : 'NO_BODY'`, returnByValue: true, }); console.log(' body:', e2?.result?.value); } catch(e) {} // Check document title try { const e3 = await cdpCommand(ws, 'Runtime.evaluate', { expression: `document.title`, returnByValue: true, }); console.log(' title:', e3?.result?.value); } catch(e) {} ws.close(); console.log('\n=== SUMMARY ==='); console.log('Console messages:', consoleMessages.length); consoleMessages.slice(0, 15).forEach(m => console.log(' ', m.substring(0, 200))); console.log('Errors:', errors.length); errors.forEach((e, i) => console.log(` ERR${i+1}: ${e.substring(0, 500)}`)); } main().catch(e => { console.error('Fatal:', e.message); process.exit(1); });