Index: content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java |
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java |
index 5276a36b54d305ec8d10d4514e8f973bed56ee94..2bde02816514a1250d26e1219e7ecc1de1287022 100644 |
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java |
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java |
@@ -18,11 +18,11 @@ import android.view.inputmethod.EditorInfo; |
import org.chromium.base.ThreadUtils; |
import org.chromium.base.test.util.Feature; |
-import org.chromium.base.test.util.UrlUtils; |
import org.chromium.content.browser.ContentViewCore; |
import org.chromium.content.browser.test.util.Criteria; |
import org.chromium.content.browser.test.util.CriteriaHelper; |
import org.chromium.content.browser.test.util.DOMUtils; |
+import org.chromium.content.browser.test.util.JavaScriptUtils; |
import org.chromium.content.browser.test.util.TestCallbackHelperContainer; |
import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper; |
import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper.Range; |
@@ -41,24 +41,12 @@ import java.util.concurrent.TimeoutException; |
* Integration tests for text input using cases based on fixed regressions. |
*/ |
public class ImeTest extends ContentShellTestBase { |
- private static final String DATA_URL = UrlUtils.encodeHtmlDataUri( |
- "<html><head><meta name=\"viewport\"" |
- + "content=\"width=device-width\" /></head>" |
- + "<body><form action=\"about:blank\">" |
- + "<input id=\"input_text\" type=\"text\" /><br/></form><form>" |
- + "<br/><input id=\"input_radio\" type=\"radio\" style=\"width:50px;height:50px\" />" |
- + "<br/><textarea id=\"textarea\" rows=\"4\" cols=\"20\"></textarea>" |
- + "<br/><textarea id=\"textarea2\" rows=\"4\" cols=\"20\" autocomplete=\"off\">" |
- + "</textarea>" |
- + "<br/><input id=\"input_number1\" type=\"number\" /><br/>" |
- + "<br/><input id=\"input_number2\" type=\"number\" /><br/>" |
- + "<br/><p><span id=\"plain_text\">This is Plain Text One</span></p>" |
- + "</form></body></html>"); |
- |
private TestAdapterInputConnection mConnection; |
private TestAdapterInputConnectionFactory mConnectionFactory; |
private ImeAdapter mImeAdapter; |
+ private static final String INPUT_FORM_HTML = "content/test/data/android/ime/input_forms.html"; |
+ |
private ContentViewCore mContentViewCore; |
private WebContents mWebContents; |
private TestCallbackHelperContainer mCallbackContainer; |
@@ -67,9 +55,7 @@ public class ImeTest extends ContentShellTestBase { |
@Override |
public void setUp() throws Exception { |
super.setUp(); |
- |
- launchContentShellWithUrl(DATA_URL); |
- waitForActiveShellToBeDoneLoading(); |
+ startActivityWithTestUrl(INPUT_FORM_HTML); |
mContentViewCore = getContentViewCore(); |
mWebContents = getWebContents(); |
@@ -150,10 +136,10 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testImeCopy() throws Exception { |
commitText("hello", 1); |
- waitAndVerifyStates(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStates(1, "hello", 5, 5, -1, -1); |
setSelection(2, 5); |
- waitAndVerifyStates(1, "hello", 2, 5, -1, -1); |
+ waitAndVerifyStates(2, "hello", 2, 5, -1, -1); |
copy(); |
assertClipboardContents(getActivity(), "llo"); |
@@ -163,7 +149,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testEnterTextAndRefocus() throws Exception { |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
DOMUtils.clickNode(this, mContentViewCore, "input_radio"); |
assertWaitForKeyboardStatus(false); |
@@ -253,7 +239,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testKeyboardNotDismissedAfterCopySelection() throws Exception { |
commitText("Sample Text", 1); |
- waitAndVerifyStatesAndCalls(0, "Sample Text", 11, 11, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "Sample Text", 11, 11, -1, -1); |
// This will select 'Text' part. |
DOMUtils.clickNode(this, mContentViewCore, "input_text"); |
@@ -274,7 +260,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testImeNotDismissedAfterCutSelection() throws Exception { |
commitText("Sample Text", 1); |
- waitAndVerifyStatesAndCalls(0, "Sample Text", 11, 11, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "Sample Text", 11, 11, -1, -1); |
DOMUtils.longPressNode(this, mContentViewCore, "input_text"); |
assertWaitForSelectActionBarStatus(true); |
assertWaitForKeyboardStatus(true); |
@@ -376,6 +362,17 @@ public class ImeTest extends ContentShellTestBase { |
}); |
} |
+ private void reloadPage() { |
+ // Reload the page, then focus will be lost and keyboard should be hidden. |
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ final String currentUrl = getContentViewCore().getWebContents().getUrl(); |
+ getActivity().getActiveShell().loadUrl(currentUrl); |
+ } |
+ }); |
+ } |
+ |
@SmallTest |
@Feature({"TextInput"}) |
public void testPhysicalKeyboard_AttachDetach() throws Exception { |
@@ -389,13 +386,8 @@ public class ImeTest extends ContentShellTestBase { |
// Now we really show soft keyboard. We also call restartInput when configuration changes. |
waitForKeyboardStates(2, 0, 2, new Integer[] {TextInputType.TEXT, TextInputType.TEXT}); |
- // Reload the page, then focus will be lost and keyboard should be hidden. |
- getInstrumentation().runOnMainSync(new Runnable() { |
- @Override |
- public void run() { |
- getActivity().getActiveShell().loadUrl(DATA_URL); |
- } |
- }); |
+ reloadPage(); |
+ |
// Depending on the timing, hideSoftInput and restartInput call counts may vary here |
// because render widget gets restarted. But the end result should be the same. |
assertWaitForKeyboardStatus(false); |
@@ -420,6 +412,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testSelectActionBarClearedOnTappingInput() throws Exception { |
commitText("Sample Text", 1); |
+ waitAndVerifyStatesAndCalls(1, "Sample Text", 11, 11, -1, -1); |
DOMUtils.longPressNode(this, mContentViewCore, "input_text"); |
assertWaitForKeyboardStatus(true); |
assertWaitForSelectActionBarStatus(true); |
@@ -431,6 +424,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testSelectActionBarClearedOnTappingOutsideInput() throws Exception { |
commitText("Sample Text", 1); |
+ waitAndVerifyStatesAndCalls(1, "Sample Text", 11, 11, -1, -1); |
DOMUtils.longPressNode(this, mContentViewCore, "input_text"); |
assertWaitForKeyboardStatus(true); |
assertWaitForSelectActionBarStatus(true); |
@@ -468,13 +462,13 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testImeCut() throws Exception { |
commitText("snarful", 1); |
- waitAndVerifyStatesAndCalls(0, "snarful", 7, 7, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "snarful", 7, 7, -1, -1); |
setSelection(1, 5); |
- waitAndVerifyStatesAndCalls(1, "snarful", 1, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(2, "snarful", 1, 5, -1, -1); |
cut(); |
- waitAndVerifyStatesAndCalls(2, "sul", 1, 1, -1, -1); |
+ waitAndVerifyStatesAndCalls(3, "sul", 1, 1, -1, -1); |
assertClipboardContents(getActivity(), "narf"); |
} |
@@ -511,10 +505,10 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testImeSelectAndUnSelectAll() throws Exception { |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
selectAll(); |
- waitAndVerifyStatesAndCalls(1, "hello", 0, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(2, "hello", 0, 5, -1, -1); |
unselect(); |
@@ -539,22 +533,22 @@ public class ImeTest extends ContentShellTestBase { |
focusElementAndWaitForStateUpdate("textarea"); |
commitText("hllo", 1); |
- waitAndVerifyStatesAndCalls(0, "hllo", 4, 4, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hllo", 4, 4, -1, -1); |
commitText(" ", 1); |
- waitAndVerifyStatesAndCalls(1, "hllo ", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(3, "hllo ", 5, 5, -1, -1); |
setSelection(1, 1); |
- waitAndVerifyStatesAndCalls(2, "hllo ", 1, 1, -1, -1); |
+ waitAndVerifyStatesAndCalls(4, "hllo ", 1, 1, -1, -1); |
setComposingRegion(0, 4); |
- waitAndVerifyStatesAndCalls(3, "hllo ", 1, 1, 0, 4); |
+ waitAndVerifyStatesAndCalls(5, "hllo ", 1, 1, 0, 4); |
finishComposingText(); |
- waitAndVerifyStatesAndCalls(4, "hllo ", 1, 1, -1, -1); |
+ waitAndVerifyStatesAndCalls(6, "hllo ", 1, 1, -1, -1); |
commitText("\n", 1); |
- waitAndVerifyStatesAndCalls(5, "h\nllo ", 2, 2, -1, -1); |
+ waitAndVerifyStatesAndCalls(7, "h\nllo ", 2, 2, -1, -1); |
} |
/* |
@@ -653,19 +647,19 @@ public class ImeTest extends ContentShellTestBase { |
final String smiley = "\uD83D\uDE0A"; |
commitText(smiley, 1); |
- waitAndVerifyStatesAndCalls(0, smiley, 2, 2, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, smiley, 2, 2, -1, -1); |
// DEL, sent via dispatchKeyEvent like it is in Android WebView or a physical keyboard. |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); |
- waitAndVerifyStatesAndCalls(1, "", 0, 0, -1, -1); |
+ waitAndVerifyStatesAndCalls(2, "", 0, 0, -1, -1); |
// Make sure that we accept further typing after deleting the smiley. |
setComposingText("s", 1); |
- waitAndVerifyStatesAndCalls(2, "s", 1, 1, 0, 1); |
+ waitAndVerifyStatesAndCalls(3, "s", 1, 1, 0, 1); |
setComposingText("sm", 1); |
- waitAndVerifyStatesAndCalls(3, "sm", 2, 2, 0, 2); |
+ waitAndVerifyStatesAndCalls(4, "sm", 2, 2, 0, 2); |
} |
@SmallTest |
@@ -778,7 +772,7 @@ public class ImeTest extends ContentShellTestBase { |
assertEquals("hô", mConnection.getTextBeforeCursor(9, 0)); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_O)); |
assertEquals("hô", mConnection.getTextBeforeCursor(9, 0)); |
- waitAndVerifyStatesAndCalls(2, "hô", 2, 2, -1, -1); |
+ waitAndVerifyStatesAndCalls(3, "hô", 2, 2, -1, -1); |
// ALT-i |
dispatchKeyEvent(new KeyEvent( |
@@ -787,7 +781,7 @@ public class ImeTest extends ContentShellTestBase { |
dispatchKeyEvent(new KeyEvent( |
0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_ALT_ON)); |
assertEquals("hôˆ", mConnection.getTextBeforeCursor(9, 0)); |
- waitAndVerifyStatesAndCalls(3, "hôˆ", 3, 3, 2, 3); |
+ waitAndVerifyStatesAndCalls(4, "hôˆ", 3, 3, 2, 3); |
// ALT-i again should have no effect |
dispatchKeyEvent(new KeyEvent( |
@@ -804,8 +798,8 @@ public class ImeTest extends ContentShellTestBase { |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_B)); |
assertEquals("hôˆb", mConnection.getTextBeforeCursor(9, 0)); |
// A transitional state due to finishComposingText. |
- waitAndVerifyStates(4, "hôˆ", 3, 3, -1, -1); |
- waitAndVerifyStatesAndCalls(5, "hôˆb", 4, 4, -1, -1); |
+ waitAndVerifyStates(5, "hôˆ", 3, 3, -1, -1); |
+ waitAndVerifyStatesAndCalls(6, "hôˆb", 4, 4, -1, -1); |
// ALT-i |
dispatchKeyEvent(new KeyEvent( |
@@ -814,7 +808,7 @@ public class ImeTest extends ContentShellTestBase { |
dispatchKeyEvent(new KeyEvent( |
0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_I, 0, KeyEvent.META_ALT_ON)); |
assertEquals("hôˆbˆ", mConnection.getTextBeforeCursor(9, 0)); |
- waitAndVerifyStatesAndCalls(6, "hôˆbˆ", 5, 5, 4, 5); |
+ waitAndVerifyStatesAndCalls(8, "hôˆbˆ", 5, 5, 4, 5); |
// Backspace |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); |
@@ -823,8 +817,8 @@ public class ImeTest extends ContentShellTestBase { |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); |
assertEquals("hôˆb", mConnection.getTextBeforeCursor(9, 0)); |
// A transitional state due to finishComposingText in deleteSurroundingTextImpl. |
- waitAndVerifyStates(7, "hôˆbˆ", 5, 5, -1, -1); |
- waitAndVerifyStatesAndCalls(8, "hôˆb", 4, 4, -1, -1); |
+ waitAndVerifyStates(9, "hôˆbˆ", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(10, "hôˆb", 4, 4, -1, -1); |
} |
@SmallTest |
@@ -844,17 +838,17 @@ public class ImeTest extends ContentShellTestBase { |
focusElementAndWaitForStateUpdate("textarea"); |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER)); |
// TODO(aurimas): remove this workaround when crbug.com/278584 is fixed. |
// The second new line is not a user visible/editable one, it is a side-effect of Blink |
// using <br> internally. This only happens when \n is at the end. |
- waitAndVerifyStatesAndCalls(1, "hello\n\n", 6, 6, -1, -1); |
+ waitAndVerifyStatesAndCalls(2, "hello\n\n", 6, 6, -1, -1); |
commitText("world", 1); |
- waitAndVerifyStatesAndCalls(2, "hello\nworld", 11, 11, -1, -1); |
+ waitAndVerifyStatesAndCalls(4, "hello\nworld", 11, 11, -1, -1); |
} |
@SmallTest |
@@ -876,7 +870,7 @@ public class ImeTest extends ContentShellTestBase { |
waitAndVerifyStatesAndCalls(2, "hello\n\n", 6, 6, -1, -1); |
commitText("world", 1); |
- waitAndVerifyStatesAndCalls(3, "hello\nworld", 11, 11, -1, -1); |
+ waitAndVerifyStatesAndCalls(4, "hello\nworld", 11, 11, -1, -1); |
} |
@SmallTest |
@@ -896,7 +890,7 @@ public class ImeTest extends ContentShellTestBase { |
focusElementAndWaitForStateUpdate("textarea"); |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT)); |
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT)); |
@@ -924,13 +918,13 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testPastePopupShowAndHide() throws Throwable { |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
selectAll(); |
- waitAndVerifyStatesAndCalls(1, "hello", 0, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(2, "hello", 0, 5, -1, -1); |
cut(); |
- waitAndVerifyStatesAndCalls(2, "", 0, 0, -1, -1); |
+ waitAndVerifyStatesAndCalls(3, "", 0, 0, -1, -1); |
DOMUtils.longPressNode(this, mContentViewCore, "input_text"); |
CriteriaHelper.pollForUIThreadCriteria(new Criteria() { |
@@ -957,7 +951,7 @@ public class ImeTest extends ContentShellTestBase { |
@Feature({"TextInput"}) |
public void testSelectionClearedOnKeyEvent() throws Throwable { |
commitText("hello", 1); |
- waitAndVerifyStatesAndCalls(0, "hello", 5, 5, -1, -1); |
+ waitAndVerifyStatesAndCalls(1, "hello", 5, 5, -1, -1); |
DOMUtils.clickNode(this, mContentViewCore, "input_text"); |
assertWaitForKeyboardStatus(true); |
@@ -1050,6 +1044,21 @@ public class ImeTest extends ContentShellTestBase { |
waitAndVerifyStatesAndCalls(8, "aibefcd", 1, 1, -1, -1); |
} |
+ @MediumTest |
+ @Feature({"TextInput"}) |
+ public void testCommitTextTriggersCompositionEvents() throws Throwable { |
+ focusElementAndWaitForStateUpdate("contenteditable0"); |
+ commitText("a", 1); |
+ assertEquals("a", getTextBeforeCursor(10, 0)); |
+ waitAndVerifyStatesAndCalls(1, "a", 1, 1, -1, -1); |
+ |
+ final String code = "getLogs()"; |
+ final String expectedLogs = "keydown(229),compositionstart(),compositionupdate(a)," |
+ + "keyup(229),compositionend(a),"; |
+ assertEquals('"' + expectedLogs + '"', JavaScriptUtils.executeJavaScriptAndWaitForResult( |
+ getContentViewCore().getWebContents(), code)); |
+ } |
+ |
private CharSequence getTextBeforeCursor(final int length, final int flags) |
throws ExecutionException { |
return ThreadUtils.runOnUiThreadBlocking(new Callable<CharSequence>() { |