/** * 通过 CDP 读取运行中的 Electron 页面:文本、节点数量与控制台错误。 * 用法:node scripts/cdp-probe.mjs [expression] */ const endpoint = process.env.CDP_ENDPOINT || "http://127.0.0.1:9223"; const targets = await (await fetch(`${endpoint}/json/list`)).json(); const page = targets.find((item) => item.type === "page"); if (!page) throw new Error("no page target"); const ws = new WebSocket(page.webSocketDebuggerUrl); const pending = new Map(); const events = []; let seq = 0; function send(method, params = {}) { return new Promise((resolve, reject) => { const id = ++seq; pending.set(id, { resolve, reject }); ws.send(JSON.stringify({ id, method, params })); }); } await new Promise((resolve, reject) => { ws.onopen = resolve; ws.onerror = reject; }); ws.onmessage = (event) => { const message = JSON.parse(event.data); if (message.id && pending.has(message.id)) { const { resolve, reject } = pending.get(message.id); pending.delete(message.id); if (message.error) reject(new Error(JSON.stringify(message.error))); else resolve(message.result); } else { events.push(message); } }; await send("Runtime.enable"); await send("Log.enable"); const expression = process.argv[2] || "document.body.innerText.slice(0, 6000)"; const result = await send("Runtime.evaluate", { expression, returnByValue: true, awaitPromise: true }); console.log("=== result ==="); console.log(JSON.stringify(result.result?.value ?? result, null, 2)); const errors = events.filter( (item) => item.method === "Runtime.exceptionThrown" || (item.method === "Log.entryAdded" && ["error", "warning"].includes(item.params?.entry?.level)) ); console.log("\n=== errors/warnings ==="); console.log(JSON.stringify(errors.map((item) => item.params), null, 2).slice(0, 6000)); ws.close();