ci speed: desktop boot check runs its cases in parallel (one browser, killed at the end; a page per case; condition waits instead of fixed sleeps: element, text or a quiet window of host calls and DOM); shots capture / render close the browser with a 3 s cap, then kill it; console engine waits injectable for tests (WAITS / engineWaits: poll rounds, a missing step ends once its loaded page stays quiet, team switch settle, field-miss grace), fillPage looks up each data type's dialog once per round and skips dialog sections when no dialog is open; browser tests run 4 at a time per file (testScope().concurrent with a scope per test, --max-concurrency in ci), 20 ms rounds; capture-web counts boots per test and runs its browser tests concurrently; console-session / -persist Chrome tests concurrent; recorded test timings smoothed (mergeTimings) so one loaded run does not skew the shard split

This commit is contained in:
CRTkafa 2026-10-13 02:20:03 +08:00
parent f2d7062bcb
commit 9ba8471002
16 changed files with 390 additions and 178 deletions

View file

@ -16,6 +16,11 @@ export const HEAVY = [
'tests/capture-web.test.ts', 'tests/console-session.test.ts', 'tests/console-persist.test.ts', 'tests/console-flow.test.ts',
];
/** Browser tests of one file at the same time (bun test --max-concurrency for the shards with a HEAVY file; the
* tests opt in with testScope().concurrent, tests/helpers/browser.ts): enough to overlap their waits, few enough that
* a loaded machine does not stretch each one towards its timeout. */
export const BROWSER_CONCURRENCY = 4;
/** Changes that can affect every test: run the whole suite. */
export const GLOBAL = /^(package\.json|bun\.lock|bunfig\.toml|tsconfig\.json|tests\/helpers\/preload\.ts)$/;
@ -50,6 +55,17 @@ export function writeTimings(t: Record<string, number>, file = TIMINGS): void {
try { mkdirSync(dirname(file), { recursive: true }); writeFileSync(file, `${JSON.stringify(t, null, 1)}\n`); } catch { /* cache only */ }
}
/**
* The recorded time of each file after a run: a new file takes its measurement; a known one moves halfway towards it
* and never above it. The machine is shared, so one run under heavy load (other sessions' CI, cargo) must not make a
* file look several times slower for the next split, while a file that really got faster or slower still converges.
*/
export function mergeTimings(old: Record<string, number>, fresh: Record<string, number>): Record<string, number> {
const out = { ...old };
for (const [f, t] of Object.entries(fresh)) out[f] = old[f] === undefined ? t : Math.min(t, (old[f]! + t) / 2);
return out;
}
/** Per-file seconds from bun's JUnit report (the top-level <testsuite> of each file). */
export function junitTimes(xml: string): Record<string, number> {
const out: Record<string, number> = {};