You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Playwright: debug logging in _locate() blocks for the full timeout when the element is removed (--verbose/--debug) #5739
I.dontSeeElement() (and anything else built on _locate()) should return in milliseconds when the element disappears, whether or not --verbose / --debug is on.
What do you get instead?
With --verbose or --debug, if the matched element is removed from the DOM at the wrong moment, the step blocks for the full helper timeout and then fails with:
TimeoutError: evaluate: Timeout 3000ms exceeded.
Without --verbose the same test never stalls.
We hit this on CI: a modal closed during a retried I.dontSeeElement('.modal'), the step blocked for 30 s (our timeout), and a 5 s success toast shown when the modal closed was gone by the time the next step looked for it.
Cause
Since #4712 (3.7.2), _locate() logs the found elements in debug mode:
and elToString() does await el.evaluate(node => node.outerHTML).
findElements() returns locator(...).all(), i.e. Playwright Locators (nth(i)), not element handles. Locator.evaluate() auto-waits for the element to be attached. When the element is removed between .all() and evaluate(), evaluate() waits for the page default timeout (set from the helper's timeout) and throws.
import{tryTo}from'codeceptjs/effects'Feature('dontSeeElement stall')Scenario('element removed between all() and evaluate()',async({ I })=>{letstalls=0for(leti=0;i<200;i++){I.executeScript(()=>{constel=document.createElement('div')el.id='modal'el.textContent='modal'document.body.append(el)setTimeout(()=>el.remove(),Math.random()*5)})conststart=Date.now()awaittryTo(()=>I.dontSeeElement('#modal'))constms=Date.now()-startif(ms>1000){stalls++I.say(`STALL attempt ${i}: dontSeeElement took ${ms}ms`)}}I.say(`stalls: ${stalls}/200`)})
Results:
Mode
Stalls
Duration
bunx --bun codeceptjs run --verbose
25 / 200, each TimeoutError: evaluate: Timeout 3000ms exceeded.
1 min
bunx --bun codeceptjs run
0 / 200
243 ms
Affected versions
3.7.2 and later, including 4.2.0. 3.7.1 and older have no debug logging in _locate(), so they don't stall.
Possible fix
Make the debug preview best-effort so it never blocks or fails the step, e.g. a short timeout and a fallback in elToString():
Activity
fix(playwright): don't block on debug element preview when element is…