Validation server: HTTP Range support, bounded settle, crash-proof reporting

- serveStatic answers single-range requests with proper 206/Content-Range
  (416 for unsatisfiable), so Chromium streams large media in bounded
  chunks instead of holding one throttled progressive request open past
  the navigation budget
- goto policy: waitUntil "load" + up to 10s of sustained-quiet polling
  replaces the hard networkidle timeout - long autoplaying media can no
  longer make validation unreachable (applied to renderApp, probe widths,
  and the interaction gate)
- validateRun catches render crashes and records them as runtime errors,
  so a failed render writes a report with a failed gate 0 instead of
  crashing reportless

292 tests pass (14 new), typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samraaj Bath
2026-07-04 01:26:22 -07:00
co-authored by Claude Fable 5
parent b445b62a69
commit 23505ee229
4 changed files with 249 additions and 4 deletions
+7
View File
@@ -122,6 +122,13 @@ export async function validateRun(runDir: string, opts?: { harnessDir?: string;
motionGate = await driveMotionGate({ url: server.url + "/", viewports, ir, motion: capture.motion });
log({ event: "motion_gate", pass: motionGate.pass, metrics: motionGate.metrics });
}
} catch (e) {
// A render crash (e.g. a page.goto timeout on trickling media, or a Playwright fault)
// must NOT escape reportless — otherwise validation/ stays empty and the run looks
// un-validated. Record the error as a runtime error so httpStatus stays 0, gate 0 fails
// with a visible issue, and the normal downstream path writes report.json as usual.
runtimeErrors.push(`render error: ${e instanceof Error ? e.message : String(e)}`);
log({ event: "render_error", error: e instanceof Error ? e.message : String(e) });
} finally {
await server.close();
}