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.
source to share
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.
source to share