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

Commit 88cabede authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi
Browse files

Add mouse interaction UI test for TextView.

Bug: 19544351
Bug: 24475013
Change-Id: If8109ad30a13d5cef4c7aff212b2a8389db0e57d
parent f48e1e21
Loading
Loading
Loading
Loading
+52 −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;

import static android.widget.espresso.TextViewActions.mouseDragOnText;
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.typeTextIntoFocusedView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

import com.android.frameworks.coretests.R;

import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;

/**
 * Tests mouse interaction of the TextView widget from an Activity
 */
public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2<TextViewActivity>{

    public TextViewActivityMouseTest() {
        super(TextViewActivity.class);
    }

    @SmallTest
    public void testSelectTextByDrag() 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(
                mouseDragOnText(helloWorld.indexOf("llo"), helloWorld.indexOf("ld!")));

        onView(withId(R.id.textview)).check(hasSelection("llo wor"));
    }
}
+48 −7
Original line number Diff line number Diff line
@@ -20,25 +20,22 @@ import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFro
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static com.android.internal.util.Preconditions.checkNotNull;
import static org.hamcrest.Matchers.allOf;

import android.annotation.Nullable;
import android.os.SystemClock;
import android.support.test.espresso.UiController;
import android.support.test.espresso.PerformException;
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.PrecisionDescriber;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Swiper;
import android.support.test.espresso.action.Tap;
import android.support.test.espresso.util.HumanReadables;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.TextView;

import org.hamcrest.Matcher;


@@ -51,11 +48,48 @@ import org.hamcrest.Matcher;
 * <ul>
 */
public final class DragOnTextViewActions implements ViewAction {
    public interface Dragger extends Swiper {
        UiController wrapUiController(UiController uiController);
    }

    /**
     * Executes different "drag on text" types to given positions.
     */
    public enum Drag implements Swiper {
    public enum Drag implements Dragger {

        /**
         * Starts a drag with a mouse down.
         */
        MOUSE_DOWN {
            private DownMotionPerformer downMotion = new DownMotionPerformer() {
                @Override
                public MotionEvent perform(
                        UiController uiController, float[] coordinates, float[] precision) {
                    MotionEvent 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 down and drag to select";
            }

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

        /**
         * Starts a drag with a long-press.
@@ -197,6 +231,11 @@ public final class DragOnTextViewActions implements ViewAction {

            return res;
        }

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

    /**
@@ -215,13 +254,13 @@ public final class DragOnTextViewActions implements ViewAction {
        MotionEvent perform(UiController uiController, float[] coordinates, float[] precision);
    }

    private final Swiper mDragger;
    private final Dragger mDragger;
    private final CoordinatesProvider mStartCoordinatesProvider;
    private final CoordinatesProvider mEndCoordinatesProvider;
    private final PrecisionDescriber mPrecisionDescriber;

    public DragOnTextViewActions(
            Swiper dragger,
            Dragger dragger,
            CoordinatesProvider startCoordinatesProvider,
            CoordinatesProvider endCoordinatesProvider,
            PrecisionDescriber precisionDescriber) {
@@ -242,6 +281,8 @@ public final class DragOnTextViewActions implements ViewAction {
        checkNotNull(uiController);
        checkNotNull(view);

        uiController = mDragger.wrapUiController(uiController);

        float[] startCoordinates = mStartCoordinatesProvider.calculateCoordinates(view);
        float[] endCoordinates = mEndCoordinatesProvider.calculateCoordinates(view);
        float[] precision = mPrecisionDescriber.describePrecision();
+63 −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 android.support.test.espresso.InjectEventSecurityException;
import android.support.test.espresso.UiController;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;

/**
 * Class to wrap an UiController to overwrite source of motion events to SOURCE_MOUSE.
 * Note that this doesn't change the tool type.
 */
public class MouseUiController implements UiController {
    private final UiController mUiController;

    public MouseUiController(UiController uiController) {
        mUiController = uiController;
    }

    @Override
    public boolean injectKeyEvent(KeyEvent event) throws InjectEventSecurityException {
        return mUiController.injectKeyEvent(event);
    }

    @Override
    public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException {
        // Modify the event to mimic mouse primary button event.
        event.setSource(InputDevice.SOURCE_MOUSE);
        event.setButtonState(MotionEvent.BUTTON_PRIMARY);
        return mUiController.injectMotionEvent(event);
    }

    @Override
    public boolean injectString(String str) throws InjectEventSecurityException {
        return mUiController.injectString(str);
    }

    @Override
    public void loopMainThreadForAtLeast(long millisDelay) {
        mUiController.loopMainThreadForAtLeast(millisDelay);
    }

    @Override
    public void loopMainThreadUntilIdle() {
        mUiController.loopMainThreadUntilIdle();
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -123,6 +123,27 @@ public final class TextViewActions {
                        Press.FINGER));
    }

    /**
     * Returns an action that 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 mouseDragOnText(int startIndex, int endIndex) {
        return actionWithAssertions(
                new DragOnTextViewActions(
                        DragOnTextViewActions.Drag.MOUSE_DOWN,
                        new TextCoordinates(startIndex),
                        new TextCoordinates(endIndex),
                        Press.PINPOINT));
    }

    /**
     * A provider of the x, y coordinates of the text at the specified index in a text view.
     */