| Index: chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e9a413312d7c838faf8752705656e8315314c7af
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
|
| @@ -0,0 +1,442 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.omnibox;
|
| +
|
| +import android.content.Intent;
|
| +import android.test.suitebuilder.annotation.SmallTest;
|
| +import android.text.Editable;
|
| +import android.view.inputmethod.BaseInputConnection;
|
| +
|
| +import com.google.android.apps.chrome.R;
|
| +
|
| +import org.chromium.base.ThreadUtils;
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.chromium.chrome.browser.ChromeActivity;
|
| +import org.chromium.chrome.test.ChromeActivityTestCaseBase;
|
| +import org.chromium.chrome.test.util.OmniboxTestUtils;
|
| +import org.chromium.chrome.test.util.OmniboxTestUtils.StubAutocompleteController;
|
| +
|
| +import java.util.concurrent.Callable;
|
| +import java.util.concurrent.ExecutionException;
|
| +import java.util.concurrent.atomic.AtomicBoolean;
|
| +import java.util.concurrent.atomic.AtomicReference;
|
| +
|
| +/**
|
| + * Tests for the URL bar UI component.
|
| + */
|
| +public class UrlBarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
|
| +
|
| + public UrlBarTest() {
|
| + super(ChromeActivity.class);
|
| + }
|
| +
|
| + private UrlBar getUrlBar() {
|
| + return (UrlBar) getActivity().findViewById(R.id.url_bar);
|
| + }
|
| +
|
| + private void stubLocationBarAutocomplete() {
|
| + ThreadUtils.runOnUiThread(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + LocationBarLayout locationBar =
|
| + (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
|
| + locationBar.setAutocompleteController(new StubAutocompleteController());
|
| + }
|
| + });
|
| + }
|
| +
|
| + private static class AutocompleteState {
|
| + public final boolean hasAutocomplete;
|
| + public final String textWithoutAutocomplete;
|
| + public final String textWithAutocomplete;
|
| +
|
| + public AutocompleteState(
|
| + boolean hasAutocomplete, String textWithoutAutocomplete,
|
| + String textWithAutocomplete) {
|
| + this.hasAutocomplete = hasAutocomplete;
|
| + this.textWithoutAutocomplete = textWithoutAutocomplete;
|
| + this.textWithAutocomplete = textWithAutocomplete;
|
| + }
|
| + }
|
| +
|
| + private Editable getUrlBarText(final UrlBar urlBar) throws ExecutionException {
|
| + return ThreadUtils.runOnUiThreadBlocking(new Callable<Editable>() {
|
| + @Override
|
| + public Editable call() throws Exception {
|
| + return urlBar.getText();
|
| + }
|
| + });
|
| + }
|
| +
|
| + private AutocompleteState getAutocompleteState(
|
| + final UrlBar urlBar, final Runnable action) {
|
| + final AtomicBoolean hasAutocomplete = new AtomicBoolean();
|
| + final AtomicReference<String> textWithoutAutocomplete = new AtomicReference<String>();
|
| + final AtomicReference<String> textWithAutocomplete = new AtomicReference<String>();
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + if (action != null) action.run();
|
| + textWithoutAutocomplete.set(urlBar.getTextWithoutAutocomplete());
|
| + textWithAutocomplete.set(urlBar.getQueryText());
|
| + hasAutocomplete.set(urlBar.hasAutocomplete());
|
| + }
|
| + });
|
| +
|
| + return new AutocompleteState(
|
| + hasAutocomplete.get(), textWithoutAutocomplete.get(), textWithAutocomplete.get());
|
| + }
|
| +
|
| + private void setTextAndVerifyNoAutocomplete(final UrlBar urlBar, final String text) {
|
| + AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.setText(text);
|
| + }
|
| + });
|
| +
|
| + assertEquals(text, state.textWithoutAutocomplete);
|
| + assertEquals(text, state.textWithAutocomplete);
|
| + assertFalse(state.hasAutocomplete);
|
| + }
|
| +
|
| + private void setAutocomplete(final UrlBar urlBar,
|
| + final String userText, final String autocompleteText) {
|
| + AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.setAutocompleteText(userText, autocompleteText);
|
| + }
|
| + });
|
| +
|
| + assertEquals(userText, state.textWithoutAutocomplete);
|
| + assertEquals(userText + autocompleteText, state.textWithAutocomplete);
|
| + assertTrue(state.hasAutocomplete);
|
| + }
|
| +
|
| + private AutocompleteState setSelection(
|
| + final UrlBar urlBar, final int selectionStart, final int selectionEnd) {
|
| + return getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.setSelection(selectionStart, selectionEnd);
|
| + }
|
| + });
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testRefocusing() throws InterruptedException {
|
| + startMainActivityOnBlankPage();
|
| + UrlBar urlBar = getUrlBar();
|
| + assertFalse(OmniboxTestUtils.doesUrlBarHaveFocus(urlBar));
|
| + OmniboxTestUtils.checkUrlBarRefocus(urlBar, 5);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testAutocompleteUpdatedOnSetText() throws InterruptedException {
|
| + startMainActivityOnBlankPage();
|
| + stubLocationBarAutocomplete();
|
| + final UrlBar urlBar = getUrlBar();
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| +
|
| + // Verify that setting a new string will clear the autocomplete.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + setTextAndVerifyNoAutocomplete(urlBar, "new string");
|
| +
|
| + // Replace part of the non-autocomplete text and see that the autocomplete is cleared.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.setText(urlBar.getText().replace(1, 2, "a"));
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("tasting is fun", state.textWithoutAutocomplete);
|
| + assertEquals("tasting is fun", state.textWithAutocomplete);
|
| +
|
| + // Replace part of the autocomplete text and see that the autocomplete is cleared.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.setText(urlBar.getText().replace(8, 10, "no"));
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing no fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing no fun", state.textWithAutocomplete);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testAutocompleteUpdatedOnSelection() throws InterruptedException {
|
| + startMainActivityOnBlankPage();
|
| + stubLocationBarAutocomplete();
|
| + final UrlBar urlBar = getUrlBar();
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| +
|
| + // Verify that setting a selection before the autocomplete clears it.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + AutocompleteState state = setSelection(urlBar, 1, 1);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("test", state.textWithoutAutocomplete);
|
| + assertEquals("test", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection range before the autocomplete clears it.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 0, 4);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("test", state.textWithoutAutocomplete);
|
| + assertEquals("test", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection at the start of the autocomplete clears it.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 4, 4);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("test", state.textWithoutAutocomplete);
|
| + assertEquals("test", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection range that covers a portion of the non-autocomplete
|
| + // and autocomplete text does not delete the autocomplete text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 2, 5);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing is fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection range that over the entire string does not delete
|
| + // the autocomplete text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 0, 14);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing is fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection at the end of the text does not delete the autocomplete
|
| + // text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 14, 14);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing is fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection in the middle of the autocomplete text does not delete
|
| + // the autocomplete text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 9, 9);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing is fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting a selection range in the middle of the autocomplete text does not
|
| + // delete the autocomplete text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 8, 11);
|
| + assertFalse(state.hasAutocomplete);
|
| + assertEquals("testing is fun", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| +
|
| + // Verify that setting the same selection does not clear the autocomplete text.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + state = setSelection(urlBar, 4, 14);
|
| + assertTrue(state.hasAutocomplete);
|
| + assertEquals("test", state.textWithoutAutocomplete);
|
| + assertEquals("testing is fun", state.textWithAutocomplete);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testAutocompleteUpdatedOnDefocus() throws InterruptedException {
|
| + startMainActivityOnBlankPage();
|
| + stubLocationBarAutocomplete();
|
| + final UrlBar urlBar = getUrlBar();
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| +
|
| + // Verify that defocusing the UrlBar clears the autocomplete.
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, false);
|
| + AutocompleteState state = getAutocompleteState(urlBar, null);
|
| + assertFalse(state.hasAutocomplete);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testAutocompleteClearedOnComposition()
|
| + throws InterruptedException, ExecutionException {
|
| + startMainActivityOnBlankPage();
|
| + stubLocationBarAutocomplete();
|
| + final UrlBar urlBar = getUrlBar();
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true);
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "test");
|
| + setAutocomplete(urlBar, "test", "ing is fun");
|
| +
|
| + assertNotNull(urlBar.mInputConnection);
|
| + AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingText("ing compose", 4);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + Editable urlText = getUrlBarText(urlBar);
|
| + assertEquals("testing compose", urlText.toString());
|
| + // TODO(tedchoc): Investigate why this fails on x86.
|
| + //assertEquals(4, BaseInputConnection.getComposingSpanStart(urlText));
|
| + //assertEquals(15, BaseInputConnection.getComposingSpanEnd(urlText));
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature("Omnibox")
|
| + public void testDelayedCompositionCorrectedWithAutocomplete()
|
| + throws InterruptedException, ExecutionException {
|
| + startMainActivityOnBlankPage();
|
| + stubLocationBarAutocomplete();
|
| +
|
| + final UrlBar urlBar = getUrlBar();
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true);
|
| +
|
| + assertNotNull(urlBar.mInputConnection);
|
| +
|
| + // Test with a single autocomplete
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "chrome://f");
|
| + setAutocomplete(urlBar, "chrome://f", "lags");
|
| +
|
| + AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingRegion(13, 14);
|
| + urlBar.mInputConnection.setComposingText("f", 1);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + Editable urlText = getUrlBarText(urlBar);
|
| + assertEquals("chrome://f", urlText.toString());
|
| + assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
|
| + assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
|
| +
|
| + // Test with > 1 characters in composition.
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "chrome://fl");
|
| + setAutocomplete(urlBar, "chrome://fl", "ags");
|
| +
|
| + state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingRegion(12, 14);
|
| + urlBar.mInputConnection.setComposingText("fl", 1);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + urlText = getUrlBarText(urlBar);
|
| + assertEquals("chrome://fl", urlText.toString());
|
| + assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
|
| + assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
|
| +
|
| + // Test with non-matching composition. Should just append to the URL text.
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "chrome://f");
|
| + setAutocomplete(urlBar, "chrome://f", "lags");
|
| +
|
| + state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingRegion(13, 14);
|
| + urlBar.mInputConnection.setComposingText("g", 1);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + urlText = getUrlBarText(urlBar);
|
| + assertEquals("chrome://fg", urlText.toString());
|
| + assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
|
| + assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
|
| +
|
| + // Test with composition text that matches the entire text w/o autocomplete.
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "chrome://f");
|
| + setAutocomplete(urlBar, "chrome://f", "lags");
|
| +
|
| + state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingRegion(13, 14);
|
| + urlBar.mInputConnection.setComposingText("chrome://f", 1);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + urlText = getUrlBarText(urlBar);
|
| + assertEquals("chrome://f", urlText.toString());
|
| + assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 0);
|
| + assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
|
| +
|
| + // Test with composition text longer than the URL text. Shouldn't crash and should
|
| + // just append text.
|
| +
|
| + setTextAndVerifyNoAutocomplete(urlBar, "chrome://f");
|
| + setAutocomplete(urlBar, "chrome://f", "lags");
|
| +
|
| + state = getAutocompleteState(urlBar, new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + urlBar.mInputConnection.setComposingRegion(13, 14);
|
| + urlBar.mInputConnection.setComposingText("blahblahblah", 1);
|
| + }
|
| + });
|
| + assertFalse(state.hasAutocomplete);
|
| +
|
| + urlText = getUrlBarText(urlBar);
|
| + assertEquals("chrome://fblahblahblah", urlText.toString());
|
| + assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
|
| + assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 22);
|
| + }
|
| +
|
| + /**
|
| + * Test to verify the omnibox can take focus during startup before native libraries have
|
| + * loaded.
|
| + */
|
| + @SmallTest
|
| + @Feature({"Omnibox"})
|
| + public void testFocusingOnStartup() throws InterruptedException {
|
| + Intent intent = new Intent(Intent.ACTION_MAIN);
|
| + intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
| + prepareUrlIntent(intent, "about:blank");
|
| + startActivityCompletely(intent);
|
| +
|
| + UrlBar urlBar = getUrlBar();
|
| + assertNotNull(urlBar);
|
| + OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
|
| + assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true));
|
| + }
|
| +
|
| + @Override
|
| + public void startMainActivity() throws InterruptedException {
|
| + // Each test will start the activity.
|
| + }
|
| +}
|
|
|