Issue
Is there a way in Espresso to check the state of a BottomSheetBehavior
? For example, I would like to be able to write the following code to check that the BottomSheetBehavior
attached to myLayout
has state BottomSheetBehavior.STATE_COLLAPSED
:
onView(withId(R.id.myLayout)).check(matches(hasBottomSheetBehaviorState(BottomSheetBehavior.STATE_COLLAPSED)))
Are there any Espresso matchers for a Layout
's BottomSheetBehavior
?
Solution
Adding onto Michael's answer, one thing that might help with a more friendly error message if your test fails is a simple function converting the Int
into a user friendly message.
private fun getFriendlyBottomSheetBehaviorStateDescription(state: Int): String = when (state) {
BottomSheetBehavior.STATE_DRAGGING -> "dragging"
BottomSheetBehavior.STATE_SETTLING -> "settling"
BottomSheetBehavior.STATE_EXPANDED -> "expanded"
BottomSheetBehavior.STATE_COLLAPSED -> "collapsed"
BottomSheetBehavior.STATE_HIDDEN -> "hidden"
BottomSheetBehavior.STATE_HALF_EXPANDED -> "half-expanded"
else -> "unknown but the value was $state"
}
fun hasBottomSheetBehaviorState(expectedState: Int): Matcher<in View>? {
return object : BoundedMatcher<View, View>(View::class.java) {
override fun describeTo(description: Description) {
description.appendText("has BottomSheetBehavior state: ${getFriendlyBottomSheetBehaviorStateDescription(expectedState)}")
}
override fun matchesSafely(view: View): Boolean {
val bottomSheetBehavior = BottomSheetBehavior.from(view)
return expectedState == bottomSheetBehavior.state
}
}
}
Then if you were to run the test with the original sample.
onView(withId(R.id.myLayout)).check(matches(hasBottomSheetBehaviorState(BottomSheetBehavior.STATE_COLLAPSED)))
It would output the following instead of just a number.
Caused by: junit.framework.AssertionFailedError: 'has BottomSheetBehavior state: collapsed' doesn't match the selected view.
Also worth noting using the following approach does require creating an idling resource to avoid espresso trying to achieve this assertion while the bottom sheet behavior is not settled. There might be a better way, but I made use of the CountingIdlingResource to increment when the bottom sheet was settling and decrementing for everything else which worked in my use case of testing.
bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_SETTLING) {
countingIdlingResource.increment()
} else {
countingIdlingResource.decrement()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
Answered By - Andrew Steinmetz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.