AmbiguousViewMatcherException multiple RecyclerViews
Asked Answered
L

4

8

I have a Fragment that contains RecyclerView. But since I have a lot of elements in this Fragment, I want to swipe up the list to see and check all the elements that are in this Fragment.

Earlier this method helped me, but now for some reason it does not work:

Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())

I have many RecyclerViews with same id in my project:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"/>

Also in my tests I've written something like this:

onView(allOf( withId(R.id.recyclerView), isDisplayed()))
onView(withId(R.id.recyclerView)).perform(swipeUp())

But caught error only on second line.

android.support.test.espresso.AmbiguousViewMatcherException: 'with id: com.fentury.android:id/recyclerView' matches multiple views in the hierarchy. Problem views are marked with '****MATCHES****' below.

Loopy answered 14/6, 2017 at 7:45 Comment(1)
Clarify what "doesn't work" is supposed to mean. Show your view hierarchy, so that we can understand what possibly may have gone wrong.Phaidra
P
7

You have multiple views with id R.id.recyclerView in your view hierarchy, therefore espresso lacks to perform correct matching. Make the ids of those RecyclerViews unique.


onView(allOf(withId(R.id.recyclerView), isDisplayed())) onView(withId(R.id.recyclerView)).perform(swipeUp())

But caught error only on second line.

Then perform matching this way:

onView(allOf(withId(R.id.recyclerView), isDisplayed())).perform(swipeUp())
Phaidra answered 14/6, 2017 at 11:16 Comment(2)
Bad advice, because in my application this recyclerView is used in many places.Loopy
Then you have to perform matching using some other criteria, i.e. allOf(withParent(withId(R.id.parentId)), withId(R.id.recyclerView)) or some other combination.Phaidra
E
0

Solution:

onView(allOf(withId(R.id.recyclerview), isDisplayed())).perform(swipeUp());
Exchange answered 17/4, 2019 at 6:2 Comment(0)
B
-1

You should use on data for recycler view where you can assert using recycler view's id as well as type of data it holds. This should help assuming different recycler views would not have same type of data but its better practice to use different ids for different view based on what its used for.

You may also want to use perform(ViewActions.scrollTo())

Baggy answered 20/6, 2017 at 7:5 Comment(1)
Sometimes you want to reuse the same layout file for two different fragments. Then you have the same ids.Aunt
A
-1

I had a similar problem with multiple RecyclerViews in two fragments inside a ViewPager when I found this question. Both fragments used the same layout file, containing just the RecyclerView with id = @id/list.

As there was no parent to match I made this custom ViewMatcher to match the list by Adapter-Class: (Kotlin)

fun hasAdapterOfType(T: Class<out RecyclerView.Adapter<out RecyclerView.ViewHolder>>): BoundedMatcher<View, RecyclerView> {

    return object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {
        override fun describeTo(description: Description) {
            description.appendText("RecycleView adapter class matches " + T.name)
        }

        override fun matchesSafely(view: RecyclerView): Boolean {
            return (view.adapter.javaClass.name == T.name)
        }
    }
}

Usage like this:

onView(allOf(withId(list), hasAdapterOfType(AccessAttemptListAdapter::class.java))).check(blabla)
Aunt answered 29/5, 2018 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.