Repository navigation
Conversation
…tate selectors A selector such as `containsChild: "Submit"` with `enabled: true` never matched, although the parent contains the text and is enabled. The deepest match for the basic filters was picked first (the enabled text itself) and only then intersected with the relative filters, which dropped it, leaving nothing. When a selector has both kinds of filters, search for the deepest basic match among the nodes the relative filters allow instead. Fixes mobile-dev-inc#3501
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.
Why
A selector that combines
containsChildwithenabled: truenever matches in 2.x, soassertVisibletimes out andtapOnfails with "Element not found", even though the hierarchy has an enabled element containing that child. The same applies toselected,checked,focused,text,idand the other basic selector fields whenever they are combined withcontainsChild,below,above,leftOf,rightOforcontainsDescendants, and a child of the wanted element matches the basic fields on its own.Fixes #3501
Approach
Since #2711,
buildFilterpicks the deepest element that matches the basic filters first, and only then intersects that result with the relative filters. WithcontainsChild: "Submit"andenabled: true, the deepest enabled element is the "Submit" text itself. The intersection drops it, because the text doesn't contain itself as a child, and the enabled button above it is never considered.Relative filters look at the whole hierarchy, so they can't run inside
deepestMatchingElement, which checks one node at a time. A newFilters.deepestMatchingElement(filter, within)overload runswithinonce over all nodes, then does the usual deepest-match search but only accepts nodes thatwithinreturned.buildFilteruses it when a selector has both kinds of filters. Selectors with only basic filters, or only relative filters, go through the same code as before.Points worth a close look:
index:, though, an extra match could shift which element a given index picks.Verification
Case 160(160_contains_child_enabled.yaml). The layout follows the issue: an enabled button whose "Submit" text is an enabled child, plus a disabled button containing "Delete". The flow assertscontainsChild: "Delete"+enabled: false(the control from the issue), then tapscontainsChild: "Submit"+enabled: trueand checks that the tap lands on the button, not on the text.main(028c18b) it fails:ElementNotFound: Element not found: Contains child: "Submit", Enabled.DeepestMatchingElementTestfor the new overload. One checks that a deeper match rejected bywithingives way to its parent. The other checks that it still returns the deepest match when everything is allowed.Orchestra.ktchange makesCase 160fail again. Making the overload ignorewithinmakesCase 160and the first new unit test fail../gradlew :maestro-orchestra:detektMain :maestro-client:detektMainpasses../gradlew test, minus:maestro-android(no Android SDK on this machine): 1379 tests, 0 failures, 9 skipped. Onmain: 1376 tests, 0 failures, 9 skipped. The difference is the 3 new tests.osx-aarch_64build ofprotoc-gen-grpc-java1.50.2 is an x86_64 binary. This machine has no Rosetta, so I generated the gRPC stubs with the same plugin version'slinux-aarch_64build in a container, using a local Gradle init script. No build files were changed.:maestro-androidunit tests, the iOS/Swift tests, and the e2e flows on a device or emulator. I didn't run the reporter's repro app.