Repository navigation
fix: treat an element with no area as not visible - #6
Merged
Merged
Conversation
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
marked this pull request as ready for review
September 24, 2026 15:47
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
DouweBos
added a commit
that referenced
this pull request
Oct 9, 2026
getVisiblePercentage only short-circuited when both dimensions were zero, so a box with one zero dimension divided zero by zero and returned NaN. filterOutOfBounds keeps anything failing `visiblePercentage < 0.1`, and NaN fails every comparison, so a collapsed element stayed in the hierarchy and read as visible. A Lightning nav drawer collapsed to [-452,0][-452,72] is what surfaced it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
UiElement.getVisiblePercentagereturnedNaNfor a box with exactly one zero dimension: the early return only coveredwidth == 0 && height == 0, so everything else fell through tovisibleArea / totalArea, and a zero dimension makes both sides0.TreeNode.filterOutOfBoundsprunes onvisiblePercentage < 0.1, andNaNfails every comparison, so those elements were never pruned — an element collapsed to no area stayed in the hierarchy and satisfiedassertVisible. Widening the guard to||fixes it, and matches what the existing&&guard was already reaching for.This makes visibility stricter on every platform, not just web. A flow that currently passes because it asserts on a zero-area element will start failing. That is the intended correction, but it is worth a full E2E run before release.
Found via a Plex Lightning nav drawer: collapsed off-screen at
[-452,0][-452,72], Maestro reported it visible, and awhile notVisible:gate meant to expand the rail was skipped outright — so the flow pressed no keys and failed several commands later on an unrelated assertion.Testing
./gradlew :maestro-client:test— 297 tests, 0 failures.Four new cases, confirmed red before the fix for the right reason (
expected: 0 but was: NaN, and the zero-area node surviving the filter):UiElementTest— zero width and zero height each return0ViewHierarchyTest(new file) —filterOutOfBoundsdrops a zero-width and a zero-height node, and still keeps an ordinary on-screen oneNo demo-app flow: the defect is in hierarchy filtering rather than in any on-device behavior, and the unit tests pin it at the layer it occurs. Happy to add a
defects_screen.dartwidget plus a flow if you'd rather have the e2e coverage too.Issues fixed
Unblocks the
search.tvandnavigation.tvLightning smoke flows inplexinc/react-native-client, which have been failing onAssertion is false: id: primary-navigation-account, focused is visible.