// 实测:点击右下角「设置」Tab -> 设置抽屉是否弹出 const { spawn } = require('child_process'); const fs = require('fs'); const CHROME = '/usr/bin/chromium'; const OUT_DIR = __dirname; const URL = 'http://127.0.0.1:9522/index.html'; const chrome = spawn(CHROME, [ '--headless=new','--no-sandbox','--disable-gpu','--disable-dev-shm-usage', '--remote-debugging-port=9226', `--user-data-dir=${OUT_DIR}/.chrome-test2`, '--window-size=420,900','about:blank' ], { stdio: ['ignore','ignore','pipe'] }); const stderr = []; chrome.stderr.on('data', d => stderr.push(d.toString())); const sleep = ms => new Promise(r => setTimeout(r, ms)); async function getWsUrl() { for (let i = 0; i < 40; i++) { try { const tabs = await (await fetch('http://127.0.0.1:9226/json/list')).json(); if (tabs.length) return tabs[0].webSocketDebuggerUrl; } catch (e) {} await sleep(250); } throw new Error('CDP 连接失败: ' + stderr.join('').slice(-400)); } (async () => { try { const wsUrl = await getWsUrl(); const ws = new WebSocket(wsUrl); let id = 0; const pending = new Map(); const logs = []; let openRes; const openP = new Promise(r => openRes = r); ws.onopen = openRes; ws.onmessage = ev => { const m = JSON.parse(ev.data); if (m.id && pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id); } else if (m.method === 'Runtime.consoleAPICalled') logs.push('C ' + (m.params.args||[]).map(a=>a.value??a.description??'').join(' ')); else if (m.method === 'Runtime.exceptionThrown') logs.push('EXC ' + JSON.stringify(m.params.exceptionDetails)); }; await openP; const send = (method, params={}) => new Promise(res => { const mid=++id; pending.set(mid,res); ws.send(JSON.stringify({id:mid,method,params})); }); const ev = async (expr) => { const r = await send('Runtime.evaluate', { expression: expr, awaitPromise: true, returnByValue: true }); if (r.result && r.result.exceptionDetails) return { __err: JSON.stringify(r.result.exceptionDetails) }; return r.result && r.result.result && r.result.result.value; }; await send('Runtime.enable'); await send('Page.enable'); await send('Page.navigate', { url: URL }); await sleep(2200); // 定位底部 tab 按钮(文字为「设置」的