Commit 5a6c5bf0 authored by changwan's avatar changwan Committed by Commit bot

Overhaul WebView IME test

There are some problems with existing WebView IME test.

First off, the example is misleading. Creating a selection range in
JavaScript is not straightforward and is not representative of what
WebView developers should be doing. Focusing on editor is a better use
case.

Also, it was flaky in some old device that we deprecated. As found in
crbug.com/621049, we actually need to wait for document focus before
we can focus on content-editable body.

The reason is that Android's view focus gets propagated to the renderer
process as input message while JavaScript execution gets propagated to
the renderer process as frame message, so JavaScript may be executed
before document gets focused, and focusing on content-editable body
is an invalid operation when document isn't yet focused. I suspect that
this is the reason why some OEM email client was using selection range
trick in the first place.

Finally, we were testing against real input method, which can be another
cause of flakiness, so it's fixed by a fake input method manager.

BUG=621049, 611928

Review-Url: https://codereview.chromium.org/2180853002
Cr-Commit-Position: refs/heads/master@{#408291}
parent bfff1719
...@@ -8,6 +8,7 @@ import android.content.Context; ...@@ -8,6 +8,7 @@ import android.content.Context;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.webkit.JavascriptInterface;
import android.widget.EditText; import android.widget.EditText;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
...@@ -15,21 +16,36 @@ import org.chromium.base.test.util.Feature; ...@@ -15,21 +16,36 @@ import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
/** /**
* Tests for IME (input method editor) on Android WebView. * Tests for IME (input method editor) on Android WebView.
*/ */
public class AwImeTest extends AwTestBase { public class AwImeTest extends AwTestBase {
private static class TestJavascriptInterface {
private final CallbackHelper mFocusCallbackHelper = new CallbackHelper();
@JavascriptInterface
public void onEditorFocused() {
mFocusCallbackHelper.notifyCalled();
}
public CallbackHelper getFocusCallbackHelper() {
return mFocusCallbackHelper;
}
}
private TestAwContentsClient mContentsClient; private TestAwContentsClient mContentsClient;
private AwTestContainerView mTestContainerView; private AwTestContainerView mTestContainerView;
private EditText mEditText; private EditText mEditText;
private final TestJavascriptInterface mTestJavascriptInterface = new TestJavascriptInterface();
private TestInputMethodManagerWrapper mInputMethodManagerWrapper;
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
mContentsClient = new TestAwContentsClient(); mContentsClient = new TestAwContentsClient();
ThreadUtils.runOnUiThreadBlocking(new Runnable() { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -38,13 +54,21 @@ public class AwImeTest extends AwTestBase { ...@@ -38,13 +54,21 @@ public class AwImeTest extends AwTestBase {
mEditText = new EditText(getActivity()); mEditText = new EditText(getActivity());
getActivity().addView(mEditText); getActivity().addView(mEditText);
getActivity().addView(mTestContainerView); getActivity().addView(mTestContainerView);
mTestContainerView.getAwContents().addJavascriptInterface(
mTestJavascriptInterface, "test");
// Let's not test against real input method.
mInputMethodManagerWrapper = new TestInputMethodManagerWrapper(
mTestContainerView.getContentViewCore());
mTestContainerView.getContentViewCore().getImeAdapterForTest()
.setInputMethodManagerWrapperForTest(mInputMethodManagerWrapper);
} }
}); });
}
final CallbackHelper loadHelper = mContentsClient.getOnPageFinishedHelper(); private void loadContentEditableBody() throws Exception {
final String mime = "text/html"; final String mime = "text/html";
final String htmlDocument = "<html><body contenteditable id='editor'></body></html>"; final String htmlDocument = "<html><body contenteditable id='editor'></body></html>";
final CallbackHelper loadHelper = mContentsClient.getOnPageFinishedHelper();
loadDataSync(mTestContainerView.getAwContents(), loadHelper, htmlDocument, mime, false); loadDataSync(mTestContainerView.getAwContents(), loadHelper, htmlDocument, mime, false);
} }
...@@ -70,19 +94,21 @@ public class AwImeTest extends AwTestBase { ...@@ -70,19 +94,21 @@ public class AwImeTest extends AwTestBase {
}); });
enableJavaScriptOnUiThread(mTestContainerView.getAwContents()); enableJavaScriptOnUiThread(mTestContainerView.getAwContents());
// This is the usual pattern for email client using webview: // View focus may not have been propagated to the renderer process yet. If document is not
// we want the cursor to be there even without tapping the editor. // yet focused, and focusing on an element is an invalid operation. See crbug.com/622151
// for details.
executeJavaScriptAndWaitForResult(mTestContainerView.getAwContents(), mContentsClient, executeJavaScriptAndWaitForResult(mTestContainerView.getAwContents(), mContentsClient,
"(function() {" "function onDocumentFocused() {\n"
+ "var sel = window.getSelection();" + " document.getElementById('editor').focus();\n"
+ "var range = document.createRange();" + " test.onEditorFocused();\n"
+ "var editor = document.getElementById('editor');" + "}\n"
+ "range.setStart(editor, 0);" + "(function() {\n"
+ "range.setEnd(editor, 0);" + "if (document.hasFocus()) {\n"
+ "range.collapse(false);" + " onDocumentFocused();"
+ "sel.removeAllRanges();" + "} else {\n"
+ "sel.addRange(range);" + " window.addEventListener('focus', onDocumentFocused);\n"
+ "})();"); + "}})();");
mTestJavascriptInterface.getFocusCallbackHelper().waitForCallback(0);
} }
private void waitForNonNullInputConnection() throws InterruptedException { private void waitForNonNullInputConnection() throws InterruptedException {
...@@ -96,10 +122,14 @@ public class AwImeTest extends AwTestBase { ...@@ -96,10 +122,14 @@ public class AwImeTest extends AwTestBase {
}); });
} }
/**
* Tests that moving from EditText to WebView keeps the keyboard showing.
*/
// https://crbug.com/569556 // https://crbug.com/569556
@SmallTest @SmallTest
@Feature({"AndroidWebView", "TextInput"}) @Feature({"AndroidWebView", "TextInput"})
public void testPressNextFromEditTextAndType() throws Throwable { public void testPressNextFromEditTextAndType() throws Throwable {
loadContentEditableBody();
focusOnEditTextAndShowKeyboard(); focusOnEditTextAndShowKeyboard();
focusOnWebViewAndEnableEditing(); focusOnWebViewAndEnableEditing();
waitForNonNullInputConnection(); waitForNonNullInputConnection();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment