Reputation: 19826
I am currently trying to add Espresso UI testing to my Android application and I want to be able to target a TextInputEditText via it's Hint field and then click on it and enter in some text. (I know it's better practice to target ids but I need to target hint in this instance)
Here is how I have tried to do this:
Espresso.onView(Matchers.allOf(Matchers.instanceOf(TextInputEditText::class.java),
ViewMatchers.withHint("My Hint"))).
perform(ViewActions.click(), ViewActions.typeText("type this"))
However when trying to execute this I get the following error:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (an instance of android.support.design.widget.TextInputEditText and with hint: is "Old Password")
Even though the output shows that the hierarchy actually does hold this view as follows:
TextInputEditText{id=2131820762, res-name=input_data, visibility=VISIBLE, width=1328, height=168, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=true, is-focusable=true, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=true, editor-info=[inputType=0x80091 imeOptions=0x8000005 privateImeOptions=null actionLabel=null actionId=0 initialSelStart=0 initialSelEnd=0 initialCapsMode=0x0 hintText=My Hint label=null packageName=null fieldId=0 fieldName=null extras=null hintLocales=null contentMimeTypes=null ], x=0.0, y=0.0, text=, input-type=524433, ime-target=true, has-links=false}
Is the ViewMatchers.withHint method broken in Espresso or is there a particular way to use it? Why would it fail to find the view but then in the output actually show it is in the hierarchy?
Upvotes: 2
Views: 1273
Reputation: 3420
I faced the same issue, and found no solution on stackoverflow. My hypothesis is that the hint is of a CharSequence
that doesn't match the expected string. So that, I think the hint needs to be converted to string before matching. Using hasToString
works for me.
onView(allOf(
instanceOf(TextInputEditText::class.java),
withHint(hasToString("My Hint"))
)).perform(click(), typeText("type this"))
Upvotes: 1
Reputation: 1097
There is a bug open for this already. See: https://issuetracker.google.com/issues/37139118
Upvotes: 2
Reputation: 3894
The printing in your Logcat may be misleading. If your TextInputEditText
is a child view of TextInputLayout
with hint is enabled, the TextInputLayout
will set the same hint internally on itself via TextInputLayout.setHint, then set the hint on TextInputEditText
to null.
You need to create a custom matcher to match hints of TextInputEditText
as workaround:
fun withHint(title: String): Matcher<View> = withHint(equalTo(title))
fun withHint(matcher: Matcher<String>): Matcher<View> = object : BoundedMatcher<View, TextInputEditText>(TextInputEditText::class.java) {
override fun describeTo(description: Description) {
description.appendText("with hint: ")
matcher.describeTo(description)
}
override fun matchesSafely(item: TextInputEditText): Boolean {
val parent = item.parent.parent
return if (parent is TextInputLayout) matcher.matches(parent.hint) else matcher.matches(item.hint)
}
}
And just replace your ViewMatchers.withHint("My Hint")
to TextInputEditTextCustomMatchers.withHint("My Hint")
.
Upvotes: 0