Setting the file. One moment. Start Capture · Browser Trace · browserbase/skills · Skills Docs(opens in a new tab)
scripts/start-capture.mjs
JavaScript·82 lines·3 KB
{ spawn }
from
'node:child_process'
;
14import { fileURLToPath } from 'node:url';
15
16import {
17 runDir, ensureDir, isoUtcSeconds, isAlive, sleepMs, writeJson,
18} from './lib.mjs';
19
20const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
22const [target, runIdArg, intervalArg] = process.argv.slice(2);
23if (!target) {
24 console.error('usage: start-capture.mjs <port|ws-url> [run-id] [interval-seconds]');
25 process.exit(2);
26}
27
28const runId = runIdArg || isoUtcSeconds().replace(/[-:]/g, '');
29const interval = Number(intervalArg) || 2;
30const domainsList = (process.env.O11Y_DOMAINS || 'Network Console Runtime Log Page').trim().split(/\s+/);
31const domainArgs = domainsList.flatMap(d => ['--domain', d]);
32
33const RD = runDir(runId);
34ensureDir(path.join(RD, 'cdp'));
35ensureDir(path.join(RD, 'screenshots'));
36ensureDir(path.join(RD, 'dom'));
37
38writeJson(path.join(RD, 'manifest.json'), {
39 run_id: runId,
40 target,
41 domains: domainsList.join(' '),
42 interval_seconds: interval,
43 started_at: isoUtcSeconds(),
44});
45
46// Spawn the CDP firehose in the background. Detach + unref so it survives this
47// process exiting. browse cdp writes one JSON object per line to stdout.
48const rawFd = fs.openSync(path.join(RD, 'cdp', 'raw.ndjson'), 'w');
49const errFd = fs.openSync(path.join(RD, 'cdp', 'stderr.log'), 'w');
50const cdp = spawn('browse', ['cdp', target, ...domainArgs], {
51 detached: true,
52 stdio: ['ignore', rawFd, errFd],
53});
54cdp.unref();
55fs.writeFileSync(path.join(RD, '.cdp.pid'), String(cdp.pid));
56
57// Spawn the periodic screenshot/DOM/url sampler (separate process so it can
58// be SIGTERM'd independently from the CDP stream).
59const loopFd = fs.openSync(path.join(RD, 'snapshot-loop.log'), 'w');
60const loopScript = path.join(__dirname, 'snapshot-loop.mjs');
61const loop = spawn(process.execPath, [loopScript, target, RD, String(interval)], {
62 detached: true,
63 stdio: ['ignore', loopFd, loopFd],
64});
65loop.unref();
66fs.writeFileSync(path.join(RD, '.loop.pid'), String(loop.pid));
67
68// Give browse cdp a beat to fail loudly on bad targets so the user sees the
69// real error instead of a silent zero-event capture.
70await sleepMs(1000);
71if (!isAlive(cdp.pid)) {
72 console.error(`browse cdp exited immediately — check ${RD}/cdp/stderr.log`);
73 try { console.error(fs.readFileSync(path.join(RD, 'cdp', 'stderr.log'), 'utf8')); } catch {}
74 try { process.kill(loop.pid); } catch {}
75 process.exit(1);
76}
77
78console.log(`run_id=${runId}`);
79console.log(`run_dir=${RD}`);
80console.log(`target=${target}`);
81console.log(`cdp_pid=${cdp.pid}`);
82console.log(`loop_pid=${loop.pid}`);