1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package android.widget; 18 19 20 import static android.support.test.espresso.Espresso.onView; 21 import static android.support.test.espresso.Espresso.pressBack; 22 import static android.support.test.espresso.action.ViewActions.replaceText; 23 import static android.support.test.espresso.action.ViewActions.typeText; 24 import static android.support.test.espresso.assertion.ViewAssertions.matches; 25 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 26 import static android.support.test.espresso.matcher.ViewMatchers.withId; 27 import static android.support.test.espresso.matcher.ViewMatchers.withText; 28 import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemDisabled; 29 import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemEnabled; 30 import static android.widget.espresso.ContextMenuUtils.assertContextMenuIsNotDisplayed; 31 import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles; 32 import static android.widget.espresso.DragHandleUtils.onHandleView; 33 import static android.widget.espresso.TextViewActions.mouseClick; 34 import static android.widget.espresso.TextViewActions.mouseClickOnTextAtIndex; 35 import static android.widget.espresso.TextViewActions.mouseDoubleClickAndDragOnText; 36 import static android.widget.espresso.TextViewActions.mouseDoubleClickOnTextAtIndex; 37 import static android.widget.espresso.TextViewActions.mouseDragOnText; 38 import static android.widget.espresso.TextViewActions.mouseLongClickAndDragOnText; 39 import static android.widget.espresso.TextViewActions.mouseLongClickOnTextAtIndex; 40 import static android.widget.espresso.TextViewActions.mouseTripleClickAndDragOnText; 41 import static android.widget.espresso.TextViewActions.mouseTripleClickOnTextAtIndex; 42 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex; 43 import static android.widget.espresso.TextViewAssertions.hasSelection; 44 45 import android.app.Activity; 46 import android.support.test.filters.MediumTest; 47 import android.support.test.filters.Suppress; 48 import android.support.test.rule.ActivityTestRule; 49 import android.support.test.runner.AndroidJUnit4; 50 import android.view.MotionEvent; 51 import android.view.textclassifier.TextClassificationManager; 52 import android.view.textclassifier.TextClassifier; 53 54 import com.android.frameworks.coretests.R; 55 56 import org.junit.Before; 57 import org.junit.Rule; 58 import org.junit.Test; 59 import org.junit.runner.RunWith; 60 61 /** 62 * Tests mouse interaction of the TextView widget from an Activity 63 */ 64 @RunWith(AndroidJUnit4.class) 65 @MediumTest 66 @Suppress // Consistently failing. b/29591177 67 public class TextViewActivityMouseTest { 68 69 @Rule 70 public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>( 71 TextViewActivity.class); 72 73 private Activity mActivity; 74 75 @Before 76 public void setUp() { 77 mActivity = mActivityRule.getActivity(); 78 mActivity.getSystemService(TextClassificationManager.class) 79 .setTextClassifier(TextClassifier.NO_OP); 80 } 81 82 @Test 83 public void testSelectTextByDrag() { 84 final String helloWorld = "Hello world!"; 85 onView(withId(R.id.textview)).perform(mouseClick()); 86 onView(withId(R.id.textview)).perform(replaceText(helloWorld)); 87 88 assertNoSelectionHandles(); 89 90 onView(withId(R.id.textview)).perform( 91 mouseDragOnText(helloWorld.indexOf("llo"), helloWorld.indexOf("ld!"))); 92 93 onView(withId(R.id.textview)).check(hasSelection("llo wor")); 94 95 onHandleView(com.android.internal.R.id.selection_start_handle) 96 .check(matches(isDisplayed())); 97 onHandleView(com.android.internal.R.id.selection_end_handle) 98 .check(matches(isDisplayed())); 99 100 onView(withId(R.id.textview)).perform(mouseClickOnTextAtIndex(helloWorld.indexOf("w"))); 101 onView(withId(R.id.textview)).check(hasSelection("")); 102 103 assertNoSelectionHandles(); 104 } 105 106 @Test 107 public void testSelectTextByDrag_reverse() { 108 final String helloWorld = "Hello world!"; 109 onView(withId(R.id.textview)).perform(mouseClick()); 110 onView(withId(R.id.textview)).perform(replaceText(helloWorld)); 111 onView(withId(R.id.textview)).perform( 112 mouseDragOnText( helloWorld.indexOf("ld!"), helloWorld.indexOf("llo"))); 113 114 onView(withId(R.id.textview)).check(hasSelection("llo wor")); 115 } 116 117 @Test 118 public void testContextMenu() { 119 final String text = "abc def ghi."; 120 onView(withId(R.id.textview)).perform(mouseClick()); 121 onView(withId(R.id.textview)).perform(replaceText(text)); 122 123 assertContextMenuIsNotDisplayed(); 124 125 onView(withId(R.id.textview)).perform( 126 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); 127 128 assertContextMenuContainsItemDisabled( 129 mActivity.getString(com.android.internal.R.string.copy)); 130 assertContextMenuContainsItemDisabled( 131 mActivity.getString(com.android.internal.R.string.undo)); 132 133 // Hide context menu. 134 pressBack(); 135 assertContextMenuIsNotDisplayed(); 136 137 // type something to enable Undo 138 onView(withId(R.id.textview)).perform( 139 mouseClickOnTextAtIndex(text.indexOf("."))); 140 onView(withId(R.id.textview)).perform(typeText(" ")); 141 142 onView(withId(R.id.textview)).perform( 143 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); 144 145 assertContextMenuContainsItemDisabled( 146 mActivity.getString(com.android.internal.R.string.copy)); 147 assertContextMenuContainsItemEnabled( 148 mActivity.getString(com.android.internal.R.string.undo)); 149 150 // Hide context menu. 151 pressBack(); 152 assertContextMenuIsNotDisplayed(); 153 154 onView(withId(R.id.textview)).perform( 155 mouseDragOnText(text.indexOf("c"), text.indexOf("h"))); 156 onView(withId(R.id.textview)).perform( 157 mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); 158 159 assertContextMenuContainsItemEnabled( 160 mActivity.getString(com.android.internal.R.string.copy)); 161 assertContextMenuContainsItemEnabled( 162 mActivity.getString(com.android.internal.R.string.undo)); 163 164 // Hide context menu. 165 pressBack(); 166 167 onView(withId(R.id.textview)).check(hasSelection("c def g")); 168 169 onView(withId(R.id.textview)).perform( 170 mouseClickOnTextAtIndex(text.indexOf("i"), MotionEvent.BUTTON_SECONDARY)); 171 assertContextMenuContainsItemDisabled( 172 mActivity.getString(com.android.internal.R.string.copy)); 173 assertContextMenuContainsItemEnabled( 174 mActivity.getString(com.android.internal.R.string.undo)); 175 176 // Hide context menu. 177 pressBack(); 178 179 onView(withId(R.id.textview)).check(hasSelection("")); 180 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("i"))); 181 182 // TODO: Add tests for suggestions 183 } 184 185 @Test 186 public void testDragAndDrop() { 187 final String text = "abc def ghi."; 188 onView(withId(R.id.textview)).perform(mouseClick()); 189 onView(withId(R.id.textview)).perform(replaceText(text)); 190 onView(withId(R.id.textview)).perform( 191 mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1)); 192 193 onView(withId(R.id.textview)).perform( 194 mouseDragOnText(text.indexOf("e"), text.length())); 195 196 onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); 197 onView(withId(R.id.textview)).check(hasSelection("")); 198 assertNoSelectionHandles(); 199 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); 200 } 201 202 @Test 203 public void testDragAndDrop_longClick() { 204 final String text = "abc def ghi."; 205 onView(withId(R.id.textview)).perform(mouseClick()); 206 onView(withId(R.id.textview)).perform(replaceText(text)); 207 onView(withId(R.id.textview)).perform( 208 mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1)); 209 210 onView(withId(R.id.textview)).perform( 211 mouseLongClickAndDragOnText(text.indexOf("e"), text.length())); 212 213 onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); 214 onView(withId(R.id.textview)).check(hasSelection("")); 215 assertNoSelectionHandles(); 216 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); 217 } 218 219 @Test 220 public void testSelectTextByLongClick() { 221 final String helloWorld = "Hello world!"; 222 onView(withId(R.id.textview)).perform(mouseClick()); 223 onView(withId(R.id.textview)).perform(replaceText(helloWorld)); 224 225 onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(0)); 226 onView(withId(R.id.textview)).check(hasSelection("Hello")); 227 228 onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex( 229 helloWorld.indexOf("world"))); 230 onView(withId(R.id.textview)).check(hasSelection("world")); 231 232 onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex( 233 helloWorld.indexOf("llo"))); 234 onView(withId(R.id.textview)).check(hasSelection("Hello")); 235 236 onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex( 237 helloWorld.indexOf("rld"))); 238 onView(withId(R.id.textview)).check(hasSelection("world")); 239 240 onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(helloWorld.length())); 241 onView(withId(R.id.textview)).check(hasSelection("!")); 242 } 243 244 @Test 245 public void testSelectTextByDoubleClick() { 246 final String helloWorld = "hello world!"; 247 248 onView(withId(R.id.textview)).perform(mouseClick()); 249 onView(withId(R.id.textview)).perform(replaceText(helloWorld)); 250 251 onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(1)); 252 onView(withId(R.id.textview)).check(hasSelection("hello")); 253 254 onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex( 255 helloWorld.indexOf("world"))); 256 onView(withId(R.id.textview)).check(hasSelection("world")); 257 258 onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex( 259 helloWorld.indexOf("llo"))); 260 onView(withId(R.id.textview)).check(hasSelection("hello")); 261 262 onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex( 263 helloWorld.indexOf("rld"))); 264 onView(withId(R.id.textview)).check(hasSelection("world")); 265 266 onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(helloWorld.length())); 267 onView(withId(R.id.textview)).check(hasSelection("!")); 268 } 269 270 @Test 271 public void testSelectTextByDoubleClickAndDrag() { 272 final String text = "abcd efg hijk lmn"; 273 onView(withId(R.id.textview)).perform(mouseClick()); 274 onView(withId(R.id.textview)).perform(replaceText(text)); 275 276 onView(withId(R.id.textview)).perform( 277 mouseDoubleClickAndDragOnText(text.indexOf("f"), text.indexOf("j"))); 278 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 279 } 280 281 @Test 282 public void testSelectTextByDoubleClickAndDrag_reverse() { 283 final String text = "abcd efg hijk lmn"; 284 onView(withId(R.id.textview)).perform(mouseClick()); 285 onView(withId(R.id.textview)).perform(replaceText(text)); 286 287 onView(withId(R.id.textview)).perform( 288 mouseDoubleClickAndDragOnText(text.indexOf("j"), text.indexOf("f"))); 289 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 290 } 291 292 @Test 293 public void testSelectTextByLongPressAndDrag() { 294 final String text = "abcd efg hijk lmn"; 295 onView(withId(R.id.textview)).perform(mouseClick()); 296 onView(withId(R.id.textview)).perform(replaceText(text)); 297 298 onView(withId(R.id.textview)).perform( 299 mouseLongClickAndDragOnText(text.indexOf("f"), text.indexOf("j"))); 300 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 301 } 302 303 @Test 304 public void testSelectTextByLongPressAndDrag_reverse() { 305 final String text = "abcd efg hijk lmn"; 306 onView(withId(R.id.textview)).perform(mouseClick()); 307 onView(withId(R.id.textview)).perform(replaceText(text)); 308 309 onView(withId(R.id.textview)).perform( 310 mouseLongClickAndDragOnText(text.indexOf("j"), text.indexOf("f"))); 311 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 312 } 313 314 @Test 315 public void testSelectTextByTripleClick() { 316 final StringBuilder builder = new StringBuilder(); 317 builder.append("First paragraph.\n"); 318 builder.append("Second paragraph."); 319 for (int i = 0; i < 10; i++) { 320 builder.append(" This paragraph is very long."); 321 } 322 builder.append('\n'); 323 builder.append("Third paragraph."); 324 final String text = builder.toString(); 325 326 onView(withId(R.id.textview)).perform(mouseClick()); 327 onView(withId(R.id.textview)).perform(replaceText(text)); 328 329 onView(withId(R.id.textview)).perform( 330 mouseTripleClickOnTextAtIndex(text.indexOf("rst"))); 331 onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n")); 332 333 onView(withId(R.id.textview)).perform( 334 mouseTripleClickOnTextAtIndex(text.indexOf("cond"))); 335 onView(withId(R.id.textview)).check(hasSelection( 336 text.substring(text.indexOf("Second"), text.indexOf("Third")))); 337 338 onView(withId(R.id.textview)).perform( 339 mouseTripleClickOnTextAtIndex(text.indexOf("ird"))); 340 onView(withId(R.id.textview)).check(hasSelection("Third paragraph.")); 341 342 onView(withId(R.id.textview)).perform( 343 mouseTripleClickOnTextAtIndex(text.indexOf("very long"))); 344 onView(withId(R.id.textview)).check(hasSelection( 345 text.substring(text.indexOf("Second"), text.indexOf("Third")))); 346 } 347 348 @Test 349 public void testSelectTextByTripleClickAndDrag() { 350 final StringBuilder builder = new StringBuilder(); 351 builder.append("First paragraph.\n"); 352 builder.append("Second paragraph."); 353 for (int i = 0; i < 10; i++) { 354 builder.append(" This paragraph is very long."); 355 } 356 builder.append('\n'); 357 builder.append("Third paragraph."); 358 final String text = builder.toString(); 359 360 onView(withId(R.id.textview)).perform(mouseClick()); 361 onView(withId(R.id.textview)).perform(replaceText(text)); 362 363 onView(withId(R.id.textview)).perform( 364 mouseTripleClickAndDragOnText(text.indexOf("irst"), text.indexOf("st"))); 365 onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n")); 366 367 onView(withId(R.id.textview)).perform( 368 mouseTripleClickAndDragOnText(text.indexOf("cond"), text.indexOf("Third") - 2)); 369 onView(withId(R.id.textview)).check(hasSelection( 370 text.substring(text.indexOf("Second"), text.indexOf("Third")))); 371 372 onView(withId(R.id.textview)).perform( 373 mouseTripleClickAndDragOnText(text.indexOf("First"), text.indexOf("ird"))); 374 onView(withId(R.id.textview)).check(hasSelection(text)); 375 } 376 377 @Test 378 public void testSelectTextByTripleClickAndDrag_reverse() { 379 final StringBuilder builder = new StringBuilder(); 380 builder.append("First paragraph.\n"); 381 builder.append("Second paragraph."); 382 for (int i = 0; i < 10; i++) { 383 builder.append(" This paragraph is very long."); 384 } 385 builder.append('\n'); 386 builder.append("Third paragraph."); 387 final String text = builder.toString(); 388 389 onView(withId(R.id.textview)).perform(mouseClick()); 390 onView(withId(R.id.textview)).perform(replaceText(text)); 391 392 onView(withId(R.id.textview)).perform( 393 mouseTripleClickAndDragOnText(text.indexOf("st"), text.indexOf("irst"))); 394 onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n")); 395 396 onView(withId(R.id.textview)).perform( 397 mouseTripleClickAndDragOnText(text.indexOf("Third") - 2, text.indexOf("cond"))); 398 onView(withId(R.id.textview)).check(hasSelection( 399 text.substring(text.indexOf("Second"), text.indexOf("Third")))); 400 401 onView(withId(R.id.textview)).perform( 402 mouseTripleClickAndDragOnText(text.indexOf("ird"), text.indexOf("First"))); 403 onView(withId(R.id.textview)).check(hasSelection(text)); 404 } 405 } 406