I have the following list item that is used within a RecyclerView that has a vertical LinearLayout Manager. I am using espresso, and I would like to simulate clicking the id/action_save menu item. Below is my latest attempts at figuring this one out. I have tried using onData method combined with onChildView, but a MenuItem is not a View. The onView and withId methods works well if the menu item is located in a toolbar that is in the action bar, but while being embedded inside of a RecyclerView.
List Item
<android.support.v7.widget.CardView xmlns:android="http://ift.tt/nIICcg"
xmlns:app="http://ift.tt/GEGVYd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="0dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/MyDarkToolbarStyle"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ProgressBar
android:id="@+id/progress"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true" />
<android.support.v7.widget.AppCompatImageView
android:id="@+id/imgPalette"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="250dp" />
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="-2dp"
android:elevation="4dp"
android:outlineProvider="bounds"
android:paddingTop="2dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</FrameLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://ift.tt/nIICcg"
xmlns:app="http://ift.tt/GEGVYd">
<item
android:id="@+id/action_save"
android:title="@string/save"
app:showAsAction="never" />
</menu>
Main Layout
<RelativeLayout xmlns:android="http://ift.tt/nIICcg"
xmlns:app="http://ift.tt/GEGVYd"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/banner" />
...
</RelativeLayout>
Java (Espresso / JUnit Test Case)
...
// mProducts is a list that is backed by the adapter and is of Type Product
for (int i = 0; i < mProducts.size(); i++) {
onView(allOf(withId(R.id.recyclerView), withParent(withId(R.id.container))))
.perform(actionOnItemAtPosition(i, clickOverflow(R.id.toolbar)));
// Add delay for system to respond to overflow being opened
SystemClock.sleep(1000);
onView(withId(R.id.recyclerView)).perform(actionOnItemAtPosition(i, clickMenuItem(R.id.toolbar, R.id.action_save)));
}
...
public static ViewAction clickMenuItem(final int toolbarId, final int id) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return null;
}
@Override
public String getDescription() {
return "Click on a child view with specified id.";
}
@Override
public void perform(UiController uiController, View view) {
Toolbar toolbar = (Toolbar) view.findViewById(toolbarId);
for (int i = 0; i < toolbar.getChildCount(); i++) {
if (toolbar.getChildAt(i) instanceof ActionMenuView) {
ViewGroup viewGroup = ((ViewGroup) toolbar.getChildAt(i));
for (int j = 0; j < viewGroup.getChildCount(); j++) {
if (viewGroup.getChildAt(j).getId() == id) {
viewGroup.getChildAt(j).performClick();
break;
}
}
}
}
}
};
}
public static ViewAction clickOverflow(final int toolbarId) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return null;
}
@Override
public String getDescription() {
return "Click on a child view with specified id.";
}
@Override
public void perform(UiController uiController, View view) {
Toolbar toolbar = (Toolbar) view.findViewById(toolbarId);
((ViewGroup) toolbar.getChildAt(0)).getChildAt(0).performClick();
}
};
}
Error
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.variable.inspire:id/recyclerView
If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from one of the following AdapterViews:android.support.v7.widget.MenuPopupWindow$MenuDropDownListView{92d26ac VFED.VC.. .F...... 0,0-515,252}
Aucun commentaire:
Enregistrer un commentaire