How to click on Action Bar items when testing with Android Espresso?

Issue

I am using Android Espresso to test my activity. I have multiple action bar items, most of which are hidden in the overflow. I am trying to run this test but the error says there is no view in the hierarchy (different from not visible):

@MediumTest
public void testClickInsertItem() {
  Espresso.onView(ViewMatchers.withId(R.id.action_insert)).perform(ViewActions.click());
}

And the error:

android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: blogr.vpm.fr.blogr:id/action_insert
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.widget.ListView{5283cfb0 VFED.VC. ........ 2,2-762,973 #7f07000b app:id/allitems}

View Hierarchy:
+>DecorView{id-1, visibilityVISIBLE, width768, height1184, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+->ActionBarOverlayLayout{id16909075, res-nameaction_bar_overlay_layout, visibilityVISIBLE, width768, height1184, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count3}
|
+-->FrameLayout{id16908290, res-namecontent, visibilityVISIBLE, width768, height1038, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y146.0, child-count1}
|
+--->RelativeLayout{id-1, visibilityVISIBLE, width768, height1038, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+---->ViewPager{id2131165186, res-namepager, visibilityVISIBLE, width764, height1034, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x2.0, y2.0, child-count3}
|
+----->PagerTitleStrip{id2131165187, res-namepager_title_strip, visibilityVISIBLE, width764, height59, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x763.0, y0.0, child-count3}
|
+------>TextView{id-1, visibilityVISIBLE, width125, height43, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y8.0, textFree text, input-type0, ime-targetfalse, has-linksfalse}
|
(...)
|
+-->ActionBarContainer{id16909076, res-nameaction_bar_container, visibilityVISIBLE, width768, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y50.0, child-count2}
|
+--->ActionBarView{id16909077, res-nameaction_bar, visibilityVISIBLE, width768, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+---->LinearLayout{id-1, descHello, Navigate up, visibilityVISIBLE, width124, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+----->HomeView{id-1, visibilityVISIBLE, width97, height96, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+------>ImageView{id16908890, res-nameup, visibilityVISIBLE, width32, height32, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y32.0}
|
+------>ImageView{id16908332, res-namehome, visibilityVISIBLE, width64, height64, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x25.0, y16.0}
|
+----->LinearLayout{id-1, visibilityVISIBLE, width27, height49, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x97.0, y23.0, child-count2}
|
+------>TextView{id16908901, res-nameaction_bar_title, visibilityVISIBLE, width11, height49, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, textHello, input-type0, ime-targetfalse, has-linksfalse}
|
+------>TextView{id16908902, res-nameaction_bar_subtitle, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, text, input-type0, ime-targetfalse, has-linksfalse}
|
+---->ActionMenuView{id-1, visibilityVISIBLE, width644, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x124.0, y0.0, child-count3}
|
+----->EditText{id2131165210, res-namepostTitle, visibilityVISIBLE, width420, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectiontrue, editor-info[inputType0x1 imeOptions0x8000005 privateImeOptionsnull actionLabelnull actionId0 initialSelStart0 initialSelEnd0 initialCapsMode0x0 hintTextNew Post labelnull packageNamenull fieldId0 fieldNamenull extrasnull ], x0.0, y0.0, textHello, hintNew Post, input-type1, ime-targetfalse, has-linksfalse}
|
+----->ActionMenuItemView{id2131165222, res-nameaction_publish, descPublish, visibilityVISIBLE, width112, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x420.0, y0.0, text, input-type0, ime-targetfalse, has-linksfalse}
|
+----->OverflowMenuButton{id-1, descMore options, visibilityVISIBLE, width112, height96, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x532.0, y0.0}
|
+--->ActionBarContextView{id16909078, res-nameaction_context_bar, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count0}
|
+-->ActionBarContainer{id16909079, res-namesplit_action_bar, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count0}
|
at dalvik.system.VMStack.getThreadStackTrace(Native Method)

So, how am I supposed to access the button item with ID R.id.action_insert?

I noticed the OverflowMenuButton. I could click it, but I then get another view hierarchy that does not look like a list of action items. Am I supposed to dig in the view hierarchies until I find my action item or is there a better, designated way to click on action items in the overflow? I could not find any documentation on action bars in the Android documentation.

Solution

Espresso has openActionBarOverflowOrOptionsMenu(Context context) method to open the action bar menu. You have to put it before your test action on the menu items.

import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;

@Test
public void testClickInsertItem() {
    openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getInstrumentation().getTargetContext());
    onView(withId(R.id.action_insert)).perform(click());
}

Answered By – denys

Leave a Comment