--- /dev/null
+/*
+ * 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"));
+ }
+}
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;
* <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.
return res;
}
+
+ @Override
+ public UiController wrapUiController(UiController uiController) {
+ return uiController;
+ }
}
/**
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) {
checkNotNull(uiController);
checkNotNull(view);
+ uiController = mDragger.wrapUiController(uiController);
+
float[] startCoordinates = mStartCoordinatesProvider.calculateCoordinates(view);
float[] endCoordinates = mEndCoordinatesProvider.calculateCoordinates(view);
float[] precision = mPrecisionDescriber.describePrecision();
--- /dev/null
+/*
+ * 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();
+ }
+}
}
/**
+ * 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.
*/
private static final class TextCoordinates implements CoordinatesProvider {