Skip to content

Instantly share code, notes, and snippets.

@gildor
Last active March 17, 2022 02:29
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gildor/d371f8dcd17b0d398d698d28ab9fd3f3 to your computer and use it in GitHub Desktop.
Save gildor/d371f8dcd17b0d398d698d28ab9fd3f3 to your computer and use it in GitHub Desktop.
Simple implementation of Android Espresso onView with timeout
import android.view.View
import androidx.test.espresso.Espresso
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import org.hamcrest.Matcher
/**
* onView with retry logic, it will try to find view using [matcher]
* until it passes [retryAssertion] check, if it passed, [ViewInteraction] for
* this view will be returned
*
* Default [retryAssertion] checks that view is at least visible, if it hidden, we will retry attempt
* it doesn't check for isDisplayed() because it not related to this check
* (that view is displayed to user), the fact that view isDisplayed must be ensured
* by test itself, this matcher only retries until view becomes visible.
* But this behaviour can be changed if you pass custom [retryAssertion]
*
* This method should be used only for views which showed asynchronously
* and do not have any loading indicator for this asynchronous operation
*
* So it's better than simple Thread.sleep(SomeRandomDelay), but worse than relying on UI loader
*/
fun onViewWithTimeout(
retries: Int = 10,
retryDelayMs: Long = 500,
retryAssertion: ViewAssertion = matches(withEffectiveVisibility(Visibility.VISIBLE)),
matcher: Matcher<View>
): ViewInteraction {
repeat(retries) { i ->
try {
val viewInteraction = Espresso.onView(matcher)
viewInteraction.check(retryAssertion)
return viewInteraction
} catch (e: NoMatchingViewException) {
if (i >= retries) {
throw e
} else {
Thread.sleep(retryDelayMs)
}
}
}
throw AssertionError("View matcher is broken for $matcher")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment