| Index: chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ee77b9ebf2c095d235f180425996dad322748360
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
|
| @@ -0,0 +1,356 @@
|
| +// 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;
|
| +
|
| +import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_TABLET;
|
| +
|
| +import android.test.FlakyTest;
|
| +import android.test.suitebuilder.annotation.MediumTest;
|
| +
|
| +import com.google.android.apps.chrome.R;
|
| +
|
| +import org.chromium.base.ThreadUtils;
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.chromium.base.test.util.Restriction;
|
| +import org.chromium.base.test.util.UrlUtils;
|
| +import org.chromium.chrome.browser.tabmodel.TabModel;
|
| +import org.chromium.chrome.browser.tabmodel.TabModelUtils;
|
| +import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
|
| +import org.chromium.chrome.test.util.ChromeTabUtils;
|
| +import org.chromium.chrome.test.util.TestHttpServerClient;
|
| +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.UiUtils;
|
| +import org.chromium.net.test.util.TestWebServer;
|
| +
|
| +import java.net.URLEncoder;
|
| +import java.util.concurrent.Callable;
|
| +import java.util.concurrent.ExecutionException;
|
| +import java.util.concurrent.Semaphore;
|
| +import java.util.concurrent.TimeUnit;
|
| +import java.util.concurrent.TimeoutException;
|
| +
|
| +/**
|
| + * Navigate in UrlBar tests.
|
| + */
|
| +public class NavigateTest extends ChromeTabbedActivityTestBase {
|
| + private static final String HTTP_SCHEME = "http://";
|
| + private static final String NEW_TAB_PAGE = "chrome-native://newtab/";
|
| +
|
| + /**
|
| + * @return the expected contents of the location bar after navigating to url.
|
| + */
|
| + private String expectedLocation(String url) {
|
| + assertTrue(url.startsWith(HTTP_SCHEME));
|
| + return url.replaceFirst(HTTP_SCHEME, "");
|
| + }
|
| +
|
| + /**
|
| + * Verify Selection on the Location Bar
|
| + * Bug: crbug.com/413277
|
| + * @Smoke
|
| + * @MediumTest
|
| + * @Feature({"Navigation", "Main"})
|
| + */
|
| + @FlakyTest
|
| + public void testNavigate() throws InterruptedException {
|
| + String url = TestHttpServerClient.getUrl("chrome/test/data/android/navigate/simple.html");
|
| + String result = typeInOmniboxAndNavigate(url);
|
| + assertEquals(expectedLocation(url), result.trim());
|
| + }
|
| +
|
| + @Restriction(RESTRICTION_TYPE_TABLET)
|
| + @MediumTest
|
| + @Feature({"Navigation"})
|
| + public void testNavigateMany() throws InterruptedException {
|
| + final String[] urls = {
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/one.html"),
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/two.html"),
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/three.html")
|
| + };
|
| + final int repeats = 3;
|
| + for (int i = 0; i < repeats; i++) {
|
| + for (int j = 0; j < urls.length; j++) {
|
| + String result = typeInOmniboxAndNavigate(urls[j]);
|
| + assertEquals(expectedLocation(urls[j]), result);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Verify Selection on the Location Bar in Landscape Mode
|
| + */
|
| + @MediumTest
|
| + @Feature({"Navigation"})
|
| + public void testNavigateLandscape() throws InterruptedException {
|
| + // '0' is Landscape Mode. '1' is Portrait.
|
| + getActivity().setRequestedOrientation(0);
|
| + String url = TestHttpServerClient.getUrl("chrome/test/data/android/navigate/simple.html");
|
| + String result = typeInOmniboxAndNavigate(url);
|
| + assertEquals(expectedLocation(url), result);
|
| + }
|
| +
|
| + /**
|
| + * Verify New Tab Open and Navigate.
|
| + */
|
| + @MediumTest
|
| + @Feature({"Navigation"})
|
| + public void testOpenAndNavigate() throws InterruptedException {
|
| + final int tabCount = getActivity().getCurrentTabModel().getCount();
|
| + ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity());
|
| + UiUtils.settleDownUI(getInstrumentation());
|
| +
|
| + assertEquals("Wrong number of tabs",
|
| + tabCount + 1, getActivity().getCurrentTabModel().getCount());
|
| + String url = TestHttpServerClient.getUrl("chrome/test/data/android/navigate/simple.html");
|
| + String result = typeInOmniboxAndNavigate(url);
|
| + assertEquals(expectedLocation(url), result);
|
| + }
|
| +
|
| + /**
|
| + * Test Opening a link and verify that the desired page is loaded.
|
| + * Bug: crbug.com/171037
|
| + * @MediumTest
|
| + * @Feature({"Navigation"})
|
| + */
|
| + @FlakyTest
|
| + public void testOpenLink() throws InterruptedException, TimeoutException {
|
| + String url = TestHttpServerClient.getUrl("chrome/test/data/android/google.html");
|
| + typeInOmniboxAndNavigate(url);
|
| + assertEquals(url, getActivity().getActivityTab().getUrl());
|
| +
|
| + Tab tab = getActivity().getActivityTab();
|
| + DOMUtils.clickNode(this, tab.getContentViewCore(), "aboutLink");
|
| + ChromeTabUtils.waitForTabPageLoaded(
|
| + tab, TestHttpServerClient.getUrl("chrome/test/data/android/about.html"));
|
| +
|
| + String expectedUrl = TestHttpServerClient.getUrl("chrome/test/data/android/about.html");
|
| + assertEquals("Desired Link not open", expectedUrl,
|
| + getActivity().getActivityTab().getUrl());
|
| + }
|
| +
|
| + /**
|
| + * Test re-direct functionality for a web-page.
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @Feature({"Navigation"})
|
| + public void testNavigateRedirect() throws Exception {
|
| + final String initialUrl =
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/redirect/about.html");
|
| + final String redirectedUrl =
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/redirect/one.html");
|
| + typeInOmniboxAndNavigate(initialUrl);
|
| +
|
| + assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
|
| + @Override
|
| + public boolean isSatisfied() {
|
| + return getActivity().getActivityTab().getUrl().equals(redirectedUrl);
|
| + }
|
| + }));
|
| + }
|
| +
|
| + /**
|
| + * Test fallback works as intended and that we can go back to the original URL
|
| + * even when redirected via Java redirection.
|
| + */
|
| + @MediumTest
|
| + @Feature({"Navigation"})
|
| + public void testIntentFallbackRedirection() throws Exception {
|
| + getInstrumentation().waitForIdleSync();
|
| + assertEquals(NEW_TAB_PAGE, getActivity().getActivityTab().getUrl());
|
| +
|
| + final String redirectionUrl =
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/redirect/about.html");
|
| + final String initialUrl = TestHttpServerClient.getUrl(
|
| + "chrome/test/data/android/redirect/js_redirect.cgi?location="
|
| + + URLEncoder.encode("intent://non_existent/#Intent;scheme=non_existent;"
|
| + + "S.browser_fallback_url=" + redirectionUrl + ";end",
|
| + "UTF-8"));
|
| + final String targetUrl =
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/redirect/one.html");
|
| + typeInOmniboxAndNavigate(initialUrl);
|
| +
|
| + // Now intent fallback should be triggered assuming 'non_existent' scheme cannot be handled.
|
| + assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
|
| + @Override
|
| + public boolean isSatisfied() {
|
| + return getActivity().getActivityTab().getUrl().equals(targetUrl);
|
| + }
|
| + }));
|
| +
|
| + // Check if Java redirections were removed from the history.
|
| + // Note that if we try to go back in the test: NavigateToEntry() is called, but
|
| + // DidNavigate() does not get called. But in real cases we can go back to initial page
|
| + // without any problem.
|
| + // TODO(changwan): figure out why we cannot go back on this test.
|
| + int index = getActivity().getActivityTab().getWebContents().getNavigationController()
|
| + .getLastCommittedEntryIndex();
|
| + assertEquals(1, index);
|
| + String previousNavigationUrl = getActivity().getActivityTab().getWebContents()
|
| + .getNavigationController().getEntryAtIndex(0).getUrl();
|
| + assertEquals(NEW_TAB_PAGE, previousNavigationUrl);
|
| + }
|
| +
|
| + /**
|
| + * Test back and forward buttons.
|
| + *
|
| + * crbug.com/268463
|
| + * @Restriction(RESTRICTION_TYPE_TABLET)
|
| + * @MediumTest
|
| + * @Feature({"Navigation"})
|
| + */
|
| + @FlakyTest
|
| + public void testNavigateBackAndForwardButtons() throws InterruptedException {
|
| + final String[] urls = {
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/one.html"),
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/two.html"),
|
| + TestHttpServerClient.getUrl("chrome/test/data/android/navigate/three.html")
|
| + };
|
| +
|
| + for (String url : urls) {
|
| + typeInOmniboxAndNavigate(url);
|
| + }
|
| +
|
| + final int repeats = 3;
|
| + for (int i = 0; i < repeats; i++) {
|
| + singleClickView(getActivity().findViewById(R.id.back_button));
|
| + UiUtils.settleDownUI(getInstrumentation());
|
| + assertEquals(String.format(
|
| + "URL mismatch after pressing back button for the 1st time in repetition %d.",
|
| + i), urls[1], getActivity().getActivityTab().getUrl());
|
| +
|
| + singleClickView(getActivity().findViewById(R.id.back_button));
|
| + UiUtils.settleDownUI(getInstrumentation());
|
| + assertEquals(String.format(
|
| + "URL mismatch after pressing back button for the 2nd time in repetition %d.",
|
| + i), urls[0], getActivity().getActivityTab().getUrl());
|
| +
|
| + singleClickView(getActivity().findViewById(R.id.forward_button));
|
| + UiUtils.settleDownUI(getInstrumentation());
|
| + assertEquals(String.format(
|
| + "URL mismatch after pressing fwd button for the 1st time in repetition %d.", i),
|
| + urls[1], getActivity().getActivityTab().getUrl());
|
| +
|
| + singleClickView(getActivity().findViewById(R.id.forward_button));
|
| + UiUtils.settleDownUI(getInstrumentation());
|
| + assertEquals(String.format(
|
| + "URL mismatch after pressing fwd button for the 2nd time in repetition %d.", i),
|
| + urls[2], getActivity().getActivityTab().getUrl());
|
| + }
|
| + }
|
| +
|
| + /*
|
| + * Bug: crbug.com/413186
|
| + * @MediumTest
|
| + * @Feature({"Navigation"})
|
| + */
|
| + @FlakyTest
|
| + public void testWindowOpenUrlSpoof() throws Exception {
|
| + TestWebServer webServer = TestWebServer.start();
|
| + try {
|
| + // Make sure that we start with one tab.
|
| + final TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + assertEquals("Invalid starting number of tabs", 1, model.getCount());
|
| +
|
| + final Semaphore urlServedSemaphore = new Semaphore(0);
|
| + Runnable checkAction = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + final Tab tab = TabModelUtils.getCurrentTab(model);
|
| +
|
| + // Make sure that we are showing the spoofed data and a blank URL.
|
| + String url = getTabUrlOnUIThread(tab);
|
| + boolean spoofedUrl = "".equals(url) || "about:blank".equals(url);
|
| + assertTrue("URL Spoofed", spoofedUrl);
|
| + assertEquals("Not showing mocked content", "\"Spoofed\"", getTabBodyText(tab));
|
| + urlServedSemaphore.release();
|
| + }
|
| + };
|
| +
|
| + // Mock out the test URL
|
| + final String mockedUrl = webServer.setResponseWithRunnableAction(
|
| + "/mockme.html", "<html><body>Real</body></html>", null, checkAction);
|
| +
|
| + // Navigate to the spoofable URL
|
| + loadUrl(UrlUtils.encodeHtmlDataUri(
|
| + "<head>"
|
| + + " <meta name=\"viewport\""
|
| + + " content=\"initial-scale=1,maximum-scale=1,user-scalable=no\">"
|
| + + "</head>"
|
| + + "<script>"
|
| + + " function spoof() {"
|
| + + " var w = open();"
|
| + + " w.opener = null;"
|
| + + " w.document.write('Spoofed');"
|
| + + " w.location = '" + mockedUrl + "'"
|
| + + " }"
|
| + + "</script>"
|
| + + "<a href='JavaScript:spoof()' id='link'>Go</a>"));
|
| +
|
| + assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
|
| + @Override
|
| + public boolean isSatisfied() {
|
| + return getActivity().getCurrentContentViewCore().getScale() == 1.f;
|
| + }
|
| + }));
|
| +
|
| + // Click the 'Go' link
|
| + DOMUtils.clickNode(this, getActivity().getCurrentContentViewCore(), "link");
|
| +
|
| + // Wait for the proper URL to be served.
|
| + assertTrue(urlServedSemaphore.tryAcquire(5, TimeUnit.SECONDS));
|
| +
|
| + final Tab tab = TabModelUtils.getCurrentTab(model);
|
| +
|
| + // Wait for the url to change.
|
| + assertTrue("Page url didn't change",
|
| + CriteriaHelper.pollForCriteria(new Criteria() {
|
| + @Override
|
| + public boolean isSatisfied() {
|
| + return mockedUrl.equals(getTabUrlOnUIThread(tab));
|
| + }
|
| + }, 5000, 50));
|
| +
|
| + // Make sure that we're showing new content now.
|
| + assertEquals("Still showing spoofed data", "\"Real\"", getTabBodyText(tab));
|
| + } finally {
|
| + webServer.shutdown();
|
| + }
|
| + }
|
| +
|
| + private String getTabUrlOnUIThread(final Tab tab) {
|
| + try {
|
| + return ThreadUtils.runOnUiThreadBlocking(new Callable<String>() {
|
| + @Override
|
| + public String call() throws Exception {
|
| + return tab.getUrl();
|
| + }
|
| + });
|
| + } catch (ExecutionException ex) {
|
| + assert false : "Unexpected ExecutionException";
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + private String getTabBodyText(Tab tab) {
|
| + try {
|
| + return JavaScriptUtils.executeJavaScriptAndWaitForResult(
|
| + tab.getWebContents(), "document.body.innerText");
|
| + } catch (InterruptedException ex) {
|
| + assert false : "Unexpected InterruptedException";
|
| + } catch (TimeoutException ex) {
|
| + assert false : "Unexpected TimeoutException";
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + @Override
|
| + public void startMainActivity() throws InterruptedException {
|
| + startMainActivityFromLauncher();
|
| + }
|
| +}
|
|
|