Is it possible to check if the background color matches a given color with espresso?
Update:
I made a custom matcher, similar to what @Irfa
I am not sure about that but we can retrieve the color of some of elements like button and text views `
Button button = (Button) findViewById(R.id.my_button);
Drawable buttonBackground = button.getBackground();
and you can try like this
ColorDrawable b_color = (ColorDrawable) button.getBackground();
and then
int color = b_color.getColor();
if (color == R.color.green) {
log("color is green");
}
Hope this will get you started.
I am late but this might be helpful to someone else
public static Matcher<View> matchesBackgroundColor(final int expectedResourceId) {
return new BoundedMatcher<View, View>(View.class) {
int actualColor;
int expectedColor;
String message;
@Override
protected boolean matchesSafely(View item) {
if (item.getBackground() == null) {
message = item.getId() + " does not have a background";
return false;
}
Resources resources = item.getContext().getResources();
expectedColor = ResourcesCompat.getColor(resources, expectedResourceId, null);
try {
actualColor = ((ColorDrawable) item.getBackground()).getColor();
}
catch (Exception e) {
actualColor = ((GradientDrawable) item.getBackground()).getColor().getDefaultColor();
}
finally {
if (actualColor == expectedColor) {
Timber.i("Success...: Expected Color " + String.format("#%06X", (0xFFFFFF & expectedColor))
+ " Actual Color " + String.format("#%06X", (0xFFFFFF & actualColor)));
}
}
return actualColor == expectedColor;
}
@Override
public void describeTo(final Description description) {
if (actualColor != 0) { message = "Background color did not match: Expected "
+ String.format("#%06X", (0xFFFFFF & expectedColor))
+ " was " + String.format("#%06X", (0xFFFFFF & actualColor));
}
description.appendText(message);
}
};
}
I also logged the expected and actual color In hex format which might be helpful.
Usage: onView(withId(R.id.viewId)).check(matches(matchesBackgroundColor(R.color.colorId)));
It is possible to to test on color. I created a method to test on TextView
background color as below. Also notice that am passing color resource.
private fun withBackgroundColor(@ColorInt color: Int): Matcher<View> {
Checks.checkNotNull(color)
return object : BoundedMatcher<View, TextView>(TextView::class.java) {
override fun describeTo(description: Description?) {
description?.appendText("TextView background color to be $color")
}
override fun matchesSafely(item: TextView?): Boolean {
val backgroundColor = item?.background as ColorDrawable
val colorDrawable = ColorDrawable(ContextCompat.getColor(item.context, color))
return colorDrawable.color == backgroundColor.color
}
}
}
I create ColorDrawable
object from color resource and get color from the object.
Comparing color from resource without the ColorDrawable
does not pass. Hope this helps you.
Another approach to check TextView text's color could be via hasTextColor(int color)
as it comes directly from Espresso.
import static android.support.test.espresso.matcher.ViewMatchers.hasTextColor;
onView(withId(R.id.anyTextView)).check(matches(hasTextColor(R.color.red)));
Be aware that this method is currently in Beta for Espresso 3.0.1
private fun hasBackgroundColor(colorRes: Int): Matcher<View> {
Checks.checkNotNull(colorRes)
return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) {
description?.appendText("background color: $colorRes")
}
override fun matchesSafely(item: View?): Boolean {
val context = item?.context
val textViewColor = (item?.background as ColorDrawable).color
val expectedColor: Int?
if (Build.VERSION.SDK_INT <= 22) {
expectedColor = context?.resources?.getColor(colorRes)
} else {
expectedColor = context?.getColor(colorRes)
}
return textViewColor == expectedColor
}
}
}
In my tests I have the following matcher for testing EditText
color:
public static Matcher<View> withTextColor(final int color) {
Checks.checkNotNull(color);
return new BoundedMatcher<View, EditText>(EditText.class) {
@Override
public boolean matchesSafely(EditText warning) {
return color == warning.getCurrentTextColor();
}
@Override
public void describeTo(Description description) {
description.appendText("with text color: ");
}
};
}
And usage is :
onView(withId(R.id.password_edittext)).check(matches(withTextColor(Color.RED)));