Skip to content

fix(playwright): don't block in see() when a matched element is removed - #5746

Merged
DavertMik merged 2 commits into
codeceptjs:4.xfrom
mirao:fix/playwright-see-removed-element-stall
Oct 11, 2026
Merged

DavertMik merged 2 commits into
codeceptjs:4.xfrom
mirao:fix/playwright-see-removed-element-stall

Conversation

@mirao

@mirao mirao commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #5745

Problem

I.see(text, context) reads the text of every element matched by context via Locator.innerText(). Locators returned by .all() auto-wait for the element to be attached, so if one matched element is removed between .all() and innerText(), the step blocks for the full helper timeout and fails with innerText: Timeout ...ms exceeded, even when another matched element contains the expected text. Unlike #5739, this does not need --verbose / --debug.

A typical case is toast messages: an old toast auto-closes while the step checks a new one.

Fix

proceedSee() reads the texts with Locator.evaluateAll(), which does not wait, so a removed element contributes no text. This affects see, dontSee and seeTextEquals with a context.

Two related cases are handled so that the check can't pass by accident:

  • If every matched element is removed before its text is read, the step fails with the usual "element was not found" error instead of asserting against an empty list (seeTextEquals would pass silently).
  • For non-HTML elements such as SVG <text>, which have no innerText, the text falls back to textContent. Previously Locator.innerText() threw on such elements.

Test

Added regression tests to test/helper/Playwright_test.js:

  • One of two matched elements is removed right after Locator.all() resolves: see on the remaining element and dontSee on the removed one finish in under 1 s. Both fail without the fix (timeout).
  • Every matched element is removed: seeTextEquals fails with "was not found" in under 1 s.
  • see / dontSee on an SVG <text> element.

🤖 Generated with Claude Code

Jaromir Obr and others added 2 commits October 11, 2026 10:58
proceedSee() read the text of each element matched by the context via
Locator.innerText(), which auto-waits for the element to be attached. If
one of the elements was removed between all() and innerText(), the step
blocked for the full helper timeout and failed, even when another matched
element contained the expected text. Read the texts with evaluateAll(),
which doesn't wait, so a removed element contributes no text.

Fixes codeceptjs#5745

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ents

Reading texts with evaluateAll() left two false passes in proceedSee():

- When every matched element was removed after it was located, no text
  was read, so seeTextEquals() asserted nothing and passed. Report the
  element as not found instead.
- Non-HTML elements such as SVG have no innerText and were read as empty
  text, so dontSee() passed on text that was on the page. Fall back to
  textContent.

Refs codeceptjs#5745

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DavertMik

Copy link
Copy Markdown
Contributor

thank you! good catch!

@DavertMik
DavertMik merged commit 1822860 into codeceptjs:4.x Oct 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Playwright: I.see(text, context) blocks for the full timeout when one of the matched elements is removed

2 participants