Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ff41d4a authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi
Browse files

Add TextView mouse tests for long click and double click.

Bug: 19544351
Change-Id: I4f3fe633c01c443441ff0ef1617bad34c17ab508
parent 8286a6d8
Loading
Loading
Loading
Loading
+104 −0
Original line number Diff line number Diff line
@@ -16,7 +16,11 @@

package android.widget;

import static android.widget.espresso.TextViewActions.mouseDoubleClickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.mouseLongClickOnTextAtIndex;
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.TextViewAssertions.hasSelection;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
@@ -62,4 +66,104 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2<

        onView(withId(R.id.textview)).check(hasSelection("llo wor"));
    }

    @SmallTest
    public void testSelectTextByLongClick() throws Exception {
        getActivity();

        final String helloWorld = "Hello world!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));

        onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(0));
        onView(withId(R.id.textview)).check(hasSelection("Hello"));

        onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(
                helloWorld.indexOf("world")));
        onView(withId(R.id.textview)).check(hasSelection("world"));

        onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(
                helloWorld.indexOf("llo")));
        onView(withId(R.id.textview)).check(hasSelection("Hello"));

        onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(
                helloWorld.indexOf("rld")));
        onView(withId(R.id.textview)).check(hasSelection("world"));
    }

    @SmallTest
    public void testSelectTextByDoubleClick() throws Exception {
        getActivity();

        final String helloWorld = "Hello world!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));

        onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(0));
        onView(withId(R.id.textview)).check(hasSelection("Hello"));

        onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(
                helloWorld.indexOf("world")));
        onView(withId(R.id.textview)).check(hasSelection("world"));

        onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(
                helloWorld.indexOf("llo")));
        onView(withId(R.id.textview)).check(hasSelection("Hello"));

        onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(
                helloWorld.indexOf("rld")));
        onView(withId(R.id.textview)).check(hasSelection("world"));
    }

    @SmallTest
    public void testSelectTextByDoubleClickAndDrag() throws Exception {
        getActivity();

        final String text = "abcd efg hijk lmn";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));

        onView(withId(R.id.textview)).perform(
                mouseDoubleClickAndDragOnText(text.indexOf("f"), text.indexOf("j")));
        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
    }

    @SmallTest
    public void testSelectTextByDoubleClickAndDrag_reverse() throws Exception {
        getActivity();

        final String text = "abcd efg hijk lmn";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));

        onView(withId(R.id.textview)).perform(
                mouseDoubleClickAndDragOnText(text.indexOf("j"), text.indexOf("f")));
        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
    }

    @SmallTest
    public void testSelectTextByLongPressAndDrag() throws Exception {
        getActivity();

        final String text = "abcd efg hijk lmn";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));

        onView(withId(R.id.textview)).perform(
                mouseLongClickAndDragOnText(text.indexOf("f"), text.indexOf("j")));
        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
    }

    @SmallTest
    public void testSelectTextByLongPressAndDrag_reverse() throws Exception {
        getActivity();

        final String text = "abcd efg hijk lmn";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));

        onView(withId(R.id.textview)).perform(
                mouseLongClickAndDragOnText(text.indexOf("j"), text.indexOf("f")));
        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
    }
}
+105 −28
Original line number Diff line number Diff line
@@ -90,6 +90,72 @@ public final class DragAction implements ViewAction {
            }
        },

        /**
         * Starts a drag with a mouse double click.
         */
        MOUSE_DOUBLE_CLICK {
            private DownMotionPerformer downMotion = new DownMotionPerformer() {
                @Override
                @Nullable
                public MotionEvent perform(
                        UiController uiController,  float[] coordinates, float[] precision) {
                    return performDoubleTap(uiController, coordinates, precision);
                }
            };

            @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 double click and drag to select";
            }

            @Override
            public UiController wrapUiController(UiController uiController) {
                return new MouseUiController(uiController);
            }
        },

        /**
         * Starts a drag with a mouse long click.
         */
        MOUSE_LONG_CLICK {
            private DownMotionPerformer downMotion = new DownMotionPerformer() {
                @Override
                public MotionEvent perform(
                        UiController uiController, float[] coordinates, float[] precision) {
                    MotionEvent downEvent = MotionEvents.sendDown(
                            uiController, coordinates, precision)
                            .down;
                    return performLongPress(uiController, coordinates, precision);
                }
            };

            @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 long click and drag to select";
            }

            @Override
            public UiController wrapUiController(UiController uiController) {
                return new MouseUiController(uiController);
            }
        },

        /**
         * Starts a drag with a tap.
         */
@@ -127,15 +193,7 @@ public final class DragAction implements ViewAction {
                @Override
                public MotionEvent perform(
                        UiController uiController, float[] coordinates, float[] precision) {
                    MotionEvent downEvent = MotionEvents.sendDown(
                            uiController, coordinates, precision)
                            .down;
                    // Duration before a press turns into a long press.
                    // Factor 1.5 is needed, otherwise a long press is not safely detected.
                    // See android.test.TouchUtils longClickView
                    long longPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
                    uiController.loopMainThreadForAtLeast(longPressTimeout);
                    return downEvent;
                    return performLongPress(uiController, coordinates, precision);
                }
            };

