Confirmed render-tick flushing for E2E detectors (#1651).
A detector that only sees a bug on the Nth draw needs those draws to have
HAPPENED. waitForNextRender(page, N) in helpers.ts is documented as
best-effort and its fallback is silent, so a caller cannot tell a confirmed
flush from a fallback. flushRenderTicks kicks the renderer and
confirms each tick against the renderer's own frame counter, then
reportFlushVerdict decides — from evidence, not from the tick count —
whether a flush that confirmed NOTHING is worth failing the run over.
This lives in its own module rather than in helpers.ts so it can be
unit-tested without a browser: the only page surface it touches is
page.evaluate and page.waitForFunction, both easy to fake (see
src/tests/unit/tests/e2e-render-ticks.test.ts).
KNOWN LIMITATION (WebGPU backend). The counter probe reads
info.render.frame and falls back to info.frame. WebGPURenderer has no
info.render.frame, so on that backend the fallback is what answers — and
THREE assigns info.frame from its OWN internal animation loop, which
advances whether or not anything was drawn. A "confirmed" tick is therefore
weaker there than on WebGL (where info.render.frame counts actual
renderer.render() calls), and N ticks is roughly N animation frames rather
than the ~N/2 the WebGL two-pass pipeline gives. Not fixed here — stated so a
reader does not over-read a WebGPU flush report.
Confirmed render-tick flushing for E2E detectors (#1651).
A detector that only sees a bug on the Nth draw needs those draws to have HAPPENED.
waitForNextRender(page, N)inhelpers.tsis documented as best-effort and its fallback is silent, so a caller cannot tell a confirmed flush from a fallback. flushRenderTicks kicks the renderer and confirms each tick against the renderer's own frame counter, then reportFlushVerdict decides — from evidence, not from the tick count — whether a flush that confirmed NOTHING is worth failing the run over.This lives in its own module rather than in
helpers.tsso it can be unit-tested without a browser: the only page surface it touches ispage.evaluateandpage.waitForFunction, both easy to fake (seesrc/tests/unit/tests/e2e-render-ticks.test.ts).KNOWN LIMITATION (WebGPU backend). The counter probe reads
info.render.frameand falls back toinfo.frame.WebGPURendererhas noinfo.render.frame, so on that backend the fallback is what answers — and THREE assignsinfo.framefrom its OWN internal animation loop, which advances whether or not anything was drawn. A "confirmed" tick is therefore weaker there than on WebGL (whereinfo.render.framecounts actualrenderer.render()calls), and N ticks is roughly N animation frames rather than the ~N/2 the WebGL two-pass pipeline gives. Not fixed here — stated so a reader does not over-read a WebGPU flush report.