How To Let Espresso Click A Specific RecyclerView Item?
Solution 1:
You can implement your custom RecyclerView
matcher. Let's assume you have RecyclerView
where each element has subject you want to match:
public static Matcher<RecyclerView.ViewHolder> withItemSubject(final String subject) {
Checks.checkNotNull(subject);
return new BoundedMatcher<RecyclerView.ViewHolder, MyCustomViewHolder>(
MyCustomViewHolder.class) {
@Override
protected boolean matchesSafely(MyCustomViewHolder viewHolder) {
TextView subjectTextView = (TextView)viewHolder.itemView.findViewById(R.id.subject_text_view_id);
return ((subject.equals(subjectTextView.getText().toString())
&& (subjectTextView.getVisibility() == View.VISIBLE)));
}
@Override
public void describeTo(Description description) {
description.appendText("item with subject: " + subject);
}
};
}
And usage:
onView(withId(R.id.my_recycler_view_id)
.perform(RecyclerViewActions.actionOnHolderItem(withItemSubject("My subject"), click()));
Basically you can match anything you want. In this example we used subject TextView
but it can be any element inside the RecyclerView
item.
One more thing to clarify is check for visibility (subjectTextView.getVisibility() == View.VISIBLE)
. We need to have it because sometimes other views inside RecyclerView
can have the same subject but it would be with View.GONE
. This way we avoid multiple matches of our custom matcher and target only item that actually displays our subject.
Solution 2:
actionOnItem()
matches against the itemView of the ViewHolder. In this case, the TextView is wrapped in the RelativeLayout, so you need to update the Matcher to account for it.
onView(allOf(withId(R.id.grid), isDisplayed()))
.perform(actionOnItem(withChild(withText("Foobar")), click()));
You can also use hasDescendant() to wrap your matcher is the case of a more complex nesting.
Post a Comment for "How To Let Espresso Click A Specific RecyclerView Item?"