Loading core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java +60 −22 Original line number Diff line number Diff line Loading @@ -26,8 +26,11 @@ 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.hasInsertionPointerAtIndex; import static android.widget.espresso.TextViewAssertions.hasSelection; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.Espresso.pressBack; 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; Loading @@ -37,8 +40,11 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId; import com.android.frameworks.coretests.R; import android.support.test.espresso.Espresso; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.MotionEvent; import android.widget.espresso.ContextMenuUtils; /** * Tests mouse interaction of the TextView widget from an Activity Loading @@ -49,10 +55,13 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< super(TextViewActivity.class); } @SmallTest public void testSelectTextByDrag() throws Exception { @Override public void setUp() { getActivity(); } @SmallTest public void testSelectTextByDrag() throws Exception { final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -77,8 +86,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByDrag_reverse() throws Exception { getActivity(); final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -89,9 +96,56 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< } @SmallTest public void testSelectTextByLongClick() throws Exception { getActivity(); public void testContextMenu() throws Exception { final String text = "abc def ghi."; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); ContextMenuUtils.assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); ContextMenuUtils.assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseDragOnText(text.indexOf("c"), text.indexOf("h"))); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); onView(withId(R.id.textview)).check(hasSelection("c def g")); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("i"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); onView(withId(R.id.textview)).check(hasSelection("")); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("i"))); } @SmallTest public void testSelectTextByLongClick() throws Exception { final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -117,8 +171,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -144,8 +196,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -157,8 +207,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -170,8 +218,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -183,8 +229,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -196,8 +240,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClick() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading Loading @@ -232,8 +274,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClickAndDrag() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading Loading @@ -263,8 +303,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClickAndDrag_reverse() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java 0 → 100644 +110 −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 static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.hasFocus; import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.not; import com.android.internal.view.menu.ListMenuItemView; import android.support.test.espresso.NoMatchingRootException; import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.ViewInteraction; import android.support.test.espresso.matcher.ViewMatchers; import android.widget.MenuPopupWindow.MenuDropDownListView; /** * Espresso utility methods for the context menu. */ public final class ContextMenuUtils { private ContextMenuUtils() {} private static ViewInteraction onContextMenu() { // TODO: Have more reliable way to get context menu. return onView(ViewMatchers.isAssignableFrom(MenuDropDownListView.class)) .inRoot(withDecorView(hasFocus())); } /** * Asserts that the context menu is displayed * * @throws AssertionError if the assertion fails */ private static void assertContextMenuIsDisplayed() { onContextMenu().check(matches(isDisplayed())); } /** * Asserts that the context menu is not displayed * * @throws AssertionError if the assertion fails */ public static void assertContextMenuIsNotDisplayed() { try { assertContextMenuIsDisplayed(); } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) { return; } throw new AssertionError("Context menu is displayed"); } /** * Asserts that the context menu contains the specified item and the item has specified enabled * state. * * @param itemLabel label of the item. * @param enabled enabled state of the item. * @throws AssertionError if the assertion fails */ private static void asssertContextMenuContainsItemWithEnabledState(String itemLabel, boolean enabled) { onContextMenu().check(matches( hasDescendant(allOf( isAssignableFrom(ListMenuItemView.class), enabled ? isEnabled() : not(isEnabled()), hasDescendant(withText(itemLabel)))))); } /** * Asserts that the context menu contains the specified item and the item is enabled. * * @param itemLabel label of the item. * @throws AssertionError if the assertion fails */ public static void assertContextMenuContainsItemEnabled(String itemLabel) { asssertContextMenuContainsItemWithEnabledState(itemLabel, true); } /** * Asserts that the context menu contains the specified item and the item is disabled. * * @param itemLabel label of the item. * @throws AssertionError if the assertion fails */ public static void assertContextMenuContainsItemDisabled(String itemLabel) { asssertContextMenuContainsItemWithEnabledState(itemLabel, false); } } core/tests/coretests/src/android/widget/espresso/MouseClickAction.java +18 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ 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.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading @@ -35,6 +35,8 @@ import android.view.ViewConfiguration; */ public final class MouseClickAction implements ViewAction { private final GeneralClickAction mGeneralClickAction; @MouseUiController.MouseButton private final int mButton; public enum CLICK implements Tapper { TRIPLE { Loading Loading @@ -86,8 +88,20 @@ public final class MouseClickAction implements ViewAction { }; public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider) { mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, Press.PINPOINT); this(tapper, coordinatesProvider, MotionEvent.BUTTON_PRIMARY); } /** * Constructs MouseClickAction * * @param tapper the tapper * @param coordinatesProvider the provider of the event coordinates * @param button the mouse button used to send motion events */ public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider, @MouseUiController.MouseButton int button) { mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, Press.PINPOINT); mButton = button; } @Override Loading @@ -102,7 +116,7 @@ public final class MouseClickAction implements ViewAction { @Override public void perform(UiController uiController, View view) { mGeneralClickAction.perform(new MouseUiController(uiController), view); mGeneralClickAction.perform(new MouseUiController(uiController, mButton), view); long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); if (0 < doubleTapTimeout) { // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be Loading core/tests/coretests/src/android/widget/espresso/MouseUiController.java +29 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,12 @@ package android.widget.espresso; import static com.android.internal.util.Preconditions.checkNotNull; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import android.annotation.IntDef; import android.support.test.espresso.InjectEventSecurityException; import android.support.test.espresso.UiController; import android.view.InputDevice; Loading @@ -26,11 +32,28 @@ 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 { public final class MouseUiController implements UiController { @Retention(RetentionPolicy.SOURCE) @IntDef({MotionEvent.BUTTON_PRIMARY, MotionEvent.BUTTON_SECONDARY, MotionEvent.BUTTON_TERTIARY}) public @interface MouseButton {} private final UiController mUiController; @MouseButton private final int mButton; public MouseUiController(UiController uiController) { mUiController = uiController; this(uiController, MotionEvent.BUTTON_PRIMARY); } /** * Constructs MouseUiController. * * @param uiController the uiController to wrap * @param button the button to be used for generating input events. */ public MouseUiController(UiController uiController, @MouseButton int button) { mUiController = checkNotNull(uiController); mButton = button; } @Override Loading @@ -40,9 +63,11 @@ public class MouseUiController implements UiController { @Override public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException { // Modify the event to mimic mouse primary button event. // Modify the event to mimic mouse event. event.setSource(InputDevice.SOURCE_MOUSE); event.setButtonState(MotionEvent.BUTTON_PRIMARY); if (event.getActionMasked() != MotionEvent.ACTION_UP) { event.setButtonState(mButton); } return mUiController.injectMotionEvent(event); } Loading core/tests/coretests/src/android/widget/espresso/TextViewActions.java +18 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.support.test.espresso.action.Press; import android.support.test.espresso.action.Tap; import android.support.test.espresso.util.HumanReadables; import android.text.Layout; import android.view.MotionEvent; import android.view.View; import android.widget.Editor; import android.widget.TextView; Loading Loading @@ -63,8 +64,24 @@ public final class TextViewActions { * @param index The index of the TextView's text to click on. */ public static ViewAction mouseClickOnTextAtIndex(int index) { return mouseClickOnTextAtIndex(index, MotionEvent.BUTTON_PRIMARY); } /** * 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. * @param button the mouse button to use. */ public static ViewAction mouseClickOnTextAtIndex(int index, @MouseUiController.MouseButton int button) { return actionWithAssertions( new MouseClickAction(Tap.SINGLE, new TextCoordinates(index))); new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), button)); } /** Loading Loading
core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java +60 −22 Original line number Diff line number Diff line Loading @@ -26,8 +26,11 @@ 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.hasInsertionPointerAtIndex; import static android.widget.espresso.TextViewAssertions.hasSelection; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.Espresso.pressBack; 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; Loading @@ -37,8 +40,11 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId; import com.android.frameworks.coretests.R; import android.support.test.espresso.Espresso; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.MotionEvent; import android.widget.espresso.ContextMenuUtils; /** * Tests mouse interaction of the TextView widget from an Activity Loading @@ -49,10 +55,13 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< super(TextViewActivity.class); } @SmallTest public void testSelectTextByDrag() throws Exception { @Override public void setUp() { getActivity(); } @SmallTest public void testSelectTextByDrag() throws Exception { final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -77,8 +86,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByDrag_reverse() throws Exception { getActivity(); final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -89,9 +96,56 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< } @SmallTest public void testSelectTextByLongClick() throws Exception { getActivity(); public void testContextMenu() throws Exception { final String text = "abc def ghi."; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); ContextMenuUtils.assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); ContextMenuUtils.assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseDragOnText(text.indexOf("c"), text.indexOf("h"))); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); onView(withId(R.id.textview)).check(hasSelection("c def g")); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("i"), MotionEvent.BUTTON_SECONDARY)); ContextMenuUtils.assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); ContextMenuUtils.assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); onView(withId(R.id.textview)).check(hasSelection("")); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("i"))); } @SmallTest public void testSelectTextByLongClick() throws Exception { final String helloWorld = "Hello world!"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); Loading @@ -117,8 +171,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -144,8 +196,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -157,8 +207,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -170,8 +218,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -183,8 +229,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @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)); Loading @@ -196,8 +240,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClick() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading Loading @@ -232,8 +274,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClickAndDrag() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading Loading @@ -263,8 +303,6 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< @SmallTest public void testSelectTextByTripleClickAndDrag_reverse() throws Exception { getActivity(); final StringBuilder builder = new StringBuilder(); builder.append("First paragraph.\n"); builder.append("Second paragraph."); Loading
core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java 0 → 100644 +110 −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 static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.hasFocus; import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.not; import com.android.internal.view.menu.ListMenuItemView; import android.support.test.espresso.NoMatchingRootException; import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.ViewInteraction; import android.support.test.espresso.matcher.ViewMatchers; import android.widget.MenuPopupWindow.MenuDropDownListView; /** * Espresso utility methods for the context menu. */ public final class ContextMenuUtils { private ContextMenuUtils() {} private static ViewInteraction onContextMenu() { // TODO: Have more reliable way to get context menu. return onView(ViewMatchers.isAssignableFrom(MenuDropDownListView.class)) .inRoot(withDecorView(hasFocus())); } /** * Asserts that the context menu is displayed * * @throws AssertionError if the assertion fails */ private static void assertContextMenuIsDisplayed() { onContextMenu().check(matches(isDisplayed())); } /** * Asserts that the context menu is not displayed * * @throws AssertionError if the assertion fails */ public static void assertContextMenuIsNotDisplayed() { try { assertContextMenuIsDisplayed(); } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) { return; } throw new AssertionError("Context menu is displayed"); } /** * Asserts that the context menu contains the specified item and the item has specified enabled * state. * * @param itemLabel label of the item. * @param enabled enabled state of the item. * @throws AssertionError if the assertion fails */ private static void asssertContextMenuContainsItemWithEnabledState(String itemLabel, boolean enabled) { onContextMenu().check(matches( hasDescendant(allOf( isAssignableFrom(ListMenuItemView.class), enabled ? isEnabled() : not(isEnabled()), hasDescendant(withText(itemLabel)))))); } /** * Asserts that the context menu contains the specified item and the item is enabled. * * @param itemLabel label of the item. * @throws AssertionError if the assertion fails */ public static void assertContextMenuContainsItemEnabled(String itemLabel) { asssertContextMenuContainsItemWithEnabledState(itemLabel, true); } /** * Asserts that the context menu contains the specified item and the item is disabled. * * @param itemLabel label of the item. * @throws AssertionError if the assertion fails */ public static void assertContextMenuContainsItemDisabled(String itemLabel) { asssertContextMenuContainsItemWithEnabledState(itemLabel, false); } }
core/tests/coretests/src/android/widget/espresso/MouseClickAction.java +18 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ 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.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading @@ -35,6 +35,8 @@ import android.view.ViewConfiguration; */ public final class MouseClickAction implements ViewAction { private final GeneralClickAction mGeneralClickAction; @MouseUiController.MouseButton private final int mButton; public enum CLICK implements Tapper { TRIPLE { Loading Loading @@ -86,8 +88,20 @@ public final class MouseClickAction implements ViewAction { }; public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider) { mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, Press.PINPOINT); this(tapper, coordinatesProvider, MotionEvent.BUTTON_PRIMARY); } /** * Constructs MouseClickAction * * @param tapper the tapper * @param coordinatesProvider the provider of the event coordinates * @param button the mouse button used to send motion events */ public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider, @MouseUiController.MouseButton int button) { mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, Press.PINPOINT); mButton = button; } @Override Loading @@ -102,7 +116,7 @@ public final class MouseClickAction implements ViewAction { @Override public void perform(UiController uiController, View view) { mGeneralClickAction.perform(new MouseUiController(uiController), view); mGeneralClickAction.perform(new MouseUiController(uiController, mButton), view); long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); if (0 < doubleTapTimeout) { // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be Loading
core/tests/coretests/src/android/widget/espresso/MouseUiController.java +29 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,12 @@ package android.widget.espresso; import static com.android.internal.util.Preconditions.checkNotNull; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import android.annotation.IntDef; import android.support.test.espresso.InjectEventSecurityException; import android.support.test.espresso.UiController; import android.view.InputDevice; Loading @@ -26,11 +32,28 @@ 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 { public final class MouseUiController implements UiController { @Retention(RetentionPolicy.SOURCE) @IntDef({MotionEvent.BUTTON_PRIMARY, MotionEvent.BUTTON_SECONDARY, MotionEvent.BUTTON_TERTIARY}) public @interface MouseButton {} private final UiController mUiController; @MouseButton private final int mButton; public MouseUiController(UiController uiController) { mUiController = uiController; this(uiController, MotionEvent.BUTTON_PRIMARY); } /** * Constructs MouseUiController. * * @param uiController the uiController to wrap * @param button the button to be used for generating input events. */ public MouseUiController(UiController uiController, @MouseButton int button) { mUiController = checkNotNull(uiController); mButton = button; } @Override Loading @@ -40,9 +63,11 @@ public class MouseUiController implements UiController { @Override public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException { // Modify the event to mimic mouse primary button event. // Modify the event to mimic mouse event. event.setSource(InputDevice.SOURCE_MOUSE); event.setButtonState(MotionEvent.BUTTON_PRIMARY); if (event.getActionMasked() != MotionEvent.ACTION_UP) { event.setButtonState(mButton); } return mUiController.injectMotionEvent(event); } Loading
core/tests/coretests/src/android/widget/espresso/TextViewActions.java +18 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.support.test.espresso.action.Press; import android.support.test.espresso.action.Tap; import android.support.test.espresso.util.HumanReadables; import android.text.Layout; import android.view.MotionEvent; import android.view.View; import android.widget.Editor; import android.widget.TextView; Loading Loading @@ -63,8 +64,24 @@ public final class TextViewActions { * @param index The index of the TextView's text to click on. */ public static ViewAction mouseClickOnTextAtIndex(int index) { return mouseClickOnTextAtIndex(index, MotionEvent.BUTTON_PRIMARY); } /** * 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. * @param button the mouse button to use. */ public static ViewAction mouseClickOnTextAtIndex(int index, @MouseUiController.MouseButton int button) { return actionWithAssertions( new MouseClickAction(Tap.SINGLE, new TextCoordinates(index))); new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), button)); } /** Loading