CircularProgressLayout not double clicking in Espresso

105 views Asked by At

For an Android Wear app, we use a CircularProgressLayout. Instead of allowing users to cancel their click, we want them to confirm their click within 2 seconds. So, users need to click twice within 2 seconds, to exit the app. We use a nice circular animation, so users can see how much time they have left to confirm their action.

I want to test that users can exit our app using Espresso, so I call click twice.

onView(withId(R.id.exit)).perform(click(), click());
// code to verify app was closed here

Unfortunately, Espresso will:

  • execute the 1st click
  • wait for 2 seconds
  • performs the 2nd click

Resulting in a failing test. I believe, Espresso will wait for the animation to finish, before executing the 2nd click. But in this scenario, I need the click to be executed immediately.

Extra info:

  • Animations/Transitions are disabled off course, but that does not stop the CircularProgressLayout from animating.
  • I tried perform(doubleClick()); as well, but even that will wait 2 seconds between the first and the second click.
  • I also tried abusing onLongClick() as a hack to confirm exiting the app. This does work, but it's a hack. I just want espresso to click twice.

Any suggestions how to make Espresso click twice without waiting for the animation?

1

There are 1 answers

0
Entreco On

Decided to write my own ClickTwiceViewAction. Inside the ViewAction.perform() method, it's easy to call performClick() twice.

Usage in your test:

onView(withId(R.id.exit)).perform(clickTwice(200)); // 200 is the delay between both clicks

And here's the ClickTwiceAction i write:

public class ClickTwiceViewAction implements ViewAction {

    public static ViewAction clickTwice(long delayInMillis) {
        return actionWithAssertions(new ClickTwiceViewAction(delayInMillis));
    }

    private final long mDelayInMillis;

    private ClickTwiceViewAction(long delayInMillis) {
        mDelayInMillis = delayInMillis;
    }

    @Override
    public Matcher<View> getConstraints() {
        return ViewMatchers.isAssignableFrom(CircularProgressLayout.class);
    }

    @Override
    public String getDescription() {
        return "click twice on displayed view";
    }

    @Override
    public void perform(UiController uiController, View view) {
        view.postDelayed(view::performClick, 0);
        view.postDelayed(view::performClick, mDelayInMillis);
    }
}

I constrained this action to CircularProgressLayout's only, but it can be applied to any View (if desired) by changing the getConstraints()