I am new to using espresso. I cannot really get what I wanted to test using this code:
onData(withId(R.id.relativelayout_tag))
.inAdapterView(withId(R.id.recyclerview_tag_list))
.onChildView(withId(R.id.imageview_tag))
.atPosition(1)
.check(matches(isDisplayed()));
Where R.id.imageview_tag
is a child of R.id.relativelayout_tag
. R.id.relativelayout_tag
holds the entire content for my adapter item. R.id.recyclerview_tag_list
is the name of my RecyclerView
on which I assigned a particular RecyclerView
Adapter
.
This is a very very basic test. Here are the user procedures:
RecyclerView
(I don't really care what
text is on the view). Also do not suggest using view text to identify the first item. I DONT CARE ABOUT THE ADAPTER ITEM'S CONTENT or even putting a unique tag on some view. Very basic and simple. It is so hard to write a test for this basic user story using Espresso. When I run that particular test it always fail stating this:
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(is assignable from class: class android.widget.AdapterView and is displayed on the screen to the user)
Target view: "RecyclerView{id=2131624115, res-name=recyclerview_tag_list, visibility=VISIBLE, width=480, height=1032, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=15}"
It doesn't make sense as I have the list already visible. I can even run this test just fine:
onView(withId(R.id.recyclerview_tag_list))
.perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
Here is the full test:
@Test
public void shouldTagToggleSelected()
{
onView(withId(R.id.recyclerview_tag_list))
.perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
onData(withId(R.id.relativelayout_tag))
.inAdapterView(withId(R.id.recyclerview_tag_list))
.onChildView(withId(R.id.imageview_tag))
.atPosition(1)
.check(matches(isDisplayed()));
//onView(withId(R.id.imageview_tag))
// .check(matches(isDisplayed()));
}
What I wanted to test if the indicator view has a visibility set to visible
ONLY on that particular item (or any item of my choosing).
Any thoughts? Maybe I missed something dearly.
Thanks a lot!
OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super. onScrolled(recyclerView, dx, dy); LinearLayout ll = (LinearLayout) recyclerView. findChildViewUnder(dx, dy); if (ll != null) { TextureVideoView tvv = (TextureVideoView) ll.
A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View. findViewById(int) results.
onData
does not work with RecyclerView
as RecyclerView
does not extend AdapterView
.
You need to use onView
to make your assertions. If it's the first item in the recycler view, then you can use something like this matcher to make your assertion:
public static Matcher<View> withViewAtPosition(final int position, final Matcher<View> itemMatcher) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
@Override
public void describeTo(Description description) {
itemMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(RecyclerView recyclerView) {
final RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
return viewHolder != null && itemMatcher.matches(viewHolder.itemView);
}
};
}
And the usage is the following:
onView(withId(R.id.recyclerview_tag_list))
.check(matches(withViewAtPosition(1, hasDescendant(allOf(withId(R.id.imageview_tag), isDisplayed())))));
Keep in mind that this matcher will fail if your ViewHolder has not been laid out yet. If that's the case you need to scroll to the ViewHolder with RecyclerViewActions. You don't need to scroll if you are clicking the item in the test prior to using the matcher.
I had an exception error when checking element linear layout that was not visible. To resolve it, I had to add withFailureHandler as follows:
class MyTest {
boolean isViewVisible = true;
public void test1(){
onView(withRecyclerView(R.id.recycler_view)
.atPositionOnView(index, R.id.linear_layout))
.withFailureHandler(new FailureHandler() {
@Override
public void handle(Throwable error, Matcher<View> viewMatcher){
isViewVisible = false;
}
})
.check(isVisible());
//wait for failure handler to finish
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(isViewVisible){
//do something
}
}
}
class MyTestUtil {
public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) {
return new RecyclerViewMatcher(recyclerViewId);
}
public static ViewAssertion isVisible() {
return new ViewAssertion() {
public void check(View view, NoMatchingViewException noView) {
assertThat(view, new VisibilityMatcher(View.VISIBLE));
}
};
}
}
public class RecyclerViewMatcher {
private final int recyclerViewId;
public RecyclerViewMatcher(int recyclerViewId) {
this.recyclerViewId = recyclerViewId;
}
public Matcher<View> atPosition(final int position) {
return atPositionOnView(position, -1);
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources = null;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
new Object[] { Integer.valueOf
(recyclerViewId) });
}
}
description.appendText("with id: " + idDescription);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
}
else {
return false;
}
}
if (targetViewId == -1) {
return view == childView;
} else {
View targetView = childView.findViewById(targetViewId);
return view == targetView;
}
}
};
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With