How to check that MenuItem is enabled / disabled in Espresso UI Automation Test

I am writing UI Automation tests in Espresso for Android and came across a scenario for which I don't have a solution yet.

In one Fragment

I have OptionsMenu

with one element. The state of this is MenuItem

set according to the value from the API response.

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    menu.clear();
    getActivity().getMenuInflater().inflate(R.menu.menu_cancel_order, menu);
    MenuItem cancelMenuItem = menu.findItem(R.id.cancel_order);
    if(something) { // something can be a boolean value from server
        cancelMenuItem.setEnabled(true);
    } else {
        cancelMenuItem.setEnabled(false);
    } 
}

      

For UI testing, I need to write a test case to check if this is enabled MenuItem

/ disabled.

To go to overflow,

ViewInteraction actionMenuItemView = onView(
            allOf(withId(R.id.action_settings), withContentDescription("Settings"), isDisplayed()));
actionMenuItemView.perform(click());

      

And so far I've tried to verify the statement below.

onView(allOf(withText("Cancel Order"), withId(R.id.cancel_order))).check(matches(not(isEnabled())));

      

But it works NoMatchingViewException

with the message

NoMatchingViewException: no views were found in the hierarchy: (with text: "Cancel order" and id: com.equinix.ecp.betatest: id / cancel _order)

So I tried to change it to

onView(allOf(withText("Cancel Order"))).check(matches(not(isEnabled())));

      

Somehow it matched the view, but it was not a MenuItem, but a TextView inside a MenuItem, and since I am setting setEnabled()

to a MenuItem, the check()

Assertion will not work as expected as it does TextView

.

So my question is how to write a Test to check the enabled / disabled state of the MenuItem.

+3


source to share


1 answer


I would suggest you use menu item IDs to do your checks. I tried it with this menu:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="at.hellobank.hellomarkets.symbols.DetailActivity">

<item
    android:id="@+id/action_1"
    android:icon="@android:drawable/arrow_down_float"
    android:title="Menu1"
    app:showAsAction="always" />

<item
    android:id="@+id/action_2"
    android:enabled="false"
    android:icon="@android:drawable/arrow_down_float"
    android:title="Menu2"
    app:showAsAction="always" />
</menu>

      

Thus, one menu item is enabled, one is disabled. My test to check it looks like this and works as expected:



@Test
public void testMenuItemsStatus() throws Exception {
    onView(withId(R.id.action_1)).check(matches(isEnabled()));
    onView(withId(R.id.action_2)).check(matches(not(isEnabled())));
}

      

Usually using IDs in tests is better imho because you are more independent of typos and common language. withText("Cancel Order")

probably won't work if you test your app localized in a different language.

0


source







All Articles