I use RecyclerView pretty often, but I still tend to forget how to write a custom Espresso matcher for tests that allows me to scroll and click item according to my custom criteria.

This is just a quick reminder for me, so that I can look it up here in case I forget.

The scenario here is the following

  • I have a RecyclerView with id rvPackageList in my layout
  • The adapter loads data from a list of PackageInfo items
  • In ViewHolder the text of a TextView with id tvPackageName, that is part of a single RecyclerView item, is assigned the value of packageName member of PackageInfo class

The item of the RecyclerView can contain many other child views, but I'm only interested in the TextView tvPackageName.

I want to click/scroll to an item with specific package name.

The custom matcher would look like this

fun withItemPackageInViewHolder(packageName: String): Matcher<RecyclerView.ViewHolder> {
    return object : BoundedMatcher<RecyclerView.ViewHolder, PackageAdapter.ViewHolder>(
        PackageAdapter.ViewHolder::class.java
    ){
        override fun describeTo(description: Description?) {
            description?.appendText("with item package name " + packageName)
        }

        override fun matchesSafely(item: PackageAdapter.ViewHolder?): Boolean {
            return item?.tvPackageName?.text == packageName
        }
    }
}

To click on an item with the given package name

onView(withId(R.id.rvPackageList)).perform(actionOnHolderItem(withItemPackageInViewHolder(expectedPackageName), click()))

If you you're an Android enthusiast that likes to learn more about Android internals, I highly recommend to check out my Bugjaeger app. It allows you to connect 2 Android devices through USB OTG and perform many of the tasks that are normally only accessible from a developer machine via ADB directly from your Android phone/tablet.

Add a comment