summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Keisuke Kuroyanagi <ksk@google.com> 2015-12-06 10:03:23 -0800
committer Keisuke Kuroyanagi <ksk@google.com> 2015-12-06 10:03:23 -0800
commit46faad60230ade76b6a4944a2b9fae274698ab91 (patch)
tree447edbf47fcdbc9d94c78343f5cd7bc0f4596c8b
parentd42cb8ffa77266abe3bcffe98212d313d223a86c (diff)
TextView tests: Add mouse triple click tests.
Bug: 19544351 Change-Id: I20f1b169915a8013f7786684f97172767c162420
-rw-r--r--core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java101
-rw-r--r--core/tests/coretests/src/android/widget/espresso/DragAction.java53
-rw-r--r--core/tests/coretests/src/android/widget/espresso/MouseClickAction.java66
-rw-r--r--core/tests/coretests/src/android/widget/espresso/TextViewActions.java43
4 files changed, 257 insertions, 6 deletions
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index 7e84fb8d89af..83a9e01761d9 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -24,9 +24,12 @@ import static android.widget.espresso.TextViewActions.mouseLongClickOnTextAtInde
import static android.widget.espresso.TextViewActions.mouseDoubleClickAndDragOnText;
import static android.widget.espresso.TextViewActions.mouseDragOnText;
import static android.widget.espresso.TextViewActions.mouseLongClickAndDragOnText;
+import static android.widget.espresso.TextViewActions.mouseTripleClickAndDragOnText;
+import static android.widget.espresso.TextViewActions.mouseTripleClickOnTextAtIndex;
import static android.widget.espresso.TextViewAssertions.hasSelection;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.replaceText;
import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
@@ -190,4 +193,102 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2<
mouseLongClickAndDragOnText(text.indexOf("j"), text.indexOf("f")));
onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
}
+
+ @SmallTest
+ public void testSelectTextByTripleClick() throws Exception {
+ getActivity();
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("First paragraph.\n");
+ builder.append("Second paragraph.");
+ for (int i = 0; i < 10; i++) {
+ builder.append(" This paragraph is very long.");
+ }
+ builder.append('\n');
+ builder.append("Third paragraph.");
+ final String text = builder.toString();
+
+ onView(withId(R.id.textview)).perform(click());
+ onView(withId(R.id.textview)).perform(replaceText(text));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickOnTextAtIndex(text.indexOf("rst")));
+ onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickOnTextAtIndex(text.indexOf("cond")));
+ onView(withId(R.id.textview)).check(hasSelection(
+ text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickOnTextAtIndex(text.indexOf("ird")));
+ onView(withId(R.id.textview)).check(hasSelection("Third paragraph."));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickOnTextAtIndex(text.indexOf("very long")));
+ onView(withId(R.id.textview)).check(hasSelection(
+ text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+ }
+
+ @SmallTest
+ public void testSelectTextByTripleClickAndDrag() throws Exception {
+ getActivity();
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("First paragraph.\n");
+ builder.append("Second paragraph.");
+ for (int i = 0; i < 10; i++) {
+ builder.append(" This paragraph is very long.");
+ }
+ builder.append('\n');
+ builder.append("Third paragraph.");
+ final String text = builder.toString();
+
+ onView(withId(R.id.textview)).perform(click());
+ onView(withId(R.id.textview)).perform(replaceText(text));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("irst"), text.indexOf("st")));
+ onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("cond"), text.indexOf("Third") - 2));
+ onView(withId(R.id.textview)).check(hasSelection(
+ text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("First"), text.indexOf("ird")));
+ onView(withId(R.id.textview)).check(hasSelection(text));
+ }
+
+ @SmallTest
+ public void testSelectTextByTripleClickAndDrag_reverse() throws Exception {
+ getActivity();
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("First paragraph.\n");
+ builder.append("Second paragraph.");
+ for (int i = 0; i < 10; i++) {
+ builder.append(" This paragraph is very long.");
+ }
+ builder.append('\n');
+ builder.append("Third paragraph.");
+ final String text = builder.toString();
+
+ onView(withId(R.id.textview)).perform(click());
+ onView(withId(R.id.textview)).perform(replaceText(text));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("st"), text.indexOf("irst")));
+ onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("Third") - 2, text.indexOf("cond")));
+ onView(withId(R.id.textview)).check(hasSelection(
+ text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+ onView(withId(R.id.textview)).perform(
+ mouseTripleClickAndDragOnText(text.indexOf("ird"), text.indexOf("First")));
+ onView(withId(R.id.textview)).check(hasSelection(text));
+ }
}
diff --git a/core/tests/coretests/src/android/widget/espresso/DragAction.java b/core/tests/coretests/src/android/widget/espresso/DragAction.java
index ce975688a894..b2c8e38141b8 100644
--- a/core/tests/coretests/src/android/widget/espresso/DragAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/DragAction.java
@@ -157,6 +157,59 @@ public final class DragAction implements ViewAction {
},
/**
+ * Starts a drag with a mouse triple click.
+ */
+ MOUSE_TRIPLE_CLICK {
+ private DownMotionPerformer downMotion = new DownMotionPerformer() {
+ @Override
+ @Nullable
+ public MotionEvent perform(
+ UiController uiController, float[] coordinates, float[] precision) {
+ MotionEvent downEvent = MotionEvents.sendDown(
+ uiController, coordinates, precision)
+ .down;
+ for (int i = 0; i < 2; ++i) {
+ try {
+ if (!MotionEvents.sendUp(uiController, downEvent)) {
+ String logMessage = "Injection of up event as part of the triple "
+ + "click failed. Sending cancel event.";
+ Log.d(TAG, logMessage);
+ MotionEvents.sendCancel(uiController, downEvent);
+ return null;
+ }
+
+ long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
+ uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);
+ } finally {
+ downEvent.recycle();
+ }
+ downEvent = MotionEvents.sendDown(
+ uiController, coordinates, precision).down;
+ }
+ return downEvent;
+ }
+ };
+
+ @Override
+ public Status sendSwipe(
+ UiController uiController,
+ float[] startCoordinates, float[] endCoordinates, float[] precision) {
+ return sendLinearDrag(
+ uiController, downMotion, startCoordinates, endCoordinates, precision);
+ }
+
+ @Override
+ public String toString() {
+ return "mouse triple click and drag to select";
+ }
+
+ @Override
+ public UiController wrapUiController(UiController uiController) {
+ return new MouseUiController(uiController);
+ }
+ },
+
+ /**
* Starts a drag with a tap.
*/
TAP {
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
index de640ca1053d..e51f27857a4b 100644
--- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
@@ -22,9 +22,13 @@ import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.CoordinatesProvider;
import android.support.test.espresso.action.GeneralClickAction;
+import android.support.test.espresso.action.MotionEvents;
+import android.support.test.espresso.action.MotionEvents.DownResultHolder;
import android.support.test.espresso.action.PrecisionDescriber;
+import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Tapper;
import android.view.View;
+import android.view.ViewConfiguration;
/**
* ViewAction for performing an click on View by a mouse.
@@ -32,10 +36,58 @@ import android.view.View;
public final class MouseClickAction implements ViewAction {
private final GeneralClickAction mGeneralClickAction;
- public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider,
- PrecisionDescriber precisionDescriber) {
+ public enum CLICK implements Tapper {
+ TRIPLE {
+ @Override
+ public Tapper.Status sendTap(UiController uiController, float[] coordinates,
+ float[] precision) {
+ Tapper.Status stat = sendSingleTap(uiController, coordinates, precision);
+ boolean warning = false;
+ if (stat == Tapper.Status.FAILURE) {
+ return Tapper.Status.FAILURE;
+ } else if (stat == Tapper.Status.WARNING) {
+ warning = true;
+ }
+
+ long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
+ for (int i = 0; i < 2; i++) {
+ if (0 < doubleTapMinimumTimeout) {
+ uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);
+ }
+ stat = sendSingleTap(uiController, coordinates, precision);
+ if (stat == Tapper.Status.FAILURE) {
+ return Tapper.Status.FAILURE;
+ } else if (stat == Tapper.Status.WARNING) {
+ warning = true;
+ }
+ }
+
+ if (warning) {
+ return Tapper.Status.WARNING;
+ } else {
+ return Tapper.Status.SUCCESS;
+ }
+ }
+ };
+
+ private static Tapper.Status sendSingleTap(UiController uiController,
+ float[] coordinates, float[] precision) {
+ DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision);
+ try {
+ if (!MotionEvents.sendUp(uiController, res.down)) {
+ MotionEvents.sendCancel(uiController, res.down);
+ return Tapper.Status.FAILURE;
+ }
+ } finally {
+ res.down.recycle();
+ }
+ return res.longPress ? Tapper.Status.WARNING : Tapper.Status.SUCCESS;
+ }
+ };
+
+ public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider) {
mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider,
- precisionDescriber);
+ Press.PINPOINT);
}
@Override
@@ -51,5 +103,13 @@ public final class MouseClickAction implements ViewAction {
@Override
public void perform(UiController uiController, View view) {
mGeneralClickAction.perform(new MouseUiController(uiController), view);
+ long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout();
+ if (0 < doubleTapTimeout) {
+ // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be
+ // detected as a triple click. e.g. 2 double clicks are detected as a triple click and
+ // a single click because espresso isn't aware of triple click detection logic, which
+ // is TextView specific gesture.
+ uiController.loopMainThreadForAtLeast(doubleTapTimeout);
+ }
}
}
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 32cc6d648556..54d5823c7aca 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -64,7 +64,7 @@ public final class TextViewActions {
*/
public static ViewAction mouseClickOnTextAtIndex(int index) {
return actionWithAssertions(
- new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), Press.PINPOINT));
+ new MouseClickAction(Tap.SINGLE, new TextCoordinates(index)));
}
/**
@@ -94,7 +94,7 @@ public final class TextViewActions {
*/
public static ViewAction mouseDoubleClickOnTextAtIndex(int index) {
return actionWithAssertions(
- new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.PINPOINT));
+ new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index)));
}
/**
@@ -124,7 +124,22 @@ public final class TextViewActions {
*/
public static ViewAction mouseLongClickOnTextAtIndex(int index) {
return actionWithAssertions(
- new MouseClickAction(Tap.LONG, new TextCoordinates(index), Press.PINPOINT));
+ new MouseClickAction(Tap.LONG, new TextCoordinates(index)));
+ }
+
+ /**
+ * Returns an action that triple-clicks by mouse on text at an index on the TextView.<br>
+ * <br>
+ * View constraints:
+ * <ul>
+ * <li>must be a TextView displayed on screen
+ * <ul>
+ *
+ * @param index The index of the TextView's text to triple-click on.
+ */
+ public static ViewAction mouseTripleClickOnTextAtIndex(int index) {
+ return actionWithAssertions(
+ new MouseClickAction(MouseClickAction.CLICK.TRIPLE, new TextCoordinates(index)));
}
/**
@@ -237,6 +252,28 @@ public final class TextViewActions {
TextView.class));
}
+ /**
+ * Returns an action that triple click then drags by mouse on text from startIndex to endIndex
+ * on the TextView.<br>
+ * <br>
+ * View constraints:
+ * <ul>
+ * <li>must be a TextView displayed on screen
+ * <ul>
+ *
+ * @param startIndex The index of the TextView's text to start a drag from
+ * @param endIndex The index of the TextView's text to end the drag at
+ */
+ public static ViewAction mouseTripleClickAndDragOnText(int startIndex, int endIndex) {
+ return actionWithAssertions(
+ new DragAction(
+ DragAction.Drag.MOUSE_TRIPLE_CLICK,
+ new TextCoordinates(startIndex),
+ new TextCoordinates(endIndex),
+ Press.PINPOINT,
+ TextView.class));
+ }
+
public enum Handle {
SELECTION_START,
SELECTION_END,