Wait until a predicate over accumulated WebGL errors returns true.
getWebGLErrorsdrains the GL queue on each call, so this helper
accumulates errors across polls into a closure-local buffer and tests the
predicate against the union. Use for "wait until at least one error of type
X appears" patterns. For the inverse ("there should be no errors"), use
waitForRenderStable then a single getWebGLErrors read.
Each read is bounded by whatever is left of timeout, no FURTHER read is
dispatched into a remainder smaller than one pollMs, and a read that consumed
the whole remainder is not followed by one more pollMs sleep past the deadline
(#1726). getWebGLErrors
is a bare page.evaluate, which has no timeout of its own, so the FIRST
unanswered read used to blow straight through this budget to the whole test's.
The helper does not throw on GIVE-UP — it returns data, and an empty result is a
legitimate one — and a give-up emits one console.warn saying whether any read
answered at all, so an unsatisfied predicate cannot be mistaken for "the page
was healthy and produced no such error". It is not throw-free, though: a read
that REJECTS propagates (a closed page, a destroyed execution context, an
in-page throw out of getWebGLErrors), as does the trailing
page.waitForTimeout on a page that goes away mid-poll.
Enforcing the budget has a cost worth stating plainly: getWebGLErrors DRAINS
the GL queue in-page, so an answer arriving after the deadline is discarded
along with whatever real errors it already cleared, and a later read in the
same spec then sees a clean queue. That is what a budget means for a helper
that returns data; the proper fix is bounding getWebGLErrors itself — the
same treatment #1651 gave getLuxarState and getConsoleMessages — which
reaches 21 direct call sites across 11 spec files and is left out of scope
here rather than tracked anywhere, #1651 being closed. Not dispatching a
FURTHER read into a sliver of
budget it cannot answer within keeps the tail case out of that trap; the FIRST
read is exempt from that skip, so any POSITIVE budget — however short — still
gets one tightly-bounded read, rather than returning [] without having read the
GL queue even once, which would be the very silence this helper's warn exists to
prevent. That exemption is also the one case where the call can outlast its
budget: with timeout under pollMs the first read may answer early and is then
followed by a full pollMs before the loop guard re-checks, so a 50 ms budget can
report ~100 ms. A NON-POSITIVE timeout gets zero reads: the loop guard fails on
entry, and the warn then says nothing was checked, which is exactly true.
Documented rather than special-cased, since no caller asks for a zero budget.
Unit-tested in src/tests/unit/tests/e2e-helpers-silent-waits.test.ts.
Wait until a predicate over accumulated WebGL errors returns true.
getWebGLErrorsdrains the GL queue on each call, so this helper accumulates errors across polls into a closure-local buffer and tests the predicate against the union. Use for "wait until at least one error of type X appears" patterns. For the inverse ("there should be no errors"), usewaitForRenderStablethen a singlegetWebGLErrorsread.Each read is bounded by whatever is left of
timeout, no FURTHER read is dispatched into a remainder smaller than onepollMs, and a read that consumed the whole remainder is not followed by one morepollMssleep past the deadline (#1726).getWebGLErrorsis a barepage.evaluate, which has no timeout of its own, so the FIRST unanswered read used to blow straight through this budget to the whole test's. The helper does not throw on GIVE-UP — it returns data, and an empty result is a legitimate one — and a give-up emits oneconsole.warnsaying whether any read answered at all, so an unsatisfied predicate cannot be mistaken for "the page was healthy and produced no such error". It is not throw-free, though: a read that REJECTS propagates (a closed page, a destroyed execution context, an in-page throw out ofgetWebGLErrors), as does the trailingpage.waitForTimeouton a page that goes away mid-poll.Enforcing the budget has a cost worth stating plainly:
getWebGLErrorsDRAINS the GL queue in-page, so an answer arriving after the deadline is discarded along with whatever real errors it already cleared, and a later read in the same spec then sees a clean queue. That is what a budget means for a helper that returns data; the proper fix is boundinggetWebGLErrorsitself — the same treatment #1651 gavegetLuxarStateandgetConsoleMessages— which reaches 21 direct call sites across 11 spec files and is left out of scope here rather than tracked anywhere, #1651 being closed. Not dispatching a FURTHER read into a sliver of budget it cannot answer within keeps the tail case out of that trap; the FIRST read is exempt from that skip, so any POSITIVE budget — however short — still gets one tightly-bounded read, rather than returning[]without having read the GL queue even once, which would be the very silence this helper's warn exists to prevent. That exemption is also the one case where the call can outlast its budget: withtimeoutunderpollMsthe first read may answer early and is then followed by a fullpollMsbefore the loop guard re-checks, so a 50 ms budget can report ~100 ms. A NON-POSITIVEtimeoutgets zero reads: the loop guard fails on entry, and the warn then says nothing was checked, which is exactly true. Documented rather than special-cased, since no caller asks for a zero budget.Unit-tested in
src/tests/unit/tests/e2e-helpers-silent-waits.test.ts.