Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java

Issue 2766393004: Convert most of the rest of instrumentation tests in content (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser.input; 5 package org.chromium.content.browser.input;
6 6
7 import android.annotation.TargetApi;
8 import android.app.Activity;
9 import android.content.ClipData; 7 import android.content.ClipData;
10 import android.content.ClipboardManager; 8 import android.content.ClipboardManager;
11 import android.content.Context; 9 import android.content.Context;
12 import android.content.res.Configuration; 10 import android.content.res.Configuration;
13 import android.os.Handler;
14 import android.support.test.filters.MediumTest; 11 import android.support.test.filters.MediumTest;
15 import android.support.test.filters.SmallTest; 12 import android.support.test.filters.SmallTest;
16 import android.text.InputType; 13 import android.text.InputType;
17 import android.text.TextUtils;
18 import android.util.Pair;
19 import android.view.KeyEvent; 14 import android.view.KeyEvent;
20 import android.view.View;
21 import android.view.inputmethod.BaseInputConnection; 15 import android.view.inputmethod.BaseInputConnection;
22 import android.view.inputmethod.EditorInfo; 16 import android.view.inputmethod.EditorInfo;
23 import android.view.inputmethod.InputConnection; 17
18 import org.junit.Assert;
19 import org.junit.Before;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
24 23
25 import org.chromium.base.ThreadUtils; 24 import org.chromium.base.ThreadUtils;
26 import org.chromium.base.test.util.DisabledTest; 25 import org.chromium.base.test.util.DisabledTest;
27 import org.chromium.base.test.util.Feature; 26 import org.chromium.base.test.util.Feature;
28 import org.chromium.base.test.util.UrlUtils; 27 import org.chromium.base.test.util.UrlUtils;
29 import org.chromium.content.browser.ContentViewCore; 28 import org.chromium.content.browser.test.ContentJUnit4ClassRunner;
30 import org.chromium.content.browser.SelectionPopupController;
31 import org.chromium.content.browser.test.util.Criteria; 29 import org.chromium.content.browser.test.util.Criteria;
32 import org.chromium.content.browser.test.util.CriteriaHelper; 30 import org.chromium.content.browser.test.util.CriteriaHelper;
33 import org.chromium.content.browser.test.util.DOMUtils; 31 import org.chromium.content.browser.test.util.DOMUtils;
34 import org.chromium.content.browser.test.util.JavaScriptUtils; 32 import org.chromium.content.browser.test.util.JavaScriptUtils;
35 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
36 import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
37 import org.chromium.content_public.browser.WebContents;
38 import org.chromium.content_shell_apk.ContentShellTestBase;
39 import org.chromium.ui.base.ime.TextInputType; 33 import org.chromium.ui.base.ime.TextInputType;
40 34
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.concurrent.Callable; 35 import java.util.concurrent.Callable;
45 import java.util.concurrent.ExecutionException;
46 import java.util.concurrent.TimeoutException;
47 36
48 /** 37 /**
49 * IME (input method editor) and text input tests. 38 * IME (input method editor) and text input tests.
50 */ 39 */
51 public class ImeTest extends ContentShellTestBase { 40 @RunWith(ContentJUnit4ClassRunner.class)
52 protected ChromiumBaseInputConnection mConnection; 41 public class ImeTest {
53 private TestInputConnectionFactory mConnectionFactory; 42 @Rule
54 private ImeAdapter mImeAdapter; 43 public ImeActivityTestRule mRule = new ImeActivityTestRule();
55 44
56 private static final String INPUT_FORM_HTML = 45 @Before
57 "content/test/data/android/input/input_forms.html";
58
59 private ContentViewCore mContentViewCore;
60 private WebContents mWebContents;
61 private SelectionPopupController mSelectionPopupController;
62 private TestCallbackHelperContainer mCallbackContainer;
63 protected TestInputMethodManagerWrapper mInputMethodManagerWrapper;
64
65 @Override
66 public void setUp() throws Exception { 46 public void setUp() throws Exception {
67 super.setUp(); 47 mRule.setUp();
68 startActivityWithTestUrl(INPUT_FORM_HTML); 48 }
69 mContentViewCore = getContentViewCore(); 49
70 mSelectionPopupController = mContentViewCore.getSelectionPopupController ForTesting(); 50 @Test
71 mWebContents = getWebContents();
72
73 mInputMethodManagerWrapper = new TestInputMethodManagerWrapper(mContentV iewCore) {
74 private boolean mExpectsSelectionOutsideComposition;
75
76 @Override
77 public void expectsSelectionOutsideComposition() {
78 mExpectsSelectionOutsideComposition = true;
79 }
80
81 @Override
82 public void onUpdateSelection(
83 Range oldSel, Range oldComp, Range newSel, Range newComp) {
84 // We expect that selection will be outside composition in some cases. Keyboard
85 // app will not finish composition in this case.
86 if (mExpectsSelectionOutsideComposition) {
87 mExpectsSelectionOutsideComposition = false;
88 return;
89 }
90 if (oldComp == null || oldComp.start() == oldComp.end()
91 || newComp.start() == newComp.end()) {
92 return;
93 }
94 // This emulates keyboard app's behavior that finishes compositi on when
95 // selection is outside composition.
96 if (!newSel.intersects(newComp)) {
97 try {
98 finishComposingText();
99 } catch (Exception e) {
100 e.printStackTrace();
101 fail();
102 }
103 }
104 }
105 };
106 getImeAdapter().setInputMethodManagerWrapperForTest(mInputMethodManagerW rapper);
107 assertEquals(0, mInputMethodManagerWrapper.getShowSoftInputCounter());
108 mConnectionFactory =
109 new TestInputConnectionFactory(getImeAdapter().getInputConnectio nFactoryForTest());
110 getImeAdapter().setInputConnectionFactory(mConnectionFactory);
111
112 mCallbackContainer = new TestCallbackHelperContainer(mContentViewCore);
113 DOMUtils.waitForNonZeroNodeBounds(mWebContents, "input_text");
114 boolean result = DOMUtils.clickNode(mContentViewCore, "input_text");
115
116 assertEquals("Failed to dispatch touch event.", true, result);
117 assertWaitForKeyboardStatus(true);
118
119 mConnection = getInputConnection();
120 mImeAdapter = getImeAdapter();
121
122 waitForKeyboardStates(1, 0, 1, new Integer[] {TextInputType.TEXT});
123 assertEquals(0, mConnectionFactory.getOutAttrs().initialSelStart);
124 assertEquals(0, mConnectionFactory.getOutAttrs().initialSelEnd);
125
126 waitForEventLogs("selectionchange");
127 clearEventLogs();
128
129 waitAndVerifyUpdateSelection(0, 0, 0, -1, -1);
130 resetAllStates();
131 }
132
133 private void fullyLoadUrl(final String url) throws Throwable {
134 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
135 @Override
136 public void run() {
137 getActivity().getActiveShell().loadUrl(url);
138 }
139 });
140 waitForActiveShellToBeDoneLoading();
141 }
142
143 @MediumTest 51 @MediumTest
144 @Feature({"TextInput", "Main"}) 52 @Feature({"TextInput", "Main"})
145 public void testKeyboardDismissedWhenNavigating() throws Throwable { 53 public void testKeyboardDismissedWhenNavigating() throws Throwable {
146 assertWaitForKeyboardStatus(true); 54 mRule.assertWaitForKeyboardStatus(true);
147 55
148 // Hide keyboard when loading a new Url. 56 // Hide keyboard when loading a new Url.
149 fullyLoadUrl(UrlUtils.getIsolatedTestFileUrl(INPUT_FORM_HTML)); 57 mRule.fullyLoadUrl(UrlUtils.getIsolatedTestFileUrl(ImeActivityTestRule.I NPUT_FORM_HTML));
150 assertWaitForKeyboardStatus(false); 58 mRule.assertWaitForKeyboardStatus(false);
151 59
152 DOMUtils.clickNode(mContentViewCore, "input_text"); 60 DOMUtils.clickNode(mRule.getContentViewCore(), "input_text");
153 assertWaitForKeyboardStatus(true); 61 mRule.assertWaitForKeyboardStatus(true);
154 62
155 // Hide keyboard when navigating. 63 // Hide keyboard when navigating.
156 final String code = "document.getElementById(\"link\").click()"; 64 final String code = "document.getElementById(\"link\").click()";
157 JavaScriptUtils.executeJavaScriptAndWaitForResult( 65 JavaScriptUtils.executeJavaScriptAndWaitForResult(
158 getContentViewCore().getWebContents(), code); 66 mRule.getContentViewCore().getWebContents(), code);
159 assertWaitForKeyboardStatus(false); 67 mRule.assertWaitForKeyboardStatus(false);
160 } 68 }
161 69
70 @Test
162 @MediumTest 71 @MediumTest
163 @Feature({"TextInput", "Main"}) 72 @Feature({"TextInput", "Main"})
164 public void testKeyboardDismissedAfterClickingGo() throws Throwable { 73 public void testKeyboardDismissedAfterClickingGo() throws Throwable {
165 setComposingText("hello", 1); 74 mRule.setComposingText("hello", 1);
166 waitAndVerifyUpdateSelection(0, 5, 5, 0, 5); 75 mRule.waitAndVerifyUpdateSelection(0, 5, 5, 0, 5);
167 76
168 performGo(mCallbackContainer); 77 mRule.performGo(mRule.getTestCallBackHelperContainer());
169 78
170 assertWaitForKeyboardStatus(false); 79 mRule.assertWaitForKeyboardStatus(false);
171 } 80 }
172 81
82 @Test
173 @MediumTest 83 @MediumTest
174 @Feature({"TextInput", "Main"}) 84 @Feature({"TextInput", "Main"})
175 public void testDoesNotHang_getTextAfterKeyboardHides() throws Throwable { 85 public void testDoesNotHang_getTextAfterKeyboardHides() throws Throwable {
176 setComposingText("hello", 1); 86 mRule.setComposingText("hello", 1);
177 waitAndVerifyUpdateSelection(0, 5, 5, 0, 5); 87 mRule.waitAndVerifyUpdateSelection(0, 5, 5, 0, 5);
178 88
179 performGo(mCallbackContainer); 89 mRule.performGo(mRule.getTestCallBackHelperContainer());
180 90
181 // This may time out if we do not get the information on time. 91 // This may time out if we do not get the information on time.
182 // TODO(changwan): find a way to remove the loop. 92 // TODO(changwan): find a way to remove the loop.
183 for (int i = 0; i < 100; ++i) { 93 for (int i = 0; i < 100; ++i) {
184 getTextBeforeCursor(10, 0); 94 mRule.getTextBeforeCursor(10, 0);
185 } 95 }
186 96
187 assertWaitForKeyboardStatus(false); 97 mRule.assertWaitForKeyboardStatus(false);
188 } 98 }
189 99
190 // crbug.com/643519 100 // crbug.com/643519
101 @Test
191 @SmallTest 102 @SmallTest
192 @Feature({"TextInput", "Main"}) 103 @Feature({"TextInput", "Main"})
193 public void testCompositionWithNullTextNotCrash() throws Throwable { 104 public void testCompositionWithNullTextNotCrash() throws Throwable {
194 commitText(null, 1); 105 mRule.commitText(null, 1);
195 assertTextsAroundCursor("", null, ""); 106 mRule.assertTextsAroundCursor("", null, "");
196 107
197 setComposingText(null, 1); 108 mRule.setComposingText(null, 1);
198 assertTextsAroundCursor("", null, ""); 109 mRule.assertTextsAroundCursor("", null, "");
199 } 110 }
200 111
112 @Test
201 @SmallTest 113 @SmallTest
202 @Feature({"TextInput", "Main"}) 114 @Feature({"TextInput", "Main"})
203 public void testDeleteSurroundingTextWithRangeSelection() throws Throwable { 115 public void testDeleteSurroundingTextWithRangeSelection() throws Throwable {
204 commitText("hello", 1); 116 mRule.commitText("hello", 1);
205 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 117 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
206 118
207 setSelection(1, 4); 119 mRule.setSelection(1, 4);
208 waitAndVerifyUpdateSelection(1, 1, 4, -1, -1); 120 mRule.waitAndVerifyUpdateSelection(1, 1, 4, -1, -1);
209 121
210 deleteSurroundingText(0, 0); 122 mRule.deleteSurroundingText(0, 0);
211 assertTextsAroundCursor("h", "ell", "o"); 123 mRule.assertTextsAroundCursor("h", "ell", "o");
212 124
213 deleteSurroundingText(1, 1); 125 mRule.deleteSurroundingText(1, 1);
214 assertTextsAroundCursor("", "ell", ""); 126 mRule.assertTextsAroundCursor("", "ell", "");
215 127
216 deleteSurroundingText(1, 0); 128 mRule.deleteSurroundingText(1, 0);
217 assertTextsAroundCursor("", "ell", ""); 129 mRule.assertTextsAroundCursor("", "ell", "");
218 130
219 deleteSurroundingText(0, 1); 131 mRule.deleteSurroundingText(0, 1);
220 assertTextsAroundCursor("", "ell", ""); 132 mRule.assertTextsAroundCursor("", "ell", "");
221 } 133 }
222 134
135 @Test
223 @SmallTest 136 @SmallTest
224 @Feature({"TextInput", "Main"}) 137 @Feature({"TextInput", "Main"})
225 public void testDeleteSurroundingTextWithCursorSelection() throws Throwable { 138 public void testDeleteSurroundingTextWithCursorSelection() throws Throwable {
226 commitText("hello", 1); 139 mRule.commitText("hello", 1);
227 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 140 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
228 141
229 setSelection(2, 2); 142 mRule.setSelection(2, 2);
230 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 143 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
231 144
232 deleteSurroundingText(0, 0); 145 mRule.deleteSurroundingText(0, 0);
233 assertTextsAroundCursor("he", null, "llo"); 146 mRule.assertTextsAroundCursor("he", null, "llo");
234 147
235 deleteSurroundingText(1, 1); 148 mRule.deleteSurroundingText(1, 1);
236 assertTextsAroundCursor("h", null, "lo"); 149 mRule.assertTextsAroundCursor("h", null, "lo");
237 150
238 deleteSurroundingText(1, 0); 151 mRule.deleteSurroundingText(1, 0);
239 assertTextsAroundCursor("", null, "lo"); 152 mRule.assertTextsAroundCursor("", null, "lo");
240 153
241 deleteSurroundingText(0, 10); 154 mRule.deleteSurroundingText(0, 10);
242 assertTextsAroundCursor("", null, ""); 155 mRule.assertTextsAroundCursor("", null, "");
243 156
244 deleteSurroundingText(10, 10); 157 mRule.deleteSurroundingText(10, 10);
245 assertTextsAroundCursor("", null, ""); 158 mRule.assertTextsAroundCursor("", null, "");
246 } 159 }
247 160
161 @Test
248 @SmallTest 162 @SmallTest
249 @Feature({"TextInput", "Main"}) 163 @Feature({"TextInput", "Main"})
250 public void testKeyboardAppFinishesCompositionOnUnexpectedSelectionChange() throws Throwable { 164 public void testKeyboardAppFinishesCompositionOnUnexpectedSelectionChange() throws Throwable {
251 focusElementAndWaitForStateUpdate("textarea2"); 165 mRule.focusElementAndWaitForStateUpdate("textarea2");
252 commitText("12345", 1); 166 mRule.commitText("12345", 1);
253 setSelection(3, 3); 167 mRule.setSelection(3, 3);
254 setComposingRegion(2, 3); 168 mRule.setComposingRegion(2, 3);
255 169
256 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 170 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
257 waitAndVerifyUpdateSelection(1, 3, 3, -1, -1); 171 mRule.waitAndVerifyUpdateSelection(1, 3, 3, -1, -1);
258 waitAndVerifyUpdateSelection(2, 3, 3, 2, 3); 172 mRule.waitAndVerifyUpdateSelection(2, 3, 3, 2, 3);
259 173
260 // Unexpected selection change occurs, e.g., the user clicks on an area. 174 // Unexpected selection change occurs, e.g., the user clicks on an area.
261 DOMUtils.clickNode(mContentViewCore, "textarea2"); 175 DOMUtils.clickNode(mRule.getContentViewCore(), "textarea2");
262 waitAndVerifyUpdateSelection(3, 5, 5, 2, 3); 176 mRule.waitAndVerifyUpdateSelection(3, 5, 5, 2, 3);
263 // Keyboard app finishes composition. We emulate this in TestInputMethod ManagerWrapper. 177 // Keyboard app finishes composition. We emulate this in TestInputMethod ManagerWrapper.
264 waitAndVerifyUpdateSelection(4, 5, 5, -1, -1); 178 mRule.waitAndVerifyUpdateSelection(4, 5, 5, -1, -1);
265 } 179 }
266 180
181 @Test
267 @SmallTest 182 @SmallTest
268 @Feature({"TextInput", "Main"}) 183 @Feature({"TextInput", "Main"})
269 public void testDeleteSurroundingTextInCodePointsWithRangeSelection() throws Throwable { 184 public void testDeleteSurroundingTextInCodePointsWithRangeSelection() throws Throwable {
270 final String trophy = "\uD83C\uDFC6"; 185 final String trophy = "\uD83C\uDFC6";
271 commitText("ab" + trophy + "cdef" + trophy + "gh", 1); 186 mRule.commitText("ab" + trophy + "cdef" + trophy + "gh", 1);
272 waitAndVerifyUpdateSelection(0, 12, 12, -1, -1); 187 mRule.waitAndVerifyUpdateSelection(0, 12, 12, -1, -1);
273 188
274 setSelection(6, 8); 189 mRule.setSelection(6, 8);
275 waitAndVerifyUpdateSelection(1, 6, 8, -1, -1); 190 mRule.waitAndVerifyUpdateSelection(1, 6, 8, -1, -1);
276 assertTextsAroundCursor("ab" + trophy + "cd", "ef", trophy + "gh"); 191 mRule.assertTextsAroundCursor("ab" + trophy + "cd", "ef", trophy + "gh") ;
277 192
278 deleteSurroundingTextInCodePoints(2, 2); 193 mRule.deleteSurroundingTextInCodePoints(2, 2);
279 waitAndVerifyUpdateSelection(2, 4, 6, -1, -1); 194 mRule.waitAndVerifyUpdateSelection(2, 4, 6, -1, -1);
280 assertTextsAroundCursor("ab" + trophy, "ef", "h"); 195 mRule.assertTextsAroundCursor("ab" + trophy, "ef", "h");
281 } 196 }
282 197
198 @Test
283 @SmallTest 199 @SmallTest
284 @Feature({"TextInput", "Main"}) 200 @Feature({"TextInput", "Main"})
285 public void testDeleteSurroundingTextInCodePointsWithCursorSelection() throw s Throwable { 201 public void testDeleteSurroundingTextInCodePointsWithCursorSelection() throw s Throwable {
286 final String trophy = "\uD83C\uDFC6"; 202 final String trophy = "\uD83C\uDFC6";
287 commitText("ab" + trophy + "cd" + trophy, 1); 203 mRule.commitText("ab" + trophy + "cd" + trophy, 1);
288 waitAndVerifyUpdateSelection(0, 8, 8, -1, -1); 204 mRule.waitAndVerifyUpdateSelection(0, 8, 8, -1, -1);
289 205
290 setSelection(4, 4); 206 mRule.setSelection(4, 4);
291 waitAndVerifyUpdateSelection(1, 4, 4, -1, -1); 207 mRule.waitAndVerifyUpdateSelection(1, 4, 4, -1, -1);
292 assertTextsAroundCursor("ab" + trophy, null, "cd" + trophy); 208 mRule.assertTextsAroundCursor("ab" + trophy, null, "cd" + trophy);
293 209
294 deleteSurroundingTextInCodePoints(2, 2); 210 mRule.deleteSurroundingTextInCodePoints(2, 2);
295 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 211 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
296 assertTextsAroundCursor("a", null, trophy); 212 mRule.assertTextsAroundCursor("a", null, trophy);
297 } 213 }
298 214
215 @Test
299 @SmallTest 216 @SmallTest
300 @Feature({"TextInput", "Main"}) 217 @Feature({"TextInput", "Main"})
301 public void testSetComposingTextForNewCursorPositions() throws Throwable { 218 public void testSetComposingTextForNewCursorPositions() throws Throwable {
302 // Cursor is on the right of composing text when newCursorPosition > 0. 219 // Cursor is on the right of composing text when newCursorPosition > 0.
303 setComposingText("ab", 1); 220 mRule.setComposingText("ab", 1);
304 waitAndVerifyUpdateSelection(0, 2, 2, 0, 2); 221 mRule.waitAndVerifyUpdateSelection(0, 2, 2, 0, 2);
305 222
306 finishComposingText(); 223 mRule.finishComposingText();
307 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 224 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
308 225
309 // Cursor exceeds the left boundary. 226 // Cursor exceeds the left boundary.
310 setComposingText("cdef", -100); 227 mRule.setComposingText("cdef", -100);
311 waitAndVerifyUpdateSelection(2, 0, 0, 2, 6); 228 mRule.waitAndVerifyUpdateSelection(2, 0, 0, 2, 6);
312 229
313 // Cursor is on the left boundary. 230 // Cursor is on the left boundary.
314 mInputMethodManagerWrapper.expectsSelectionOutsideComposition(); 231 mRule.getInputMethodManagerWrapper().expectsSelectionOutsideComposition( );
315 setComposingText("cd", -2); 232 mRule.setComposingText("cd", -2);
316 waitAndVerifyUpdateSelection(3, 0, 0, 2, 4); 233 mRule.waitAndVerifyUpdateSelection(3, 0, 0, 2, 4);
317 234
318 mInputMethodManagerWrapper.expectsSelectionOutsideComposition(); 235 mRule.getInputMethodManagerWrapper().expectsSelectionOutsideComposition( );
319 // Cursor is between the left boundary and the composing text. 236 // Cursor is between the left boundary and the composing text.
320 setComposingText("cd", -1); 237 mRule.setComposingText("cd", -1);
321 waitAndVerifyUpdateSelection(4, 1, 1, 2, 4); 238 mRule.waitAndVerifyUpdateSelection(4, 1, 1, 2, 4);
322 239
323 // Cursor is on the left of composing text. 240 // Cursor is on the left of composing text.
324 setComposingText("cd", 0); 241 mRule.setComposingText("cd", 0);
325 waitAndVerifyUpdateSelection(5, 2, 2, 2, 4); 242 mRule.waitAndVerifyUpdateSelection(5, 2, 2, 2, 4);
326 243
327 finishComposingText(); 244 mRule.finishComposingText();
328 waitAndVerifyUpdateSelection(6, 2, 2, -1, -1); 245 mRule.waitAndVerifyUpdateSelection(6, 2, 2, -1, -1);
329 246
330 // Cursor is on the right of composing text. 247 // Cursor is on the right of composing text.
331 setComposingText("ef", 1); 248 mRule.setComposingText("ef", 1);
332 waitAndVerifyUpdateSelection(7, 4, 4, 2, 4); 249 mRule.waitAndVerifyUpdateSelection(7, 4, 4, 2, 4);
333 250
334 mInputMethodManagerWrapper.expectsSelectionOutsideComposition(); 251 mRule.getInputMethodManagerWrapper().expectsSelectionOutsideComposition( );
335 // Cursor is between the composing text and the right boundary. 252 // Cursor is between the composing text and the right boundary.
336 setComposingText("ef", 2); 253 mRule.setComposingText("ef", 2);
337 waitAndVerifyUpdateSelection(8, 5, 5, 2, 4); 254 mRule.waitAndVerifyUpdateSelection(8, 5, 5, 2, 4);
338 255
339 mInputMethodManagerWrapper.expectsSelectionOutsideComposition(); 256 mRule.getInputMethodManagerWrapper().expectsSelectionOutsideComposition( );
340 // Cursor is on the right boundary. 257 // Cursor is on the right boundary.
341 setComposingText("ef", 3); 258 mRule.setComposingText("ef", 3);
342 waitAndVerifyUpdateSelection(9, 6, 6, 2, 4); 259 mRule.waitAndVerifyUpdateSelection(9, 6, 6, 2, 4);
343 260
344 mInputMethodManagerWrapper.expectsSelectionOutsideComposition(); 261 mRule.getInputMethodManagerWrapper().expectsSelectionOutsideComposition( );
345 // Cursor exceeds the right boundary. 262 // Cursor exceeds the right boundary.
346 setComposingText("efgh", 100); 263 mRule.setComposingText("efgh", 100);
347 waitAndVerifyUpdateSelection(10, 8, 8, 2, 6); 264 mRule.waitAndVerifyUpdateSelection(10, 8, 8, 2, 6);
348 } 265 }
349 266
267 @Test
350 @SmallTest 268 @SmallTest
351 @Feature({"TextInput", "Main"}) 269 @Feature({"TextInput", "Main"})
352 public void testCommitTextForNewCursorPositions() throws Throwable { 270 public void testCommitTextForNewCursorPositions() throws Throwable {
353 // Cursor is on the left of committing text. 271 // Cursor is on the left of committing text.
354 commitText("ab", 0); 272 mRule.commitText("ab", 0);
355 waitAndVerifyUpdateSelection(0, 0, 0, -1, -1); 273 mRule.waitAndVerifyUpdateSelection(0, 0, 0, -1, -1);
356 274
357 // Cursor is on the right of committing text. 275 // Cursor is on the right of committing text.
358 commitText("cd", 1); 276 mRule.commitText("cd", 1);
359 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 277 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
360 278
361 // Cursor is between the committing text and the right boundary. 279 // Cursor is between the committing text and the right boundary.
362 commitText("ef", 2); 280 mRule.commitText("ef", 2);
363 waitAndVerifyUpdateSelection(2, 5, 5, -1, -1); 281 mRule.waitAndVerifyUpdateSelection(2, 5, 5, -1, -1);
364 282
365 // Cursor is between the left boundary and the committing text. 283 // Cursor is between the left boundary and the committing text.
366 commitText("gh", -3); 284 mRule.commitText("gh", -3);
367 waitAndVerifyUpdateSelection(3, 2, 2, -1, -1); 285 mRule.waitAndVerifyUpdateSelection(3, 2, 2, -1, -1);
368 286
369 // Cursor is on the right boundary. 287 // Cursor is on the right boundary.
370 commitText("ij", 7); 288 mRule.commitText("ij", 7);
371 waitAndVerifyUpdateSelection(4, 10, 10, -1, -1); 289 mRule.waitAndVerifyUpdateSelection(4, 10, 10, -1, -1);
372 290
373 // Cursor is on the left boundary. 291 // Cursor is on the left boundary.
374 commitText("kl", -10); 292 mRule.commitText("kl", -10);
375 waitAndVerifyUpdateSelection(5, 0, 0, -1, -1); 293 mRule.waitAndVerifyUpdateSelection(5, 0, 0, -1, -1);
376 294
377 // Cursor exceeds the right boundary. 295 // Cursor exceeds the right boundary.
378 commitText("mn", 100); 296 mRule.commitText("mn", 100);
379 waitAndVerifyUpdateSelection(6, 14, 14, -1, -1); 297 mRule.waitAndVerifyUpdateSelection(6, 14, 14, -1, -1);
380 298
381 // Cursor exceeds the left boundary. 299 // Cursor exceeds the left boundary.
382 commitText("op", -100); 300 mRule.commitText("op", -100);
383 waitAndVerifyUpdateSelection(7, 0, 0, -1, -1); 301 mRule.waitAndVerifyUpdateSelection(7, 0, 0, -1, -1);
384 } 302 }
385 303
304 @Test
386 @SmallTest 305 @SmallTest
387 @Feature({"TextInput", "Main"}) 306 @Feature({"TextInput", "Main"})
388 public void testSetComposingTextWithEmptyText() throws Throwable { 307 public void testSetComposingTextWithEmptyText() throws Throwable {
389 commitText("hello", 1); 308 mRule.commitText("hello", 1);
390 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 309 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
391 310
392 setComposingText("AB", 1); 311 mRule.setComposingText("AB", 1);
393 waitAndVerifyUpdateSelection(1, 7, 7, 5, 7); 312 mRule.waitAndVerifyUpdateSelection(1, 7, 7, 5, 7);
394 313
395 // With previous composition. 314 // With previous composition.
396 setComposingText("", -3); 315 mRule.setComposingText("", -3);
397 waitAndVerifyUpdateSelection(2, 2, 2, -1, -1); 316 mRule.waitAndVerifyUpdateSelection(2, 2, 2, -1, -1);
398 assertTextsAroundCursor("he", null, "llo"); 317 mRule.assertTextsAroundCursor("he", null, "llo");
399 318
400 // Without previous composition. 319 // Without previous composition.
401 setComposingText("", 3); 320 mRule.setComposingText("", 3);
402 waitAndVerifyUpdateSelection(3, 4, 4, -1, -1); 321 mRule.waitAndVerifyUpdateSelection(3, 4, 4, -1, -1);
403 assertTextsAroundCursor("hell", null, "o"); 322 mRule.assertTextsAroundCursor("hell", null, "o");
404 } 323 }
405 324
325 @Test
406 @SmallTest 326 @SmallTest
407 @Feature({"TextInput", "Main"}) 327 @Feature({"TextInput", "Main"})
408 public void testCommitTextWithEmptyText() throws Throwable { 328 public void testCommitTextWithEmptyText() throws Throwable {
409 commitText("hello", 1); 329 mRule.commitText("hello", 1);
410 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 330 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
411 setSelection(2, 2); 331 mRule.setSelection(2, 2);
412 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 332 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
413 333
414 setComposingText("world", 1); 334 mRule.setComposingText("world", 1);
415 waitAndVerifyUpdateSelection(2, 7, 7, 2, 7); 335 mRule.waitAndVerifyUpdateSelection(2, 7, 7, 2, 7);
416 // With previous composition. 336 // With previous composition.
417 commitText("", 2); 337 mRule.commitText("", 2);
418 waitAndVerifyUpdateSelection(3, 3, 3, -1, -1); 338 mRule.waitAndVerifyUpdateSelection(3, 3, 3, -1, -1);
419 339
420 // Without previous composition. 340 // Without previous composition.
421 commitText("", -1); 341 mRule.commitText("", -1);
422 waitAndVerifyUpdateSelection(4, 2, 2, -1, -1); 342 mRule.waitAndVerifyUpdateSelection(4, 2, 2, -1, -1);
423 } 343 }
424 344
345 @Test
425 @SmallTest 346 @SmallTest
426 @Feature({"TextInput", "Main"}) 347 @Feature({"TextInput", "Main"})
427 public void testCommitWhileComposingText() throws Throwable { 348 public void testCommitWhileComposingText() throws Throwable {
428 setComposingText("h", 1); 349 mRule.setComposingText("h", 1);
429 waitAndVerifyUpdateSelection(0, 1, 1, 0, 1); 350 mRule.waitAndVerifyUpdateSelection(0, 1, 1, 0, 1);
430 351
431 setComposingText("he", 1); 352 mRule.setComposingText("he", 1);
432 waitAndVerifyUpdateSelection(1, 2, 2, 0, 2); 353 mRule.waitAndVerifyUpdateSelection(1, 2, 2, 0, 2);
433 354
434 setComposingText("hel", 1); 355 mRule.setComposingText("hel", 1);
435 waitAndVerifyUpdateSelection(2, 3, 3, 0, 3); 356 mRule.waitAndVerifyUpdateSelection(2, 3, 3, 0, 3);
436 357
437 commitText("hel", 1); 358 mRule.commitText("hel", 1);
438 waitAndVerifyUpdateSelection(3, 3, 3, -1, -1); 359 mRule.waitAndVerifyUpdateSelection(3, 3, 3, -1, -1);
439 360
440 setComposingText("lo", 1); 361 mRule.setComposingText("lo", 1);
441 waitAndVerifyUpdateSelection(4, 5, 5, 3, 5); 362 mRule.waitAndVerifyUpdateSelection(4, 5, 5, 3, 5);
442 363
443 commitText("", 1); 364 mRule.commitText("", 1);
444 waitAndVerifyUpdateSelection(5, 3, 3, -1, -1); 365 mRule.waitAndVerifyUpdateSelection(5, 3, 3, -1, -1);
445 366
446 assertTextsAroundCursor("hel", null, ""); 367 mRule.assertTextsAroundCursor("hel", null, "");
447 } 368 }
448 369
370 @Test
449 @SmallTest 371 @SmallTest
450 @Feature({"TextInput", "Main"}) 372 @Feature({"TextInput", "Main"})
451 public void testCommitEnterKeyWhileComposingText() throws Throwable { 373 public void testCommitEnterKeyWhileComposingText() throws Throwable {
452 focusElementAndWaitForStateUpdate("textarea"); 374 mRule.focusElementAndWaitForStateUpdate("textarea");
453 375
454 setComposingText("hello", 1); 376 mRule.setComposingText("hello", 1);
455 waitAndVerifyUpdateSelection(0, 5, 5, 0, 5); 377 mRule.waitAndVerifyUpdateSelection(0, 5, 5, 0, 5);
456 378
457 // Cancel the current composition and replace it with enter. 379 // Cancel the current composition and replace it with enter.
458 commitText("\n", 1); 380 mRule.commitText("\n", 1);
459 waitAndVerifyUpdateSelection(1, 1, 1, -1, -1); 381 mRule.waitAndVerifyUpdateSelection(1, 1, 1, -1, -1);
460 // The second new line is not a user visible/editable one, it is a side- effect of Blink 382 // The second new line is not a user visible/editable one, it is a side- effect of Blink
461 // using <br> internally. This only happens when \n is at the end. 383 // using <br> internally. This only happens when \n is at the end.
462 assertTextsAroundCursor("\n", null, "\n"); 384 mRule.assertTextsAroundCursor("\n", null, "\n");
463 385
464 commitText("world", 1); 386 mRule.commitText("world", 1);
465 waitAndVerifyUpdateSelection(2, 6, 6, -1, -1); 387 mRule.waitAndVerifyUpdateSelection(2, 6, 6, -1, -1);
466 assertTextsAroundCursor("\nworld", null, ""); 388 mRule.assertTextsAroundCursor("\nworld", null, "");
467 } 389 }
468 390
391 @Test
469 @SmallTest 392 @SmallTest
470 @Feature({"TextInput"}) 393 @Feature({"TextInput"})
471 public void testImeCopy() throws Exception { 394 public void testImeCopy() throws Exception {
472 commitText("hello", 1); 395 mRule.commitText("hello", 1);
473 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 396 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
474 397
475 setSelection(2, 5); 398 mRule.setSelection(2, 5);
476 waitAndVerifyUpdateSelection(1, 2, 5, -1, -1); 399 mRule.waitAndVerifyUpdateSelection(1, 2, 5, -1, -1);
477 400
478 copy(); 401 mRule.copy();
479 assertClipboardContents(getActivity(), "llo"); 402 mRule.assertClipboardContents(mRule.getActivity(), "llo");
480 } 403 }
481 404
405 @Test
482 @SmallTest 406 @SmallTest
483 @Feature({"TextInput"}) 407 @Feature({"TextInput"})
484 public void testEnterTextAndRefocus() throws Exception { 408 public void testEnterTextAndRefocus() throws Exception {
485 commitText("hello", 1); 409 mRule.commitText("hello", 1);
486 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 410 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
487 restartInput(); 411 mRule.restartInput();
488 DOMUtils.clickNode(mContentViewCore, "input_text"); 412 DOMUtils.clickNode(mRule.getContentViewCore(), "input_text");
489 assertWaitForKeyboardStatus(true); 413 mRule.assertWaitForKeyboardStatus(true);
490 414
491 assertEquals(5, mConnectionFactory.getOutAttrs().initialSelStart); 415 Assert.assertEquals(5, mRule.getConnectionFactory().getOutAttrs().initia lSelStart);
492 assertEquals(5, mConnectionFactory.getOutAttrs().initialSelEnd); 416 Assert.assertEquals(5, mRule.getConnectionFactory().getOutAttrs().initia lSelEnd);
493 } 417 }
494 418
419 @Test
495 @SmallTest 420 @SmallTest
496 @DisabledTest(message = "crbug.com/694812") 421 @DisabledTest(message = "crbug.com/694812")
497 @Feature({"TextInput"}) 422 @Feature({"TextInput"})
498 public void testShowAndHideSoftInput() throws Exception { 423 public void testShowAndHideSoftInput() throws Exception {
499 focusElement("input_radio", false); 424 mRule.focusElement("input_radio", false);
500 425
501 // hideSoftKeyboard(), restartInput() 426 // hideSoftKeyboard(), mRule.restartInput()
502 waitForKeyboardStates(0, 1, 1, new Integer[] {}); 427 mRule.waitForKeyboardStates(0, 1, 1, new Integer[] {});
503 428
504 // When input connection is null, we still need to set flags to prevent InputMethodService 429 // When input connection is null, we still need to set flags to prevent InputMethodService
505 // from entering fullscreen mode and from opening custom UI. 430 // from entering fullscreen mode and from opening custom UI.
506 CriteriaHelper.pollUiThread(new Criteria() { 431 CriteriaHelper.pollUiThread(new Criteria() {
507 @Override 432 @Override
508 public boolean isSatisfied() { 433 public boolean isSatisfied() {
509 return getInputConnection() == null; 434 return mRule.getInputConnection() == null;
510 } 435 }
511 }); 436 });
512 assertTrue( 437 Assert.assertTrue(
513 (mConnectionFactory.getOutAttrs().imeOptions 438 (mRule.getConnectionFactory().getOutAttrs().imeOptions
514 & (EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_FL AG_NO_EXTRACT_UI)) 439 & (EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_FL AG_NO_EXTRACT_UI))
515 != 0); 440 != 0);
516 441
517 // showSoftInput(), restartInput() 442 // showSoftInput(), mRule.restartInput()
518 focusElement("input_number1"); 443 mRule.focusElement("input_number1");
519 waitForKeyboardStates(1, 1, 2, new Integer[] {TextInputType.NUMBER}); 444 mRule.waitForKeyboardStates(1, 1, 2, new Integer[] {TextInputType.NUMBER });
520 assertNotNull(mInputMethodManagerWrapper.getInputConnection()); 445 Assert.assertNotNull(mRule.getInputMethodManagerWrapper().getInputConnec tion());
521 446
522 focusElement("input_number2"); 447 mRule.focusElement("input_number2");
523 // Hide should never be called here. Otherwise we will see a flicker. Re started to 448 // Hide should never be called here. Otherwise we will see a flicker. Re started to
524 // reset internal states to handle the new input form. 449 // reset internal states to handle the new input form.
525 waitForKeyboardStates(2, 1, 3, new Integer[] {TextInputType.NUMBER, Text InputType.NUMBER}); 450 mRule.waitForKeyboardStates(
526 451 2, 1, 3, new Integer[] {TextInputType.NUMBER, TextInputType.NUMB ER});
527 focusElement("input_text"); 452
528 // showSoftInput() on input_text. restartInput() on input_number1 due to focus change, 453 mRule.focusElement("input_text");
529 // and restartInput() on input_text later. 454 // showSoftInput() on input_text. mRule.restartInput() on input_number1 due to focus change,
530 waitForKeyboardStates(3, 1, 4, 455 // and mRule.restartInput() on input_text later.
456 mRule.waitForKeyboardStates(3, 1, 4,
531 new Integer[] {TextInputType.NUMBER, TextInputType.NUMBER, TextI nputType.TEXT}); 457 new Integer[] {TextInputType.NUMBER, TextInputType.NUMBER, TextI nputType.TEXT});
532 458
533 resetUpdateSelectionList(); 459 mRule.resetUpdateSelectionList();
534 setComposingText("a", 1); 460 mRule.setComposingText("a", 1);
535 waitAndVerifyUpdateSelection(0, 1, 1, 0, 1); 461 mRule.waitAndVerifyUpdateSelection(0, 1, 1, 0, 1);
536 resetUpdateSelectionList(); 462 mRule.resetUpdateSelectionList();
537 463
538 // JavaScript changes focus. 464 // JavaScript changes focus.
539 String code = "(function() { " 465 String code = "(function() { "
540 + "var textarea = document.getElementById('textarea');" 466 + "var textarea = document.getElementById('textarea');"
541 + "textarea.focus();" 467 + "textarea.focus();"
542 + "})();"; 468 + "})();";
543 JavaScriptUtils.executeJavaScriptAndWaitForResult( 469 JavaScriptUtils.executeJavaScriptAndWaitForResult(
544 getContentViewCore().getWebContents(), code); 470 mRule.getContentViewCore().getWebContents(), code);
545 waitAndVerifyUpdateSelection(0, 0, 0, -1, -1); 471 mRule.waitAndVerifyUpdateSelection(0, 0, 0, -1, -1);
546 resetUpdateSelectionList(); 472 mRule.resetUpdateSelectionList();
547 473
548 waitForKeyboardStates(4, 1, 5, new Integer[] { 474 mRule.waitForKeyboardStates(4, 1, 5,
549 TextInputType.NUMBER, TextInputType.NUMBER, TextInputType.TEXT, 475 new Integer[] {TextInputType.NUMBER, TextInputType.NUMBER, TextI nputType.TEXT,
550 TextInputType.TEXT_AREA}); 476 TextInputType.TEXT_AREA});
551 assertEquals(0, mConnectionFactory.getOutAttrs().initialSelStart); 477 Assert.assertEquals(0, mRule.getConnectionFactory().getOutAttrs().initia lSelStart);
552 assertEquals(0, mConnectionFactory.getOutAttrs().initialSelEnd); 478 Assert.assertEquals(0, mRule.getConnectionFactory().getOutAttrs().initia lSelEnd);
553 479
554 setComposingText("aa", 1); 480 mRule.setComposingText("aa", 1);
555 waitAndVerifyUpdateSelection(0, 2, 2, 0, 2); 481 mRule.waitAndVerifyUpdateSelection(0, 2, 2, 0, 2);
556 482
557 focusElement("input_text"); 483 mRule.focusElement("input_text");
558 waitForKeyboardStates(5, 1, 6, new Integer[] { 484 mRule.waitForKeyboardStates(5, 1, 6,
559 TextInputType.NUMBER, TextInputType.NUMBER, TextInputType.TEXT, 485 new Integer[] {TextInputType.NUMBER, TextInputType.NUMBER, TextI nputType.TEXT,
560 TextInputType.TEXT_AREA, TextInputType.TEXT}); 486 TextInputType.TEXT_AREA, TextInputType.TEXT});
561 assertEquals(1, mConnectionFactory.getOutAttrs().initialSelStart); 487 Assert.assertEquals(1, mRule.getConnectionFactory().getOutAttrs().initia lSelStart);
562 assertEquals(1, mConnectionFactory.getOutAttrs().initialSelEnd); 488 Assert.assertEquals(1, mRule.getConnectionFactory().getOutAttrs().initia lSelEnd);
563 489
564 focusElement("input_radio", false); 490 mRule.focusElement("input_radio", false);
565 // hideSoftInput(), restartInput() 491 // hideSoftInput(), mRule.restartInput()
566 waitForKeyboardStates(5, 2, 7, new Integer[] { 492 mRule.waitForKeyboardStates(5, 2, 7,
567 TextInputType.NUMBER, TextInputType.NUMBER, TextInputType.TEXT, 493 new Integer[] {TextInputType.NUMBER, TextInputType.NUMBER, TextI nputType.TEXT,
568 TextInputType.TEXT_AREA, TextInputType.TEXT}); 494 TextInputType.TEXT_AREA, TextInputType.TEXT});
569 } 495 }
570 496 @Test
571 private void assertTextsAroundCursor(
572 CharSequence before, CharSequence selected, CharSequence after) thro ws Exception {
573 assertEquals(before, getTextBeforeCursor(100, 0));
574 assertEquals(selected, getSelectedText(0));
575 assertEquals(after, getTextAfterCursor(100, 0));
576 }
577
578 private void waitForKeyboardStates(int show, int hide, int restart, Integer[ ] history) {
579 final String expected = stringifyKeyboardStates(show, hide, restart, his tory);
580 CriteriaHelper.pollUiThread(Criteria.equals(expected, new Callable<Strin g>() {
581 @Override
582 public String call() {
583 return getKeyboardStates();
584 }
585 }));
586 }
587
588 private void resetAllStates() {
589 mInputMethodManagerWrapper.reset();
590 mConnectionFactory.clearTextInputTypeHistory();
591 }
592
593 private String getKeyboardStates() {
594 int showCount = mInputMethodManagerWrapper.getShowSoftInputCounter();
595 int hideCount = mInputMethodManagerWrapper.getHideSoftInputCounter();
596 int restartCount = mInputMethodManagerWrapper.getRestartInputCounter();
597 Integer[] history = mConnectionFactory.getTextInputTypeHistory();
598 return stringifyKeyboardStates(showCount, hideCount, restartCount, histo ry);
599 }
600
601 private String stringifyKeyboardStates(int show, int hide, int restart, Inte ger[] history) {
602 return "show count: " + show + ", hide count: " + hide + ", restart coun t: " + restart
603 + ", input type history: " + Arrays.deepToString(history);
604 }
605
606 @SmallTest 497 @SmallTest
607 @Feature({"TextInput"}) 498 @Feature({"TextInput"})
608 public void testKeyboardNotDismissedAfterCopySelection() throws Exception { 499 public void testKeyboardNotDismissedAfterCopySelection() throws Exception {
609 commitText("Sample Text", 1); 500 mRule.commitText("Sample Text", 1);
610 waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); 501 mRule.waitAndVerifyUpdateSelection(0, 11, 11, -1, -1);
611 502
612 // Select 'text' part. 503 // Select 'text' part.
613 DOMUtils.longPressNode(mContentViewCore, "input_text"); 504 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
614 505
615 assertWaitForSelectActionBarStatus(true); 506 mRule.assertWaitForSelectActionBarStatus(true);
616 507
617 selectAll(); 508 mRule.selectAll();
618 copy(); 509 mRule.copy();
619 assertClipboardContents(getActivity(), "Sample Text"); 510 mRule.assertClipboardContents(mRule.getActivity(), "Sample Text");
620 assertEquals(11, mInputMethodManagerWrapper.getSelection().end()); 511 Assert.assertEquals(11, mRule.getInputMethodManagerWrapper().getSelectio n().end());
621 assertWaitForKeyboardStatus(true); 512 mRule.assertWaitForKeyboardStatus(true);
622 } 513 }
623 514
515 @Test
624 @SmallTest 516 @SmallTest
625 @Feature({"TextInput"}) 517 @Feature({"TextInput"})
626 public void testImeNotDismissedAfterCutSelection() throws Exception { 518 public void testImeNotDismissedAfterCutSelection() throws Exception {
627 commitText("Sample Text", 1); 519 mRule.commitText("Sample Text", 1);
628 waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); 520 mRule.waitAndVerifyUpdateSelection(0, 11, 11, -1, -1);
629 DOMUtils.longPressNode(mContentViewCore, "input_text"); 521 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
630 assertWaitForSelectActionBarStatus(true); 522 mRule.assertWaitForSelectActionBarStatus(true);
631 assertWaitForKeyboardStatus(true); 523 mRule.assertWaitForKeyboardStatus(true);
632 cut(); 524 mRule.cut();
633 assertWaitForKeyboardStatus(true); 525 mRule.assertWaitForKeyboardStatus(true);
634 assertWaitForSelectActionBarStatus(false); 526 mRule.assertWaitForSelectActionBarStatus(false);
635 } 527 }
636 528
529 @Test
637 @SmallTest 530 @SmallTest
638 @Feature({"TextInput"}) 531 @Feature({"TextInput"})
639 public void testImeNotShownOnLongPressingEmptyInput() throws Exception { 532 public void testImeNotShownOnLongPressingEmptyInput() throws Exception {
640 DOMUtils.focusNode(mWebContents, "input_radio"); 533 DOMUtils.focusNode(mRule.getWebContents(), "input_radio");
641 DOMUtils.longPressNode(mContentViewCore, "input_text"); 534 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
642 assertWaitForKeyboardStatus(false); 535 mRule.assertWaitForKeyboardStatus(false);
643 commitText("Sample Text", 1); 536 mRule.commitText("Sample Text", 1);
644 DOMUtils.longPressNode(mContentViewCore, "input_text"); 537 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
645 assertWaitForKeyboardStatus(true); 538 mRule.assertWaitForKeyboardStatus(true);
646 } 539 }
647 540
541 @Test
648 @SmallTest 542 @SmallTest
649 @Feature({"TextInput"}) 543 @Feature({"TextInput"})
650 public void testSelectActionBarShownOnLongPressingInput() throws Exception { 544 public void testSelectActionBarShownOnLongPressingInput() throws Exception {
651 DOMUtils.longPressNode(mContentViewCore, "input_text"); 545 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
652 assertWaitForSelectActionBarStatus(false); 546 mRule.assertWaitForSelectActionBarStatus(false);
653 commitText("Sample Text", 1); 547 mRule.commitText("Sample Text", 1);
654 DOMUtils.longPressNode(mContentViewCore, "input_text"); 548 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
655 assertWaitForSelectActionBarStatus(true); 549 mRule.assertWaitForSelectActionBarStatus(true);
656 } 550 }
657 551
552 @Test
658 @SmallTest 553 @SmallTest
659 @Feature({"TextInput"}) 554 @Feature({"TextInput"})
660 public void testLongPressInputWhileComposingText() throws Exception { 555 public void testLongPressInputWhileComposingText() throws Exception {
661 assertWaitForSelectActionBarStatus(false); 556 mRule.assertWaitForSelectActionBarStatus(false);
662 setComposingText("Sample Text", 1); 557 mRule.setComposingText("Sample Text", 1);
663 waitAndVerifyUpdateSelection(0, 11, 11, 0, 11); 558 mRule.waitAndVerifyUpdateSelection(0, 11, 11, 0, 11);
664 DOMUtils.longPressNode(mContentViewCore, "input_text"); 559 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
665 560
666 assertWaitForSelectActionBarStatus(true); 561 mRule.assertWaitForSelectActionBarStatus(true);
667 562
668 // Long press will first change selection region, and then trigger IME a pp to show up. 563 // Long press will first change selection region, and then trigger IME a pp to show up.
669 // See RenderFrameImpl::didChangeSelection() and RenderWidget::didHandle GestureEvent(). 564 // See RenderFrameImpl::didChangeSelection() and RenderWidget::didHandle GestureEvent().
670 waitAndVerifyUpdateSelection(1, 7, 11, 0, 11); 565 mRule.waitAndVerifyUpdateSelection(1, 7, 11, 0, 11);
671 566
672 // Now IME app wants to finish composing text because an external select ion 567 // Now IME app wants to finish composing text because an external select ion
673 // change has been detected. At least Google Latin IME and Samsung IME 568 // change has been detected. At least Google Latin IME and Samsung IME
674 // behave this way. 569 // behave this way.
675 finishComposingText(); 570 mRule.finishComposingText();
676 waitAndVerifyUpdateSelection(2, 7, 11, -1, -1); 571 mRule.waitAndVerifyUpdateSelection(2, 7, 11, -1, -1);
677 } 572 }
678 573
574 @Test
679 @SmallTest 575 @SmallTest
680 @Feature({"TextInput"}) 576 @Feature({"TextInput"})
681 public void testImeShownWhenLongPressOnAlreadySelectedText() throws Exceptio n { 577 public void testImeShownWhenLongPressOnAlreadySelectedText() throws Exceptio n {
682 assertWaitForSelectActionBarStatus(false); 578 mRule.assertWaitForSelectActionBarStatus(false);
683 commitText("Sample Text", 1); 579 mRule.commitText("Sample Text", 1);
684 580
685 int showCount = mInputMethodManagerWrapper.getShowSoftInputCounter(); 581 int showCount = mRule.getInputMethodManagerWrapper().getShowSoftInputCou nter();
686 DOMUtils.longPressNode(mContentViewCore, "input_text"); 582 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
687 assertWaitForSelectActionBarStatus(true); 583 mRule.assertWaitForSelectActionBarStatus(true);
688 assertEquals(showCount + 1, mInputMethodManagerWrapper.getShowSoftInputC ounter()); 584 Assert.assertEquals(
585 showCount + 1, mRule.getInputMethodManagerWrapper().getShowSoftI nputCounter());
689 586
690 // Now long press again. Selection region remains the same, but the logi c 587 // Now long press again. Selection region remains the same, but the logi c
691 // should trigger IME to show up. Note that Android does not provide sho w / 588 // should trigger IME to show up. Note that Android does not provide sho w /
692 // hide status of IME, so we will just check whether showIme() has been triggered. 589 // hide status of IME, so we will just check whether showIme() has been triggered.
693 DOMUtils.longPressNode(mContentViewCore, "input_text"); 590 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
694 final int newCount = showCount + 2; 591 final int newCount = showCount + 2;
695 CriteriaHelper.pollUiThread(Criteria.equals(newCount, new Callable<Integ er>() { 592 CriteriaHelper.pollUiThread(Criteria.equals(newCount, new Callable<Integ er>() {
696 @Override 593 @Override
697 public Integer call() { 594 public Integer call() {
698 return mInputMethodManagerWrapper.getShowSoftInputCounter(); 595 return mRule.getInputMethodManagerWrapper().getShowSoftInputCoun ter();
699 } 596 }
700 })); 597 }));
701 } 598 }
702 599
703 private void attachPhysicalKeyboard() { 600 private void attachPhysicalKeyboard() {
704 Configuration hardKeyboardConfig = 601 Configuration hardKeyboardConfig = new Configuration(
705 new Configuration(mContentViewCore.getContext().getResources().g etConfiguration()); 602 mRule.getContentViewCore().getContext().getResources().getConfig uration());
706 hardKeyboardConfig.keyboard = Configuration.KEYBOARD_QWERTY; 603 hardKeyboardConfig.keyboard = Configuration.KEYBOARD_QWERTY;
707 hardKeyboardConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES; 604 hardKeyboardConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
708 hardKeyboardConfig.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN _NO; 605 hardKeyboardConfig.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN _NO;
709 onConfigurationChanged(hardKeyboardConfig); 606 onConfigurationChanged(hardKeyboardConfig);
710 } 607 }
711 608
712 private void detachPhysicalKeyboard() { 609 private void detachPhysicalKeyboard() {
713 Configuration softKeyboardConfig = 610 Configuration softKeyboardConfig = new Configuration(
714 new Configuration(mContentViewCore.getContext().getResources().g etConfiguration()); 611 mRule.getContentViewCore().getContext().getResources().getConfig uration());
715 softKeyboardConfig.keyboard = Configuration.KEYBOARD_NOKEYS; 612 softKeyboardConfig.keyboard = Configuration.KEYBOARD_NOKEYS;
716 softKeyboardConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; 613 softKeyboardConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
717 softKeyboardConfig.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN _YES; 614 softKeyboardConfig.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN _YES;
718 onConfigurationChanged(softKeyboardConfig); 615 onConfigurationChanged(softKeyboardConfig);
719 } 616 }
720 617
721 private void onConfigurationChanged(final Configuration config) { 618 private void onConfigurationChanged(final Configuration config) {
722 ThreadUtils.runOnUiThreadBlocking(new Runnable() { 619 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
723 @Override 620 @Override
724 public void run() { 621 public void run() {
725 mContentViewCore.onConfigurationChanged(config); 622 mRule.getContentViewCore().onConfigurationChanged(config);
726 } 623 }
727 }); 624 });
728 } 625 }
729 626
730 private void reloadPage() throws Throwable { 627 private void reloadPage() throws Throwable {
731 // Reload the page, then focus will be lost and keyboard should be hidde n. 628 // Reload the page, then focus will be lost and keyboard should be hidde n.
732 fullyLoadUrl(getContentViewCore().getWebContents().getUrl()); 629 mRule.fullyLoadUrl(mRule.getContentViewCore().getWebContents().getUrl()) ;
733 } 630 }
734 631
632 @Test
735 @SmallTest 633 @SmallTest
736 @Feature({"TextInput"}) 634 @Feature({"TextInput"})
737 public void testPhysicalKeyboard_AttachDetach() throws Throwable { 635 public void testPhysicalKeyboard_AttachDetach() throws Throwable {
738 attachPhysicalKeyboard(); 636 attachPhysicalKeyboard();
739 // We still call showSoftKeyboard, which will be ignored by physical key board. 637 // We still call showSoftKeyboard, which will be ignored by physical key board.
740 waitForKeyboardStates(1, 0, 1, new Integer[] {TextInputType.TEXT}); 638 mRule.waitForKeyboardStates(1, 0, 1, new Integer[] {TextInputType.TEXT}) ;
741 setComposingText("a", 1); 639 mRule.setComposingText("a", 1);
742 waitForKeyboardStates(1, 0, 1, new Integer[] {TextInputType.TEXT}); 640 mRule.waitForKeyboardStates(1, 0, 1, new Integer[] {TextInputType.TEXT}) ;
743 detachPhysicalKeyboard(); 641 detachPhysicalKeyboard();
744 assertWaitForKeyboardStatus(true); 642 mRule.assertWaitForKeyboardStatus(true);
745 // Now we really show soft keyboard. We also call restartInput when conf iguration changes. 643 // Now we really show soft keyboard. We also call mRule.restartInput whe n configuration
746 waitForKeyboardStates(2, 0, 2, new Integer[] {TextInputType.TEXT, TextIn putType.TEXT}); 644 // changes.
645 mRule.waitForKeyboardStates(
646 2, 0, 2, new Integer[] {TextInputType.TEXT, TextInputType.TEXT}) ;
747 647
748 reloadPage(); 648 reloadPage();
749 649
750 // Depending on the timing, hideSoftInput and restartInput call counts m ay vary here 650 // Depending on the timing, hideSoftInput and mRule.restartInput call co unts may vary here
751 // because render widget gets restarted. But the end result should be th e same. 651 // because render widget gets restarted. But the end result should be th e same.
752 assertWaitForKeyboardStatus(false); 652 mRule.assertWaitForKeyboardStatus(false);
753 653
754 detachPhysicalKeyboard(); 654 detachPhysicalKeyboard();
755 655
756 try { 656 try {
757 // We should not show soft keyboard here because focus has been lost . 657 // We should not show soft keyboard here because focus has been lost .
758 CriteriaHelper.pollUiThread(new Criteria() { 658 CriteriaHelper.pollUiThread(new Criteria() {
759 @Override 659 @Override
760 public boolean isSatisfied() { 660 public boolean isSatisfied() {
761 return mInputMethodManagerWrapper.isShowWithoutHideOutstandi ng(); 661 return mRule.getInputMethodManagerWrapper().isShowWithoutHid eOutstanding();
762 } 662 }
763 }); 663 });
764 fail("Keyboard incorrectly showing"); 664 Assert.fail("Keyboard incorrectly showing");
765 } catch (AssertionError e) { 665 } catch (AssertionError e) {
766 // TODO(tedchoc): This is horrible and should never timeout to deter mine success. 666 // TODO(tedchoc): This is horrible and should never timeout to deter mine success.
767 } 667 }
768 } 668 }
769 669
670 @Test
770 @SmallTest 671 @SmallTest
771 @Feature({"TextInput"}) 672 @Feature({"TextInput"})
772 public void testSelectActionBarClearedOnTappingInput() throws Exception { 673 public void testSelectActionBarClearedOnTappingInput() throws Exception {
773 commitText("Sample Text", 1); 674 mRule.commitText("Sample Text", 1);
774 DOMUtils.longPressNode(mContentViewCore, "input_text"); 675 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
775 assertWaitForKeyboardStatus(true); 676 mRule.assertWaitForKeyboardStatus(true);
776 assertWaitForSelectActionBarStatus(true); 677 mRule.assertWaitForSelectActionBarStatus(true);
777 DOMUtils.clickNode(mContentViewCore, "input_text"); 678 DOMUtils.clickNode(mRule.getContentViewCore(), "input_text");
778 assertWaitForSelectActionBarStatus(false); 679 mRule.assertWaitForSelectActionBarStatus(false);
779 } 680 }
780 681
682 @Test
781 @SmallTest 683 @SmallTest
782 @Feature({"TextInput"}) 684 @Feature({"TextInput"})
783 public void testSelectActionBarClearedOnTappingOutsideInput() throws Excepti on { 685 public void testSelectActionBarClearedOnTappingOutsideInput() throws Excepti on {
784 commitText("Sample Text", 1); 686 mRule.commitText("Sample Text", 1);
785 DOMUtils.longPressNode(mContentViewCore, "input_text"); 687 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
786 assertWaitForKeyboardStatus(true); 688 mRule.assertWaitForKeyboardStatus(true);
787 assertWaitForSelectActionBarStatus(true); 689 mRule.assertWaitForSelectActionBarStatus(true);
788 DOMUtils.clickNode(mContentViewCore, "plain_text"); 690 DOMUtils.clickNode(mRule.getContentViewCore(), "plain_text");
789 assertWaitForKeyboardStatus(false); 691 mRule.assertWaitForKeyboardStatus(false);
790 assertWaitForSelectActionBarStatus(false); 692 mRule.assertWaitForSelectActionBarStatus(false);
791 } 693 }
792 694
695 @Test
793 @SmallTest 696 @SmallTest
794 @Feature({"TextInput"}) 697 @Feature({"TextInput"})
795 public void testImeNotShownOnLongPressingDifferentEmptyInputs() throws Excep tion { 698 public void testImeNotShownOnLongPressingDifferentEmptyInputs() throws Excep tion {
796 DOMUtils.focusNode(mWebContents, "input_radio"); 699 DOMUtils.focusNode(mRule.getWebContents(), "input_radio");
797 DOMUtils.longPressNode(mContentViewCore, "input_text"); 700 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
798 assertWaitForKeyboardStatus(false); 701 mRule.assertWaitForKeyboardStatus(false);
799 DOMUtils.longPressNode(mContentViewCore, "textarea"); 702 DOMUtils.longPressNode(mRule.getContentViewCore(), "textarea");
800 assertWaitForKeyboardStatus(false); 703 mRule.assertWaitForKeyboardStatus(false);
801 } 704 }
802 705
706 @Test
803 @SmallTest 707 @SmallTest
804 @Feature({"TextInput"}) 708 @Feature({"TextInput"})
805 public void testImeStaysOnLongPressingDifferentNonEmptyInputs() throws Excep tion { 709 public void testImeStaysOnLongPressingDifferentNonEmptyInputs() throws Excep tion {
806 DOMUtils.focusNode(mWebContents, "input_text"); 710 DOMUtils.focusNode(mRule.getWebContents(), "input_text");
807 assertWaitForKeyboardStatus(true); 711 mRule.assertWaitForKeyboardStatus(true);
808 712
809 commitText("Sample Text", 1); 713 mRule.commitText("Sample Text", 1);
810 // We should wait to avoid race condition. 714 // We should wait to avoid race condition.
811 waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); 715 mRule.waitAndVerifyUpdateSelection(0, 11, 11, -1, -1);
812 716
813 DOMUtils.focusNode(mWebContents, "textarea"); 717 DOMUtils.focusNode(mRule.getWebContents(), "textarea");
814 waitAndVerifyUpdateSelection(1, 0, 0, -1, -1); 718 mRule.waitAndVerifyUpdateSelection(1, 0, 0, -1, -1);
815 719
816 commitText("Sample Text", 1); 720 mRule.commitText("Sample Text", 1);
817 waitAndVerifyUpdateSelection(2, 11, 11, -1, -1); 721 mRule.waitAndVerifyUpdateSelection(2, 11, 11, -1, -1);
818 722
819 DOMUtils.longPressNode(mContentViewCore, "input_text"); 723 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
820 assertWaitForKeyboardStatus(true); 724 mRule.assertWaitForKeyboardStatus(true);
821 assertWaitForSelectActionBarStatus(true); 725 mRule.assertWaitForSelectActionBarStatus(true);
822 726
823 DOMUtils.longPressNode(mContentViewCore, "textarea"); 727 DOMUtils.longPressNode(mRule.getContentViewCore(), "textarea");
824 assertWaitForKeyboardStatus(true); 728 mRule.assertWaitForKeyboardStatus(true);
825 } 729 }
826 730
731 @Test
827 @SmallTest 732 @SmallTest
828 @Feature({"TextInput"}) 733 @Feature({"TextInput"})
829 public void testImeCut() throws Exception { 734 public void testImeCut() throws Exception {
830 commitText("snarful", 1); 735 mRule.commitText("snarful", 1);
831 waitAndVerifyUpdateSelection(0, 7, 7, -1, -1); 736 mRule.waitAndVerifyUpdateSelection(0, 7, 7, -1, -1);
832 737
833 setSelection(1, 5); 738 mRule.setSelection(1, 5);
834 waitAndVerifyUpdateSelection(1, 1, 5, -1, -1); 739 mRule.waitAndVerifyUpdateSelection(1, 1, 5, -1, -1);
835 740
836 cut(); 741 mRule.cut();
837 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 742 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
838 assertTextsAroundCursor("s", null, "ul"); 743 mRule.assertTextsAroundCursor("s", null, "ul");
839 assertClipboardContents(getActivity(), "narf"); 744 mRule.assertClipboardContents(mRule.getActivity(), "narf");
840 } 745 }
841 746
747 @Test
842 @SmallTest 748 @SmallTest
843 @Feature({"TextInput"}) 749 @Feature({"TextInput"})
844 public void testImePaste() throws Exception { 750 public void testImePaste() throws Exception {
845 ThreadUtils.runOnUiThreadBlocking(new Runnable() { 751 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
846 @Override 752 @Override
847 public void run() { 753 public void run() {
848 ClipboardManager clipboardManager = 754 ClipboardManager clipboardManager =
849 (ClipboardManager) getActivity().getSystemService( 755 (ClipboardManager) mRule.getActivity().getSystemService(
850 Context.CLIPBOARD_SERVICE); 756 Context.CLIPBOARD_SERVICE);
851 clipboardManager.setPrimaryClip(ClipData.newPlainText("blarg", " blarg")); 757 clipboardManager.setPrimaryClip(ClipData.newPlainText("blarg", " blarg"));
852 } 758 }
853 }); 759 });
854 760
855 paste(); 761 mRule.paste();
856 // Paste is a two step process when there is a non-zero selection. 762 // Paste is a two step process when there is a non-zero selection.
857 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 763 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
858 assertTextsAroundCursor("blarg", null, ""); 764 mRule.assertTextsAroundCursor("blarg", null, "");
859 765
860 setSelection(3, 5); 766 mRule.setSelection(3, 5);
861 waitAndVerifyUpdateSelection(1, 3, 5, -1, -1); 767 mRule.waitAndVerifyUpdateSelection(1, 3, 5, -1, -1);
862 assertTextsAroundCursor("bla", "rg", ""); 768 mRule.assertTextsAroundCursor("bla", "rg", "");
863 769
864 paste(); 770 mRule.paste();
865 // Paste is a two step process when there is a non-zero selection. 771 // Paste is a two step process when there is a non-zero selection.
866 waitAndVerifyUpdateSelection(2, 8, 8, -1, -1); 772 mRule.waitAndVerifyUpdateSelection(2, 8, 8, -1, -1);
867 assertTextsAroundCursor("blablarg", null, ""); 773 mRule.assertTextsAroundCursor("blablarg", null, "");
868 774
869 paste(); 775 mRule.paste();
870 waitAndVerifyUpdateSelection(3, 13, 13, -1, -1); 776 mRule.waitAndVerifyUpdateSelection(3, 13, 13, -1, -1);
871 assertTextsAroundCursor("blablargblarg", null, ""); 777 mRule.assertTextsAroundCursor("blablargblarg", null, "");
872 } 778 }
873 779
780 @Test
874 @SmallTest 781 @SmallTest
875 @Feature({"TextInput"}) 782 @Feature({"TextInput"})
876 public void testImeSelectAndCollapseSelection() throws Exception { 783 public void testImeSelectAndCollapseSelection() throws Exception {
877 commitText("hello", 1); 784 mRule.commitText("hello", 1);
878 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 785 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
879 786
880 selectAll(); 787 mRule.selectAll();
881 waitAndVerifyUpdateSelection(1, 0, 5, -1, -1); 788 mRule.waitAndVerifyUpdateSelection(1, 0, 5, -1, -1);
882 789
883 collapseSelection(); 790 mRule.collapseSelection();
884 waitAndVerifyUpdateSelection(2, 5, 5, -1, -1); 791 mRule.waitAndVerifyUpdateSelection(2, 5, 5, -1, -1);
885 } 792 }
886 793
794 @Test
887 @SmallTest 795 @SmallTest
888 @Feature({"TextInput", "Main"}) 796 @Feature({"TextInput", "Main"})
889 public void testShowImeIfNeeded() throws Throwable { 797 public void testShowImeIfNeeded() throws Throwable {
890 // showImeIfNeeded() is now implicitly called by the updated focus 798 // showImeIfNeeded() is now implicitly called by the updated focus
891 // heuristic so no need to call explicitly. http://crbug.com/371927 799 // heuristic so no need to call explicitly. http://crbug.com/371927
892 DOMUtils.focusNode(mWebContents, "input_radio"); 800 DOMUtils.focusNode(mRule.getWebContents(), "input_radio");
893 assertWaitForKeyboardStatus(false); 801 mRule.assertWaitForKeyboardStatus(false);
894 802
895 DOMUtils.focusNode(mWebContents, "input_text"); 803 DOMUtils.focusNode(mRule.getWebContents(), "input_text");
896 assertWaitForKeyboardStatus(true); 804 mRule.assertWaitForKeyboardStatus(true);
897 } 805 }
898 806
807 @Test
899 @SmallTest 808 @SmallTest
900 @Feature({"TextInput", "Main"}) 809 @Feature({"TextInput", "Main"})
901 public void testFinishComposingText() throws Throwable { 810 public void testFinishComposingText() throws Throwable {
902 focusElementAndWaitForStateUpdate("textarea"); 811 mRule.focusElementAndWaitForStateUpdate("textarea");
903 812
904 commitText("hllo", 1); 813 mRule.commitText("hllo", 1);
905 waitAndVerifyUpdateSelection(0, 4, 4, -1, -1); 814 mRule.waitAndVerifyUpdateSelection(0, 4, 4, -1, -1);
906 815
907 commitText(" ", 1); 816 mRule.commitText(" ", 1);
908 waitAndVerifyUpdateSelection(1, 5, 5, -1, -1); 817 mRule.waitAndVerifyUpdateSelection(1, 5, 5, -1, -1);
909 818
910 setSelection(1, 1); 819 mRule.setSelection(1, 1);
911 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 820 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
912 assertTextsAroundCursor("h", null, "llo "); 821 mRule.assertTextsAroundCursor("h", null, "llo ");
913 822
914 setComposingRegion(0, 4); 823 mRule.setComposingRegion(0, 4);
915 waitAndVerifyUpdateSelection(3, 1, 1, 0, 4); 824 mRule.waitAndVerifyUpdateSelection(3, 1, 1, 0, 4);
916 825
917 finishComposingText(); 826 mRule.finishComposingText();
918 waitAndVerifyUpdateSelection(4, 1, 1, -1, -1); 827 mRule.waitAndVerifyUpdateSelection(4, 1, 1, -1, -1);
919 828
920 commitText("\n", 1); 829 mRule.commitText("\n", 1);
921 waitAndVerifyUpdateSelection(5, 2, 2, -1, -1); 830 mRule.waitAndVerifyUpdateSelection(5, 2, 2, -1, -1);
922 assertTextsAroundCursor("h\n", null, "llo "); 831 mRule.assertTextsAroundCursor("h\n", null, "llo ");
923 } 832 }
924 833
925 // http://crbug.com/445499 834 // http://crbug.com/445499
835 @Test
926 @SmallTest 836 @SmallTest
927 @Feature({"TextInput", "Main"}) 837 @Feature({"TextInput", "Main"})
928 public void testDeleteText() throws Throwable { 838 public void testDeleteText() throws Throwable {
929 focusElement("textarea"); 839 mRule.focusElement("textarea");
930 840
931 // The calls below are a reflection of what the stock Google Keyboard (A ndr 841 // The calls below are a reflection of what the stock Google Keyboard (A ndr
932 // when the noted key is touched on screen. 842 // when the noted key is touched on screen.
933 // H 843 // H
934 setComposingText("h", 1); 844 mRule.setComposingText("h", 1);
935 assertEquals("h", getTextBeforeCursor(9, 0)); 845 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
936 846
937 // O 847 // O
938 setComposingText("ho", 1); 848 mRule.setComposingText("ho", 1);
939 assertEquals("ho", getTextBeforeCursor(9, 0)); 849 Assert.assertEquals("ho", mRule.getTextBeforeCursor(9, 0));
940 850
941 setComposingText("h", 1); 851 mRule.setComposingText("h", 1);
942 setComposingRegion(0, 1); 852 mRule.setComposingRegion(0, 1);
943 setComposingText("h", 1); 853 mRule.setComposingText("h", 1);
944 assertEquals("h", getTextBeforeCursor(9, 0)); 854 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
945 855
946 // I 856 // I
947 setComposingText("hi", 1); 857 mRule.setComposingText("hi", 1);
948 assertEquals("hi", getTextBeforeCursor(9, 0)); 858 Assert.assertEquals("hi", mRule.getTextBeforeCursor(9, 0));
949 859
950 // SPACE 860 // SPACE
951 commitText("hi", 1); 861 mRule.commitText("hi", 1);
952 commitText(" ", 1); 862 mRule.commitText(" ", 1);
953 assertEquals("hi ", getTextBeforeCursor(9, 0)); 863 Assert.assertEquals("hi ", mRule.getTextBeforeCursor(9, 0));
954 864
955 // DEL 865 // DEL
956 deleteSurroundingText(1, 0); 866 mRule.deleteSurroundingText(1, 0);
957 setComposingRegion(0, 2); 867 mRule.setComposingRegion(0, 2);
958 assertEquals("hi", getTextBeforeCursor(9, 0)); 868 Assert.assertEquals("hi", mRule.getTextBeforeCursor(9, 0));
959 869
960 setComposingText("h", 1); 870 mRule.setComposingText("h", 1);
961 assertEquals("h", getTextBeforeCursor(9, 0)); 871 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
962 872
963 commitText("", 1); 873 mRule.commitText("", 1);
964 assertEquals("", getTextBeforeCursor(9, 0)); 874 Assert.assertEquals("", mRule.getTextBeforeCursor(9, 0));
965 875
966 // DEL (on empty input) 876 // DEL (on empty input)
967 deleteSurroundingText(1, 0); // DEL on empty still sends 1,0 877 mRule.deleteSurroundingText(1, 0); // DEL on empty still sends 1,0
968 assertEquals("", getTextBeforeCursor(9, 0)); 878 Assert.assertEquals("", mRule.getTextBeforeCursor(9, 0));
969 } 879 }
970 880
971 881 @Test
972 @SmallTest 882 @SmallTest
973 @Feature({"TextInput", "Main"}) 883 @Feature({"TextInput", "Main"})
974 public void testSwipingText() throws Throwable { 884 public void testSwipingText() throws Throwable {
975 focusElement("textarea"); 885 mRule.focusElement("textarea");
976 886
977 // The calls below are a reflection of what the stock Google Keyboard (A ndroid 4.4) sends 887 // The calls below are a reflection of what the stock Google Keyboard (A ndroid 4.4) sends
978 // when the word is swiped on the soft keyboard. Exercise care when alt ering to make sure 888 // when the word is swiped on the soft keyboard. Exercise care when alt ering to make sure
979 // that the test reflects reality. If this test breaks, it's possible t hat code has 889 // that the test reflects reality. If this test breaks, it's possible t hat code has
980 // changed and different calls need to be made instead. 890 // changed and different calls need to be made instead.
981 // "three" 891 // "three"
982 setComposingText("three", 1); 892 mRule.setComposingText("three", 1);
983 assertEquals("three", getTextBeforeCursor(99, 0)); 893 Assert.assertEquals("three", mRule.getTextBeforeCursor(99, 0));
984 894
985 // "word" 895 // "word"
986 commitText("three", 1); 896 mRule.commitText("three", 1);
987 commitText(" ", 1); 897 mRule.commitText(" ", 1);
988 setComposingText("word", 1); 898 mRule.setComposingText("word", 1);
989 assertEquals("three word", getTextBeforeCursor(99, 0)); 899 Assert.assertEquals("three word", mRule.getTextBeforeCursor(99, 0));
990 900
991 // "test" 901 // "test"
992 commitText("word", 1); 902 mRule.commitText("word", 1);
993 commitText(" ", 1); 903 mRule.commitText(" ", 1);
994 setComposingText("test", 1); 904 mRule.setComposingText("test", 1);
995 assertEquals("three word test", getTextBeforeCursor(99, 0)); 905 Assert.assertEquals("three word test", mRule.getTextBeforeCursor(99, 0)) ;
996 } 906 }
997 907
908 @Test
998 @SmallTest 909 @SmallTest
999 @Feature({"TextInput", "Main"}) 910 @Feature({"TextInput", "Main"})
1000 public void testDeleteMultiCharacterCodepoint() throws Throwable { 911 public void testDeleteMultiCharacterCodepoint() throws Throwable {
1001 // This smiley is a multi character codepoint. 912 // This smiley is a multi character codepoint.
1002 final String smiley = "\uD83D\uDE0A"; 913 final String smiley = "\uD83D\uDE0A";
1003 914
1004 commitText(smiley, 1); 915 mRule.commitText(smiley, 1);
1005 waitAndVerifyUpdateSelection(0, 2, 2, -1, -1); 916 mRule.waitAndVerifyUpdateSelection(0, 2, 2, -1, -1);
1006 assertTextsAroundCursor(smiley, null, ""); 917 mRule.assertTextsAroundCursor(smiley, null, "");
1007 918
1008 // DEL, sent via dispatchKeyEvent like it is in Android WebView or a phy sical keyboard. 919 // DEL, sent via mRule.dispatchKeyEvent like it is in Android WebView or a physical
1009 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL )); 920 // keyboard.
1010 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)) ; 921 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DEL));
1011 922 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _DEL));
1012 waitAndVerifyUpdateSelection(1, 0, 0, -1, -1); 923
924 mRule.waitAndVerifyUpdateSelection(1, 0, 0, -1, -1);
1013 925
1014 // Make sure that we accept further typing after deleting the smiley. 926 // Make sure that we accept further typing after deleting the smiley.
1015 setComposingText("s", 1); 927 mRule.setComposingText("s", 1);
1016 setComposingText("sm", 1); 928 mRule.setComposingText("sm", 1);
1017 waitAndVerifyUpdateSelection(2, 1, 1, 0, 1); 929 mRule.waitAndVerifyUpdateSelection(2, 1, 1, 0, 1);
1018 waitAndVerifyUpdateSelection(3, 2, 2, 0, 2); 930 mRule.waitAndVerifyUpdateSelection(3, 2, 2, 0, 2);
1019 } 931 }
1020 932
933 @Test
1021 @SmallTest 934 @SmallTest
1022 @Feature({"TextInput", "Main"}) 935 @Feature({"TextInput", "Main"})
1023 public void testBackspaceKeycode() throws Throwable { 936 public void testBackspaceKeycode() throws Throwable {
1024 focusElement("textarea"); 937 mRule.focusElement("textarea");
1025 938
1026 // H 939 // H
1027 commitText("h", 1); 940 mRule.commitText("h", 1);
1028 assertEquals("h", getTextBeforeCursor(9, 0)); 941 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
1029 942
1030 // O 943 // O
1031 commitText("o", 1); 944 mRule.commitText("o", 1);
1032 assertEquals("ho", getTextBeforeCursor(9, 0)); 945 Assert.assertEquals("ho", mRule.getTextBeforeCursor(9, 0));
1033 946
1034 // DEL, sent via dispatchKeyEvent like it is in Android WebView or a phy sical keyboard. 947 // DEL, sent via mRule.dispatchKeyEvent like it is in Android WebView or a physical
1035 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL )); 948 // keyboard.
1036 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)) ; 949 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DEL));
950 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _DEL));
1037 951
1038 // DEL 952 // DEL
1039 assertEquals("h", getTextBeforeCursor(9, 0)); 953 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
1040 } 954 }
1041 955
956 @Test
1042 @SmallTest 957 @SmallTest
1043 @Feature({"TextInput", "Main"}) 958 @Feature({"TextInput", "Main"})
1044 public void testRepeatBackspaceKeycode() throws Throwable { 959 public void testRepeatBackspaceKeycode() throws Throwable {
1045 focusElement("textarea"); 960 mRule.focusElement("textarea");
1046 961
1047 // H 962 // H
1048 commitText("h", 1); 963 mRule.commitText("h", 1);
1049 assertEquals("h", getTextBeforeCursor(9, 0)); 964 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
1050 965
1051 // O 966 // O
1052 commitText("o", 1); 967 mRule.commitText("o", 1);
1053 assertEquals("ho", getTextBeforeCursor(9, 0)); 968 Assert.assertEquals("ho", mRule.getTextBeforeCursor(9, 0));
1054 969
1055 // Multiple keydowns should each delete one character (this is for physi cal keyboard 970 // Multiple keydowns should each delete one character (this is for physi cal keyboard
1056 // key-repeat). 971 // key-repeat).
1057 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL )); 972 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DEL));
1058 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL )); 973 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DEL));
1059 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)) ; 974 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _DEL));
1060 975
1061 // DEL 976 // DEL
1062 assertEquals("", getTextBeforeCursor(9, 0)); 977 Assert.assertEquals("", mRule.getTextBeforeCursor(9, 0));
1063 } 978 }
1064 979
980 @Test
1065 @SmallTest 981 @SmallTest
1066 @Feature({"TextInput", "Main"}) 982 @Feature({"TextInput", "Main"})
1067 public void testPhysicalKeyboard() throws Throwable { 983 public void testPhysicalKeyboard() throws Throwable {
1068 focusElementAndWaitForStateUpdate("textarea"); 984 mRule.focusElementAndWaitForStateUpdate("textarea");
1069 985
1070 // Type 'a' using a physical keyboard. 986 // Type 'a' using a physical keyboard.
1071 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)) ; 987 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_A));
1072 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A)); 988 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _A));
1073 waitAndVerifyUpdateSelection(0, 1, 1, -1, -1); 989 mRule.waitAndVerifyUpdateSelection(0, 1, 1, -1, -1);
1074 990
1075 // Type 'enter' key. 991 // Type 'enter' key.
1076 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENT ER)); 992 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_ENTER));
1077 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER )); 993 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _ENTER));
1078 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 994 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
1079 assertTextsAroundCursor("a\n", null, "\n"); 995 mRule.assertTextsAroundCursor("a\n", null, "\n");
1080 996
1081 // Type 'b'. 997 // Type 'b'.
1082 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)) ; 998 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_B));
1083 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_B)); 999 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _B));
1084 waitAndVerifyUpdateSelection(2, 3, 3, -1, -1); 1000 mRule.waitAndVerifyUpdateSelection(2, 3, 3, -1, -1);
1085 assertTextsAroundCursor("a\nb", null, ""); 1001 mRule.assertTextsAroundCursor("a\nb", null, "");
1086 } 1002 }
1087 1003
1004 @Test
1088 @SmallTest 1005 @SmallTest
1089 @Feature({"TextInput", "Main"}) 1006 @Feature({"TextInput", "Main"})
1090 public void testPhysicalKeyboard_AccentKeyCodes() throws Throwable { 1007 public void testPhysicalKeyboard_AccentKeyCodes() throws Throwable {
1091 focusElementAndWaitForStateUpdate("textarea"); 1008 mRule.focusElementAndWaitForStateUpdate("textarea");
1092 1009
1093 // h 1010 // h
1094 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_H)) ; 1011 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_H));
1095 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_H)); 1012 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _H));
1096 assertEquals("h", getTextBeforeCursor(9, 0)); 1013 Assert.assertEquals("h", mRule.getTextBeforeCursor(9, 0));
1097 waitAndVerifyUpdateSelection(0, 1, 1, -1, -1); 1014 mRule.waitAndVerifyUpdateSelection(0, 1, 1, -1, -1);
1098 1015
1099 // ALT-i (circumflex accent key on virtual keyboard) 1016 // ALT-i (circumflex accent key on virtual keyboard)
1100 dispatchKeyEvent(new KeyEvent( 1017 mRule.dispatchKeyEvent(new KeyEvent(
1101 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON)); 1018 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON));
1102 assertEquals("hˆ", getTextBeforeCursor(9, 0)); 1019 Assert.assertEquals("hˆ", mRule.getTextBeforeCursor(9, 0));
1103 dispatchKeyEvent(new KeyEvent( 1020 mRule.dispatchKeyEvent(new KeyEvent(
1104 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON)); 1021 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON));
1105 assertEquals("hˆ", getTextBeforeCursor(9, 0)); 1022 Assert.assertEquals("hˆ", mRule.getTextBeforeCursor(9, 0));
1106 waitAndVerifyUpdateSelection(1, 2, 2, 1, 2); 1023 mRule.waitAndVerifyUpdateSelection(1, 2, 2, 1, 2);
1107 1024
1108 // o 1025 // o
1109 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_O)) ; 1026 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_O));
1110 assertEquals("hô", getTextBeforeCursor(9, 0)); 1027 Assert.assertEquals("hô", mRule.getTextBeforeCursor(9, 0));
1111 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_O)); 1028 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _O));
1112 assertEquals("hô", getTextBeforeCursor(9, 0)); 1029 Assert.assertEquals("hô", mRule.getTextBeforeCursor(9, 0));
1113 waitAndVerifyUpdateSelection(2, 2, 2, -1, -1); 1030 mRule.waitAndVerifyUpdateSelection(2, 2, 2, -1, -1);
1114 1031
1115 // ALT-i 1032 // ALT-i
1116 dispatchKeyEvent(new KeyEvent( 1033 mRule.dispatchKeyEvent(new KeyEvent(
1117 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON)); 1034 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON));
1118 dispatchKeyEvent(new KeyEvent( 1035 mRule.dispatchKeyEvent(new KeyEvent(
1119 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON)); 1036 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON));
1120 assertEquals("hôˆ", getTextBeforeCursor(9, 0)); 1037 Assert.assertEquals("hôˆ", mRule.getTextBeforeCursor(9, 0));
1121 waitAndVerifyUpdateSelection(3, 3, 3, 2, 3); 1038 mRule.waitAndVerifyUpdateSelection(3, 3, 3, 2, 3);
1122 1039
1123 // ALT-i again should have no effect 1040 // ALT-i again should have no effect
1124 dispatchKeyEvent(new KeyEvent( 1041 mRule.dispatchKeyEvent(new KeyEvent(
1125 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON)); 1042 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON));
1126 dispatchKeyEvent(new KeyEvent( 1043 mRule.dispatchKeyEvent(new KeyEvent(
1127 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON)); 1044 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON));
1128 assertEquals("hôˆ", getTextBeforeCursor(9, 0)); 1045 Assert.assertEquals("hôˆ", mRule.getTextBeforeCursor(9, 0));
1129 1046
1130 // b (cannot be accented, should just appear after) 1047 // b (cannot be accented, should just appear after)
1131 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)) ; 1048 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_B));
1132 assertEquals("hôˆb", getTextBeforeCursor(9, 0)); 1049 Assert.assertEquals("hôˆb", mRule.getTextBeforeCursor(9, 0));
1133 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_B)); 1050 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _B));
1134 assertEquals("hôˆb", getTextBeforeCursor(9, 0)); 1051 Assert.assertEquals("hôˆb", mRule.getTextBeforeCursor(9, 0));
1135 int index = 4; 1052 int index = 4;
1136 waitAndVerifyUpdateSelection(index++, 4, 4, -1, -1); 1053 mRule.waitAndVerifyUpdateSelection(index++, 4, 4, -1, -1);
1137 1054
1138 // ALT-i 1055 // ALT-i
1139 dispatchKeyEvent(new KeyEvent( 1056 mRule.dispatchKeyEvent(new KeyEvent(
1140 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON)); 1057 0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_I, 0, KeyEvent.META _ALT_ON));
1141 dispatchKeyEvent(new KeyEvent( 1058 mRule.dispatchKeyEvent(new KeyEvent(
1142 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON)); 1059 0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_A LT_ON));
1143 assertEquals("hôˆbˆ", getTextBeforeCursor(9, 0)); 1060 Assert.assertEquals("hôˆbˆ", mRule.getTextBeforeCursor(9, 0));
1144 waitAndVerifyUpdateSelection(index++, 5, 5, 4, 5); 1061 mRule.waitAndVerifyUpdateSelection(index++, 5, 5, 4, 5);
1145 1062
1146 // Backspace 1063 // Backspace
1147 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL )); 1064 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DEL));
1148 assertEquals("hôˆb", getTextBeforeCursor(9, 0)); 1065 Assert.assertEquals("hôˆb", mRule.getTextBeforeCursor(9, 0));
1149 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)) ; 1066 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _DEL));
1150 assertEquals("hôˆb", getTextBeforeCursor(9, 0)); 1067 Assert.assertEquals("hôˆb", mRule.getTextBeforeCursor(9, 0));
1151 waitAndVerifyUpdateSelection(index++, 4, 4, -1, -1); 1068 mRule.waitAndVerifyUpdateSelection(index++, 4, 4, -1, -1);
1152 } 1069 }
1153 1070
1071 @Test
1154 @SmallTest 1072 @SmallTest
1155 @Feature({"TextInput", "Main"}) 1073 @Feature({"TextInput", "Main"})
1156 public void testSetComposingRegionOutOfBounds() throws Throwable { 1074 public void testSetComposingRegionOutOfBounds() throws Throwable {
1157 focusElementAndWaitForStateUpdate("textarea"); 1075 mRule.focusElementAndWaitForStateUpdate("textarea");
1158 setComposingText("hello", 1); 1076 mRule.setComposingText("hello", 1);
1159 waitAndVerifyUpdateSelection(0, 5, 5, 0, 5); 1077 mRule.waitAndVerifyUpdateSelection(0, 5, 5, 0, 5);
1160 1078
1161 setComposingRegion(0, 0); 1079 mRule.setComposingRegion(0, 0);
1162 waitAndVerifyUpdateSelection(1, 5, 5, -1, -1); 1080 mRule.waitAndVerifyUpdateSelection(1, 5, 5, -1, -1);
1163 setComposingRegion(0, 9); 1081 mRule.setComposingRegion(0, 9);
1164 waitAndVerifyUpdateSelection(2, 5, 5, 0, 5); 1082 mRule.waitAndVerifyUpdateSelection(2, 5, 5, 0, 5);
1165 setComposingRegion(9, 1); 1083 mRule.setComposingRegion(9, 1);
1166 waitAndVerifyUpdateSelection(3, 5, 5, 1, 5); 1084 mRule.waitAndVerifyUpdateSelection(3, 5, 5, 1, 5);
1167 } 1085 }
1168 1086
1087 @Test
1169 @SmallTest 1088 @SmallTest
1170 @Feature({"TextInput", "Main"}) 1089 @Feature({"TextInput", "Main"})
1171 public void testEnterKey_AfterCommitText() throws Throwable { 1090 public void testEnterKey_AfterCommitText() throws Throwable {
1172 focusElementAndWaitForStateUpdate("textarea"); 1091 mRule.focusElementAndWaitForStateUpdate("textarea");
1173 1092
1174 commitText("hello", 1); 1093 mRule.commitText("hello", 1);
1175 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1094 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1176 1095
1177 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENT ER)); 1096 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_ENTER));
1178 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER )); 1097 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _ENTER));
1179 waitAndVerifyUpdateSelection(1, 6, 6, -1, -1); 1098 mRule.waitAndVerifyUpdateSelection(1, 6, 6, -1, -1);
1180 assertTextsAroundCursor("hello\n", null, "\n"); 1099 mRule.assertTextsAroundCursor("hello\n", null, "\n");
1181 1100
1182 commitText("world", 1); 1101 mRule.commitText("world", 1);
1183 waitAndVerifyUpdateSelection(2, 11, 11, -1, -1); 1102 mRule.waitAndVerifyUpdateSelection(2, 11, 11, -1, -1);
1184 assertTextsAroundCursor("hello\nworld", null, ""); 1103 mRule.assertTextsAroundCursor("hello\nworld", null, "");
1185 } 1104 }
1186 1105
1106 @Test
1187 @SmallTest 1107 @SmallTest
1188 @Feature({"TextInput", "Main"}) 1108 @Feature({"TextInput", "Main"})
1189 public void testEnterKey_WhileComposingText() throws Throwable { 1109 public void testEnterKey_WhileComposingText() throws Throwable {
1190 focusElementAndWaitForStateUpdate("textarea"); 1110 mRule.focusElementAndWaitForStateUpdate("textarea");
1191 1111
1192 setComposingText("hello", 1); 1112 mRule.setComposingText("hello", 1);
1193 waitAndVerifyUpdateSelection(0, 5, 5, 0, 5); 1113 mRule.waitAndVerifyUpdateSelection(0, 5, 5, 0, 5);
1194 1114
1195 // IME app should call this, otherwise enter key should clear the curren t composition. 1115 // IME app should call this, otherwise enter key should clear the curren t composition.
1196 finishComposingText(); 1116 mRule.finishComposingText();
1197 waitAndVerifyUpdateSelection(1, 5, 5, -1, -1); 1117 mRule.waitAndVerifyUpdateSelection(1, 5, 5, -1, -1);
1198 1118
1199 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENT ER)); 1119 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_ENTER));
1200 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER )); 1120 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _ENTER));
1201 1121
1202 // The second new line is not a user visible/editable one, it is a side- effect of Blink 1122 // The second new line is not a user visible/editable one, it is a side- effect of Blink
1203 // using <br> internally. This only happens when \n is at the end. 1123 // using <br> internally. This only happens when \n is at the end.
1204 waitAndVerifyUpdateSelection(2, 6, 6, -1, -1); 1124 mRule.waitAndVerifyUpdateSelection(2, 6, 6, -1, -1);
1205 1125
1206 commitText("world", 1); 1126 mRule.commitText("world", 1);
1207 waitAndVerifyUpdateSelection(3, 11, 11, -1, -1); 1127 mRule.waitAndVerifyUpdateSelection(3, 11, 11, -1, -1);
1208 assertTextsAroundCursor("hello\nworld", null, ""); 1128 mRule.assertTextsAroundCursor("hello\nworld", null, "");
1209 } 1129 }
1210 1130
1131 @Test
1211 @SmallTest 1132 @SmallTest
1212 @Feature({"TextInput", "Main"}) 1133 @Feature({"TextInput", "Main"})
1213 public void testDpadKeyCodesWhileSwipingText() throws Throwable { 1134 public void testDpadKeyCodesWhileSwipingText() throws Throwable {
1214 focusElement("textarea"); 1135 mRule.focusElement("textarea");
1215 1136
1216 // DPAD_CENTER should cause keyboard to appear 1137 // DPAD_CENTER should cause keyboard to appear
1217 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPA D_CENTER)); 1138 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DPAD_CENTER));
1218 1139
1219 // TODO(changwan): should really check this. 1140 // TODO(changwan): should really check this.
1220 } 1141 }
1221 1142
1143 @Test
1222 @SmallTest 1144 @SmallTest
1223 @Feature({"TextInput", "Main"}) 1145 @Feature({"TextInput", "Main"})
1224 public void testNavigateTextWithDpadKeyCodes() throws Throwable { 1146 public void testNavigateTextWithDpadKeyCodes() throws Throwable {
1225 focusElementAndWaitForStateUpdate("textarea"); 1147 mRule.focusElementAndWaitForStateUpdate("textarea");
1226 1148
1227 commitText("hello", 1); 1149 mRule.commitText("hello", 1);
1228 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1150 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1229 1151
1230 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPA D_LEFT)); 1152 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DPAD_LEFT));
1231 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_ LEFT)); 1153 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE _DPAD_LEFT));
1232 1154
1233 assertTextsAroundCursor("hell", null, "o"); 1155 mRule.assertTextsAroundCursor("hell", null, "o");
1234 } 1156 }
1235 1157
1158 @Test
1236 @SmallTest 1159 @SmallTest
1237 @Feature({"TextInput"}) 1160 @Feature({"TextInput"})
1238 public void testPastePopupShowAndHide() throws Throwable { 1161 public void testPastePopupShowAndHide() throws Throwable {
1239 commitText("hello", 1); 1162 mRule.commitText("hello", 1);
1240 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1163 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1241 1164
1242 selectAll(); 1165 mRule.selectAll();
1243 waitAndVerifyUpdateSelection(1, 0, 5, -1, -1); 1166 mRule.waitAndVerifyUpdateSelection(1, 0, 5, -1, -1);
1244 assertTextsAroundCursor("", "hello", ""); 1167 mRule.assertTextsAroundCursor("", "hello", "");
1245 1168
1246 cut(); 1169 mRule.cut();
1247 waitAndVerifyUpdateSelection(2, 0, 0, -1, -1); 1170 mRule.waitAndVerifyUpdateSelection(2, 0, 0, -1, -1);
1248 assertTextsAroundCursor("", null, ""); 1171 mRule.assertTextsAroundCursor("", null, "");
1249 1172
1250 DOMUtils.longPressNode(mContentViewCore, "input_text"); 1173 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
1251 CriteriaHelper.pollUiThread(new Criteria() { 1174 CriteriaHelper.pollUiThread(new Criteria() {
1252 @Override 1175 @Override
1253 public boolean isSatisfied() { 1176 public boolean isSatisfied() {
1254 return mSelectionPopupController.isPastePopupShowing() 1177 return mRule.getSelectionPopupController().isPastePopupShowing()
1255 && mSelectionPopupController.isInsertion(); 1178 && mRule.getSelectionPopupController().isInsertion();
1256 } 1179 }
1257 }); 1180 });
1258 1181
1259 setComposingText("h", 1); 1182 mRule.setComposingText("h", 1);
1260 CriteriaHelper.pollUiThread(new Criteria() { 1183 CriteriaHelper.pollUiThread(new Criteria() {
1261 @Override 1184 @Override
1262 public boolean isSatisfied() { 1185 public boolean isSatisfied() {
1263 return !mSelectionPopupController.isPastePopupShowing(); 1186 return !mRule.getSelectionPopupController().isPastePopupShowing( );
1264 } 1187 }
1265 }); 1188 });
1266 assertFalse(mSelectionPopupController.isInsertion()); 1189 Assert.assertFalse(mRule.getSelectionPopupController().isInsertion());
1267 } 1190 }
1268 1191
1192 @Test
1269 @SmallTest 1193 @SmallTest
1270 @Feature({"TextInput"}) 1194 @Feature({"TextInput"})
1271 public void testSelectionClearedOnKeyEvent() throws Throwable { 1195 public void testSelectionClearedOnKeyEvent() throws Throwable {
1272 commitText("Sample Text", 1); 1196 mRule.commitText("Sample Text", 1);
1273 waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); 1197 mRule.waitAndVerifyUpdateSelection(0, 11, 11, -1, -1);
1274 1198
1275 DOMUtils.longPressNode(mContentViewCore, "input_text"); 1199 DOMUtils.longPressNode(mRule.getContentViewCore(), "input_text");
1276 assertWaitForSelectActionBarStatus(true); 1200 mRule.assertWaitForSelectActionBarStatus(true);
1277 1201
1278 setComposingText("h", 1); 1202 mRule.setComposingText("h", 1);
1279 assertWaitForSelectActionBarStatus(false); 1203 mRule.assertWaitForSelectActionBarStatus(false);
1280 assertFalse(mSelectionPopupController.hasSelection()); 1204 Assert.assertFalse(mRule.getSelectionPopupController().hasSelection());
1281 } 1205 }
1282 1206
1207 @Test
1283 @SmallTest 1208 @SmallTest
1284 @Feature({"TextInput"}) 1209 @Feature({"TextInput"})
1285 public void testTextHandlesPreservedWithDpadNavigation() throws Throwable { 1210 public void testTextHandlesPreservedWithDpadNavigation() throws Throwable {
1286 DOMUtils.longPressNode(mContentViewCore, "plain_text"); 1211 DOMUtils.longPressNode(mRule.getContentViewCore(), "plain_text");
1287 assertWaitForSelectActionBarStatus(true); 1212 mRule.assertWaitForSelectActionBarStatus(true);
1288 assertTrue(mSelectionPopupController.hasSelection()); 1213 Assert.assertTrue(mRule.getSelectionPopupController().hasSelection());
1289 1214
1290 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPA D_DOWN)); 1215 mRule.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCO DE_DPAD_DOWN));
1291 assertWaitForSelectActionBarStatus(true); 1216 mRule.assertWaitForSelectActionBarStatus(true);
1292 assertTrue(mSelectionPopupController.hasSelection()); 1217 Assert.assertTrue(mRule.getSelectionPopupController().hasSelection());
1293 } 1218 }
1294 1219
1220 @Test
1295 @MediumTest 1221 @MediumTest
1296 @Feature({"TextInput"}) 1222 @Feature({"TextInput"})
1297 public void testRestartInputWhileComposingText() throws Throwable { 1223 public void testRestartInputWhileComposingText() throws Throwable {
1298 setComposingText("abc", 1); 1224 mRule.setComposingText("abc", 1);
1299 waitAndVerifyUpdateSelection(0, 3, 3, 0, 3); 1225 mRule.waitAndVerifyUpdateSelection(0, 3, 3, 0, 3);
1300 restartInput(); 1226 mRule.restartInput();
1301 // We don't do anything when input gets restarted. But we depend on Andr oid's 1227 // We don't do anything when input gets restarted. But we depend on Andr oid's
1302 // InputMethodManager and/or input methods to call finishComposingText() in setting 1228 // InputMethodManager and/or input methods to call mRule.finishComposing Text() in setting
1303 // current input connection as active or finishing the current input con nection. 1229 // current input connection as active or finishing the current input con nection.
1304 Thread.sleep(1000); 1230 Thread.sleep(1000);
1305 assertEquals(1, mInputMethodManagerWrapper.getUpdateSelectionList().size ()); 1231 Assert.assertEquals(
1306 } 1232 1, mRule.getInputMethodManagerWrapper().getUpdateSelectionList() .size());
1307 1233 }
1234
1235 @Test
1308 @MediumTest 1236 @MediumTest
1309 @Feature({"TextInput"}) 1237 @Feature({"TextInput"})
1310 public void testRestartInputKeepsTextAndCursor() throws Exception { 1238 public void testRestartInputKeepsTextAndCursor() throws Exception {
1311 commitText("ab", 2); 1239 mRule.commitText("ab", 2);
1312 restartInput(); 1240 mRule.restartInput();
1313 assertEquals("ab", getTextBeforeCursor(10, 0)); 1241 Assert.assertEquals("ab", mRule.getTextBeforeCursor(10, 0));
1314 } 1242 }
1315 1243
1244 @Test
1316 @MediumTest 1245 @MediumTest
1317 @Feature({"TextInput"}) 1246 @Feature({"TextInput"})
1318 public void testContentEditableEvents_ComposingText() throws Throwable { 1247 public void testContentEditableEvents_ComposingText() throws Throwable {
1319 focusElementAndWaitForStateUpdate("contenteditable_event"); 1248 mRule.focusElementAndWaitForStateUpdate("contenteditable_event");
1320 waitForEventLogs("selectionchange"); 1249 mRule.waitForEventLogs("selectionchange");
1321 clearEventLogs(); 1250 mRule.clearEventLogs();
1322 1251
1323 setComposingText("a", 1); 1252 mRule.setComposingText("a", 1);
1324 waitAndVerifyUpdateSelection(0, 1, 1, 0, 1); 1253 mRule.waitAndVerifyUpdateSelection(0, 1, 1, 0, 1);
1325 // TODO(changwan): reduce the number of selection changes. 1254 // TODO(changwan): reduce the number of selection changes.
1326 waitForEventLogs("keydown(229),compositionstart(),compositionupdate(a),i nput,keyup(229)," 1255 mRule.waitForEventLogs(
1256 "keydown(229),compositionstart(),compositionupdate(a),input,keyu p(229),"
1327 + "selectionchange,selectionchange"); 1257 + "selectionchange,selectionchange");
1328 clearEventLogs(); 1258 mRule.clearEventLogs();
1329 1259
1330 finishComposingText(); 1260 mRule.finishComposingText();
1331 waitAndVerifyUpdateSelection(1, 1, 1, -1, -1); 1261 mRule.waitAndVerifyUpdateSelection(1, 1, 1, -1, -1);
1332 waitForEventLogs( 1262 mRule.waitForEventLogs("compositionend(a)");
1333 "compositionend(a)"); 1263 }
1334 } 1264
1335 1265 @Test
1336 @MediumTest 1266 @MediumTest
1337 @Feature({"TextInput"}) 1267 @Feature({"TextInput"})
1338 public void testInputTextEvents_ComposingText() throws Throwable { 1268 public void testInputTextEvents_ComposingText() throws Throwable {
1339 setComposingText("a", 1); 1269 mRule.setComposingText("a", 1);
1340 waitAndVerifyUpdateSelection(0, 1, 1, 0, 1); 1270 mRule.waitAndVerifyUpdateSelection(0, 1, 1, 0, 1);
1341 // TODO(changwan): reduce the number of selection changes. 1271 // TODO(changwan): reduce the number of selection changes.
1342 waitForEventLogs("keydown(229),compositionstart(),compositionupdate(a)," 1272 mRule.waitForEventLogs("keydown(229),compositionstart(),compositionupdat e(a),"
1343 + "input,keyup(229),selectionchange,selectionchange"); 1273 + "input,keyup(229),selectionchange,selectionchange");
1344 clearEventLogs(); 1274 mRule.clearEventLogs();
1345 1275
1346 finishComposingText(); 1276 mRule.finishComposingText();
1347 waitAndVerifyUpdateSelection(1, 1, 1, -1, -1); 1277 mRule.waitAndVerifyUpdateSelection(1, 1, 1, -1, -1);
1348 waitForEventLogs("compositionend(a)"); 1278 mRule.waitForEventLogs("compositionend(a)");
1349 } 1279 }
1350 1280
1281 @Test
1351 @MediumTest 1282 @MediumTest
1352 @Feature({"TextInput"}) 1283 @Feature({"TextInput"})
1353 public void testContentEditableEvents_CommitText() throws Throwable { 1284 public void testContentEditableEvents_CommitText() throws Throwable {
1354 focusElementAndWaitForStateUpdate("contenteditable_event"); 1285 mRule.focusElementAndWaitForStateUpdate("contenteditable_event");
1355 waitForEventLogs("selectionchange"); 1286 mRule.waitForEventLogs("selectionchange");
1356 clearEventLogs(); 1287 mRule.clearEventLogs();
1357 1288
1358 commitText("a", 1); 1289 mRule.commitText("a", 1);
1359 waitAndVerifyUpdateSelection(0, 1, 1, -1, -1); 1290 mRule.waitAndVerifyUpdateSelection(0, 1, 1, -1, -1);
1360 1291
1361 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1292 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1362 } 1293 }
1363 1294
1295 @Test
1364 @MediumTest 1296 @MediumTest
1365 @Feature({"TextInput"}) 1297 @Feature({"TextInput"})
1366 public void testInputTextEvents_CommitText() throws Throwable { 1298 public void testInputTextEvents_CommitText() throws Throwable {
1367 commitText("a", 1); 1299 mRule.commitText("a", 1);
1368 waitAndVerifyUpdateSelection(0, 1, 1, -1, -1); 1300 mRule.waitAndVerifyUpdateSelection(0, 1, 1, -1, -1);
1369 1301
1370 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1302 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1371 } 1303 }
1372 1304
1305 @Test
1373 @MediumTest 1306 @MediumTest
1374 @Feature({"TextInput"}) 1307 @Feature({"TextInput"})
1375 public void testContentEditableEvents_DeleteSurroundingText() throws Throwab le { 1308 public void testContentEditableEvents_DeleteSurroundingText() throws Throwab le {
1376 focusElementAndWaitForStateUpdate("contenteditable_event"); 1309 mRule.focusElementAndWaitForStateUpdate("contenteditable_event");
1377 waitForEventLogs("selectionchange"); 1310 mRule.waitForEventLogs("selectionchange");
1378 clearEventLogs(); 1311 mRule.clearEventLogs();
1379 1312
1380 commitText("hello", 1); 1313 mRule.commitText("hello", 1);
1381 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1314 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1382 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1315 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1383 clearEventLogs(); 1316 mRule.clearEventLogs();
1384 1317
1385 setSelection(2, 2); 1318 mRule.setSelection(2, 2);
1386 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 1319 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
1387 waitForEventLogs("selectionchange"); 1320 mRule.waitForEventLogs("selectionchange");
1388 clearEventLogs(); 1321 mRule.clearEventLogs();
1389 1322
1390 deleteSurroundingText(1, 1); 1323 mRule.deleteSurroundingText(1, 1);
1391 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 1324 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
1325
1392 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s. 1326 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s.
1393 waitForEventLogs("keydown(229),input,input,keyup(229),selectionchange,se lectionchange"); 1327 mRule.waitForEventLogs(
1394 } 1328 "keydown(229),input,input,keyup(229),selectionchange,selectionch ange");
1395 1329 }
1330
1331 @Test
1396 @MediumTest 1332 @MediumTest
1397 @Feature({"TextInput"}) 1333 @Feature({"TextInput"})
1398 public void testInputTextEvents_DeleteSurroundingText() throws Throwable { 1334 public void testInputTextEvents_DeleteSurroundingText() throws Throwable {
1399 commitText("hello", 1); 1335 mRule.commitText("hello", 1);
1400 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1336 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1401 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1337 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1402 clearEventLogs(); 1338 mRule.clearEventLogs();
1403 1339
1404 setSelection(2, 2); 1340 mRule.setSelection(2, 2);
1405 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 1341 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
1406 waitForEventLogs("selectionchange"); 1342 mRule.waitForEventLogs("selectionchange");
1407 clearEventLogs(); 1343 mRule.clearEventLogs();
1408 1344
1409 deleteSurroundingText(1, 1); 1345 mRule.deleteSurroundingText(1, 1);
1410 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 1346 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
1411 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s. 1347 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s.
1412 waitForEventLogs("keydown(229),input,input,keyup(229),selectionchange,se lectionchange"); 1348 mRule.waitForEventLogs(
1413 } 1349 "keydown(229),input,input,keyup(229),selectionchange,selectionch ange");
1414 1350 }
1351
1352 @Test
1415 @MediumTest 1353 @MediumTest
1416 @Feature({"TextInput"}) 1354 @Feature({"TextInput"})
1417 public void testContentEditableEvents_DeleteSurroundingTextInCodePoints() th rows Throwable { 1355 public void testContentEditableEvents_DeleteSurroundingTextInCodePoints() th rows Throwable {
1418 focusElementAndWaitForStateUpdate("contenteditable_event"); 1356 mRule.focusElementAndWaitForStateUpdate("contenteditable_event");
1419 waitForEventLogs("selectionchange"); 1357 mRule.waitForEventLogs("selectionchange");
1420 clearEventLogs(); 1358 mRule.clearEventLogs();
1421 1359
1422 commitText("hello", 1); 1360 mRule.commitText("hello", 1);
1423 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1361 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1424 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1362 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1425 clearEventLogs(); 1363 mRule.clearEventLogs();
1426 1364
1427 setSelection(2, 2); 1365 mRule.setSelection(2, 2);
1428 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 1366 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
1429 waitForEventLogs("selectionchange"); 1367 mRule.waitForEventLogs("selectionchange");
1430 clearEventLogs(); 1368 mRule.clearEventLogs();
1431 1369
1432 deleteSurroundingTextInCodePoints(1, 1); 1370 mRule.deleteSurroundingTextInCodePoints(1, 1);
1433 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 1371 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
1434 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s. 1372 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s.
1435 waitForEventLogs("keydown(229),input,input,keyup(229),selectionchange,se lectionchange"); 1373 mRule.waitForEventLogs(
1436 } 1374 "keydown(229),input,input,keyup(229),selectionchange,selectionch ange");
1437 1375 }
1376
1377 @Test
1438 @MediumTest 1378 @MediumTest
1439 @Feature({"TextInput"}) 1379 @Feature({"TextInput"})
1440 public void testInputTextEvents_DeleteSurroundingTextInCodePoints() throws T hrowable { 1380 public void testInputTextEvents_DeleteSurroundingTextInCodePoints() throws T hrowable {
1441 commitText("hello", 1); 1381 mRule.commitText("hello", 1);
1442 waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); 1382 mRule.waitAndVerifyUpdateSelection(0, 5, 5, -1, -1);
1443 waitForEventLogs("keydown(229),input,keyup(229),selectionchange"); 1383 mRule.waitForEventLogs("keydown(229),input,keyup(229),selectionchange");
1444 clearEventLogs(); 1384 mRule.clearEventLogs();
1445 1385
1446 setSelection(2, 2); 1386 mRule.setSelection(2, 2);
1447 waitAndVerifyUpdateSelection(1, 2, 2, -1, -1); 1387 mRule.waitAndVerifyUpdateSelection(1, 2, 2, -1, -1);
1448 waitForEventLogs("selectionchange"); 1388 mRule.waitForEventLogs("selectionchange");
1449 clearEventLogs(); 1389 mRule.clearEventLogs();
1450 1390
1451 deleteSurroundingTextInCodePoints(1, 1); 1391 mRule.deleteSurroundingTextInCodePoints(1, 1);
1452 waitAndVerifyUpdateSelection(2, 1, 1, -1, -1); 1392 mRule.waitAndVerifyUpdateSelection(2, 1, 1, -1, -1);
1453 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s. 1393 // TODO(yabinh): It should only fire 1 input and 1 selectionchange event s.
1454 waitForEventLogs("keydown(229),input,input,keyup(229),selectionchange,se lectionchange"); 1394 mRule.waitForEventLogs(
1455 } 1395 "keydown(229),input,input,keyup(229),selectionchange,selectionch ange");
1456 1396 }
1397
1398 @Test
1457 @MediumTest 1399 @MediumTest
1458 @Feature({"TextInput"}) 1400 @Feature({"TextInput"})
1459 public void testGetCursorCapsMode() throws Throwable { 1401 public void testGetCursorCapsMode() throws Throwable {
1460 focusElementAndWaitForStateUpdate("contenteditable_event"); 1402 mRule.focusElementAndWaitForStateUpdate("contenteditable_event");
1461 commitText("Hello World", 1); 1403 mRule.commitText("Hello World", 1);
1462 waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); 1404 mRule.waitAndVerifyUpdateSelection(0, 11, 11, -1, -1);
1463 assertEquals(0, 1405 Assert.assertEquals(0, mRule.getCursorCapsMode(InputType.TYPE_TEXT_FLAG_ CAP_WORDS));
1464 getCursorCapsMode(InputType.TYPE_TEXT_FLAG_CAP_WORDS)); 1406 mRule.setSelection(6, 6);
1465 setSelection(6, 6); 1407 mRule.waitAndVerifyUpdateSelection(1, 6, 6, -1, -1);
1466 waitAndVerifyUpdateSelection(1, 6, 6, -1, -1); 1408 Assert.assertEquals(InputType.TYPE_TEXT_FLAG_CAP_WORDS,
1467 assertEquals(InputType.TYPE_TEXT_FLAG_CAP_WORDS, 1409 mRule.getCursorCapsMode(InputType.TYPE_TEXT_FLAG_CAP_WORDS));
1468 getCursorCapsMode(InputType.TYPE_TEXT_FLAG_CAP_WORDS)); 1410 mRule.commitText("\n", 1);
1469 commitText("\n", 1); 1411 Assert.assertEquals(InputType.TYPE_TEXT_FLAG_CAP_WORDS,
1470 assertEquals(InputType.TYPE_TEXT_FLAG_CAP_WORDS, 1412 mRule.getCursorCapsMode(InputType.TYPE_TEXT_FLAG_CAP_WORDS));
1471 getCursorCapsMode(InputType.TYPE_TEXT_FLAG_CAP_WORDS));
1472 }
1473
1474 private void clearEventLogs() throws Exception {
1475 final String code = "clearEventLogs()";
1476 JavaScriptUtils.executeJavaScriptAndWaitForResult(
1477 getContentViewCore().getWebContents(), code);
1478 }
1479
1480 private void waitForEventLogs(String expectedLogs) throws Exception {
1481 final String code = "getEventLogs()";
1482 final String sanitizedExpectedLogs = "\"" + expectedLogs + "\"";
1483 assertEquals(sanitizedExpectedLogs, JavaScriptUtils.executeJavaScriptAnd WaitForResult(
1484 getContentViewCore().getWebC ontents(), code));
1485 } 1413 }
1486 1414
1487 // https://crbug.com/604675 1415 // https://crbug.com/604675
1416 @Test
1488 @MediumTest 1417 @MediumTest
1489 @Feature({"TextInput"}) 1418 @Feature({"TextInput"})
1490 public void testAlertInKeyUpListenerDoesNotCrash() throws Exception { 1419 public void testAlertInKeyUpListenerDoesNotCrash() throws Exception {
1491 // Call 'alert()' when 'keyup' event occurs. Since we are in contentshel l, 1420 // Call 'alert()' when 'keyup' event occurs. Since we are in contentshel l,
1492 // this does not actually pops up the alert window. 1421 // this does not actually pops up the alert window.
1493 String code = "(function() { " 1422 String code = "(function() { "
1494 + "var editor = document.getElementById('input_text');" 1423 + "var editor = document.getElementById('input_text');"
1495 + "editor.addEventListener('keyup', function(e) { alert('keyup') });" 1424 + "editor.addEventListener('keyup', function(e) { alert('keyup') });"
1496 + "})();"; 1425 + "})();";
1497 JavaScriptUtils.executeJavaScriptAndWaitForResult( 1426 JavaScriptUtils.executeJavaScriptAndWaitForResult(
1498 getContentViewCore().getWebContents(), code); 1427 mRule.getContentViewCore().getWebContents(), code);
1499 setComposingText("ab", 1); 1428 mRule.setComposingText("ab", 1);
1500 finishComposingText(); 1429 mRule.finishComposingText();
1501 assertEquals("ab", getTextBeforeCursor(10, 0)); 1430 Assert.assertEquals("ab", mRule.getTextBeforeCursor(10, 0));
1502 } 1431 }
1503 1432
1504 // https://crbug.com/616334 1433 // https://crbug.com/616334
1434 @Test
1505 @SmallTest 1435 @SmallTest
1506 @Feature({"TextInput"}) 1436 @Feature({"TextInput"})
1507 public void testCastToBaseInputConnection() throws Exception { 1437 public void testCastToBaseInputConnection() throws Exception {
1508 commitText("a", 1); 1438 mRule.commitText("a", 1);
1509 final BaseInputConnection baseInputConnection = (BaseInputConnection) mC onnection; 1439 final BaseInputConnection baseInputConnection = (BaseInputConnection) mR ule.getConnection();
1510 assertEquals("a", runBlockingOnImeThread(new Callable<CharSequence>() { 1440 Assert.assertEquals("a", mRule.runBlockingOnImeThread(new Callable<CharS equence>() {
1511 @Override 1441 @Override
1512 public CharSequence call() { 1442 public CharSequence call() {
1513 return baseInputConnection.getTextBeforeCursor(10, 0); 1443 return baseInputConnection.getTextBeforeCursor(10, 0);
1514 } 1444 }
1515 })); 1445 }));
1516 } 1446 }
1517 1447
1518 // Tests that the method call order is kept. 1448 // Tests that the method call order is kept.
1519 // See crbug.com/601707 for details. 1449 // See crbug.com/601707 for details.
1450 @Test
1520 @MediumTest 1451 @MediumTest
1521 @Feature({"TextInput"}) 1452 @Feature({"TextInput"})
1522 public void testSetSelectionCommitTextOrder() throws Exception { 1453 public void testSetSelectionCommitTextOrder() throws Exception {
1523 final ChromiumBaseInputConnection connection = mConnection; 1454 final ChromiumBaseInputConnection connection = mRule.getConnection();
1524 runBlockingOnImeThread(new Callable<Void>() { 1455 mRule.runBlockingOnImeThread(new Callable<Void>() {
1525 @Override 1456 @Override
1526 public Void call() { 1457 public Void call() {
1527 connection.beginBatchEdit(); 1458 connection.beginBatchEdit();
1528 connection.commitText("hello world", 1); 1459 connection.commitText("hello world", 1);
1529 connection.setSelection(6, 6); 1460 connection.setSelection(6, 6);
1530 connection.deleteSurroundingText(0, 5); 1461 connection.deleteSurroundingText(0, 5);
1531 connection.commitText("'", 1); 1462 connection.commitText("'", 1);
1532 connection.commitText("world", 1); 1463 connection.commitText("world", 1);
1533 connection.setSelection(7, 7); 1464 connection.setSelection(7, 7);
1534 connection.setComposingText("", 1); 1465 connection.setComposingText("", 1);
1535 connection.endBatchEdit(); 1466 connection.endBatchEdit();
1536 return null; 1467 return null;
1537 } 1468 }
1538 }); 1469 });
1539 waitAndVerifyUpdateSelection(0, 7, 7, -1, -1); 1470 mRule.waitAndVerifyUpdateSelection(0, 7, 7, -1, -1);
1540 } 1471 }
1541 1472
1542 // crbug.com/643477 1473 // crbug.com/643477
1474 @Test
1543 @MediumTest 1475 @MediumTest
1544 @Feature({"TextInput"}) 1476 @Feature({"TextInput"})
1545 public void testUiThreadAccess() throws Exception { 1477 public void testUiThreadAccess() throws Exception {
1546 final ChromiumBaseInputConnection connection = mConnection; 1478 final ChromiumBaseInputConnection connection = mRule.getConnection();
1547 ThreadUtils.runOnUiThreadBlocking(new Runnable() { 1479 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1548 @Override 1480 @Override
1549 public void run() { 1481 public void run() {
1550 // We allow UI thread access for most functions, except for 1482 // We allow UI thread access for most functions, except for
1551 // beginBatchEdit(), endBatchEdit(), and get* methods(). 1483 // beginBatchEdit(), endBatchEdit(), and get* methods().
1552 assertTrue(connection.commitText("a", 1)); 1484 Assert.assertTrue(connection.commitText("a", 1));
1553 assertTrue(connection.setComposingText("b", 1)); 1485 Assert.assertTrue(connection.setComposingText("b", 1));
1554 assertTrue(connection.setComposingText("bc", 1)); 1486 Assert.assertTrue(connection.setComposingText("bc", 1));
1555 assertTrue(connection.finishComposingText()); 1487 Assert.assertTrue(connection.finishComposingText());
1556 } 1488 }
1557 }); 1489 });
1558 assertEquals("abc", runBlockingOnImeThread(new Callable<CharSequence>() { 1490 Assert.assertEquals("abc", mRule.runBlockingOnImeThread(new Callable<Cha rSequence>() {
1559 @Override 1491 @Override
1560 public CharSequence call() throws Exception { 1492 public CharSequence call() throws Exception {
1561 return connection.getTextBeforeCursor(5, 0); 1493 return connection.getTextBeforeCursor(5, 0);
1562 } 1494 }
1563 })); 1495 }));
1564 } 1496 }
1565 1497
1566 private void performGo(TestCallbackHelperContainer testCallbackHelperContain er)
1567 throws Throwable {
1568 final InputConnection inputConnection = mConnection;
1569 final Callable<Void> callable = new Callable<Void>() {
1570 @Override
1571 public Void call() throws Exception {
1572 inputConnection.performEditorAction(EditorInfo.IME_ACTION_GO);
1573 return null;
1574 }
1575 };
1576
1577 handleBlockingCallbackAction(
1578 testCallbackHelperContainer.getOnPageFinishedHelper(),
1579 new Runnable() {
1580 @Override
1581 public void run() {
1582 try {
1583 runBlockingOnImeThread(callable);
1584 } catch (Exception e) {
1585 e.printStackTrace();
1586 fail();
1587 }
1588 }
1589 });
1590 }
1591
1592 private void assertWaitForKeyboardStatus(final boolean show) {
1593 CriteriaHelper.pollUiThread(new Criteria() {
1594 @Override
1595 public boolean isSatisfied() {
1596 // We do not check the other way around: in some cases we need t o keep
1597 // input connection even when the last known status is 'hidden'.
1598 if (show && getInputConnection() == null) {
1599 updateFailureReason("input connection should not be null.");
1600 return false;
1601 }
1602 updateFailureReason("expected show: " + show);
1603 return show == mInputMethodManagerWrapper.isShowWithoutHideOutst anding();
1604 }
1605 });
1606 }
1607
1608 private void assertWaitForSelectActionBarStatus(final boolean show) {
1609 CriteriaHelper.pollUiThread(Criteria.equals(show, new Callable<Boolean>( ) {
1610 @Override
1611 public Boolean call() {
1612 return mContentViewCore.isSelectActionBarShowing();
1613 }
1614 }));
1615 }
1616
1617 private void waitAndVerifyUpdateSelection(final int index, final int selecti onStart,
1618 final int selectionEnd, final int compositionStart, final int compos itionEnd) {
1619 final List<Pair<Range, Range>> states = mInputMethodManagerWrapper.getUp dateSelectionList();
1620 CriteriaHelper.pollUiThread(new Criteria() {
1621 @Override
1622 public boolean isSatisfied() {
1623 return states.size() > index;
1624 }
1625 });
1626 Pair<Range, Range> selection = states.get(index);
1627 assertEquals(selectionStart, selection.first.start());
1628 assertEquals(selectionEnd, selection.first.end());
1629 assertEquals(compositionStart, selection.second.start());
1630 assertEquals(compositionEnd, selection.second.end());
1631 }
1632
1633 private void resetUpdateSelectionList() {
1634 mInputMethodManagerWrapper.getUpdateSelectionList().clear();
1635 }
1636
1637 private void assertClipboardContents(final Activity activity, final String e xpectedContents) {
1638 CriteriaHelper.pollUiThread(new Criteria() {
1639 @Override
1640 public boolean isSatisfied() {
1641 ClipboardManager clipboardManager =
1642 (ClipboardManager) activity.getSystemService(Context.CLI PBOARD_SERVICE);
1643 ClipData clip = clipboardManager.getPrimaryClip();
1644 return clip != null && clip.getItemCount() == 1
1645 && TextUtils.equals(clip.getItemAt(0).getText(), expecte dContents);
1646 }
1647 });
1648 }
1649
1650 private ImeAdapter getImeAdapter() {
1651 return mContentViewCore.getImeAdapterForTest();
1652 }
1653
1654 private ChromiumBaseInputConnection getInputConnection() {
1655 try {
1656 return ThreadUtils.runOnUiThreadBlocking(new Callable<ChromiumBaseIn putConnection>() {
1657 @Override
1658 public ChromiumBaseInputConnection call() {
1659 return mContentViewCore.getImeAdapterForTest().getInputConne ctionForTest();
1660 }
1661 });
1662 } catch (ExecutionException e) {
1663 e.printStackTrace();
1664 fail();
1665 return null;
1666 }
1667 }
1668
1669 private void restartInput() {
1670 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1671 @Override
1672 public void run() {
1673 mImeAdapter.restartInput();
1674 }
1675 });
1676 }
1677
1678 // After calling this method, we should call assertClipboardContents() to wa it for the clipboard
1679 // to get updated. See cubug.com/621046
1680 private void copy() {
1681 final WebContents webContents = mWebContents;
1682 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1683 @Override
1684 public void run() {
1685 webContents.copy();
1686 }
1687 });
1688 }
1689
1690 private void cut() {
1691 final WebContents webContents = mWebContents;
1692 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1693 @Override
1694 public void run() {
1695 webContents.cut();
1696 }
1697 });
1698 }
1699
1700 private void setClip(final CharSequence text) {
1701 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1702 @Override
1703 public void run() {
1704 final ClipboardManager clipboardManager =
1705 (ClipboardManager) getActivity().getSystemService(
1706 Context.CLIPBOARD_SERVICE);
1707 clipboardManager.setPrimaryClip(ClipData.newPlainText(null, text ));
1708 }
1709 });
1710 }
1711
1712 private void paste() {
1713 final WebContents webContents = mWebContents;
1714 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1715 @Override
1716 public void run() {
1717 webContents.paste();
1718 }
1719 });
1720 }
1721
1722 private void selectAll() {
1723 final WebContents webContents = mWebContents;
1724 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1725 @Override
1726 public void run() {
1727 webContents.selectAll();
1728 }
1729 });
1730 }
1731
1732 private void collapseSelection() {
1733 final WebContents webContents = mWebContents;
1734 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1735 @Override
1736 public void run() {
1737 webContents.collapseSelection();
1738 }
1739 });
1740 }
1741
1742 /**
1743 * Run the {@Callable} on IME thread (or UI thread if not applicable).
1744 * @param c The callable
1745 * @return The result from running the callable.
1746 */
1747 protected <T> T runBlockingOnImeThread(Callable<T> c) throws Exception {
1748 return ImeTestUtils.runBlockingOnHandler(mConnectionFactory.getHandler() , c);
1749 }
1750
1751 private boolean beginBatchEdit() throws Exception {
1752 final ChromiumBaseInputConnection connection = mConnection;
1753 return runBlockingOnImeThread(new Callable<Boolean>() {
1754 @Override
1755 public Boolean call() {
1756 return connection.beginBatchEdit();
1757 }
1758 });
1759 }
1760
1761 private boolean endBatchEdit() throws Exception {
1762 final ChromiumBaseInputConnection connection = mConnection;
1763 return runBlockingOnImeThread(new Callable<Boolean>() {
1764 @Override
1765 public Boolean call() {
1766 return connection.endBatchEdit();
1767 }
1768 });
1769 }
1770
1771 private boolean commitText(final CharSequence text, final int newCursorPosit ion)
1772 throws Exception {
1773 final ChromiumBaseInputConnection connection = mConnection;
1774 return runBlockingOnImeThread(new Callable<Boolean>() {
1775 @Override
1776 public Boolean call() {
1777 return connection.commitText(text, newCursorPosition);
1778 }
1779 });
1780 }
1781
1782 private boolean setSelection(final int start, final int end) throws Exceptio n {
1783 final ChromiumBaseInputConnection connection = mConnection;
1784 return runBlockingOnImeThread(new Callable<Boolean>() {
1785 @Override
1786 public Boolean call() {
1787 return connection.setSelection(start, end);
1788 }
1789 });
1790 }
1791
1792 private boolean setComposingRegion(final int start, final int end) throws Ex ception {
1793 final ChromiumBaseInputConnection connection = mConnection;
1794 return runBlockingOnImeThread(new Callable<Boolean>() {
1795 @Override
1796 public Boolean call() {
1797 return connection.setComposingRegion(start, end);
1798 }
1799 });
1800 }
1801
1802 protected boolean setComposingText(final CharSequence text, final int newCur sorPosition)
1803 throws Exception {
1804 final ChromiumBaseInputConnection connection = mConnection;
1805 return runBlockingOnImeThread(new Callable<Boolean>() {
1806 @Override
1807 public Boolean call() {
1808 return connection.setComposingText(text, newCursorPosition);
1809 }
1810 });
1811 }
1812
1813 private boolean finishComposingText() throws Exception {
1814 final ChromiumBaseInputConnection connection = mConnection;
1815 return runBlockingOnImeThread(new Callable<Boolean>() {
1816 @Override
1817 public Boolean call() {
1818 return connection.finishComposingText();
1819 }
1820 });
1821 }
1822
1823 private boolean deleteSurroundingText(final int before, final int after) thr ows Exception {
1824 final ChromiumBaseInputConnection connection = mConnection;
1825 return runBlockingOnImeThread(new Callable<Boolean>() {
1826 @Override
1827 public Boolean call() {
1828 return connection.deleteSurroundingText(before, after);
1829 }
1830 });
1831 }
1832
1833 // Note that deleteSurroundingTextInCodePoints() was introduced in Android N (Api level 24), but
1834 // the Android repository used in Chrome is behind that (level 23). So this function can't be
1835 // called by keyboard apps currently.
1836 @TargetApi(24)
1837 private boolean deleteSurroundingTextInCodePoints(final int before, final in t after)
1838 throws Exception {
1839 final ThreadedInputConnection connection = (ThreadedInputConnection) mCo nnection;
1840 return runBlockingOnImeThread(new Callable<Boolean>() {
1841 @Override
1842 public Boolean call() {
1843 return connection.deleteSurroundingTextInCodePoints(before, afte r);
1844 }
1845 });
1846 }
1847
1848 private CharSequence getTextBeforeCursor(final int length, final int flags) throws Exception {
1849 final ChromiumBaseInputConnection connection = mConnection;
1850 return runBlockingOnImeThread(new Callable<CharSequence>() {
1851 @Override
1852 public CharSequence call() {
1853 return connection.getTextBeforeCursor(length, flags);
1854 }
1855 });
1856 }
1857
1858 private CharSequence getSelectedText(final int flags) throws Exception {
1859 final ChromiumBaseInputConnection connection = mConnection;
1860 return runBlockingOnImeThread(new Callable<CharSequence>() {
1861 @Override
1862 public CharSequence call() {
1863 return connection.getSelectedText(flags);
1864 }
1865 });
1866 }
1867
1868 private CharSequence getTextAfterCursor(final int length, final int flags) t hrows Exception {
1869 final ChromiumBaseInputConnection connection = mConnection;
1870 return runBlockingOnImeThread(new Callable<CharSequence>() {
1871 @Override
1872 public CharSequence call() {
1873 return connection.getTextAfterCursor(length, flags);
1874 }
1875 });
1876 }
1877
1878 private int getCursorCapsMode(final int reqModes) throws Throwable {
1879 final ChromiumBaseInputConnection connection = mConnection;
1880 return runBlockingOnImeThread(new Callable<Integer>() {
1881 @Override
1882 public Integer call() {
1883 return connection.getCursorCapsMode(reqModes);
1884 }
1885 });
1886 }
1887
1888 private void dispatchKeyEvent(final KeyEvent event) {
1889 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
1890 @Override
1891 public void run() {
1892 mImeAdapter.dispatchKeyEvent(event);
1893 }
1894 });
1895 }
1896
1897 /**
1898 * Focus element, wait for a single state update, reset state update list.
1899 * @param id ID of the element to focus.
1900 */
1901 private void focusElementAndWaitForStateUpdate(String id)
1902 throws InterruptedException, TimeoutException {
1903 resetUpdateSelectionList();
1904 focusElement(id);
1905 waitAndVerifyUpdateSelection(0, 0, 0, -1, -1);
1906 resetUpdateSelectionList();
1907 }
1908
1909 private void focusElement(final String id) throws InterruptedException, Time outException {
1910 focusElement(id, true);
1911 }
1912
1913 private void focusElement(final String id, boolean shouldShowKeyboard)
1914 throws InterruptedException, TimeoutException {
1915 DOMUtils.focusNode(mWebContents, id);
1916 assertWaitForKeyboardStatus(shouldShowKeyboard);
1917 CriteriaHelper.pollInstrumentationThread(Criteria.equals(id, new Callabl e<String>() {
1918 @Override
1919 public String call() throws Exception {
1920 return DOMUtils.getFocusedNode(mWebContents);
1921 }
1922 }));
1923 // When we focus another element, the connection may be recreated.
1924 mConnection = getInputConnection();
1925 }
1926
1927 private static class TestInputConnectionFactory implements ChromiumBaseInput Connection.Factory {
1928 private final ChromiumBaseInputConnection.Factory mFactory;
1929
1930 private final List<Integer> mTextInputTypeList = new ArrayList<>();
1931 private EditorInfo mOutAttrs;
1932
1933 public TestInputConnectionFactory(ChromiumBaseInputConnection.Factory fa ctory) {
1934 mFactory = factory;
1935 }
1936
1937 @Override
1938 public ChromiumBaseInputConnection initializeAndGet(View view, ImeAdapte r imeAdapter,
1939 int inputType, int inputFlags, int inputMode, int selectionStart , int selectionEnd,
1940 EditorInfo outAttrs) {
1941 mTextInputTypeList.add(inputType);
1942 mOutAttrs = outAttrs;
1943 return mFactory.initializeAndGet(view, imeAdapter, inputType, inputM ode, inputFlags,
1944 selectionStart, selectionEnd, outAttrs);
1945 }
1946
1947 @Override
1948 public Handler getHandler() {
1949 return mFactory.getHandler();
1950 }
1951
1952 public Integer[] getTextInputTypeHistory() {
1953 Integer[] result = new Integer[mTextInputTypeList.size()];
1954 mTextInputTypeList.toArray(result);
1955 return result;
1956 }
1957
1958 public void clearTextInputTypeHistory() {
1959 mTextInputTypeList.clear();
1960 }
1961
1962 public EditorInfo getOutAttrs() {
1963 return mOutAttrs;
1964 }
1965
1966 @Override
1967 public void onWindowFocusChanged(boolean gainFocus) {
1968 mFactory.onWindowFocusChanged(gainFocus);
1969 }
1970
1971 @Override
1972 public void onViewFocusChanged(boolean gainFocus) {
1973 mFactory.onViewFocusChanged(gainFocus);
1974 }
1975
1976 @Override
1977 public void onViewAttachedToWindow() {
1978 mFactory.onViewAttachedToWindow();
1979 }
1980
1981 @Override
1982 public void onViewDetachedFromWindow() {
1983 mFactory.onViewDetachedFromWindow();
1984 }
1985 }
1986 } 1498 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698