TextViewActivityTest.java revision 183fd5071ea84aab82209c827fa0e4ff84a6b590
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 17package android.widget; 18 19import static android.support.test.espresso.action.ViewActions.longClick; 20import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles; 21import static android.widget.espresso.DragHandleUtils.onHandleView; 22import static android.widget.espresso.FloatingToolbarEspressoUtils.onFloatingToolBarItem; 23import static android.widget.espresso.TextViewActions.clickOnTextAtIndex; 24import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText; 25import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex; 26import static android.widget.espresso.TextViewActions.dragHandle; 27import static android.widget.espresso.TextViewActions.Handle; 28import static android.widget.espresso.TextViewActions.longPressAndDragOnText; 29import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex; 30import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex; 31import static android.widget.espresso.TextViewAssertions.hasSelection; 32import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed; 33import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed; 34import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup; 35import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem; 36import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem; 37import static android.support.test.espresso.Espresso.onView; 38import static android.support.test.espresso.action.ViewActions.click; 39import static android.support.test.espresso.action.ViewActions.pressKey; 40import static android.support.test.espresso.action.ViewActions.replaceText; 41import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView; 42import static android.support.test.espresso.assertion.ViewAssertions.matches; 43import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 44import static android.support.test.espresso.matcher.ViewMatchers.withId; 45import static android.support.test.espresso.matcher.ViewMatchers.withText; 46 47import com.android.frameworks.coretests.R; 48 49import android.support.test.espresso.action.EspressoKey; 50import android.test.ActivityInstrumentationTestCase2; 51import android.test.suitebuilder.annotation.SmallTest; 52import android.text.Selection; 53import android.text.Spannable; 54import android.text.InputType; 55import android.view.KeyEvent; 56 57import static org.hamcrest.Matchers.anyOf; 58import static org.hamcrest.Matchers.is; 59 60/** 61 * Tests the TextView widget from an Activity 62 */ 63public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextViewActivity>{ 64 65 public TextViewActivityTest() { 66 super(TextViewActivity.class); 67 } 68 69 @Override 70 public void setUp() { 71 getActivity(); 72 } 73 74 @SmallTest 75 public void testTypedTextIsOnScreen() throws Exception { 76 final String helloWorld = "Hello world!"; 77 onView(withId(R.id.textview)).perform(click()); 78 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 79 80 onView(withId(R.id.textview)).check(matches(withText(helloWorld))); 81 } 82 83 @SmallTest 84 public void testPositionCursorAtTextAtIndex() throws Exception { 85 final String helloWorld = "Hello world!"; 86 onView(withId(R.id.textview)).perform(click()); 87 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 88 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world"))); 89 90 // Delete text at specified index and see if we got the right one. 91 onView(withId(R.id.textview)).perform(pressKey(KeyEvent.KEYCODE_FORWARD_DEL)); 92 onView(withId(R.id.textview)).check(matches(withText("Hello orld!"))); 93 } 94 95 @SmallTest 96 public void testPositionCursorAtTextAtIndex_arabic() throws Exception { 97 // Arabic text. The expected cursorable boundary is 98 // | \u0623 \u064F | \u067A | \u0633 \u0652 | 99 final String text = "\u0623\u064F\u067A\u0633\u0652"; 100 onView(withId(R.id.textview)).perform(click()); 101 onView(withId(R.id.textview)).perform(replaceText(text)); 102 103 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0)); 104 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0)); 105 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1)); 106 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2)))); 107 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2)); 108 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2)); 109 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(3)); 110 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(3)); 111 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(4)); 112 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(3), is(5)))); 113 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(5)); 114 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(5)); 115 } 116 117 @SmallTest 118 public void testPositionCursorAtTextAtIndex_devanagari() throws Exception { 119 // Devanagari text. The expected cursorable boundary is | \u0915 \u093E | 120 final String text = "\u0915\u093E"; 121 onView(withId(R.id.textview)).perform(click()); 122 onView(withId(R.id.textview)).perform(replaceText(text)); 123 124 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0)); 125 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0)); 126 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1)); 127 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2)))); 128 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2)); 129 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2)); 130 } 131 132 @SmallTest 133 public void testLongPressToSelect() throws Exception { 134 final String helloWorld = "Hello Kirk!"; 135 onView(withId(R.id.textview)).perform(click()); 136 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 137 onView(withId(R.id.textview)).perform( 138 longPressOnTextAtIndex(helloWorld.indexOf("Kirk"))); 139 140 onView(withId(R.id.textview)).check(hasSelection("Kirk")); 141 } 142 143 @SmallTest 144 public void testLongPressEmptySpace() throws Exception { 145 final String helloWorld = "Hello big round sun!"; 146 onView(withId(R.id.textview)).perform(click()); 147 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 148 // Move cursor somewhere else 149 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("big"))); 150 // Long-press at end of line. 151 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(helloWorld.length())); 152 153 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length())); 154 } 155 156 @SmallTest 157 public void testLongPressAndDragToSelect() throws Exception { 158 final String helloWorld = "Hello little handsome boy!"; 159 onView(withId(R.id.textview)).perform(click()); 160 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 161 onView(withId(R.id.textview)).perform( 162 longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!"))); 163 164 onView(withId(R.id.textview)).check(hasSelection("little handsome")); 165 } 166 167 @SmallTest 168 public void testDragAndDrop() throws Exception { 169 final String text = "abc def ghi."; 170 onView(withId(R.id.textview)).perform(click()); 171 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 172 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e"))); 173 174 onView(withId(R.id.textview)).perform( 175 longPressAndDragOnText(text.indexOf("e"), text.length())); 176 177 onView(withId(R.id.textview)).check(matches(withText("abc ghi.def"))); 178 onView(withId(R.id.textview)).check(hasSelection("")); 179 assertNoSelectionHandles(); 180 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); 181 182 // Test undo returns to the original state. 183 onView(withId(R.id.textview)).perform(pressKey( 184 (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z) 185 .build())); 186 onView(withId(R.id.textview)).check(matches(withText(text))); 187 } 188 189 @SmallTest 190 public void testDoubleTapToSelect() throws Exception { 191 final String helloWorld = "Hello SuetYi!"; 192 onView(withId(R.id.textview)).perform(click()); 193 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 194 onView(withId(R.id.textview)).perform( 195 doubleClickOnTextAtIndex(helloWorld.indexOf("SuetYi"))); 196 197 onView(withId(R.id.textview)).check(hasSelection("SuetYi")); 198 } 199 200 @SmallTest 201 public void testDoubleTapAndDragToSelect() throws Exception { 202 final String helloWorld = "Hello young beautiful girl!"; 203 onView(withId(R.id.textview)).perform(click()); 204 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 205 onView(withId(R.id.textview)).perform( 206 doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!"))); 207 208 onView(withId(R.id.textview)).check(hasSelection("young beautiful")); 209 } 210 211 @SmallTest 212 public void testSelectBackwordsByTouch() throws Exception { 213 final String helloWorld = "Hello king of the Jungle!"; 214 onView(withId(R.id.textview)).perform(click()); 215 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld)); 216 onView(withId(R.id.textview)).perform( 217 doubleTapAndDragOnText(helloWorld.indexOf(" Jungle!"), helloWorld.indexOf("king"))); 218 219 onView(withId(R.id.textview)).check(hasSelection("king of the")); 220 } 221 222 @SmallTest 223 public void testToolbarAppearsAfterSelection() throws Exception { 224 final String text = "Toolbar appears after selection."; 225 onView(withId(R.id.textview)).perform(click()); 226 assertFloatingToolbarIsNotDisplayed(); 227 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 228 onView(withId(R.id.textview)).perform( 229 longPressOnTextAtIndex(text.indexOf("appears"))); 230 231 sleepForFloatingToolbarPopup(); 232 assertFloatingToolbarIsDisplayed(); 233 234 final String text2 = "Toolbar disappears after typing text."; 235 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text2)); 236 assertFloatingToolbarIsNotDisplayed(); 237 } 238 239 @SmallTest 240 public void testToolbarAppearsAfterSelection_withFirstStringLtrAlgorithmAndRtlHint() 241 throws Exception { 242 // after the hint layout change, the floating toolbar was not visible in the case below 243 // this test tests that the floating toolbar is displayed on the screen and is visible to 244 // user. 245 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 246 textView.post(new Runnable() { 247 @Override 248 public void run() { 249 textView.setTextDirection(TextView.TEXT_DIRECTION_FIRST_STRONG_LTR); 250 textView.setInputType(InputType.TYPE_CLASS_TEXT); 251 textView.setSingleLine(true); 252 textView.setHint("الروبوت"); 253 } 254 }); 255 getInstrumentation().waitForIdleSync(); 256 257 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView("test")); 258 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(1)); 259 onFloatingToolBarItem(withText(com.android.internal.R.string.cut)).perform(click()); 260 onView(withId(R.id.textview)).perform(longClick()); 261 sleepForFloatingToolbarPopup(); 262 263 assertFloatingToolbarIsDisplayed(); 264 } 265 266 @SmallTest 267 public void testToolbarAndInsertionHandle() throws Exception { 268 final String text = "text"; 269 onView(withId(R.id.textview)).perform(click()); 270 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 271 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length())); 272 assertFloatingToolbarIsNotDisplayed(); 273 274 onHandleView(com.android.internal.R.id.insertion_handle).perform(click()); 275 sleepForFloatingToolbarPopup(); 276 assertFloatingToolbarIsDisplayed(); 277 278 assertFloatingToolbarContainsItem( 279 getActivity().getString(com.android.internal.R.string.selectAll)); 280 assertFloatingToolbarDoesNotContainItem( 281 getActivity().getString(com.android.internal.R.string.copy)); 282 assertFloatingToolbarDoesNotContainItem( 283 getActivity().getString(com.android.internal.R.string.cut)); 284 } 285 286 @SmallTest 287 public void testToolbarAndSelectionHandle() throws Exception { 288 final String text = "abcd efg hijk"; 289 onView(withId(R.id.textview)).perform(click()); 290 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 291 292 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f"))); 293 sleepForFloatingToolbarPopup(); 294 assertFloatingToolbarIsDisplayed(); 295 296 assertFloatingToolbarContainsItem( 297 getActivity().getString(com.android.internal.R.string.selectAll)); 298 assertFloatingToolbarContainsItem( 299 getActivity().getString(com.android.internal.R.string.copy)); 300 assertFloatingToolbarContainsItem( 301 getActivity().getString(com.android.internal.R.string.cut)); 302 303 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 304 onHandleView(com.android.internal.R.id.selection_start_handle) 305 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); 306 sleepForFloatingToolbarPopup(); 307 assertFloatingToolbarIsDisplayed(); 308 309 onHandleView(com.android.internal.R.id.selection_end_handle) 310 .perform(dragHandle(textView, Handle.SELECTION_END, text.length())); 311 sleepForFloatingToolbarPopup(); 312 assertFloatingToolbarIsDisplayed(); 313 314 assertFloatingToolbarDoesNotContainItem( 315 getActivity().getString(com.android.internal.R.string.selectAll)); 316 assertFloatingToolbarContainsItem( 317 getActivity().getString(com.android.internal.R.string.copy)); 318 assertFloatingToolbarContainsItem( 319 getActivity().getString(com.android.internal.R.string.cut)); 320 } 321 322 @SmallTest 323 public void testInsertionHandle() throws Exception { 324 final String text = "abcd efg hijk "; 325 onView(withId(R.id.textview)).perform(click()); 326 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 327 328 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length())); 329 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length())); 330 331 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 332 333 onHandleView(com.android.internal.R.id.insertion_handle) 334 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a'))); 335 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a"))); 336 337 onHandleView(com.android.internal.R.id.insertion_handle) 338 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f'))); 339 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f"))); 340 } 341 342 @SmallTest 343 public void testInsertionHandle_multiLine() throws Exception { 344 final String text = "abcd\n" + "efg\n" + "hijk\n"; 345 onView(withId(R.id.textview)).perform(click()); 346 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 347 348 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length())); 349 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length())); 350 351 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 352 353 onHandleView(com.android.internal.R.id.insertion_handle) 354 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a'))); 355 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a"))); 356 357 onHandleView(com.android.internal.R.id.insertion_handle) 358 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f'))); 359 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f"))); 360 } 361 362 @SmallTest 363 public void testSelectionHandles() throws Exception { 364 final String text = "abcd efg hijk lmn"; 365 onView(withId(R.id.textview)).perform(click()); 366 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 367 368 assertNoSelectionHandles(); 369 370 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f'))); 371 372 onHandleView(com.android.internal.R.id.selection_start_handle) 373 .check(matches(isDisplayed())); 374 onHandleView(com.android.internal.R.id.selection_end_handle) 375 .check(matches(isDisplayed())); 376 377 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 378 onHandleView(com.android.internal.R.id.selection_start_handle) 379 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); 380 onView(withId(R.id.textview)).check(hasSelection("abcd efg")); 381 382 onHandleView(com.android.internal.R.id.selection_end_handle) 383 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1)); 384 onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk")); 385 } 386 387 @SmallTest 388 public void testSelectionHandles_bidi() throws Exception { 389 final String text = "abc \u0621\u0622\u0623 def"; 390 onView(withId(R.id.textview)).perform(click()); 391 onView(withId(R.id.textview)).perform(replaceText(text)); 392 393 assertNoSelectionHandles(); 394 395 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0622'))); 396 397 onHandleView(com.android.internal.R.id.selection_start_handle) 398 .check(matches(isDisplayed())); 399 onHandleView(com.android.internal.R.id.selection_end_handle) 400 .check(matches(isDisplayed())); 401 402 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623")); 403 404 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 405 onHandleView(com.android.internal.R.id.selection_start_handle) 406 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f'))); 407 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623")); 408 409 onHandleView(com.android.internal.R.id.selection_end_handle) 410 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a'))); 411 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623")); 412 413 onHandleView(com.android.internal.R.id.selection_start_handle) 414 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0623') + 1, 415 false)); 416 onView(withId(R.id.textview)).check(hasSelection("\u0623")); 417 418 onHandleView(com.android.internal.R.id.selection_start_handle) 419 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0621'), 420 false)); 421 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623")); 422 423 onHandleView(com.android.internal.R.id.selection_start_handle) 424 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); 425 onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623")); 426 427 onHandleView(com.android.internal.R.id.selection_end_handle) 428 .perform(dragHandle(textView, Handle.SELECTION_END, text.length())); 429 onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def")); 430 } 431 432 @SmallTest 433 public void testSelectionHandles_multiLine() throws Exception { 434 final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr"; 435 onView(withId(R.id.textview)).perform(click()); 436 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 437 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 438 439 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 440 onHandleView(com.android.internal.R.id.selection_start_handle) 441 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e'))); 442 onView(withId(R.id.textview)).check(hasSelection("efg\nhijk")); 443 444 onHandleView(com.android.internal.R.id.selection_start_handle) 445 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); 446 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk")); 447 448 onHandleView(com.android.internal.R.id.selection_end_handle) 449 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n') + 1)); 450 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn")); 451 452 onHandleView(com.android.internal.R.id.selection_end_handle) 453 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r') + 1)); 454 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr")); 455 } 456 457 @SmallTest 458 public void testSelectionHandles_multiLine_rtl() throws Exception { 459 // Arabic text. 460 final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n" 461 + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n" 462 + "\u0639\u063A\u063B"; 463 onView(withId(R.id.textview)).perform(click()); 464 onView(withId(R.id.textview)).perform(replaceText(text)); 465 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length())); 466 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0634'))); 467 468 final TextView textView = (TextView)getActivity().findViewById(R.id.textview); 469 onHandleView(com.android.internal.R.id.selection_start_handle) 470 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E'))); 471 onView(withId(R.id.textview)).check(hasSelection( 472 text.substring(text.indexOf('\u062D'), text.indexOf('\u0635') + 1))); 473 474 onHandleView(com.android.internal.R.id.selection_start_handle) 475 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062A'))); 476 onView(withId(R.id.textview)).check(hasSelection( 477 text.substring(text.indexOf('\u062A'), text.indexOf('\u0635') + 1))); 478 479 onHandleView(com.android.internal.R.id.selection_end_handle) 480 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u0638'))); 481 onView(withId(R.id.textview)).check(hasSelection( 482 text.substring(text.indexOf('\u062A'), text.indexOf('\u0638') + 1))); 483 484 onHandleView(com.android.internal.R.id.selection_end_handle) 485 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u063B'))); 486 onView(withId(R.id.textview)).check(hasSelection(text)); 487 } 488 489 490 @SmallTest 491 public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception { 492 final String text = "abcd efg hijk lmn"; 493 onView(withId(R.id.textview)).perform(click()); 494 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 495 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f'))); 496 497 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 498 onHandleView(com.android.internal.R.id.selection_start_handle) 499 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l'))); 500 onView(withId(R.id.textview)).check(hasSelection("g")); 501 502 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f'))); 503 onHandleView(com.android.internal.R.id.selection_end_handle) 504 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a'))); 505 onView(withId(R.id.textview)).check(hasSelection("e")); 506 } 507 508 @SmallTest 509 public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() throws Exception { 510 final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr"; 511 onView(withId(R.id.textview)).perform(click()); 512 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 513 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 514 515 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 516 onHandleView(com.android.internal.R.id.selection_start_handle) 517 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1)); 518 onView(withId(R.id.textview)).check(hasSelection("k")); 519 520 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 521 onHandleView(com.android.internal.R.id.selection_end_handle) 522 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a'))); 523 onView(withId(R.id.textview)).check(hasSelection("h")); 524 } 525 526 @SmallTest 527 public void testSelectionHandles_snapToWordBoundary() throws Exception { 528 final String text = "abcd efg hijk lmn opqr"; 529 onView(withId(R.id.textview)).perform(click()); 530 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 531 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 532 533 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 534 535 onHandleView(com.android.internal.R.id.selection_start_handle) 536 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f'))); 537 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 538 539 onHandleView(com.android.internal.R.id.selection_start_handle) 540 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d') + 1)); 541 onView(withId(R.id.textview)).check(hasSelection("efg hijk")); 542 543 544 onHandleView(com.android.internal.R.id.selection_start_handle) 545 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c'))); 546 onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk")); 547 548 onHandleView(com.android.internal.R.id.selection_start_handle) 549 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d'))); 550 onView(withId(R.id.textview)).check(hasSelection("d efg hijk")); 551 552 onHandleView(com.android.internal.R.id.selection_start_handle) 553 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('b'))); 554 onView(withId(R.id.textview)).check(hasSelection("bcd efg hijk")); 555 556 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 557 558 onHandleView(com.android.internal.R.id.selection_end_handle) 559 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n'))); 560 onView(withId(R.id.textview)).check(hasSelection("hijk lmn")); 561 562 onHandleView(com.android.internal.R.id.selection_end_handle) 563 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('o'))); 564 onView(withId(R.id.textview)).check(hasSelection("hijk lmn")); 565 566 onHandleView(com.android.internal.R.id.selection_end_handle) 567 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('q'))); 568 onView(withId(R.id.textview)).check(hasSelection("hijk lmn opqr")); 569 570 onHandleView(com.android.internal.R.id.selection_end_handle) 571 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p'))); 572 onView(withId(R.id.textview)).check(hasSelection("hijk lmn o")); 573 574 onHandleView(com.android.internal.R.id.selection_end_handle) 575 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r'))); 576 onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq")); 577 } 578 579 @SmallTest 580 public void testSelectionHandles_snapToWordBoundary_multiLine() throws Exception { 581 final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu"; 582 onView(withId(R.id.textview)).perform(click()); 583 onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); 584 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('m'))); 585 586 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 587 588 onHandleView(com.android.internal.R.id.selection_start_handle) 589 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c'))); 590 onView(withId(R.id.textview)).check(hasSelection("abcd efg\nhijk lmn")); 591 592 onHandleView(com.android.internal.R.id.selection_start_handle) 593 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('g'))); 594 onView(withId(R.id.textview)).check(hasSelection("g\nhijk lmn")); 595 596 onHandleView(com.android.internal.R.id.selection_start_handle) 597 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('m'))); 598 onView(withId(R.id.textview)).check(hasSelection("lmn")); 599 600 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i'))); 601 602 onHandleView(com.android.internal.R.id.selection_end_handle) 603 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('u'))); 604 onView(withId(R.id.textview)).check(hasSelection("hijk lmn\nopqr stu")); 605 606 onHandleView(com.android.internal.R.id.selection_end_handle) 607 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p'))); 608 onView(withId(R.id.textview)).check(hasSelection("hijk lmn\no")); 609 610 onHandleView(com.android.internal.R.id.selection_end_handle) 611 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i'))); 612 onView(withId(R.id.textview)).check(hasSelection("hijk")); 613 } 614 615 @SmallTest 616 public void testSetSelectionAndActionMode() throws Exception { 617 final String text = "abc def"; 618 onView(withId(R.id.textview)).perform(click()); 619 onView(withId(R.id.textview)).perform(replaceText(text)); 620 621 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 622 assertFloatingToolbarIsNotDisplayed(); 623 textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3)); 624 getInstrumentation().waitForIdleSync(); 625 sleepForFloatingToolbarPopup(); 626 // Don't automatically start action mode. 627 assertFloatingToolbarIsNotDisplayed(); 628 // Make sure that "Select All" is included in the selection action mode when the entire text 629 // is not selected. 630 onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('e'))); 631 sleepForFloatingToolbarPopup(); 632 assertFloatingToolbarIsDisplayed(); 633 // Changing the selection range by API should not interrupt the selection action mode. 634 textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0, 3)); 635 getInstrumentation().waitForIdleSync(); 636 sleepForFloatingToolbarPopup(); 637 assertFloatingToolbarIsDisplayed(); 638 assertFloatingToolbarContainsItem( 639 getActivity().getString(com.android.internal.R.string.selectAll)); 640 // Make sure that "Select All" is no longer included when the entire text is selected by 641 // API. 642 textView.post( 643 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length())); 644 getInstrumentation().waitForIdleSync(); 645 sleepForFloatingToolbarPopup(); 646 assertFloatingToolbarIsDisplayed(); 647 assertFloatingToolbarDoesNotContainItem( 648 getActivity().getString(com.android.internal.R.string.selectAll)); 649 // Make sure that shrinking the selection range to cursor (an empty range) by API 650 // terminates selection action mode and does not trigger the insertion action mode. 651 textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0)); 652 getInstrumentation().waitForIdleSync(); 653 sleepForFloatingToolbarPopup(); 654 assertFloatingToolbarIsNotDisplayed(); 655 // Make sure that user click can trigger the insertion action mode. 656 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length())); 657 onHandleView(com.android.internal.R.id.insertion_handle).perform(click()); 658 sleepForFloatingToolbarPopup(); 659 assertFloatingToolbarIsDisplayed(); 660 // Make sure that an existing insertion action mode keeps alive after the insertion point is 661 // moved by API. 662 textView.post(() -> Selection.setSelection((Spannable) textView.getText(), 0)); 663 getInstrumentation().waitForIdleSync(); 664 sleepForFloatingToolbarPopup(); 665 assertFloatingToolbarIsDisplayed(); 666 assertFloatingToolbarDoesNotContainItem( 667 getActivity().getString(com.android.internal.R.string.copy)); 668 // Make sure that selection action mode is started after selection is created by API when 669 // insertion action mode is active. 670 textView.post( 671 () -> Selection.setSelection((Spannable) textView.getText(), 1, text.length())); 672 getInstrumentation().waitForIdleSync(); 673 sleepForFloatingToolbarPopup(); 674 assertFloatingToolbarIsDisplayed(); 675 assertFloatingToolbarContainsItem( 676 getActivity().getString(com.android.internal.R.string.copy)); 677 } 678 679 @SmallTest 680 public void testTransientState() throws Exception { 681 final String text = "abc def"; 682 onView(withId(R.id.textview)).perform(click()); 683 onView(withId(R.id.textview)).perform(replaceText(text)); 684 685 final TextView textView = (TextView) getActivity().findViewById(R.id.textview); 686 assertFalse(textView.hasTransientState()); 687 688 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('b'))); 689 // hasTransientState should return true when user generated selection is active. 690 assertTrue(textView.hasTransientState()); 691 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('d'))); 692 // hasTransientState should return false as the selection has been cleared. 693 assertFalse(textView.hasTransientState()); 694 textView.post( 695 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length())); 696 getInstrumentation().waitForIdleSync(); 697 // hasTransientState should return false when selection is created by API. 698 assertFalse(textView.hasTransientState()); 699 } 700} 701