Basically I am trying to test that after login incorrectly I have an error showing in the email field.
The view is:
Its working :)
onView(withId(R.id.et_email)).check(matches(hasErrorText("Error Message")));
Please use setError() method of EditText Ex : EditText emailEditText;
if(invalidLogin)
emailEditText.setError("Error Message");
You could write a Custom Matcher:
public final class CustomItemMatchers {
private static class TextInputLayoutErrorMatcher extends BoundedMatcher<Object, Wrapper> {
private final Matcher<String> itemTextMatcher;
public TextInputLayoutErrorMatcher(final Matcher<String> itemTextMatcher){
super(TextInputLayout.class);
this.itemTextMatcher = itemTextMatcher;
}
@Override
public void describeTo(Description description) {
description.appendText("with error content: ");
itemTextMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(TextInputLayout til) {
if (til == null) {
return false;
}
return itemTextMatcher.matches((til.getError());
}
}
public static Matcher<Object> withErrorName(final Matcher<String> itemTextMatcher) {
checkNotNull(itemTextMatcher);
return new TextInputLayoutErrorMatcher(itemTextMatcher);
}
}
You can use it then with
matches(CustomItemMatchers.withErrorName(equalTo("My Error")))
This code was written with Espresso 1, but I hope it still works.
wrote a custom matcher
import android.view.View;
import com.google.android.material.textfield.TextInputLayout;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class TextInputLayoutErrorMatcher extends TypeSafeMatcher<View>{
private String expectedErrorText;
TextInputLayoutErrorMatcher(String expectedErrorText) {
this.expectedErrorText = expectedErrorText;
}
@Override
protected boolean matchesSafely(View item) {
if (!(item instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) item).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
description.appendText("with error text " + expectedErrorText);
}
}
This works with a CustomMatcher:
public static Matcher<View> hasTextInputLayoutErrorText(final String expectedErrorText) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) view).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
}
};
}
I think that you would like to set error on TextInputLayout not on EditText. If it is correct, in the following way you could achieve this.
onView(withId(R.id.ti_email)).check(matches(hasDescendant(
withText(ctx.getString(R.string.authentication_error_empty_email))))
)