/** * CDP 截屏小工具:连接正在运行的 Electron/Chromium 远程调试端口,截取页面渲染结果 * 用途:打包后无头验证渲染层 UI(登录页 logo、页面是否白屏等),无需人工肉眼确认 * 用法:node scripts/cdp-screenshot.mjs <输出png路径> * 依赖:Node 22+(内置全局 WebSocket),无需安装任何包 */ import { writeFileSync } from 'node:fs' const port = process.argv[2] || '9223' const outFile = process.argv[3] || 'screenshot.png' // 从调试端口拿到页面目标的 WebSocket 调试地址 const targets = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json() const page = targets.find((t) => t.type === 'page') if (!page) { console.error('未找到 page 类型的调试目标') process.exit(1) } const ws = new WebSocket(page.webSocketDebuggerUrl) let msgId = 0 /** 发送 CDP 命令并等待对应 id 的响应 */ function send(method, params = {}) { const id = ++msgId return new Promise((resolve, reject) => { const onMessage = (event) => { const data = JSON.parse(event.data) if (data.id === id) { ws.removeEventListener('message', onMessage) data.error ? reject(new Error(data.error.message)) : resolve(data.result) } } ws.addEventListener('message', onMessage) ws.send(JSON.stringify({ id, method, params })) }) } ws.addEventListener('open', async () => { try { // 等一帧渲染稳定后截屏 await send('Page.enable') const { data } = await send('Page.captureScreenshot', { format: 'png' }) writeFileSync(outFile, Buffer.from(data, 'base64')) console.log(`截图已保存: ${outFile}`) // 顺带收集页面控制台报错,辅助排查 const { result } = await send('Runtime.evaluate', { expression: 'document.title + " | " + location.hash', returnByValue: true, }) console.log(`页面状态: ${result.value}`) } catch (err) { console.error('CDP 操作失败:', err.message) process.exitCode = 1 } finally { ws.close() } })