Thread.sleep( ) with Espresso
android, android-espresso, testing
Solution
On my mind correct approach will be:
/** Perform action of waiting for a specific view id. */
public static ViewAction waitId(final int viewId, final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "wait for a specific view with id <" + viewId + "> during " + millis + " millis.";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
final Matcher<View> viewMatcher = withId(viewId);
do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
// found view with required ID
if (viewMatcher.matches(child)) {
return;
}
}
uiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);
// timeout happens
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(new TimeoutException())
.build();
}
};
}
And then pattern of usage will be:
// wait during 15 seconds for a view
onView(isRoot()).perform(waitId(R.id.dialogEditor, TimeUnit.SECONDS.toMillis(15)));
Problem
Espresso claims that there is no need for `Thread.sleep()` but my code doesn't work unless I include it. I am connecting to an IP and, while connecting, a progress dialog is shown. I need a `Thread.sleep()` call to wait for the dialog to dismiss. This is my test code where I use it: ``` IP.enterIP(); // fills out an IP dialog (this is done with espresso) //progress dialog is now shown Thread.sleep(1500); onView(withId(R.id.button).perform(click()); ``` I have tried this code without the `Thread.sleep()` call but it says `R.id.Button` doesn't exist. The only way I can get it to work is with the `Thread.sleep()` call. Also, I have tried replacing `Thread.sleep()` with things like `getInstrumentation().waitForIdleSync()` and still no luck. Is this the only way to do this? Or am I missing something?