Terry
Terry

Reputation: 14897

Espresso: check if NavigationDrawer list item is selected

I have an app with a NavigationDrawer. I want to test whether the right item is selected in the list of the NavigationDrawer using Espresso.

I found a way of clicking an item in the list view that works. I used the same approach to test whether or not the list item is selected. But the behavior is odd: for the first call it seems to work, but for the second call it doesn't. Any idea what could cause this, or how I could do it better?

I tried this:

// Open drawer.
openDrawer(DRAWER_LAYOUT_ID);

// We expect that the first item (map overview) is selected.
// Here it works fine. The check succeeds.
String mapOverviewTitle = mActivity.getString(R.string.map_overview);
onView(allOf(withId(R.id.title), hasSibling(withText(mapOverviewTitle))))
        .check(matches(isSelected()));

// Navigate to the login fragment. This works fine too.
openDrawer(DRAWER_LAYOUT_ID);
String loginTitle = mActivity.getString(R.string.login);
onView(allOf(withId(R.id.title), hasSibling(withText(loginTitle))))
        .perform(click());

// We expect that the login item is selected. 
openDrawer(DRAWER_LAYOUT_ID);
// This does not work. The check fails.
onView(allOf(withId(R.id.title), hasSibling(withText(loginTitle))))
        .check(matches(isSelected()));
closeDrawer(DRAWER_LAYOUT_ID);

The error message that I get from the second call is this:

android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'is selected' doesn't match the selected view.
Expected: is selected
Got: "AppCompatTextView{id=2131558468, res-name=title, visibility=VISIBLE, width=240, height=48, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=72.0, y=8.0, text=Login, input-type=0, ime-target=false, has-links=false}"

Upvotes: 4

Views: 1810

Answers (3)

RogerParis
RogerParis

Reputation: 1559

In my case I do it like this:

String fragmentTitle = mInstrumentation.getTargetContext().getString(TITLE_STRING_ID);
openDrawer(DRAWER_LAYOUT_ID);
onView(withText(fragmentTitle)).perform(click());
onView(withId(R.id.toolbar_title)).check(matches(withText(fragmentTitle)));

In case you have a toolbar with a textview toolbartitle inside you could check it like this.

Upvotes: 0

LonelyIdiot
LonelyIdiot

Reputation: 819

Why not execute the code thru the onNavigationDrawerItemSelected(int position) method like so:

public void onNavigationDrawerItemSelected(int position) {
    Fragment frag = Dialer.newInstance("uselessParam1", "uselessParam2");
    switch (position){
        case 0:
            //code
            break;
        case 2:
            //code
            break;
        case 3:
            //code
            break;
    }
}

You just see which value matches up with the list item you want.

Upvotes: 0

Bebop_
Bebop_

Reputation: 657

It looks like you will need to build a custom view matcher. You can look at the example here for the inRoot() method which will let you pick which window layer you are choosing to interact with. Your test is currently interacting with the textView on the topmost level, you want to interact with the layer one level before that and make sure your change has been initiated.

https://code.google.com/p/android-test-kit/source/browse/testapp_test/src/main/java/com/google/android/apps/common/testing/ui/testapp/MultipleWindowTest.java

Upvotes: 0

Related Questions