I'm starting to play with Espresso, got my basic tests running. Now trying to figure out how to check that my edit text has a specific hint text? Thanks.
onView(withId(R.id.locationInput)).check(matches...?)
I'm starting to play with Espresso, got my basic tests running. Now trying to figure out how to check that my edit text has a specific hint text? Thanks.
onView(withId(R.id.locationInput)).check(matches...?)
Since Espresso 2.0 just use internal ViewMatcher withHint:
onView(withId(R.id.locationInput)).check(matches(withHint("your_hint")))
Looks like I figured it out. Basically, you need to create your own matcher:
public static Matcher<View> withHint(final String expectedHint) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof EditText)) {
return false;
}
String hint = ((EditText) view).getHint().toString();
return expectedHint.equals(hint);
}
@Override
public void describeTo(Description description) {
}
};
}
Then you can use it:
onView(withId(R.id.locationInput)).check(matches(withHint("Location (Optional)")));
There is a slightly different way to do it. In my case you check that the String is not null, before pass it to matcher (as explained in Espresso examples). And also in code below you don't need the R.id of the EditText with this hint. You just check if hint with "hintText" is displayed:
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public final class Matchers {
public static Matcher<View> withItemHint(String hintText) {
// use preconditions to fail fast when a test is creating an invalid matcher.
checkArgument(!(hintText.equals(null)));
return withItemHint(is(hintText));
}
public static Matcher<View> withItemHint(final Matcher<String> matcherText) {
// use preconditions to fail fast when a test is creating an invalid matcher.
checkNotNull(matcherText);
return new BoundedMatcher<View, EditText>(EditText.class) {
@Override
public void describeTo(Description description) {
description.appendText("with item hint: " + matcherText);
}
@Override
protected boolean matchesSafely(EditText editTextField) {
return matcherText.matches(editTextField.getHint().toString());
}
};
}
}
Usage:
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isDisplayed;
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
import static com.your.package.withMatcher.withItemHint;
.
.
.
onView(withItemHint(someHintString)).check(matches(isDisplayed()));
I've created a Matcher that supports passing a resourceId instead of a String
public static Matcher<View> withHint(final int resourceId) {
return new BoundedMatcher<View, TextView>(TextView.class) {
private String resourceName = null;
private String expectedHint = null;
@Override
public boolean matchesSafely(TextView editText) {
if (null == expectedHint) {
try {
expectedHint = editText.getResources().getString(resourceId);
resourceName = editText.getResources().getResourceEntryName(resourceId);
} catch (Resources.NotFoundException ignored) {
/* view could be from a context unaware of the resource id. */
}
}
if (null != expectedHint) {
return expectedHint.equals(editText.getHint());
} else {
return false;
}
}
@Override
public void describeTo(Description description) {
description.appendText("with string from resource id: ");
description.appendValue(resourceId);
if (null != resourceName) {
description.appendText("[");
description.appendText(resourceName);
description.appendText("]");
}
if (null != expectedHint) {
description.appendText(" value: ");
description.appendText(expectedHint);
}
}
};
}
It's a replication of Espresso's withText matcher pointed by Valera Zakharov (withText(resourceId)