I am testing whether the right message is displayed after unfavoriting a recipe. To prepare for the test, I am conditionally checking whether it is already favorited. If it isn't, I favorite it in the setup so that it can be unfavorited in the test.
This is the menu item:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/save_to_favorites_menu"
android:icon="@drawable/ic_star"
android:title="@string/save_to_favorites"
app:showAsAction="ifRoom"
android:iconTint="@color/white"
tools:targetApi="o" />
</menu>
These are my tests:
@Before
fun setUp(){
// Click on the first recipe
Espresso.onView(ViewMatchers.withId(R.id.recyclerview))
.perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(0,
ViewActions.click()
))
// Add to favorites if it the favorite button is not checked
if (!isChecked(R.id.save_to_favorites_menu)){
// click on the favorites button
Espresso.onView(ViewMatchers.withId(R.id.save_to_favorites_menu))
.perform(ViewActions.click())
Thread.sleep(5000)
}
}
@Test
fun testRemoveFromFavorites(){
// click on the favorite button
Espresso.onView(ViewMatchers.withId(R.id.save_to_favorites_menu))
.perform(ViewActions.click())
// check whether the right text is displayed
Espresso.onView(ViewMatchers.withText("Removed from Favorites."))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
}
And this is my isChecked function:
// check button state by action view
fun isChecked(menuItemId: Int): Boolean {
var isChecked = false
// Use Espresso to check the menu item
Espresso.onView(ViewMatchers.withId(menuItemId))
.check { view, _ ->
if (view is MenuItem) {
isChecked = view.isActionViewExpanded
}
}
return isChecked
}
I even tried checking the state if the button by checking its color like this:
Explanation: the star is sometimes white, sometimes black when it is not checked. It is yellow when it is checked, but I don't know what I should type after "R.color" for yellow color, which is why I am testing the opposite scenario - "button not checked".
fun isNotCheckedByColor(buttonId: Int): Boolean {
var isChecked = true
val viewInteraction = Espresso.onView(ViewMatchers.withId(buttonId))
viewInteraction.check { view, _ ->
if (view is Button) {
val buttonBackground: Drawable = view.background
// Get the color resource for white
val whiteColorResource = R.color.white
val whiteColor = ContextCompat.getColor(view.context, whiteColorResource)
// Get the color resource for black
val blackColorResource = R.color.black
val blackColor = ContextCompat.getColor(view.context, blackColorResource)
val colorDrawable = buttonBackground as? ColorDrawable
if (colorDrawable != null && (colorDrawable.color == whiteColor || colorDrawable.color == blackColor)) {
isChecked = false
}
}
}
return isChecked
}
Nothing seems to work. isChecked always returns false and isNotCheckedByColor always returns true. Any idea why and how to fix it? Thank you in advance.