Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Espresso performs longClick instead of click

onData(anything()).inAdapterView(withId(R.id.ScheduleOrderListViewListView))
                .atPosition(0).perform(click());

perfoms 50% of the time a longtouch - is there are a good workaround?

like image 215
PKAP Avatar asked Sep 01 '15 11:09

PKAP


3 Answers

This is an unfortunate side effect of how tap events are passed from your test code over RPC to the Android application under test. The best description of why clicks are sometimes executed as long clicks can be found in the Espresso source code.

It is unlikely this issue will be fixed anytime soon. The best option you have of avoiding the issue is to run your tests on higher spec devices. This is because the likelihood of the issue occurring is dependent on system load.

like image 144
Charles Harley Avatar answered Nov 10 '22 04:11

Charles Harley


Adding to what Charles said, I found 3 workarounds here: https://github.com/misyobun/android-test-kit/issues/45

Workaround 1: (and maybe the best one) is to pass a rollback action in case the click turns into a long click. In case this happened, the long click would be "cancelled" and espresso will try the click again.

/**
   * Returns an action that performs a single click on the view.
   *
   * If the click takes longer than the 'long press' duration (which is possible) the provided
   * rollback action is invoked on the view and a click is attempted again.
   *
   * This is only necessary if the view being clicked on has some different behaviour for long press
   * versus a normal tap.
   *
   * For example - if a long press on a particular view element opens a popup menu -
   * ViewActions.pressBack() may be an acceptable rollback action.
   *
   * <br>
   * View constraints:
   * <ul>
   * <li>must be displayed on screen</li>
   * <li>any constraints of the rollbackAction</li>
   * <ul>
   */
  public static ViewAction click(ViewAction rollbackAction) {
    checkNotNull(rollbackAction);
    return new GeneralClickAction(Tap.SINGLE, GeneralLocation.CENTER, Press.FINGER,
        rollbackAction);
  }

Workaround 2: is not the "espresso way", but it might fit some scenarios:

public class CallOnClickAction implements ViewAction {
    @Override
    public Matcher<View> getConstraints() {
        return allOf(isClickable(), isDisplayed());
    }

    @Override
    public String getDescription() {
        return "CallOnClick";
    }

    @Override
    public void perform(UiController uiController, View view) {
        view.callOnClick();

    }
 }

Workaround 3: If you're not using double click on that view, it might be useful in this case.

like image 31
Yair Kukielka Avatar answered Nov 10 '22 02:11

Yair Kukielka


Another additional workaround is running the following command on API level > 16

adb shell settings put secure long_press_timeout 1500
like image 4
Nick Korostelev Avatar answered Nov 10 '22 03:11

Nick Korostelev