I have a TextView
that shows a "loading" string... and I need to wait till this view is gone ... I don't have a handle on the Asynctask
because this method is running in a IntentService
and sends a broadcast when the loading is finished.
Any idea about how to wait in an Espresso test for a change in a view's status? I'll need the same with some strings that will change and need to wait for that... I supposed it's the same case ...
Thanks for the help. There are not many examples or FAQs on the net.
This has been answered here.
You can handle this case by registering an IdlingResource for your web service with Espresso. Take a look at this write-up.
Most likely, you'll want to use CountingIdlingResource (which uses a simple counter to track when something is idle). This sample test demonstrates how this can be done.
You can define a ViewAction
that loops the main thread every 50 milliseconds (or a different time of your choosing) until either the visibility of the View
in question changes to View.GONE
or a maximum amount of time elapses.
Define the ViewAction
as follows:
/**
* A [ViewAction] that waits up to [timeout] milliseconds for a [View]'s visibility value to change to [View.GONE].
*/
class WaitUntilGoneAction(private val timeout: Long) : ViewAction {
override fun getConstraints(): Matcher<View> {
return any(View::class.java)
}
override fun getDescription(): String {
return "wait up to $timeout milliseconds for the view to be gone"
}
override fun perform(uiController: UiController, view: View) {
val endTime = System.currentTimeMillis() + timeout
do {
if (view.visibility == View.GONE) return
uiController.loopMainThreadForAtLeast(50)
} while (System.currentTimeMillis() < endTime)
throw PerformException.Builder()
.withActionDescription(description)
.withCause(TimeoutException("Waited $timeout milliseconds"))
.withViewDescription(HumanReadables.describe(view))
.build()
}
}
Define a function that creates an instance of this ViewAction
when called, as follows:
/**
* @return a [WaitUntilGoneAction] instance created with the given [timeout] parameter.
*/
fun waitUntilGone(timeout: Long): ViewAction {
return WaitUntilGoneAction(timeout)
}
Call on this ViewAction
in your test method as follows:
onView(withId(R.id.loadingTextView)).perform(waitUntilGone(3000L))
You can take this concept and similarly create a WaitForTextAction
class that waits until a TextView
's text changes to a certain value. In this case, however, you'll probably want to change the Matcher
returned by the getConstraints()
function from any(View::class.java)
to any(TextView::class.java)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With