2

Assume there are two activities A and B. A is login activity which has username, password fields and login button. Once username and password entered and login button clicked, it make a network call.

If we are going to test views of that in same activity it will work (if not we can use custom IdlingResource and manage).

I want to test B activity once the login process completed. But B activity is also having some network calls (meanwhile progress bar appears). So straight onView() assertions get failed. Is there is a standard way to achieve this? It can be acheived by adding Thread.sleep() statements before onView() assertions, which I don't want to do. How can I test this scenario.

Ruwanka De Silva
  • 3,555
  • 6
  • 35
  • 51
  • Which technique do you use for network calls? Espresso can only detect and wait for parallel execution when using AsyncTask class. – nenick Jun 17 '16 at 11:55
  • I am using [retrofit](http://square.github.io/retrofit/). So I use [IdlingResource](https://developer.android.com/reference/android/support/test/espresso/IdlingResource.html) to make Espresso wait until calls complete. It is working fine there is no issue. What I want have is make Espresso wait for second activity's call completion. – Ruwanka De Silva Jun 17 '16 at 15:08

1 Answers1

0

If your second activity has visual sign of operation completed, you can use this solution:

Create interface:

/**
* Interface for expectations of compliance with the conditions.
*/
public interface Condition {
 /**
  * @return text description for log output when check failed.
 */
 String getDescription();

 /**
  * @return true if the condition is met.
  */
 boolean check();
}

And use it like this:

/**
* Wait while condition come true or timeout limit.
*
* @param condition condition for exit
* @param timeout   limit in seconds
* @throws Exception exception
*/
public static void waitForCondition(Condition condition, int timeout) throws Exception {
final int CONDITION_NOT_MET = 0;
final int CONDITION_MET = 1;
final int TIMEOUT = 2;

final int INTERVAL = 250;

int status = CONDITION_NOT_MET;
int elapsedTime = 0;

do {
  if (condition.check()) {
    status = CONDITION_MET;
  } else {
    elapsedTime += INTERVAL;
    delay(INTERVAL);
  }

  if (elapsedTime >= timeout * 1000) {
    status = TIMEOUT;
    break;
  }
} while (status != CONDITION_MET);

if (status == TIMEOUT) {
  String msg = condition.getDescription() + " - took more than " + timeout + " seconds. Test stopped.";
  log(msg);
  throw new Exception(msg);
 }
}

Example:

public class MovieScreenVisible implements Condition {
  @Override
  public String getDescription() {
    return "Movie screen should be on the top";
  }

  @Override
  public boolean check() {
    Activity activity = TestBase.getCurrentActivity();
    if (activity == null || !(activity instanceof MovieActivity)) {
      return false;
    }

    ViewGroup layout = activity.findViewById(R.id.movie_fragment);
    return layout != null && layout.getVisibility() == View.VISIBLE;
  }
}

// wait maximum 30 seconds until movie screen should be visible
waitForCondition(new MovieScreenVisible(), 30); 
MaxF
  • 2,123
  • 1
  • 14
  • 17