TextViewActivityTest.java revision b0dd77c4115d333527a06cad84bc1c6ea8b4ac8e
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.widget.espresso.TextViewActions.clickOnTextAtIndex;
20import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
21import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
22import static android.widget.espresso.TextViewActions.dragHandle;
23import static android.widget.espresso.TextViewActions.Handle;
24import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
25import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
26import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
27import static android.widget.espresso.TextViewAssertions.hasSelection;
28import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
29import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed;
30import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
31import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
32import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem;
33import static android.support.test.espresso.Espresso.onView;
34import static android.support.test.espresso.action.ViewActions.click;
35import static android.support.test.espresso.action.ViewActions.pressKey;
36import static android.support.test.espresso.action.ViewActions.replaceText;
37import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
38import static android.support.test.espresso.assertion.ViewAssertions.matches;
39import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
40import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
41import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
42import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
43import static android.support.test.espresso.matcher.ViewMatchers.withId;
44import static android.support.test.espresso.matcher.ViewMatchers.withText;
45import static org.hamcrest.Matchers.allOf;
46
47import com.android.frameworks.coretests.R;
48
49import android.support.test.espresso.NoMatchingRootException;
50import android.support.test.espresso.NoMatchingViewException;
51import android.support.test.espresso.ViewInteraction;
52import android.test.ActivityInstrumentationTestCase2;
53import android.test.suitebuilder.annotation.SmallTest;
54import android.view.KeyEvent;
55
56/**
57 * Tests the TextView widget from an Activity
58 */
59public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
60
61    public TextViewActivityTest() {
62        super(TextViewActivity.class);
63    }
64
65    @Override
66    public void setUp() {
67        getActivity();
68    }
69
70    @SmallTest
71    public void testTypedTextIsOnScreen() throws Exception {
72        final String helloWorld = "Hello world!";
73        onView(withId(R.id.textview)).perform(click());
74        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
75
76        onView(withId(R.id.textview)).check(matches(withText(helloWorld)));
77    }
78
79    @SmallTest
80    public void testPositionCursorAtTextAtIndex() throws Exception {
81        final String helloWorld = "Hello world!";
82        onView(withId(R.id.textview)).perform(click());
83        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
84        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));
85
86        // Delete text at specified index and see if we got the right one.
87        onView(withId(R.id.textview)).perform(pressKey(KeyEvent.KEYCODE_FORWARD_DEL));
88        onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
89    }
90
91    @SmallTest
92    public void testLongPressToSelect() throws Exception {
93        final String helloWorld = "Hello Kirk!";
94        onView(withId(R.id.textview)).perform(click());
95        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
96        onView(withId(R.id.textview)).perform(
97                longPressOnTextAtIndex(helloWorld.indexOf("Kirk")));
98
99        onView(withId(R.id.textview)).check(hasSelection("Kirk"));
100    }
101
102    @SmallTest
103    public void testLongPressEmptySpace() throws Exception {
104        final String helloWorld = "Hello big round sun!";
105        onView(withId(R.id.textview)).perform(click());
106        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
107        // Move cursor somewhere else
108        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("big")));
109        // Long-press at end of line.
110        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(helloWorld.length()));
111
112        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
113    }
114
115    @SmallTest
116    public void testLongPressAndDragToSelect() throws Exception {
117        final String helloWorld = "Hello little handsome boy!";
118        onView(withId(R.id.textview)).perform(click());
119        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
120        onView(withId(R.id.textview)).perform(
121                longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!")));
122
123        onView(withId(R.id.textview)).check(hasSelection("little handsome"));
124    }
125
126    @SmallTest
127    public void testDoubleTapToSelect() throws Exception {
128        final String helloWorld = "Hello SuetYi!";
129        onView(withId(R.id.textview)).perform(click());
130        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
131        onView(withId(R.id.textview)).perform(
132                doubleClickOnTextAtIndex(helloWorld.indexOf("SuetYi")));
133
134        onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
135    }
136
137    @SmallTest
138    public void testDoubleTapAndDragToSelect() throws Exception {
139        final String helloWorld = "Hello young beautiful girl!";
140        onView(withId(R.id.textview)).perform(click());
141        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
142        onView(withId(R.id.textview)).perform(
143                doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));
144
145        onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
146    }
147
148    @SmallTest
149    public void testSelectBackwordsByTouch() throws Exception {
150        final String helloWorld = "Hello king of the Jungle!";
151        onView(withId(R.id.textview)).perform(click());
152        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
153        onView(withId(R.id.textview)).perform(
154                doubleTapAndDragOnText(helloWorld.indexOf(" Jungle!"), helloWorld.indexOf("king")));
155
156        onView(withId(R.id.textview)).check(hasSelection("king of the"));
157    }
158
159    @SmallTest
160    public void testToolbarAppearsAfterSelection() throws Exception {
161        final String text = "Toolbar appears after selection.";
162        onView(withId(R.id.textview)).perform(click());
163        assertFloatingToolbarIsNotDisplayed();
164        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
165        onView(withId(R.id.textview)).perform(
166                longPressOnTextAtIndex(text.indexOf("appears")));
167
168        sleepForFloatingToolbarPopup();
169        assertFloatingToolbarIsDisplayed();
170
171        final String text2 = "Toolbar disappears after typing text.";
172        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text2));
173        assertFloatingToolbarIsNotDisplayed();
174    }
175
176    @SmallTest
177    public void testToolbarAndInsertionHandle() throws Exception {
178        final String text = "text";
179        onView(withId(R.id.textview)).perform(click());
180        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
181        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
182        assertFloatingToolbarIsNotDisplayed();
183
184        onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
185        sleepForFloatingToolbarPopup();
186        assertFloatingToolbarIsDisplayed();
187
188        assertFloatingToolbarContainsItem(
189                getActivity().getString(com.android.internal.R.string.selectAll));
190        assertFloatingToolbarDoesNotContainItem(
191                getActivity().getString(com.android.internal.R.string.copy));
192        assertFloatingToolbarDoesNotContainItem(
193                getActivity().getString(com.android.internal.R.string.cut));
194    }
195
196    @SmallTest
197    public void testToolbarAndSelectionHandle() throws Exception {
198        final String text = "abcd efg hijk";
199        onView(withId(R.id.textview)).perform(click());
200        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
201
202        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f")));
203        sleepForFloatingToolbarPopup();
204        assertFloatingToolbarIsDisplayed();
205
206        assertFloatingToolbarContainsItem(
207                getActivity().getString(com.android.internal.R.string.selectAll));
208        assertFloatingToolbarContainsItem(
209                getActivity().getString(com.android.internal.R.string.copy));
210        assertFloatingToolbarContainsItem(
211                getActivity().getString(com.android.internal.R.string.cut));
212
213        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
214        onHandleView(com.android.internal.R.id.selection_start_handle)
215                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
216        sleepForFloatingToolbarPopup();
217        assertFloatingToolbarIsDisplayed();
218
219        onHandleView(com.android.internal.R.id.selection_end_handle)
220                .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
221        sleepForFloatingToolbarPopup();
222        assertFloatingToolbarIsDisplayed();
223
224        assertFloatingToolbarDoesNotContainItem(
225                getActivity().getString(com.android.internal.R.string.selectAll));
226        assertFloatingToolbarContainsItem(
227                getActivity().getString(com.android.internal.R.string.copy));
228        assertFloatingToolbarContainsItem(
229                getActivity().getString(com.android.internal.R.string.cut));
230    }
231
232    @SmallTest
233    public void testInsertionHandle() throws Exception {
234        final String text = "abcd efg hijk ";
235        onView(withId(R.id.textview)).perform(click());
236        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
237
238        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
239        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
240
241        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
242
243        onHandleView(com.android.internal.R.id.insertion_handle)
244                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
245        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
246
247        onHandleView(com.android.internal.R.id.insertion_handle)
248                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
249        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
250    }
251
252    @SmallTest
253    public void testInsertionHandle_multiLine() throws Exception {
254        final String text = "abcd\n" + "efg\n" + "hijk\n";
255        onView(withId(R.id.textview)).perform(click());
256        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
257
258        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
259        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
260
261        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
262
263        onHandleView(com.android.internal.R.id.insertion_handle)
264                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
265        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
266
267        onHandleView(com.android.internal.R.id.insertion_handle)
268                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
269        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
270    }
271
272    @SmallTest
273    public void testSelectionHandles() throws Exception {
274        final String text = "abcd efg hijk lmn";
275        onView(withId(R.id.textview)).perform(click());
276        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
277
278        assertNoSelectionHandles();
279
280        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
281
282        onHandleView(com.android.internal.R.id.selection_start_handle)
283                .check(matches(isDisplayed()));
284        onHandleView(com.android.internal.R.id.selection_end_handle)
285                .check(matches(isDisplayed()));
286
287        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
288        onHandleView(com.android.internal.R.id.selection_start_handle)
289                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
290        onView(withId(R.id.textview)).check(hasSelection("abcd efg"));
291
292        onHandleView(com.android.internal.R.id.selection_end_handle)
293                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1));
294        onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
295    }
296
297    @SmallTest
298    public void testSelectionHandles_multiLine() throws Exception {
299        final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
300        onView(withId(R.id.textview)).perform(click());
301        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
302        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
303
304        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
305        onHandleView(com.android.internal.R.id.selection_start_handle)
306                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e')));
307        onView(withId(R.id.textview)).check(hasSelection("efg\nhijk"));
308
309        onHandleView(com.android.internal.R.id.selection_start_handle)
310                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
311        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk"));
312
313        onHandleView(com.android.internal.R.id.selection_end_handle)
314                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n') + 1));
315        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn"));
316
317        onHandleView(com.android.internal.R.id.selection_end_handle)
318                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r') + 1));
319        onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
320    }
321
322    @SmallTest
323    public void testSelectionHandles_multiLine_rtl() throws Exception {
324        // Arabic text.
325        final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
326                + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n"
327                + "\u0639\u063A\u063B";
328        onView(withId(R.id.textview)).perform(click());
329        onView(withId(R.id.textview)).perform(replaceText(text));
330        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
331        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0634')));
332
333        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
334        onHandleView(com.android.internal.R.id.selection_start_handle)
335                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E')));
336        onView(withId(R.id.textview)).check(hasSelection(
337                text.substring(text.indexOf('\u062D'), text.indexOf('\u0635') + 1)));
338
339        onHandleView(com.android.internal.R.id.selection_start_handle)
340                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062A')));
341        onView(withId(R.id.textview)).check(hasSelection(
342                text.substring(text.indexOf('\u062A'), text.indexOf('\u0635') + 1)));
343
344        onHandleView(com.android.internal.R.id.selection_end_handle)
345                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u0638')));
346        onView(withId(R.id.textview)).check(hasSelection(
347                text.substring(text.indexOf('\u062A'), text.indexOf('\u0638') + 1)));
348
349        onHandleView(com.android.internal.R.id.selection_end_handle)
350                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u063B')));
351        onView(withId(R.id.textview)).check(hasSelection(text));
352    }
353
354
355    @SmallTest
356    public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
357        final String text = "abcd efg hijk lmn";
358        onView(withId(R.id.textview)).perform(click());
359        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
360        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
361
362        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
363        onHandleView(com.android.internal.R.id.selection_start_handle)
364                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l')));
365        onView(withId(R.id.textview)).check(hasSelection("g"));
366
367        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
368        onHandleView(com.android.internal.R.id.selection_end_handle)
369                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
370        onView(withId(R.id.textview)).check(hasSelection("e"));
371    }
372
373    @SmallTest
374    public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() throws Exception {
375        final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
376        onView(withId(R.id.textview)).perform(click());
377        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
378        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
379
380        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
381        onHandleView(com.android.internal.R.id.selection_start_handle)
382                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1));
383        onView(withId(R.id.textview)).check(hasSelection("k"));
384
385        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
386        onHandleView(com.android.internal.R.id.selection_end_handle)
387                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
388        onView(withId(R.id.textview)).check(hasSelection("h"));
389    }
390
391    @SmallTest
392    public void testSelectionHandles_snapToWordBoundary() throws Exception {
393        final String text = "abcd efg hijk lmn opqr";
394        onView(withId(R.id.textview)).perform(click());
395        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
396        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
397
398        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
399
400        onHandleView(com.android.internal.R.id.selection_start_handle)
401                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
402        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
403
404        onHandleView(com.android.internal.R.id.selection_start_handle)
405                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d') + 1));
406        onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
407
408
409        onHandleView(com.android.internal.R.id.selection_start_handle)
410                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
411        onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
412
413        onHandleView(com.android.internal.R.id.selection_start_handle)
414                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d')));
415        onView(withId(R.id.textview)).check(hasSelection("d efg hijk"));
416
417        onHandleView(com.android.internal.R.id.selection_start_handle)
418                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('b')));
419        onView(withId(R.id.textview)).check(hasSelection("bcd efg hijk"));
420
421        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
422
423        onHandleView(com.android.internal.R.id.selection_end_handle)
424                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n')));
425        onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
426
427        onHandleView(com.android.internal.R.id.selection_end_handle)
428                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('o')));
429        onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
430
431        onHandleView(com.android.internal.R.id.selection_end_handle)
432                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('q')));
433        onView(withId(R.id.textview)).check(hasSelection("hijk lmn opqr"));
434
435        onHandleView(com.android.internal.R.id.selection_end_handle)
436                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
437        onView(withId(R.id.textview)).check(hasSelection("hijk lmn o"));
438
439        onHandleView(com.android.internal.R.id.selection_end_handle)
440                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r')));
441        onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq"));
442    }
443
444    @SmallTest
445    public void testSelectionHandles_snapToWordBoundary_multiLine() throws Exception {
446        final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu";
447        onView(withId(R.id.textview)).perform(click());
448        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
449        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('m')));
450
451        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
452
453        onHandleView(com.android.internal.R.id.selection_start_handle)
454                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
455        onView(withId(R.id.textview)).check(hasSelection("abcd efg\nhijk lmn"));
456
457        onHandleView(com.android.internal.R.id.selection_start_handle)
458                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('g')));
459        onView(withId(R.id.textview)).check(hasSelection("g\nhijk lmn"));
460
461        onHandleView(com.android.internal.R.id.selection_start_handle)
462                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('m')));
463        onView(withId(R.id.textview)).check(hasSelection("lmn"));
464
465        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
466
467        onHandleView(com.android.internal.R.id.selection_end_handle)
468                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('u')));
469        onView(withId(R.id.textview)).check(hasSelection("hijk lmn\nopqr stu"));
470
471        onHandleView(com.android.internal.R.id.selection_end_handle)
472                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
473        onView(withId(R.id.textview)).check(hasSelection("hijk lmn\no"));
474
475        onHandleView(com.android.internal.R.id.selection_end_handle)
476                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i')));
477        onView(withId(R.id.textview)).check(hasSelection("hijk"));
478    }
479
480    private static void assertNoSelectionHandles() {
481        try {
482            onHandleView(com.android.internal.R.id.selection_start_handle)
483                    .check(matches(isDisplayed()));
484        } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
485            try {
486                onHandleView(com.android.internal.R.id.selection_end_handle)
487                        .check(matches(isDisplayed()));
488            } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e1) {
489                return;
490            }
491        }
492        throw new AssertionError("Selection handle found");
493    }
494
495    private static ViewInteraction onHandleView(int id)
496            throws NoMatchingRootException, NoMatchingViewException, AssertionError {
497        return onView(allOf(withId(id), isAssignableFrom(Editor.HandleView.class)))
498                .inRoot(withDecorView(hasDescendant(withId(id))));
499    }
500}
501