Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Espresso & Brioche
public class CustomMatchers {
public static Matcher<View> withBackground(final int resourceId) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(View view) {
return sameBitmap(view.getContext(), view.getBackground(), resourceId);
}
@Override
public void describeTo(Description description) {
description.appendText("has background resource " + resourceId);
}
};
}
public static Matcher<View> withCompoundDrawable(final int resourceId) {
return new BoundedMatcher<View, TextView>(TextView.class) {
@Override
public void describeTo(Description description) {
description.appendText("has compound drawable resource " + resourceId);
}
@Override
public boolean matchesSafely(TextView textView) {
for (Drawable drawable : textView.getCompoundDrawables()) {
if (sameBitmap(textView.getContext(), drawable, resourceId)) {
return true;
}
}
return false;
}
};
}
public static Matcher<View> withImageDrawable(final int resourceId) {
return new BoundedMatcher<View, ImageView>(ImageView.class) {
@Override
public void describeTo(Description description) {
description.appendText("has image drawable resource " + resourceId);
}
@Override
public boolean matchesSafely(ImageView imageView) {
return sameBitmap(imageView.getContext(), imageView.getDrawable(), resourceId);
}
};
}
private static boolean sameBitmap(Context context, Drawable drawable, int resourceId) {
Drawable otherDrawable = context.getResources().getDrawable(resourceId);
if (drawable == null || otherDrawable == null) {
return false;
}
if (drawable instanceof StateListDrawable && otherDrawable instanceof StateListDrawable) {
drawable = drawable.getCurrent();
otherDrawable = otherDrawable.getCurrent();
}
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap otherBitmap = ((BitmapDrawable) otherDrawable).getBitmap();
return bitmap.sameAs(otherBitmap);
}
return false;
}
}
public class EspressoTest extends ActivityInstrumentationTestCase2<ShoppingActivity> {
@Override
public void setUp() throws Exception {
super.setUp();
setupInjections();
setupPreferences();
getActivity();
}
public void test_the_background_is_visible() throws Exception {
onView(withImageDrawable(R.drawable.some_background)).check(matches(isDisplayed()));
}
public void test_the_card_has_a_specific_image() throws Exception {
onView(withId(R.id.some_card)).check(matches(withImageDrawable(R.drawable.my_card));
}
public void test_this_textview_is_reused_so_we_have_to_manually_look_for_it() throws Exception {
onView(allOf(withId(R.id.some_card), withParent(withId(R.id.textview_parent_left)))).check(matches(withCompoundDrawable(R.drawable.left_drawable));
}
}
@denyszelenchuk

This comment has been minimized.

Copy link

denyszelenchuk commented May 26, 2014

thanks, it's really helpful.

@1fish2

This comment has been minimized.

Copy link

1fish2 commented Jan 2, 2017

Very helpful!

I tweaked sameBitmap() to unconditionally call *drawable.getCurrent(), check that otherDrawable is also a BitmapDrawable, and check that bitmap != null. Over-cautious?

@xiuquanw

This comment has been minimized.

Copy link

xiuquanw commented Apr 2, 2019

great work!

@jackplugs

This comment has been minimized.

Copy link

jackplugs commented Aug 26, 2019

The method sameBitmap() doesn't work in case the drawable is chosen from a <selector/> (meaning the drawable is a StateListSelector)

I used this code instead and it works :

private fun sameBitmap(
        context: Context,
        drawable: Drawable?,
        resourceId: Int,
        view: View
    ): Boolean {
        var drawable = drawable
        val otherDrawable: Drawable? = context.resources.getDrawable(resourceId)
        if (drawable == null || otherDrawable == null) {
            return false
        }

        if (drawable is StateListDrawable && view != null) {
            val getStateDrawableIndex =
                StateListDrawable::class.java.getMethod(
                    "getStateDrawableIndex",
                    IntArray::class.java
                )
            val getStateDrawable =
                StateListDrawable::class.java.getMethod(
                    "getStateDrawable",
                    Int::class.javaPrimitiveType
                )
            val index = getStateDrawableIndex.invoke(drawable, view.drawableState)
            drawable = getStateDrawable.invoke(drawable, index) as Drawable
        }

        val bitmap = getBitmapFromDrawable(context, drawable)
        val otherBitmap = getBitmapFromDrawable(context, otherDrawable)
        return bitmap.sameAs(otherBitmap)
    }
fun getBitmapFromDrawable(context: Context?, drawable: Drawable): Bitmap {
        val bitmap: Bitmap = Bitmap.createBitmap(
            drawable.intrinsicWidth,
            drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
        )
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)
        return bitmap
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.