I have an activity that fires an asynchronous request to a server. Right when it is fired, I show a progress bar. When a result is returned to the activity, I set the progressbar to View.GONE.
I have two tests right now. One for testing trying to login with wrong credentials which works perfectly :
@Test
public void tryLogin__withWrongPassword() {
onView(withId(R.id.loginEmail))
.perform(typeText("em@ail.com"), closeSoftKeyboard());
onView(withId(R.id.loginPassword))
.perform(typeText("123456789"), closeSoftKeyboard());
onView(withId(R.id.loginSubmit))
.perform(click());
onView(withId(R.id.loginProgressBar))
.check(matches(isDisplayed()));
onView(isRoot()).perform(waitFor(3000));
onView(withId(R.id.loginProgressBar))
.check(matches(not((isDisplayed()))));
onView(withId(R.id.loginPassword))
.check(matches(hasErrorText("Wrong password")));
}
And one that I test with no internet connectivity that does not work :
@Test
public void tryLogin__withoutInternet() {
onView(withId(R.id.loginEmail))
.perform(typeText("em@ail.com"), closeSoftKeyboard());
onView(withId(R.id.loginPassword))
.perform(typeText("123456789"), closeSoftKeyboard());
onView(withId(R.id.loginSubmit))
.perform(click());
onView(withId(R.id.loginProgressBar))
.check(matches(isDisplayed()));
onView(isRoot()).perform(waitFor(3000));
onView(withId(R.id.loginProgressBar))
.check(matches(not((isDisplayed()))));
onView(withText("Network error, try again later"))
.inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView())))
.check(matches(isDisplayed()));
}
The test fails because the progressbar in this case is shown for a fraction of a second (because the error is almost immediately dispatched from the viewmodel) and seemingly Espresso cannot catch it while it is still loading.
My question is how could this potentially be fixed in my test? I have read somewhere that Espresso cannot test progress bars and the advice was to use UIAutomator instead, however I just started with Instrumented tests and chose Espresso and it is difficult for me to find the ideal tool for this case. Moreover, it seems to be working just fine when the progressbar appears for a bit more than half a second (in my first test for example)
P.S. the waitFor(long millis) method is a utility add-on method I made to force Espresso to wait for a specified amount of time before checking something (enforcing a timeout as a quality requirement)
Edit for clarification : My main question here is if anyone has an idea why the visibility is not caught when it is active for less than an amount of time vs when it lasts for more than half a second, even if the check is done immediately after the perform(click()) call.