blob: 90758ba7c4188b66b53ed4aec33271808ba46ff9 [file] [log] [blame]
Abodunrinwa Toki223c8392015-07-24 20:55:59 -07001/*
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.Espresso.onView;
20import static android.support.test.espresso.action.ViewActions.click;
Abodunrinwa Tokic5b54ba2016-10-25 10:21:36 +010021import static android.support.test.espresso.action.ViewActions.longClick;
Abodunrinwa Toki90cdfe02015-09-15 21:15:56 +010022import static android.support.test.espresso.action.ViewActions.pressKey;
Keisuke Kuroyanagi26454142015-12-02 15:04:57 -080023import static android.support.test.espresso.action.ViewActions.replaceText;
Abodunrinwa Toki223c8392015-07-24 20:55:59 -070024import static android.support.test.espresso.assertion.ViewAssertions.matches;
Abodunrinwa Tokifc6e25e2015-11-30 19:45:32 +000025import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
Abodunrinwa Toki223c8392015-07-24 20:55:59 -070026import static android.support.test.espresso.matcher.ViewMatchers.withId;
27import static android.support.test.espresso.matcher.ViewMatchers.withText;
Siyamed Sinir21914182017-06-16 15:24:00 -070028import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates;
Siyamed Sinir21914182017-06-16 15:24:00 -070029import static android.widget.espresso.DragHandleUtils.onHandleView;
Richard Ledley26b87222017-11-30 10:54:08 +000030import static android.widget.espresso.FloatingToolbarEspressoUtils
31 .assertFloatingToolbarContainsItem;
32import static android.widget.espresso.FloatingToolbarEspressoUtils
33 .assertFloatingToolbarDoesNotContainItem;
Siyamed Sinir21914182017-06-16 15:24:00 -070034import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
Siyamed Sinir21914182017-06-16 15:24:00 -070035import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarItemIndex;
36import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem;
37import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
38import static android.widget.espresso.TextViewActions.Handle;
39import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
40import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
41import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
42import static android.widget.espresso.TextViewActions.dragHandle;
43import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
44import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
45import static android.widget.espresso.TextViewAssertions.doesNotHaveStyledText;
46import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
47import static android.widget.espresso.TextViewAssertions.hasSelection;
48
Abodunrinwa Tokif299fc02018-05-17 17:36:25 +010049import static junit.framework.Assert.assertEquals;
Siyamed Sinir21914182017-06-16 15:24:00 -070050import static junit.framework.Assert.assertFalse;
51import static junit.framework.Assert.assertTrue;
52
Abodunrinwa Tokic5b54ba2016-10-25 10:21:36 +010053import static org.hamcrest.Matchers.anyOf;
54import static org.hamcrest.Matchers.is;
Abodunrinwa Toki6264cbd2017-11-06 15:12:52 +000055import static org.mockito.Matchers.any;
56import static org.mockito.Mockito.mock;
57import static org.mockito.Mockito.never;
58import static org.mockito.Mockito.verify;
59import static org.mockito.Mockito.when;
Abodunrinwa Toki223c8392015-07-24 20:55:59 -070060
Siyamed Sinir21914182017-06-16 15:24:00 -070061import android.app.Activity;
62import android.app.Instrumentation;
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +010063import android.content.ClipData;
64import android.content.ClipboardManager;
Siyamed Sinir21914182017-06-16 15:24:00 -070065import android.support.test.InstrumentationRegistry;
66import android.support.test.espresso.action.EspressoKey;
67import android.support.test.filters.MediumTest;
68import android.support.test.rule.ActivityTestRule;
69import android.support.test.runner.AndroidJUnit4;
Richard Ledley5f2f8202018-02-05 14:55:47 +000070import android.support.test.uiautomator.UiDevice;
Abodunrinwa Toki89550e82017-10-31 03:46:46 +000071import android.test.suitebuilder.annotation.Suppress;
Siyamed Sinir21914182017-06-16 15:24:00 -070072import android.text.InputType;
73import android.text.Selection;
74import android.text.Spannable;
Richard Ledley26b87222017-11-30 10:54:08 +000075import android.text.SpannableString;
76import android.text.method.LinkMovementMethod;
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +010077import android.view.ActionMode;
Siyamed Sinir21914182017-06-16 15:24:00 -070078import android.view.KeyEvent;
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +010079import android.view.Menu;
80import android.view.MenuItem;
Abodunrinwa Tokif299fc02018-05-17 17:36:25 +010081import android.view.textclassifier.SelectionEvent;
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +010082import android.view.textclassifier.TextClassificationManager;
83import android.view.textclassifier.TextClassifier;
Richard Ledley26b87222017-11-30 10:54:08 +000084import android.view.textclassifier.TextLinks;
Abodunrinwa Toki080c8542018-03-27 00:04:06 +010085import android.view.textclassifier.TextLinksParams;
Abodunrinwa Toki9479d3e2016-03-09 19:41:41 +000086import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
Abodunrinwa Toki223c8392015-07-24 20:55:59 -070087
Abodunrinwa Tokic5b54ba2016-10-25 10:21:36 +010088import com.android.frameworks.coretests.R;
Keisuke Kuroyanagie27e0852016-01-08 19:05:27 +090089
Siyamed Sinir21914182017-06-16 15:24:00 -070090import org.junit.Before;
91import org.junit.Rule;
92import org.junit.Test;
93import org.junit.runner.RunWith;
94
Abodunrinwa Tokif299fc02018-05-17 17:36:25 +010095import java.util.ArrayList;
96import java.util.List;
97
Abodunrinwa Toki223c8392015-07-24 20:55:59 -070098/**
99 * Tests the TextView widget from an Activity
100 */
Siyamed Sinir21914182017-06-16 15:24:00 -0700101@RunWith(AndroidJUnit4.class)
Abodunrinwa Tokic5b54ba2016-10-25 10:21:36 +0100102@MediumTest
Siyamed Sinir21914182017-06-16 15:24:00 -0700103public class TextViewActivityTest {
Abodunrinwa Toki223c8392015-07-24 20:55:59 -0700104
Siyamed Sinir21914182017-06-16 15:24:00 -0700105 @Rule
106 public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
107 TextViewActivity.class);
Abodunrinwa Toki223c8392015-07-24 20:55:59 -0700108
Siyamed Sinir21914182017-06-16 15:24:00 -0700109 private Activity mActivity;
110 private Instrumentation mInstrumentation;
111
112 @Before
113 public void setUp() {
114 mActivity = mActivityRule.getActivity();
115 mInstrumentation = InstrumentationRegistry.getInstrumentation();
116 mActivity.getSystemService(TextClassificationManager.class)
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +0100117 .setTextClassifier(TextClassifier.NO_OP);
Abodunrinwa Tokic9e924e2015-10-08 12:01:35 +0100118 }
119
Siyamed Sinir21914182017-06-16 15:24:00 -0700120 @Test
121 public void testTypedTextIsOnScreen() {
Abodunrinwa Toki223c8392015-07-24 20:55:59 -0700122 final String helloWorld = "Hello world!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900123 // We use replaceText instead of typeTextIntoFocusedView to input text to avoid
124 // unintentional interactions with software keyboard.
125 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Toki223c8392015-07-24 20:55:59 -0700126
127 onView(withId(R.id.textview)).check(matches(withText(helloWorld)));
128 }
Siyamed Sinir21914182017-06-16 15:24:00 -0700129 @Test
130 public void testPositionCursorAtTextAtIndex() {
Abodunrinwa Toki90cdfe02015-09-15 21:15:56 +0100131 final String helloWorld = "Hello world!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900132 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Toki90cdfe02015-09-15 21:15:56 +0100133 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));
134
135 // Delete text at specified index and see if we got the right one.
136 onView(withId(R.id.textview)).perform(pressKey(KeyEvent.KEYCODE_FORWARD_DEL));
137 onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
138 }
Abodunrinwa Tokica4aaf32015-09-22 20:31:21 +0100139
Siyamed Sinir21914182017-06-16 15:24:00 -0700140 @Test
141 public void testPositionCursorAtTextAtIndex_arabic() {
Keisuke Kuroyanagie27e0852016-01-08 19:05:27 +0900142 // Arabic text. The expected cursorable boundary is
143 // | \u0623 \u064F | \u067A | \u0633 \u0652 |
144 final String text = "\u0623\u064F\u067A\u0633\u0652";
Keisuke Kuroyanagie27e0852016-01-08 19:05:27 +0900145 onView(withId(R.id.textview)).perform(replaceText(text));
146
147 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
148 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
149 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1));
150 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2))));
151 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2));
152 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
153 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(3));
154 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(3));
155 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(4));
156 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(3), is(5))));
157 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(5));
158 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(5));
159 }
160
Siyamed Sinir21914182017-06-16 15:24:00 -0700161 @Test
162 public void testPositionCursorAtTextAtIndex_devanagari() {
Keisuke Kuroyanagie27e0852016-01-08 19:05:27 +0900163 // Devanagari text. The expected cursorable boundary is | \u0915 \u093E |
164 final String text = "\u0915\u093E";
Keisuke Kuroyanagie27e0852016-01-08 19:05:27 +0900165 onView(withId(R.id.textview)).perform(replaceText(text));
166
167 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
168 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
169 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(1));
170 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(anyOf(is(0), is(2))));
171 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(2));
172 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
173 }
174
Siyamed Sinir21914182017-06-16 15:24:00 -0700175 @Test
176 public void testLongPressToSelect() {
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100177 final String helloWorld = "Hello Kirk!";
178 onView(withId(R.id.textview)).perform(click());
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900179 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100180 onView(withId(R.id.textview)).perform(
181 longPressOnTextAtIndex(helloWorld.indexOf("Kirk")));
182
183 onView(withId(R.id.textview)).check(hasSelection("Kirk"));
184 }
185
Siyamed Sinir21914182017-06-16 15:24:00 -0700186 @Test
187 public void testLongPressEmptySpace() {
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100188 final String helloWorld = "Hello big round sun!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900189 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100190 // Move cursor somewhere else
191 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("big")));
192 // Long-press at end of line.
Abodunrinwa Toki9479d3e2016-03-09 19:41:41 +0000193 onView(withId(R.id.textview)).perform(longPressAtRelativeCoordinates(
194 RelativeCoordinatesProvider.HorizontalReference.RIGHT, -5,
195 RelativeCoordinatesProvider.VerticalReference.CENTER, 0));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100196
197 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
198 }
199
Siyamed Sinir21914182017-06-16 15:24:00 -0700200 @Test
201 public void testLongPressAndDragToSelect() {
Abodunrinwa Tokica4aaf32015-09-22 20:31:21 +0100202 final String helloWorld = "Hello little handsome boy!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900203 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Tokica4aaf32015-09-22 20:31:21 +0100204 onView(withId(R.id.textview)).perform(
205 longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!")));
206
207 onView(withId(R.id.textview)).check(hasSelection("little handsome"));
208 }
209
Siyamed Sinir21914182017-06-16 15:24:00 -0700210 @Test
211 public void testLongPressAndDragToSelect_emoji() {
Keisuke Kuroyanagi133dfc02016-07-21 18:07:23 +0900212 final String text = "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03";
Keisuke Kuroyanagi133dfc02016-07-21 18:07:23 +0900213 onView(withId(R.id.textview)).perform(replaceText(text));
214
215 onView(withId(R.id.textview)).perform(longPressAndDragOnText(4, 6));
216 onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE02"));
217
218 onView(withId(R.id.textview)).perform(click());
219
220 onView(withId(R.id.textview)).perform(longPressAndDragOnText(4, 2));
221 onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE01"));
222 }
223
Siyamed Sinir21914182017-06-16 15:24:00 -0700224 @Test
225 public void testDragAndDrop() {
Keisuke Kuroyanagi4307aeb2015-12-07 11:16:39 -0800226 final String text = "abc def ghi.";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900227 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagi4307aeb2015-12-07 11:16:39 -0800228 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e")));
229
230 onView(withId(R.id.textview)).perform(
231 longPressAndDragOnText(text.indexOf("e"), text.length()));
232
233 onView(withId(R.id.textview)).check(matches(withText("abc ghi.def")));
234 onView(withId(R.id.textview)).check(hasSelection(""));
Keisuke Kuroyanagi4307aeb2015-12-07 11:16:39 -0800235 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
Keisuke Kuroyanagifae45782016-02-24 18:53:00 -0800236
237 // Test undo returns to the original state.
238 onView(withId(R.id.textview)).perform(pressKey(
239 (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z)
240 .build()));
241 onView(withId(R.id.textview)).check(matches(withText(text)));
Keisuke Kuroyanagi4307aeb2015-12-07 11:16:39 -0800242 }
243
Siyamed Sinir21914182017-06-16 15:24:00 -0700244 @Test
245 public void testDoubleTapToSelect() {
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100246 final String helloWorld = "Hello SuetYi!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900247 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
248
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100249 onView(withId(R.id.textview)).perform(
250 doubleClickOnTextAtIndex(helloWorld.indexOf("SuetYi")));
251
252 onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
253 }
254
Siyamed Sinir21914182017-06-16 15:24:00 -0700255 @Test
256 public void testDoubleTapAndDragToSelect() {
257 final String helloWorld = "Hello young beautiful person!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900258 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Siyamed Sinir21914182017-06-16 15:24:00 -0700259 onView(withId(R.id.textview)).perform(doubleTapAndDragOnText(helloWorld.indexOf("young"),
260 helloWorld.indexOf(" person!")));
Abodunrinwa Tokica4aaf32015-09-22 20:31:21 +0100261
262 onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
263 }
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100264
Siyamed Sinir21914182017-06-16 15:24:00 -0700265 @Test
266 public void testDoubleTapAndDragToSelect_multiLine() {
Sara Kato68c433d2016-08-09 14:40:45 +0900267 final String helloWorld = "abcd\n" + "efg\n" + "hijklm\n" + "nop";
Sara Kato68c433d2016-08-09 14:40:45 +0900268 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
269 onView(withId(R.id.textview)).perform(
270 doubleTapAndDragOnText(helloWorld.indexOf("m"), helloWorld.indexOf("a")));
271 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijklm"));
272 }
273
Siyamed Sinir21914182017-06-16 15:24:00 -0700274 @Test
275 public void testSelectBackwordsByTouch() {
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100276 final String helloWorld = "Hello king of the Jungle!";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900277 onView(withId(R.id.textview)).perform(replaceText(helloWorld));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100278 onView(withId(R.id.textview)).perform(
279 doubleTapAndDragOnText(helloWorld.indexOf(" Jungle!"), helloWorld.indexOf("king")));
280
281 onView(withId(R.id.textview)).check(hasSelection("king of the"));
282 }
283
Siyamed Sinir21914182017-06-16 15:24:00 -0700284 @Test
285 public void testToolbarAppearsAfterSelection() {
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100286 final String text = "Toolbar appears after selection.";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900287 onView(withId(R.id.textview)).perform(replaceText(text));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100288 onView(withId(R.id.textview)).perform(
289 longPressOnTextAtIndex(text.indexOf("appears")));
290
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800291 sleepForFloatingToolbarPopup();
292 assertFloatingToolbarIsDisplayed();
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800293 }
294
Siyamed Sinir21914182017-06-16 15:24:00 -0700295 @Test
Siyamed Sinir987ec652016-02-17 19:44:41 -0800296 public void testToolbarAppearsAfterSelection_withFirstStringLtrAlgorithmAndRtlHint()
Siyamed Sinir21914182017-06-16 15:24:00 -0700297 throws Throwable {
Siyamed Sinir987ec652016-02-17 19:44:41 -0800298 // after the hint layout change, the floating toolbar was not visible in the case below
299 // this test tests that the floating toolbar is displayed on the screen and is visible to
300 // user.
Siyamed Sinir21914182017-06-16 15:24:00 -0700301 mActivityRule.runOnUiThread(() -> {
302 final TextView textView = mActivity.findViewById(R.id.textview);
303 textView.setTextDirection(TextView.TEXT_DIRECTION_FIRST_STRONG_LTR);
304 textView.setInputType(InputType.TYPE_CLASS_TEXT);
305 textView.setSingleLine(true);
306 textView.setHint("الروبوت");
Siyamed Sinir987ec652016-02-17 19:44:41 -0800307 });
Siyamed Sinir21914182017-06-16 15:24:00 -0700308 mInstrumentation.waitForIdleSync();
Siyamed Sinir987ec652016-02-17 19:44:41 -0800309
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900310 onView(withId(R.id.textview)).perform(replaceText("test"));
Siyamed Sinir987ec652016-02-17 19:44:41 -0800311 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(1));
Siyamed Sinir21914182017-06-16 15:24:00 -0700312 clickFloatingToolbarItem(mActivity.getString(com.android.internal.R.string.cut));
Siyamed Sinir987ec652016-02-17 19:44:41 -0800313 onView(withId(R.id.textview)).perform(longClick());
314 sleepForFloatingToolbarPopup();
315
316 assertFloatingToolbarIsDisplayed();
317 }
318
Siyamed Sinir21914182017-06-16 15:24:00 -0700319 @Test
Richard Ledley26b87222017-11-30 10:54:08 +0000320 public void testToolbarAppearsAfterLinkClicked() throws Throwable {
Richard Ledley5f2f8202018-02-05 14:55:47 +0000321 TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.textview);
322 int position = (textLink.getStart() + textLink.getEnd()) / 2;
323 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(position));
324 sleepForFloatingToolbarPopup();
325 assertFloatingToolbarIsDisplayed();
Richard Ledley724eff92017-12-21 10:11:34 +0000326 }
327
328 @Test
329 public void testToolbarAppearsAfterLinkClickedNonselectable() throws Throwable {
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100330 final TextView textView = mActivity.findViewById(R.id.nonselectable_textview);
331 final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
332 final int position = (textLink.getStart() + textLink.getEnd()) / 2;
333
Richard Ledley5f2f8202018-02-05 14:55:47 +0000334 onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
335 sleepForFloatingToolbarPopup();
336 assertFloatingToolbarIsDisplayed();
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100337 assertTrue(textView.hasSelection());
338
339 // toggle
340 onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
341 sleepForFloatingToolbarPopup();
342 assertFalse(textView.hasSelection());
343
344 onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
345 sleepForFloatingToolbarPopup();
346 assertFloatingToolbarIsDisplayed();
347 assertTrue(textView.hasSelection());
348
349 // click outside
350 onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(0));
351 sleepForFloatingToolbarPopup();
352 assertFalse(textView.hasSelection());
Richard Ledley724eff92017-12-21 10:11:34 +0000353 }
354
Richard Ledley5f2f8202018-02-05 14:55:47 +0000355 @Test
356 public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable {
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100357 final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
358 final int position = (textLink.getStart() + textLink.getEnd()) / 2;
359 final TextView textView = mActivity.findViewById(R.id.nonselectable_textview);
360 mActivityRule.runOnUiThread(() -> textView.setFocusableInTouchMode(true));
Richard Ledley5f2f8202018-02-05 14:55:47 +0000361
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100362 onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
Richard Ledley5f2f8202018-02-05 14:55:47 +0000363 sleepForFloatingToolbarPopup();
364 assertFloatingToolbarIsDisplayed();
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100365 assertTrue(textView.hasSelection());
Richard Ledley5f2f8202018-02-05 14:55:47 +0000366
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100367 mActivityRule.runOnUiThread(() -> textView.clearFocus());
368 mInstrumentation.waitForIdleSync();
Richard Ledley5f2f8202018-02-05 14:55:47 +0000369 sleepForFloatingToolbarPopup();
Richard Ledley5f2f8202018-02-05 14:55:47 +0000370
Abodunrinwa Toki29cb7682018-04-11 21:24:20 +0100371 assertFalse(textView.hasSelection());
Richard Ledley5f2f8202018-02-05 14:55:47 +0000372 }
373
374 @Test
375 public void testSelectionRemovedFromNonselectableTextWhenWindowLosesFocus() throws Throwable {
376 TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
377 int nonselectablePosition = (textLink.getStart() + textLink.getEnd()) / 2;
378 TextView nonselectableTextView = mActivity.findViewById(R.id.nonselectable_textview);
379
380 onView(withId(R.id.nonselectable_textview))
381 .perform(clickOnTextAtIndex(nonselectablePosition));
382 sleepForFloatingToolbarPopup();
383 assertFloatingToolbarIsDisplayed();
384 assertTrue(nonselectableTextView.hasSelection());
385
386 UiDevice device = UiDevice.getInstance(mInstrumentation);
387 device.openNotification();
388 Thread.sleep(2000);
389 device.pressBack();
390 Thread.sleep(2000);
391
392 assertFalse(nonselectableTextView.hasSelection());
393 }
394
395 private TextLinks.TextLink addLinkifiedTextToTextView(int id) throws Throwable {
Richard Ledley724eff92017-12-21 10:11:34 +0000396 TextView textView = mActivity.findViewById(id);
Richard Ledley26b87222017-11-30 10:54:08 +0000397 useSystemDefaultTextClassifier();
398 TextClassificationManager textClassificationManager =
399 mActivity.getSystemService(TextClassificationManager.class);
400 TextClassifier textClassifier = textClassificationManager.getTextClassifier();
Abodunrinwa Tokife20cdd2017-12-12 02:31:25 +0000401 Spannable content = new SpannableString("Call me at +19148277737");
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100402 TextLinks.Request request = new TextLinks.Request.Builder(content).build();
403 TextLinks links = textClassifier.generateLinks(request);
404 TextLinksParams applyParams = new TextLinksParams.Builder()
405 .setApplyStrategy(TextLinks.APPLY_STRATEGY_REPLACE)
406 .build();
407 applyParams.apply(content, links);
Richard Ledley26b87222017-11-30 10:54:08 +0000408
409 mActivityRule.runOnUiThread(() -> {
410 textView.setText(content);
411 textView.setMovementMethod(LinkMovementMethod.getInstance());
412 });
413 mInstrumentation.waitForIdleSync();
414
415 // Wait for the UI thread to refresh
416 Thread.sleep(1000);
417
Richard Ledley5f2f8202018-02-05 14:55:47 +0000418 return links.getLinks().iterator().next();
Richard Ledley26b87222017-11-30 10:54:08 +0000419 }
420
421 @Test
Siyamed Sinir21914182017-06-16 15:24:00 -0700422 public void testToolbarAndInsertionHandle() {
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800423 final String text = "text";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900424 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800425 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800426
427 onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
428 sleepForFloatingToolbarPopup();
429 assertFloatingToolbarIsDisplayed();
430
431 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700432 mActivity.getString(com.android.internal.R.string.selectAll));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800433 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700434 mActivity.getString(com.android.internal.R.string.copy));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800435 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700436 mActivity.getString(com.android.internal.R.string.cut));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800437 }
438
Siyamed Sinir21914182017-06-16 15:24:00 -0700439 @Test
440 public void testToolbarAndSelectionHandle() {
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800441 final String text = "abcd efg hijk";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900442 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800443
444 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f")));
445 sleepForFloatingToolbarPopup();
446 assertFloatingToolbarIsDisplayed();
447
448 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700449 mActivity.getString(com.android.internal.R.string.selectAll));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800450 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700451 mActivity.getString(com.android.internal.R.string.copy));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800452 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700453 mActivity.getString(com.android.internal.R.string.cut));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800454
Siyamed Sinir21914182017-06-16 15:24:00 -0700455 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800456 onHandleView(com.android.internal.R.id.selection_start_handle)
457 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
458 sleepForFloatingToolbarPopup();
459 assertFloatingToolbarIsDisplayed();
460
461 onHandleView(com.android.internal.R.id.selection_end_handle)
462 .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
463 sleepForFloatingToolbarPopup();
464 assertFloatingToolbarIsDisplayed();
465
466 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700467 mActivity.getString(com.android.internal.R.string.selectAll));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800468 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700469 mActivity.getString(com.android.internal.R.string.copy));
Keisuke Kuroyanagib0dd77c2015-12-02 13:27:01 -0800470 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700471 mActivity.getString(com.android.internal.R.string.cut));
Abodunrinwa Toki8a5e1ae2015-09-28 21:59:04 +0100472 }
Keisuke Kuroyanagida79ee62015-11-25 16:15:15 +0900473
Siyamed Sinir21914182017-06-16 15:24:00 -0700474 @Test
475 public void testInsertionHandle() {
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900476 final String text = "abcd efg hijk ";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900477 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900478
479 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
480 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
481
Siyamed Sinir21914182017-06-16 15:24:00 -0700482 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900483
484 onHandleView(com.android.internal.R.id.insertion_handle)
485 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
486 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
487
488 onHandleView(com.android.internal.R.id.insertion_handle)
489 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
490 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
491 }
492
Siyamed Sinir21914182017-06-16 15:24:00 -0700493 @Test
494 public void testInsertionHandle_multiLine() {
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900495 final String text = "abcd\n" + "efg\n" + "hijk\n";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900496 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900497
498 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
499 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
500
Siyamed Sinir21914182017-06-16 15:24:00 -0700501 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagie8b3dd42015-11-26 14:19:27 +0900502
503 onHandleView(com.android.internal.R.id.insertion_handle)
504 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
505 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
506
507 onHandleView(com.android.internal.R.id.insertion_handle)
508 .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
509 onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
510 }
511
Siyamed Sinir21914182017-06-16 15:24:00 -0700512 @Test
513 public void testSelectionHandles() {
Keisuke Kuroyanagida79ee62015-11-25 16:15:15 +0900514 final String text = "abcd efg hijk lmn";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900515 onView(withId(R.id.textview)).perform(replaceText(text));
Abodunrinwa Tokifc6e25e2015-11-30 19:45:32 +0000516
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900517 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
Keisuke Kuroyanagida79ee62015-11-25 16:15:15 +0900518
Abodunrinwa Tokifc6e25e2015-11-30 19:45:32 +0000519 onHandleView(com.android.internal.R.id.selection_start_handle)
520 .check(matches(isDisplayed()));
521 onHandleView(com.android.internal.R.id.selection_end_handle)
522 .check(matches(isDisplayed()));
523
Siyamed Sinir21914182017-06-16 15:24:00 -0700524 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagida79ee62015-11-25 16:15:15 +0900525 onHandleView(com.android.internal.R.id.selection_start_handle)
526 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
527 onView(withId(R.id.textview)).check(hasSelection("abcd efg"));
528
529 onHandleView(com.android.internal.R.id.selection_end_handle)
530 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1));
531 onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
532 }
Keisuke Kuroyanagic24c2bb2015-11-24 18:48:28 +0900533
Siyamed Sinir21914182017-06-16 15:24:00 -0700534 @Test
535 public void testSelectionHandles_bidi() {
Keisuke Kuroyanagif0bb87b72016-02-08 23:52:55 +0900536 final String text = "abc \u0621\u0622\u0623 def";
Keisuke Kuroyanagif0bb87b72016-02-08 23:52:55 +0900537 onView(withId(R.id.textview)).perform(replaceText(text));
538
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900539 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('\u0622')));
Keisuke Kuroyanagif0bb87b72016-02-08 23:52:55 +0900540
541 onHandleView(com.android.internal.R.id.selection_start_handle)
542 .check(matches(isDisplayed()));
543 onHandleView(com.android.internal.R.id.selection_end_handle)
544 .check(matches(isDisplayed()));
545
546 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
547
Siyamed Sinir21914182017-06-16 15:24:00 -0700548 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagif0bb87b72016-02-08 23:52:55 +0900549 onHandleView(com.android.internal.R.id.selection_start_handle)
550 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
551 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
552
553 onHandleView(com.android.internal.R.id.selection_end_handle)
554 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
555 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
556
557 onHandleView(com.android.internal.R.id.selection_start_handle)
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900558 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0623'),
Keisuke Kuroyanagif0bb87b72016-02-08 23:52:55 +0900559 false));
560 onView(withId(R.id.textview)).check(hasSelection("\u0623"));
561
562 onHandleView(com.android.internal.R.id.selection_start_handle)
563 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0621'),
564 false));
565 onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
566
567 onHandleView(com.android.internal.R.id.selection_start_handle)
568 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
569 onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623"));
570
571 onHandleView(com.android.internal.R.id.selection_end_handle)
572 .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
573 onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
574 }
575
Siyamed Sinir21914182017-06-16 15:24:00 -0700576 @Test
577 public void testSelectionHandles_multiLine() {
Keisuke Kuroyanagic24c2bb2015-11-24 18:48:28 +0900578 final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900579 onView(withId(R.id.textview)).perform(replaceText(text));
580 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagic24c2bb2015-11-24 18:48:28 +0900581
Siyamed Sinir21914182017-06-16 15:24:00 -0700582 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagic24c2bb2015-11-24 18:48:28 +0900583 onHandleView(com.android.internal.R.id.selection_start_handle)
584 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e')));
585 onView(withId(R.id.textview)).check(hasSelection("efg\nhijk"));
586
587 onHandleView(com.android.internal.R.id.selection_start_handle)
588 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
589 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk"));
590
591 onHandleView(com.android.internal.R.id.selection_end_handle)
592 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n') + 1));
593 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn"));
594
595 onHandleView(com.android.internal.R.id.selection_end_handle)
596 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r') + 1));
597 onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
598 }
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900599
Abodunrinwa Toki89550e82017-10-31 03:46:46 +0000600 @Suppress // Consistently failing.
Siyamed Sinir21914182017-06-16 15:24:00 -0700601 @Test
602 public void testSelectionHandles_multiLine_rtl() {
Keisuke Kuroyanagi26454142015-12-02 15:04:57 -0800603 // Arabic text.
604 final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
605 + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n"
606 + "\u0639\u063A\u063B";
Keisuke Kuroyanagi26454142015-12-02 15:04:57 -0800607 onView(withId(R.id.textview)).perform(replaceText(text));
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900608 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('\u0634')));
Keisuke Kuroyanagi26454142015-12-02 15:04:57 -0800609
Siyamed Sinir21914182017-06-16 15:24:00 -0700610 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagi26454142015-12-02 15:04:57 -0800611 onHandleView(com.android.internal.R.id.selection_start_handle)
612 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E')));
613 onView(withId(R.id.textview)).check(hasSelection(
614 text.substring(text.indexOf('\u062D'), text.indexOf('\u0635') + 1)));
615
616 onHandleView(com.android.internal.R.id.selection_start_handle)
617 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062A')));
618 onView(withId(R.id.textview)).check(hasSelection(
619 text.substring(text.indexOf('\u062A'), text.indexOf('\u0635') + 1)));
620
621 onHandleView(com.android.internal.R.id.selection_end_handle)
622 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u0638')));
623 onView(withId(R.id.textview)).check(hasSelection(
624 text.substring(text.indexOf('\u062A'), text.indexOf('\u0638') + 1)));
625
626 onHandleView(com.android.internal.R.id.selection_end_handle)
627 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u063B')));
628 onView(withId(R.id.textview)).check(hasSelection(text));
629 }
630
Siyamed Sinir21914182017-06-16 15:24:00 -0700631 @Test
632 public void testSelectionHandles_doesNotPassAnotherHandle() {
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900633 final String text = "abcd efg hijk lmn";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900634 onView(withId(R.id.textview)).perform(replaceText(text));
635 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900636
Siyamed Sinir21914182017-06-16 15:24:00 -0700637 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900638 onHandleView(com.android.internal.R.id.selection_start_handle)
639 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l')));
640 onView(withId(R.id.textview)).check(hasSelection("g"));
641
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900642 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900643 onHandleView(com.android.internal.R.id.selection_end_handle)
644 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
645 onView(withId(R.id.textview)).check(hasSelection("e"));
646 }
647
Siyamed Sinir21914182017-06-16 15:24:00 -0700648 @Test
649 public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() {
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900650 final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900651 onView(withId(R.id.textview)).perform(replaceText(text));
652 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900653
Siyamed Sinir21914182017-06-16 15:24:00 -0700654 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900655 onHandleView(com.android.internal.R.id.selection_start_handle)
656 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1));
657 onView(withId(R.id.textview)).check(hasSelection("k"));
658
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900659 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagicb6e8422015-11-24 18:51:48 +0900660 onHandleView(com.android.internal.R.id.selection_end_handle)
661 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
662 onView(withId(R.id.textview)).check(hasSelection("h"));
663 }
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900664
Siyamed Sinir21914182017-06-16 15:24:00 -0700665 @Test
666 public void testSelectionHandles_snapToWordBoundary() {
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900667 final String text = "abcd efg hijk lmn opqr";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900668 onView(withId(R.id.textview)).perform(replaceText(text));
669 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900670
Siyamed Sinir21914182017-06-16 15:24:00 -0700671 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900672
673 onHandleView(com.android.internal.R.id.selection_start_handle)
674 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
675 onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
676
677 onHandleView(com.android.internal.R.id.selection_start_handle)
678 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d') + 1));
679 onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
680
681
682 onHandleView(com.android.internal.R.id.selection_start_handle)
683 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
684 onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
685
686 onHandleView(com.android.internal.R.id.selection_start_handle)
687 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('d')));
688 onView(withId(R.id.textview)).check(hasSelection("d efg hijk"));
689
690 onHandleView(com.android.internal.R.id.selection_start_handle)
691 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('b')));
692 onView(withId(R.id.textview)).check(hasSelection("bcd efg hijk"));
693
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900694 onView(withId(R.id.textview)).perform(click());
695 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900696
697 onHandleView(com.android.internal.R.id.selection_end_handle)
698 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('n')));
699 onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
700
701 onHandleView(com.android.internal.R.id.selection_end_handle)
702 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('o')));
703 onView(withId(R.id.textview)).check(hasSelection("hijk lmn"));
704
705 onHandleView(com.android.internal.R.id.selection_end_handle)
706 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('q')));
707 onView(withId(R.id.textview)).check(hasSelection("hijk lmn opqr"));
708
709 onHandleView(com.android.internal.R.id.selection_end_handle)
710 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
711 onView(withId(R.id.textview)).check(hasSelection("hijk lmn o"));
712
713 onHandleView(com.android.internal.R.id.selection_end_handle)
714 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('r')));
715 onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq"));
716 }
717
Siyamed Sinir21914182017-06-16 15:24:00 -0700718 @Test
719 public void testSelectionHandles_snapToWordBoundary_multiLine() {
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900720 final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu";
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900721 onView(withId(R.id.textview)).perform(replaceText(text));
722 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('m')));
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900723
Siyamed Sinir21914182017-06-16 15:24:00 -0700724 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900725
726 onHandleView(com.android.internal.R.id.selection_start_handle)
727 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
728 onView(withId(R.id.textview)).check(hasSelection("abcd efg\nhijk lmn"));
729
730 onHandleView(com.android.internal.R.id.selection_start_handle)
731 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('g')));
732 onView(withId(R.id.textview)).check(hasSelection("g\nhijk lmn"));
733
734 onHandleView(com.android.internal.R.id.selection_start_handle)
735 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('m')));
736 onView(withId(R.id.textview)).check(hasSelection("lmn"));
737
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900738 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('i')));
Keisuke Kuroyanagiec913c02015-11-24 18:56:20 +0900739
740 onHandleView(com.android.internal.R.id.selection_end_handle)
741 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('u')));
742 onView(withId(R.id.textview)).check(hasSelection("hijk lmn\nopqr stu"));
743
744 onHandleView(com.android.internal.R.id.selection_end_handle)
745 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('p')));
746 onView(withId(R.id.textview)).check(hasSelection("hijk lmn\no"));
747
748 onHandleView(com.android.internal.R.id.selection_end_handle)
749 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i')));
750 onView(withId(R.id.textview)).check(hasSelection("hijk"));
751 }
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900752
Siyamed Sinir21914182017-06-16 15:24:00 -0700753 @Test
Abodunrinwa Tokideb2f492017-11-06 18:55:17 +0000754 public void testSelectionHandles_visibleEvenWithEmptyMenu() {
755 ((TextView) mActivity.findViewById(R.id.textview)).setCustomSelectionActionModeCallback(
756 new ActionMode.Callback() {
757 @Override
758 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
759 menu.clear();
760 return true;
761 }
762
763 @Override
764 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
765 menu.clear();
766 return true;
767 }
768
769 @Override
770 public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
771 return false;
772 }
773
774 @Override
775 public void onDestroyActionMode(ActionMode mode) {}
776 });
777 final String text = "abcd efg hijk lmn";
778 onView(withId(R.id.textview)).perform(replaceText(text));
779
780 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
781
782 onHandleView(com.android.internal.R.id.selection_start_handle)
783 .check(matches(isDisplayed()));
784 onHandleView(com.android.internal.R.id.selection_end_handle)
785 .check(matches(isDisplayed()));
786 }
787
788 @Test
Siyamed Sinir21914182017-06-16 15:24:00 -0700789 public void testSetSelectionAndActionMode() throws Throwable {
Abodunrinwa Toki6264cbd2017-11-06 15:12:52 +0000790 final TextView textView = mActivity.findViewById(R.id.textview);
791 final ActionMode.Callback amCallback = mock(ActionMode.Callback.class);
792 when(amCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class)))
793 .thenReturn(true);
794 when(amCallback.onPrepareActionMode(any(ActionMode.class), any(Menu.class)))
795 .thenReturn(true);
796 textView.setCustomSelectionActionModeCallback(amCallback);
797
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900798 final String text = "abc def";
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900799 onView(withId(R.id.textview)).perform(replaceText(text));
Siyamed Sinir21914182017-06-16 15:24:00 -0700800 mActivityRule.runOnUiThread(
801 () -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
802 mInstrumentation.waitForIdleSync();
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900803 // Don't automatically start action mode.
Abodunrinwa Toki6264cbd2017-11-06 15:12:52 +0000804 verify(amCallback, never()).onCreateActionMode(any(ActionMode.class), any(Menu.class));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900805 // Make sure that "Select All" is included in the selection action mode when the entire text
806 // is not selected.
Keisuke Kuroyanagi99e8623182016-11-16 20:05:14 +0900807 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('e')));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900808 sleepForFloatingToolbarPopup();
809 assertFloatingToolbarIsDisplayed();
810 // Changing the selection range by API should not interrupt the selection action mode.
Siyamed Sinir21914182017-06-16 15:24:00 -0700811 mActivityRule.runOnUiThread(
812 () -> Selection.setSelection((Spannable) textView.getText(), 0, 3));
813 mInstrumentation.waitForIdleSync();
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900814 sleepForFloatingToolbarPopup();
815 assertFloatingToolbarIsDisplayed();
816 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700817 mActivity.getString(com.android.internal.R.string.selectAll));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900818 // Make sure that "Select All" is no longer included when the entire text is selected by
819 // API.
Siyamed Sinir21914182017-06-16 15:24:00 -0700820 mActivityRule.runOnUiThread(
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900821 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
Siyamed Sinir21914182017-06-16 15:24:00 -0700822 mInstrumentation.waitForIdleSync();
823
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900824 sleepForFloatingToolbarPopup();
825 assertFloatingToolbarIsDisplayed();
826 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700827 mActivity.getString(com.android.internal.R.string.selectAll));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900828 // Make sure that shrinking the selection range to cursor (an empty range) by API
829 // terminates selection action mode and does not trigger the insertion action mode.
Siyamed Sinir21914182017-06-16 15:24:00 -0700830 mActivityRule.runOnUiThread(
831 () -> Selection.setSelection((Spannable) textView.getText(), 0));
832 mInstrumentation.waitForIdleSync();
833
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900834 // Make sure that user click can trigger the insertion action mode.
835 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
836 onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
837 sleepForFloatingToolbarPopup();
838 assertFloatingToolbarIsDisplayed();
839 // Make sure that an existing insertion action mode keeps alive after the insertion point is
840 // moved by API.
Siyamed Sinir21914182017-06-16 15:24:00 -0700841 mActivityRule.runOnUiThread(
842 () -> Selection.setSelection((Spannable) textView.getText(), 0));
843 mInstrumentation.waitForIdleSync();
844
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900845 sleepForFloatingToolbarPopup();
846 assertFloatingToolbarIsDisplayed();
847 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700848 mActivity.getString(com.android.internal.R.string.copy));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900849 // Make sure that selection action mode is started after selection is created by API when
850 // insertion action mode is active.
Siyamed Sinir21914182017-06-16 15:24:00 -0700851 mActivityRule.runOnUiThread(
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900852 () -> Selection.setSelection((Spannable) textView.getText(), 1, text.length()));
Siyamed Sinir21914182017-06-16 15:24:00 -0700853 mInstrumentation.waitForIdleSync();
854
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900855 sleepForFloatingToolbarPopup();
856 assertFloatingToolbarIsDisplayed();
857 assertFloatingToolbarContainsItem(
Siyamed Sinir21914182017-06-16 15:24:00 -0700858 mActivity.getString(com.android.internal.R.string.copy));
Keisuke Kuroyanagic477b582016-03-15 15:38:40 +0900859 }
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900860
Siyamed Sinir21914182017-06-16 15:24:00 -0700861 @Test
862 public void testTransientState() throws Throwable {
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900863 final String text = "abc def";
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900864 onView(withId(R.id.textview)).perform(replaceText(text));
865
Siyamed Sinir21914182017-06-16 15:24:00 -0700866 final TextView textView = mActivity.findViewById(R.id.textview);
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900867 assertFalse(textView.hasTransientState());
868
869 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('b')));
870 // hasTransientState should return true when user generated selection is active.
871 assertTrue(textView.hasTransientState());
872 onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('d')));
873 // hasTransientState should return false as the selection has been cleared.
874 assertFalse(textView.hasTransientState());
Siyamed Sinir21914182017-06-16 15:24:00 -0700875 mActivityRule.runOnUiThread(
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900876 () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length()));
Siyamed Sinir21914182017-06-16 15:24:00 -0700877 mInstrumentation.waitForIdleSync();
878
Keisuke Kuroyanagi183fd502016-04-01 15:00:53 +0900879 // hasTransientState should return false when selection is created by API.
880 assertFalse(textView.hasTransientState());
881 }
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +0100882
Siyamed Sinir21914182017-06-16 15:24:00 -0700883 @Test
884 public void testResetMenuItemTitle() throws Throwable {
885 mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
886 final TextView textView = mActivity.findViewById(R.id.textview);
Abodunrinwa Toki7b971802017-05-23 19:01:56 +0100887 final int itemId = 1;
888 final String title1 = " AFIGBO";
889 final int index = title1.indexOf('I');
890 final String title2 = title1.substring(index);
891 final String[] title = new String[]{title1};
Siyamed Sinir21914182017-06-16 15:24:00 -0700892 mActivityRule.runOnUiThread(() -> textView.setCustomSelectionActionModeCallback(
Abodunrinwa Toki7b971802017-05-23 19:01:56 +0100893 new ActionMode.Callback() {
894 @Override
895 public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
896 return true;
897 }
898
899 @Override
900 public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
901 menu.removeItem(itemId);
902 menu.add(Menu.NONE /* group */, itemId, 0 /* order */, title[0]);
903 return true;
904 }
905
906 @Override
907 public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
908 return false;
909 }
910
911 @Override
912 public void onDestroyActionMode(ActionMode actionMode) {
913 }
914 }));
Siyamed Sinir21914182017-06-16 15:24:00 -0700915 mInstrumentation.waitForIdleSync();
916
Abodunrinwa Toki7b971802017-05-23 19:01:56 +0100917 onView(withId(R.id.textview)).perform(replaceText(title1));
918 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(index));
919 sleepForFloatingToolbarPopup();
920 assertFloatingToolbarContainsItem(title1);
921
922 // Change the menu item title.
923 title[0] = title2;
924 // Change the selection to invalidate the action mode without restarting it.
925 onHandleView(com.android.internal.R.id.selection_start_handle)
926 .perform(dragHandle(textView, Handle.SELECTION_START, index));
927 sleepForFloatingToolbarPopup();
928 assertFloatingToolbarContainsItem(title2);
929 }
930
Siyamed Sinir21914182017-06-16 15:24:00 -0700931 @Test
932 public void testAssistItemIsAtIndexZero() throws Throwable {
Abodunrinwa Toki76b51dc2017-07-13 23:37:11 +0100933 useSystemDefaultTextClassifier();
Siyamed Sinir21914182017-06-16 15:24:00 -0700934 final TextView textView = mActivity.findViewById(R.id.textview);
935 mActivityRule.runOnUiThread(() -> textView.setCustomSelectionActionModeCallback(
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +0100936 new ActionMode.Callback() {
937 @Override
938 public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
939 // Create another item at order position 0 to confirm that it will never be
940 // placed before the textAssist item.
941 menu.add(Menu.NONE, 0 /* id */, 0 /* order */, "Test");
942 return true;
943 }
944
945 @Override
946 public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
947 return true;
948 }
949
950 @Override
951 public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
952 return false;
953 }
954
955 @Override
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +0100956 public void onDestroyActionMode(ActionMode actionMode) {
957 }
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +0100958 }));
Siyamed Sinir21914182017-06-16 15:24:00 -0700959 mInstrumentation.waitForIdleSync();
Abodunrinwa Toki6eecdc92017-04-11 05:15:25 +0100960 final String text = "droid@android.com";
961
962 onView(withId(R.id.textview)).perform(replaceText(text));
963 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('@')));
964 sleepForFloatingToolbarPopup();
965 assertFloatingToolbarItemIndex(android.R.id.textAssist, 0);
966 }
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +0100967
Siyamed Sinir21914182017-06-16 15:24:00 -0700968 @Test
Abodunrinwa Toki76b51dc2017-07-13 23:37:11 +0100969 public void testNoAssistItemForPasswordField() throws Throwable {
970 useSystemDefaultTextClassifier();
971 final TextView textView = mActivity.findViewById(R.id.textview);
972 mActivityRule.runOnUiThread(() -> {
973 textView.setInputType(
974 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
975 });
976 mInstrumentation.waitForIdleSync();
977 final String password = "afigbo@android.com";
978
979 onView(withId(R.id.textview)).perform(replaceText(password));
980 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(password.indexOf('@')));
981 sleepForFloatingToolbarPopup();
982 assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist);
983 }
984
985 @Test
Abodunrinwa Tokia69950c2018-11-29 13:51:56 +0000986 public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable {
987 useSystemDefaultTextClassifier();
988 final String text = "\u202Emoc.diordna.com";
989 final TextView textView = mActivity.findViewById(R.id.textview);
990 mActivityRule.runOnUiThread(() -> textView.setText(text));
991 mInstrumentation.waitForIdleSync();
992
993 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.')));
994 sleepForFloatingToolbarPopup();
995 assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist);
996 }
997
998 @Test
Abodunrinwa Tokif299fc02018-05-17 17:36:25 +0100999 public void testSelectionMetricsLogger_noAbandonAfterCopy() throws Throwable {
1000 final List<SelectionEvent> selectionEvents = new ArrayList<>();
1001 final TextClassifier classifier = new TextClassifier() {
1002 @Override
1003 public void onSelectionEvent(SelectionEvent event) {
1004 selectionEvents.add(event);
1005 }
1006 };
1007 final TextView textView = mActivity.findViewById(R.id.textview);
1008 mActivityRule.runOnUiThread(() -> textView.setTextClassifier(classifier));
1009 mInstrumentation.waitForIdleSync();
1010 final String text = "andyroid@android.com";
1011
1012 onView(withId(R.id.textview)).perform(replaceText(text));
1013 onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('@')));
1014 sleepForFloatingToolbarPopup();
1015 clickFloatingToolbarItem(mActivity.getString(com.android.internal.R.string.copy));
1016 mInstrumentation.waitForIdleSync();
1017
1018 final SelectionEvent lastEvent = selectionEvents.get(selectionEvents.size() - 1);
1019 assertEquals(SelectionEvent.ACTION_COPY, lastEvent.getEventType());
1020 }
1021
1022 @Test
Siyamed Sinir21914182017-06-16 15:24:00 -07001023 public void testPastePlainText_menuAction() {
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001024 initializeClipboardWithText(TextStyle.STYLED);
1025
1026 onView(withId(R.id.textview)).perform(replaceText(""));
1027 onView(withId(R.id.textview)).perform(longClick());
1028 sleepForFloatingToolbarPopup();
1029 clickFloatingToolbarItem(
Siyamed Sinir21914182017-06-16 15:24:00 -07001030 mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
1031 mInstrumentation.waitForIdleSync();
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001032
1033 onView(withId(R.id.textview)).check(matches(withText("styledtext")));
1034 onView(withId(R.id.textview)).check(doesNotHaveStyledText());
1035 }
1036
Siyamed Sinir21914182017-06-16 15:24:00 -07001037 @Test
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001038 public void testPastePlainText_noMenuItemForPlainText() {
1039 initializeClipboardWithText(TextStyle.PLAIN);
1040
1041 onView(withId(R.id.textview)).perform(replaceText(""));
1042 onView(withId(R.id.textview)).perform(longClick());
1043 sleepForFloatingToolbarPopup();
1044
1045 assertFloatingToolbarDoesNotContainItem(
Siyamed Sinir21914182017-06-16 15:24:00 -07001046 mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001047 }
1048
Abodunrinwa Toki76b51dc2017-07-13 23:37:11 +01001049 private void useSystemDefaultTextClassifier() {
1050 mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
1051 }
1052
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001053 private void initializeClipboardWithText(TextStyle textStyle) {
1054 final ClipData clip;
1055 switch (textStyle) {
1056 case STYLED:
1057 clip = ClipData.newHtmlText("html", "styledtext", "<b>styledtext</b>");
1058 break;
1059 case PLAIN:
1060 clip = ClipData.newPlainText("plain", "plaintext");
1061 break;
1062 default:
1063 throw new IllegalArgumentException("Invalid text style");
1064 }
Siyamed Sinir21914182017-06-16 15:24:00 -07001065 mActivity.getWindow().getDecorView().post(() ->
1066 mActivity.getSystemService(ClipboardManager.class).setPrimaryClip(clip));
1067 mInstrumentation.waitForIdleSync();
Abodunrinwa Tokiea6cb122017-04-28 22:14:13 +01001068 }
1069
1070 private enum TextStyle {
1071 PLAIN, STYLED
1072 }
Abodunrinwa Toki223c8392015-07-24 20:55:59 -07001073}