Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assert inside a RecyclerView in Espresso?

I am using espresso-contrib to perform actions on a RecyclerView, and it works as it should, ex:

//click on first item onView(withId(R.id.recycler_view))     .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); 

and I need to perform assertions on it. Something like this:

onView(withId(R.id.recycler_view))     .perform(         RecyclerViewActions.actionOnItemAtPosition(             0, check(matches(withText("Test Text")))         )     ); 

but, because RecyclerViewActions is, of course, expecting an action, it says wrong 2nd argument type. There's no RecyclerViewAssertions on espresso-contrib.

Is there any way to perform assertions on a RecyclerView?

like image 295
juhlila Avatar asked Jul 13 '15 22:07

juhlila


People also ask

Can we use RecyclerView inside RecyclerView in Android?

The RecyclerView widget manages the display and handling of items in a list. It provides Layout Managers to position these items. This way, you can create customized layout managers for RecyclerView containers. We can use a RecyclerView inside another RecyclerView.


2 Answers

Pretty easy. No extra library is needed. Do:

    onView(withId(R.id.recycler_view))             .check(matches(atPosition(0, withText("Test Text")))); 

if your ViewHolder uses ViewGroup, wrap withText() with a hasDescendant() like:

onView(withId(R.id.recycler_view))                 .check(matches(atPosition(0, hasDescendant(withText("Test Text"))))); 

with method you may put into your Utils class.

public static Matcher<View> atPosition(final int position, @NonNull final Matcher<View> itemMatcher) {     checkNotNull(itemMatcher);     return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {         @Override         public void describeTo(Description description) {             description.appendText("has item at position " + position + ": ");             itemMatcher.describeTo(description);         }          @Override         protected boolean matchesSafely(final RecyclerView view) {             RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(position);             if (viewHolder == null) {                 // has no item on such position                 return false;             }             return itemMatcher.matches(viewHolder.itemView);         }     }; } 

If your item may be not visible on the screen at first, then scroll to it before:

    onView(withId(R.id.recycler_view))             .perform(scrollToPosition(87))             .check(matches(atPosition(87, withText("Test Text")))); 
like image 85
riwnodennyk Avatar answered Sep 23 '22 17:09

riwnodennyk


You should check out Danny Roa's solution Custom RecyclerView Actions And use it like this:

onView(withRecyclerView(R.id.recycler_view)     .atPositionOnView(1, R.id.ofElementYouWantToCheck))     .check(matches(withText("Test text"))); 
like image 43
HowieH Avatar answered Sep 23 '22 17:09

HowieH