Reputation: 7941
I have a ListView:
And I want to click on a specific button within a ListView.
If I want to select with the onData selector:
onData(withId(R.id.button))
.inAdapterView(withId(R.id.list_view))
.atPosition(1)
.perform(click());
And I get this error:
android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com.example.application:id/list_view'.
...
How can I solve this?
Upvotes: 3
Views: 1503
Reputation: 4972
onData()
requires an object matcher for the item that you are interested in. If you don't care about the data in the adapter you can use Matchers.anything()
to effectively match all objects in the adapter. Alternatively you can create a data matcher (depending on data that is stored in the adapter) for your item and pass it in for a more deterministic test.
As for the button - what you are looking for is an onChildsView()
method, which allows to pass a viewmatcher for the descendant of the listitem, that was matched in the onData().atPosition()
And as a result your test will look something like this:
onData(anything()).inAdapterView(withId(R.id.list_view))
.atPosition(1)
.onChildView(withId(R.id.button))
.perform(click());
Upvotes: 7
Reputation: 7941
I used a workaround which don't use the ListView data, and the .getPosition(index)
, instead checks that the the view with the specific id is the descendant of the ListView specific position View.
public static Matcher<View> nthChildsDescendant(final Matcher<View> parentMatcher, final int childPosition) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("with " + childPosition + " child view of type parentMatcher");
}
@Override
public boolean matchesSafely(View view) {
while(view.getParent() != null) {
if(parentMatcher.matches(view.getParent())) {
return view.equals(((ViewGroup) view.getParent()).getChildAt(childPosition));
}
view = (View) view.getParent();
}
return false;
}
};
}
Example of usage:
onView(allOf(
withId(R.id.button),
nthChildsDescendant(withId(R.id.list_view), 1)))
.perform(click());
Upvotes: 0