Skip to content

fix(core): webview expect() keeps polling when the element is not in the DOM yet - #358

Merged
gmegidish merged 2 commits into
mainfrom
fix/webview-expect-missing-element
Sep 30, 2026
Merged

gmegidish merged 2 commits into
mainfrom
fix/webview-expect-missing-element

Conversation

@gmegidish

@gmegidish gmegidish commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Fixes #357

Problem

expect(webLocator).toBeVisible() on an element that is not in the DOM yet threw immediately instead of polling:

RpcError: webview evaluate failed: ... Cannot read properties of undefined (reading 'nodeType')

buildExpectEvaluate passed elements[0] straight into the injected expect(). Since Playwright 1.62 the injected matcher no longer guards against a missing element; playwright-core moved that handling server-side into Frame._expectInternal, which mobilewright does not run. The throw escaped _expect, so polling never started.

Fix

  • The evaluate now resolves to null when a single-element matcher finds no element. Array matchers (to.have.count, *.array) still receive the empty list.
  • New missingElementVerdict() in web-expect-matcher.ts decides that case, mirroring the no-element branch of Frame._expectInternal:
    • toBeHidden / toBeDetached pass.
    • not.toBeVisible / not.toBeAttached / not.toBeInViewport pass.
    • Everything else does not pass and is reported as a missing element, so polling continues until the timeout.
  • _runInjectedExpect applies it, so both callers (Playwright's expect via _expect, and mobilewright's own expect) are covered.

Tests

  • New unit tests for the verdict table, the evaluate guard, and _expect polling on a missing element
  • npm test — 822 passed, 1 skipped
  • npm run lint
  • Extended the assertions-missing conformance spec (element added to the DOM after 1.5 s, toBeHidden, toBeVisible timing out as an ordinary failure)
  • iOS simulator (iPhone 17, iOS 26.5, Playground): the spec fails with the nodeType error before the fix and passes after
  • Same spec passes under real Playwright on Chromium

@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Essentials

Run ID: 415bc3de-d06c-4cdd-8673-1a02f94365f9

📥 Commits

Reviewing files that changed from the base of the PR and between 44a4c0b and 5e1dcc0.

📒 Files selected for processing (5)
  • e2e/src/conformance/specs/assertions-missing.spec.ts
  • packages/mobilewright-core/src/web-expect-matcher.test.ts
  • packages/mobilewright-core/src/web-expect-matcher.ts
  • packages/mobilewright-core/src/web-locator.test.ts
  • packages/mobilewright-core/src/web-locator.ts

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


Walkthrough

Matcher evaluation now returns a separate missing-element verdict for absent single elements while allowing empty results for array matchers. The locator uses that verdict when injected evaluation returns null. Tests cover missing-element assertion results, visibility polling, and ordinary assertion failures.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 5e1dc

The change allows absent-element assertions to keep polling while preserving immediate success for appropriate missing-element checks. No concrete merge-blocking risk is established; Android validation remains unreported.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #357 requires a missing webview element to keep polling and to fail with a normal assertion error after timeout. The PR returns null for missing single-element matches, applies missingElementVer…
Out of Scope Changes check ✅ Passed The changed matcher logic, locator integration, unit tests, and conformance tests all support issue #357. The additional handling for hidden, detached, negated visibility, attachment, and viewport ass…
Title check ✅ Passed The title clearly and concisely describes the main change: webview expect() continues polling when the element is not yet in the DOM.
Description check ✅ Passed The description directly explains the missing-element failure, the implementation, affected matchers, and validation results.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@gmegidish
gmegidish merged commit 0df696f into main Sep 30, 2026
9 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.

expect(locator).toBeVisible() throws nodeType when the element is not in the DOM yet

1 participant