Click home icon with Espresso
Solution 1
To not depend on the app locale, you can use the code from Matt Logan by replacing "Navigate up" with R.string.abc_action_bar_up_description
:
onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
This helped me a lot because I have an app in more than 5 languages and I had to act like this.
Solution 2
Use the withContentDescription()
Matcher
:
onView(withContentDescription("Navigate up")).perform(click());
Solution 3
I had trouble navigating back from one Activity to another, but then I found top-level actions:
Espresso.pressBack();
Solution 4
I found a real solution to this issue. By using the hierarchyviewer I found that the toolbar looks like this:
This means we could match the hamburger icon (not back button) like this:
onView(withContentDescription("Open navigation")).perform(click());
But a better solution to me was to find out that the hamburger icon is the only ImageButton and a direct child view of the v7 Toolbar. So I wrote a helper method to match it:
public static Matcher<View> androidHomeMatcher() {
return allOf(
withParent(withClassName(is(Toolbar.class.getName()))),
withClassName(anyOf(
is(ImageButton.class.getName()),
is(AppCompatImageButton.class.getName())
)));
}
@Test
public void clickHamburgerIcon() throws Exception {
onView(androidHomeMatcher()).perform(click());
// ...
}
This solution is better because it should match the view no matter which locale you use in your test. :-)
EDIT: Note that Toolbar might be android.support.v7.widget.Toolbar or android.widget.Toolbar - depending on your use case!
EDIT: The support lib version 24.2.0 uses AppCompatImageButton instead of ImageButton, so I added it, too.
EDIT: You have to import the correct methods to get this to work. Here are the imports used:
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
Solution 5
I was having problems with "Navigate up" in an emulator, this worked for me:
onView(isRoot()).perform(ViewActions.pressMenuKey());
Related videos on Youtube
Comments
-
ligi almost 4 years
I am trying to click the home icon in some Espresso tests via:
onView(withId(android.R.id.home)).perform(click());
This works fine for Android > 3.0 - but fails for older versions as
appcompat
does not seem to use this id for this element then. What is a good approach to do what I want to do?-
Matt Logan over 9 yearsWondering if you found an answer to this?
-
ligi over 9 yearsAFAIR not really - I think I worked around this then. Might be worth a try if this changed in the most recent appcompat though
-
Matt Logan over 9 yearsJust found a solution (for me at least). See answer.
-
sunlover3 over 6 years@ligi Hello! Can you change the accepted answer, please?
-
ligi over 6 years@sunlover3 ack - just changed the accepted answer to yours - you are right - this solution is better. Does it work for appcompat and native?
-
sunlover3 over 6 years@ligi Great! Thank you. It should work, because the OS developers who work on this part should not change these ids. Otherwise, all the tests developed will crash. For the moment, all my tests regarding this part are working.
-
-
nickmartens1980 over 9 yearsThis works, however, this may fail on devices that are not set to English
-
DesignatedNerd over 9 yearsIf you look for this log in your failures in your language:
+------->ImageButton{id=-1, desc=Navigate up,
, thedesc
value will be the translated description in the device's current language. I'd imagine that's buried somewhere within theandroid.R.string
declarations, but I haven't been able to ferret out where it's hidden. -
Matt Logan over 9 yearsNot sure why the different language thing is a big deal, unless you're running your automated tests on devices set to a different language. Even in this case, you could just
switch
on the device's defaultLocale
to set the appropriate "Navigate up" translation. -
Ghedeon over 9 yearsUse with caution, because: 1) apparently in 4.3 content description is "<action bar title>, Navigate up" and matching will fail. 2) You can have more than one view with a such description. In particular, only
onView(allOf(withContentDescription(containsString("Navigate up")), isClickable())).perform(click())
works for me. -
bryant1410 about 8 yearsPlease notice that back navigation is not the same as up navigation: developer.android.com/design/patterns/navigation.html
-
Roc Boronat about 8 yearsThis should be the accepted answer. The accepted one only works on English devices... #fail
-
sunlover3 about 8 yearsThanks. I always think of using general commands, so this is why I searched for the android native string id. Good luck!
-
sunlover3 almost 8 yearsI would like to help you. Can you tell me how did you receive this error? You must be careful that before calling onView on any view, be sure that nothing overlaps it (like a dialog or some other screen). My code works pretty fine, you have a mistake in your code structure.
-
Frikster over 7 yearsI have the same problem as @AutonomousApps. how can I check to see of anything is overlapping? Shouldn't the withContentDescription bring the view to the top level view that contains the Navigate up button?
-
sotrh over 7 yearsFor Kotlin devs, import
is
using something likeimport org.hamcrest.Matchers.`is` as _is
. -
Felipe Porge Xavier about 7 yearsThe only that worked for my case. I was trying to close a search view.
-
Alexei about 5 yearsI found solution without workaround. Here: val upButton = onView(allOf(instanceOf(ImageButton::class.java), withParent(withId(toolBar))))
-
Beloo almost 5 yearsyes, it works, but only with
Toolbar
widget. For system navigation you should choose another solution -
Brian about 4 yearsHello! While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.
-
Clément Jean over 3 yearsfor people using androidx, it's
androidx.appcompat.R.string.abc_action_bar_up_description
-
Oya Canli over 3 yearswith navigation component, this is only working in English, when I try in French it fails. @AthaMit's answer works for both languages
-
Oya Canli over 3 yearsThanks! The accepted anwser only works in English for me since I migrated to Jetpack navigation. This solution worked in French as well.
-
sunlover3 over 3 years@OyaCanli I'm sure that since 2016 the things might have changed. Thanks for the update!