#!/usr/bin/env node /** * Fully automated session-switch latency capture for OpenChamber. * * Clicks sidebar session rows with real input events and measures, per click, * how long the page takes to acknowledge the click and to show the target * session's messages. Everything between those two moments is the * "the app strains a little" feeling users report when switching sessions. * * Reported per switch, in milliseconds after the click: * - `ack`: the clicked row is highlighted as active (first visible reaction); * - `content`: the timeline shows messages that were not on screen before; * - `longestTask`: the longest main-thread task inside the switch window; * - the requests the switch triggered, so fan-out regressions are visible. * * Every session in the plan is visited twice. The first visit is usually a * cold load (network round trip); the second is a warm switch served from the * in-memory session store. Both are reported separately because they have * different budgets. */ import { mkdir, readFile, writeFile } from "node:fs/promises" import { homedir } from "node:os" import { join, resolve } from "node:path" import process from "node:process" import { CdpClient, createPageTarget, evaluateValue, launchChrome, reservePort, resolveChrome, wait } from "./perf/cdp.mjs" import { summarizeCpuProfile } from "./perf/cpu-profile.mjs" import { expandProjects, expandSessionLists } from "./perf/scenario.mjs" import { percentile, round } from "./perf/metrics.mjs" const HELP = `Usage: bun run profile:switch -- [options] Measures how long switching sessions from the sidebar takes. Options: --url OpenChamber URL (default: http://localhost:3000) --sessions Comma-separated session ids to click, in order. Every id is visited twice (cold, then warm). Default: the first 6 rows in the sidebar. --count Number of sidebar rows to use when --sessions is not given (default: 6) --settle Wait after load before clicking (default: 12) --hover Rest the pointer on the row before pressing (default: 400). Sidebar tooltips open on hover, so a click straight after the move would measure the tooltip opening instead of the switch. --gap Wait after each click before the next (default: 2500) --output Artifact directory (default: artifacts/switch-profile-