Home » Android » android – In Espresso, how can I perform an action on all matching views without triggering an AmbiguousViewMatcherException?-Exceptionshub

android – In Espresso, how can I perform an action on all matching views without triggering an AmbiguousViewMatcherException?-Exceptionshub

Posted by: admin February 24, 2020 Leave a comment

Questions:

I’m using Espresso to run automated UI tests on an Android app. I want to perform an action on all views that match specified conditions. Espresso does use an allOf() method to find all views that a matcher matches. However, commands such as onView(withText("some text")).perform(click()) would throw an AmbiguousViewMatcherException if there is more than one match.

I do have a method for getting the nth matching view when there are multiple matches.

    private static Matcher<View> getElementFromMatchAtPosition(final Matcher<View> matcher, final int position) {
        return new BaseMatcher<View>() {
            int counter = 0;

            @Override
            public boolean matches(final Object item) {
                if (matcher.matches(item)) {
                    if(counter == position) {
                        counter++;
                        return true;
                    }
                    counter++;
                }
                return false;
            }

            @Override
            public void describeTo(final Description description) {
                description.appendText("Element at hierarchy position " + position);
            }
        };
    }

Sure, I could use this method to loop through every view. But is there a more elegant solution?

And what if I don’t know how many matching views there are?

How to&Answers:

It sounds like you may have been using allOf() incorrectly.

As you noted in your comment, allOf() should be used with matchers. You can then pick all the unique aspects of the view you want to select, comma separated.

Here’s an example:

onView(allOf(isDescendantOfA(withId(R.id.input)), withText("[email protected]"))).check(matches(isDisplayed()));