@@ -162,25 +220,7 @@ public final class DragAction implements ViewAction {
                @Nullable
                public MotionEvent perform(
                        UiController uiController,  float[] coordinates, float[] precision) {
                    MotionEvent downEvent = MotionEvents.sendDown(
                            uiController, coordinates, precision)
                            .down;
                    try {
                        if (!MotionEvents.sendUp(uiController, downEvent)) {
                            String logMessage = "Injection of up event as part of the double tap " +
                                    "failed. Sending cancel event.";
                            Log.d(TAG, logMessage);
                            MotionEvents.sendCancel(uiController, downEvent);
                            return null;
                        }

                        long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
                        uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);

                        return MotionEvents.sendDown(uiController, coordinates, precision).down;
                    } finally {
                        downEvent.recycle();
                    }
                    return performDoubleTap(uiController, coordinates, precision);
                }
            };

@@ -267,6 +307,43 @@ public final class DragAction implements ViewAction {
            return res;
        }

        private static MotionEvent performLongPress(
                UiController uiController, float[] coordinates, float[] precision) {
            MotionEvent downEvent = MotionEvents.sendDown(
                    uiController, coordinates, precision)
                    .down;
            // Duration before a press turns into a long press.
            // Factor 1.5 is needed, otherwise a long press is not safely detected.
            // See android.test.TouchUtils longClickView
            long longPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
            uiController.loopMainThreadForAtLeast(longPressTimeout);
            return downEvent;
        }

        @Nullable
        private static MotionEvent performDoubleTap(
                UiController uiController,  float[] coordinates, float[] precision) {
            MotionEvent downEvent = MotionEvents.sendDown(
                    uiController, coordinates, precision)
                    .down;
            try {
                if (!MotionEvents.sendUp(uiController, downEvent)) {
                    String logMessage = "Injection of up event as part of the double tap " +
                            "failed. Sending cancel event.";
                    Log.d(TAG, logMessage);
                    MotionEvents.sendCancel(uiController, downEvent);
                    return null;
                }

                long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
                uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);

                return MotionEvents.sendDown(uiController, coordinates, precision).down;
            } finally {
                downEvent.recycle();
            }
        }

        @Override
        public UiController wrapUiController(UiController uiController) {
            return uiController;
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.widget.espresso;

import org.hamcrest.Matcher;

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.PrecisionDescriber;
import android.support.test.espresso.action.Tapper;
import android.view.View;

/**
 * ViewAction for performing an click on View by a mouse.
 */
public final class MouseClickAction implements ViewAction {
    private final GeneralClickAction mGeneralClickAction;

    public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider,
            PrecisionDescriber precisionDescriber) {
        mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider,
                precisionDescriber);
    }

    @Override
    public Matcher<View> getConstraints() {
        return mGeneralClickAction.getConstraints();
    }

    @Override
    public String getDescription() {
        return mGeneralClickAction.getDescription();
    }

    @Override
    public void perform(UiController uiController, View view) {
        mGeneralClickAction.perform(new MouseUiController(uiController), view);
    }
}
+89 −0
Original line number Diff line number Diff line
@@ -52,6 +52,21 @@ public final class TextViewActions {
                new GeneralClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that 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 click on.
     */
    public static ViewAction mouseClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), Press.PINPOINT));
    }

    /**
     * Returns an action that double-clicks on text at an index on the TextView.<br>
     * <br>
@@ -67,6 +82,21 @@ public final class TextViewActions {
                new GeneralClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that double-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 double-click on.
     */
    public static ViewAction mouseDoubleClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.PINPOINT));
    }

    /**
     * Returns an action that long presses on text at an index on the TextView.<br>
     * <br>
@@ -82,6 +112,21 @@ public final class TextViewActions {
                new GeneralClickAction(Tap.LONG, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that long click 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 long click on.
     */
    public static ViewAction mouseLongClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new MouseClickAction(Tap.LONG, new TextCoordinates(index), Press.PINPOINT));
    }

    /**
     * Returns an action that long presses then drags on text from startIndex to endIndex on the
     * TextView.<br>
@@ -148,6 +193,50 @@ public final class TextViewActions {
                        TextView.class));
    }

    /**
     * Returns an action that double 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 mouseDoubleClickAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.MOUSE_DOUBLE_CLICK,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT,
                        TextView.class));
    }

    /**
     * Returns an action that long 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 mouseLongClickAndDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragAction(
                        DragAction.Drag.MOUSE_LONG_CLICK,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT,
                        TextView.class));
    }

    public enum Handle {
        SELECTION_START,
        SELECTION_END,