You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use long-loading RecyclerView items in a standard RecyclerView
call scrollToEnd() in a UI test
Observed Results:
The code
val lastView = view.findViewHolderForLayoutPosition(position)!!.itemView
view.scrollBy(0, lastView.height)
throws a NullPointerException because lastView is null.
Expected Results:
I expected the RecyclerView just to scroll down to have the last item fully visible.
Relevant Code:
override fun scrollToEnd() {
view.perform(object : ViewAction {
override fun getDescription() = "Scroll RecyclerView to the bottom"
override fun getConstraints() = ViewMatchers.isAssignableFrom(RecyclerView::class.java)
override fun perform(controller: UiController, view: View) {
if (view is RecyclerView) {
val position = view.adapter!!.itemCount - 1
view.scrollToPosition(position)
controller.loopMainThreadUntilIdle()
val lastView = view.findViewHolderForLayoutPosition(position)!!.itemView
view.scrollBy(0, lastView.height)
controller.loopMainThreadUntilIdle()
}
}
})
}
Workaround:
I've created an extension function to still be able to do what I'd like to do:
fun KRecyclerView.scrollToEndRepeatedly(repetitions: Int) {
view.perform(
object : ViewAction {
override fun getDescription() =
"Scroll RecyclerView to the bottom"
override fun getConstraints() =
ViewMatchers.isAssignableFrom(
RecyclerView::class.java
)
override fun perform(controller: UiController, view: View) {
if (view is RecyclerView) {
var lastViewFound = false
var tryCount = 0
do {
tryCount++
val position = view.adapter!!.itemCount - 1
view.scrollToPosition(position)
controller.loopMainThreadUntilIdle()
val lastView =
view.findViewHolderForLayoutPosition(
position
)
lastView?.let {
view.scrollBy(0, lastView.itemView.height)
lastViewFound = false
}
controller.loopMainThreadUntilIdle()
} while ((!lastViewFound) && (tryCount < repetitions))
}
}
}
)
}
While this does what it's supposed to do, I think, there must be a better solution using interceptors which fit's more naturally into Kakaos concepts, i.e. making the repetions parameter superfluous.
The text was updated successfully, but these errors were encountered:
@cee-dee@AlexeyRybakov what do you mean under "long-loading items"?
If it some view what related on async calls - you may use IdleResources for it. Otherwise it those views is "long-loaded" because of device performance it should't be a problem because it will block UI thread.
If your RecyclerView's adapter and layout manager cannot layout all children in a single layout pass - there is not much Espresso and Kakao can do for you. You either need to optimize your RecyclerView to be able to layout all items in adapter as it is expected by the system, or use your own extension or try/catch with retry blocks in the test itself.
This is a very specific corner case and is not system expected behavior, so I don't see a lot of value into supporting it as part of the library.
Steps to reproduce:
scrollToEnd()
in a UI testObserved Results:
The code
throws a
NullPointerException
becauselastView
isnull
.Expected Results:
I expected the RecyclerView just to scroll down to have the last item fully visible.
Relevant Code:
Workaround:
I've created an extension function to still be able to do what I'd like to do:
While this does what it's supposed to do, I think, there must be a better solution using interceptors which fit's more naturally into Kakaos concepts, i.e. making the
repetions
parameter superfluous.The text was updated successfully, but these errors were encountered: