Skip to content

Instantly share code, notes, and snippets.

@xanderblinov
Created July 9, 2019 12:43
Show Gist options
  • Save xanderblinov/2baa6d87d25e1fbb14d4d8195905cbde to your computer and use it in GitHub Desktop.
Save xanderblinov/2baa6d87d25e1fbb14d4d8195905cbde to your computer and use it in GitHub Desktop.
private const val WAITER_TIMEOUT_S: Long = 10L
private const val WAITER_FREQUENCY_MS: Long = 50L
private const val VISIBLE_EXCEPTION = "'view has effective visibility=VISIBLE' doesn't match the selected view."
fun KRecyclerView.waitForChildVisible(position: Int, timeoutS: Long = WAITER_TIMEOUT_S) {
doWaitForMatchingView(timeoutS) {
childAt<KRecyclerItem<Unit>>(position) {
isVisible()
}
}
}
private inline fun doWaitForMatchingView(
timeoutS: Long = WAITER_TIMEOUT_S,
checkErrorSkip: (AssertionFailedError) -> Boolean = { e -> e.message?.contains(VISIBLE_EXCEPTION) == true },
action: () -> Unit
) {
var timerMs = 0L
val startTimeMs = System.currentTimeMillis()
val frequencyMs = WAITER_FREQUENCY_MS
val timeoutMs = TimeUnit.SECONDS.toMillis(timeoutS)
var throwable: Throwable
do {
try {
action.invoke()
return
} catch (e: NoMatchingViewException) {
Thread.sleep(frequencyMs)
timerMs += frequencyMs
throwable = e
} catch (e: AssertionFailedError) {
if (checkErrorSkip.invoke(e)) {
Thread.sleep(frequencyMs)
timerMs += frequencyMs
throwable = e
} else {
throw e
}
}
} while (timerMs <= timeoutMs && System.currentTimeMillis() - startTimeMs <= timeoutMs)
throw throwable
}
fun RecyclerActions.scrollToEndWithPagination() {
scrollToEnd()
view.perform(ViewActions.swipeUp())
}
fun <T : KRecyclerItem<T>> KRecyclerView.paginateUntilChildMatching(
childMatcher: ViewBuilder.() -> Unit,
timeoutS: Long = WAITER_TIMEOUT_S) {
while (true) {
val count = getSize()
try {
val child = childWith<KRecyclerItem<T>>(childMatcher)
child.isVisible()
break
} catch (e: NoMatchingViewException) {
scrollToEndWithPagination()
waitSeconds(timeoutS)
if (count == getSize()) {
throw e
}
}
}
}
fun waitSeconds(timeoutS: Long = WAITER_TIMEOUT_S) {
Thread.sleep(TimeUnit.SECONDS.toMillis(timeoutS))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment