Co-Study4Grid / benchmarks /interaction_paint /cdp_pipe_driver.mjs
github-actions[bot]
Deploy 7688ef1
13d4e44
Raw
History Blame Contribute Delete
3.96 kB
// Launch a headed Chrome via --remote-debugging-pipe (CDP over stdio fds 3/4,
// NO TCP port — so the IDE's preview/live-reload can't discover and hijack it)
// and run the fluidity harness. Fully isolated + real GPU (headed on macOS).
import { spawn } from 'child_process';
import { openSync } from 'fs';
const CHROME = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const URL = process.env.URL || 'http://127.0.0.1:8901/real.html';
const EXPR = process.env.EXPR || `window.__runSuite(${+(process.env.DUR || 2500)}, ${+(process.env.REPS || 3)})`;
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const log = openSync('/tmp/cs4g_pipe_chrome.log', 'a');
const child = spawn(CHROME, [
'--user-data-dir=/tmp/cs4g-bench-pipe',
'--remote-debugging-pipe',
'--no-first-run', '--no-default-browser-check', '--no-startup-window=false',
'--disable-backgrounding-occluded-windows', '--disable-renderer-backgrounding',
'--disable-background-timer-throttling', '--disable-features=CalculateNativeWinOcclusion',
'--window-size=1500,1000', URL,
], { stdio: ['ignore', log, log, 'pipe', 'pipe'] });
const wr = child.stdio[3], rd = child.stdio[4];
let id = 0; const pending = new Map();
const events = [];
let buf = Buffer.alloc(0);
rd.on('data', (chunk) => {
buf = Buffer.concat([buf, chunk]);
let i;
while ((i = buf.indexOf(0)) !== -1) {
const msg = JSON.parse(buf.slice(0, i).toString('utf8'));
buf = buf.slice(i + 1);
if (msg.id && pending.has(msg.id)) { const { res, rej } = pending.get(msg.id); pending.delete(msg.id); msg.error ? rej(new Error(JSON.stringify(msg.error))) : res(msg.result); }
else if (msg.method) events.push(msg);
}
});
const send = (method, params = {}, sessionId) => new Promise((res, rej) => {
const mid = ++id; pending.set(mid, { res, rej });
const m = { id: mid, method, params }; if (sessionId) m.sessionId = sessionId;
wr.write(JSON.stringify(m) + '\0');
});
// Discover the page target and attach (flattened sessions).
await send('Target.setDiscoverTargets', { discover: true });
let targetId = null;
for (let i = 0; i < 80 && !targetId; i++) {
const { targetInfos } = await send('Target.getTargets');
const t = targetInfos.find(x => x.type === 'page' && /^https?:/.test(x.url));
if (t) targetId = t.targetId; else await sleep(250);
}
if (!targetId) { console.error('no page target'); child.kill(); process.exit(1); }
const { sessionId } = await send('Target.attachToTarget', { targetId, flatten: true });
const evalJs = async (expr, awaitPromise = false) => {
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise }, sessionId);
if (r.exceptionDetails) throw new Error('eval: ' + JSON.stringify(r.exceptionDetails).slice(0, 400));
return r.result.value;
};
await send('Runtime.enable', {}, sessionId);
// If the page isn't on our URL yet (fresh profile may show a default), navigate once.
const cur = await evalJs('location.href');
if (!cur.includes(URL.split('/').pop())) { await send('Page.enable', {}, sessionId); await send('Page.navigate', { url: URL }, sessionId); await sleep(2500); }
for (let i = 0; i < 80; i++) {
const ready = await evalJs(`(typeof window.__runSuite==='function' && typeof window.__runExtra==='function' && document.getElementById('out') && document.getElementById('out').textContent.startsWith('ready'))`).catch(() => false);
if (ready) break; await sleep(500);
}
const env = await evalJs(`(()=>{const gl=document.createElement('canvas').getContext('webgl');const d=gl&&gl.getExtension('WEBGL_debug_renderer_info');return {visibility:document.visibilityState,dpr:window.devicePixelRatio,gpu:d?gl.getParameter(d.UNMASKED_RENDERER_WEBGL):'n/a',svgChildren:document.querySelectorAll('#c svg *').length, url:location.href};})()`);
console.error('ENV', JSON.stringify(env));
const result = await evalJs(EXPR, true);
console.log(JSON.stringify(result));
child.kill();
process.exit(0);