3

I have a RecyclerView with id 'rv_list'. On clicking on any RecyclerView item, there is a View inside every item with id 'star' that gets visible.

I want to check this using expresso - Click on first RecyclerView item, check if the view R.id.star is visible.

My code is -

@Test
fun checkIfStarVisibleOnItemClick() {

  onView(withId(R.id.rv_list))
            .perform(RecyclerViewActions.actionOnItemAtPosition<RepositoriesAdapter.RepositoriesViewHolder>(0, click()))


   onView(withId(R.id.star))
            .check(matches(isDisplayed()))

 }

I get this error -

id/star' matches multiple views in the hierarchy

Gissipi_453
  • 1,250
  • 1
  • 25
  • 61

1 Answers1

3

The code to check that the item with id 'star' is visible in the first element (position 0) of the 'rv_list' RecyclerView should be:

onView(withRecyclerView(R.id.rv_list)
    .atPositionOnView(0, R.id.star))
    .check(matches(isDisplayed()));

this methods were part of espresso-contrig.

Update

Now I declare this method:

fun nthChildOf(parentMatcher: Matcher<View?>, childPosition: Int): Matcher<View?>? {
    return object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("with $childPosition child view of type parentMatcher")
        }

        override fun matchesSafely(view: View): Boolean {
            if (view.parent !is ViewGroup) {
                return parentMatcher.matches(view.parent)
            }
            val group = view.parent as ViewGroup
            return parentMatcher.matches(view.parent) && group.getChildAt(childPosition) == view
         }
    }
}

and use it this way:

onView(allOf(
    withId(R.id.star),
        isDescendantOfA(
            nthChildOf(withId(R.id.rv_list), 0))
)).check(matches(isDisplayed()))
jeprubio
  • 17,312
  • 5
  • 45
  • 56