Issue
Good day, am getting to grips with espresso and am trying to check if the PasswordVisibilityToggleEnabled button of a TextInputLayout is visible or not. I know this button is a CheckableImageButton with the id (R.id.text_input_password_toggle)
but not sure how to get it in Espresso.
I tried doing this:
onView(withId(R.id.passwordTextInputLayout)).check(hasDescendant(withId(R.id.text_input_password_toggle))).check(matches(not(isDisplayed())));
But this is not working. I guessed i might have to use a custom Matcher based on a few questions on StackOverflow but am not sure if am doing that correctly.
public static Matcher<View> getPasswordToggleView(final Matcher<View> parentMatcher, int id) {
return new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View view) {
if(!(view.getParent() instanceof ViewGroup)) {
return parentMatcher.matches(view.getParent());
}
ViewGroup group = (ViewGroup) view.getParent();
return parentMatcher.matches(view.getParent()) && view.getId() == id;
}
@Override
public void describeTo(Description description) {
description.appendText("get View with matching id");
}
};
}
and try to use it like this but still not working:
onView(getPasswordToggleView(withId(R.id.passwordTextInputLayout), R.id.text_input_password_toggle)).check(matches(not(isDisplayed())));
Any thoughts?
Solution
In your code:
onView(withId(R.id.passwordTextInputLayout))
.check(hasDescendant(withId(R.id.text_input_password_toggle))) // assume you forgot matches(...)
.check(matches(not(isDisplayed())));
The last check not(isDisplayed))
is performed on TextInputLayout, and not its CheckableImageButton
as you expected. To fix this error, simply rearrange your code to:
onView(withId(R.id.passwordTextInputLayout))
.check(matches(allOf(hasDescendant(withId(R.id.text_input_password_toggle)), not(isDisplayed()))))
So that it can perform display check on the button.
Alternatively if you want to create a custom matcher for TextInputLayout
, you can try:
public static Matcher<View> isPasswordVisibilityToggleEnabled() {
return new BoundedMatcher<View, TextInputLayout>(TextInputLayout.class) {
@Override public void describeTo(Description description) {
description.appendText("is password visibility toggle enabled");
}
@Override protected boolean matchesSafely(TextInputLayout view) {
return view.isPasswordVisibilityToggleEnabled();
}
};
}
Then you can change your test code to:
onView(withId(R.id.passwordTextInputLayout))
.check(matches(not(isPasswordVisibilityToggleEnabled())))
I think view.isPasswordVisibilityToggleEnabled()
is sufficient enough for a simple test in this case, but feel free to tweak the matcher as you like.
Answered By - Aaron
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.