1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.android_webview.test;
7 import android.test.FlakyTest;
8 import android.test.suitebuilder.annotation.MediumTest;
9 import android.test.suitebuilder.annotation.SmallTest;
11 import org.chromium.android_webview.AwContents;
12 import org.chromium.android_webview.test.util.CommonResources;
13 import org.chromium.base.ThreadUtils;
14 import org.chromium.base.test.util.DisabledTest;
15 import org.chromium.base.test.util.Feature;
16 import org.chromium.content.browser.NavigationEntry;
17 import org.chromium.content.browser.NavigationHistory;
18 import org.chromium.content.browser.test.util.HistoryUtils;
19 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
20 import org.chromium.net.test.util.TestWebServer;
22 import java.util.concurrent.Callable;
24 public class NavigationHistoryTest extends AwTestBase {
26 private static final String PAGE_1_PATH = "/page1.html";
27 private static final String PAGE_1_TITLE = "Page 1 Title";
28 private static final String PAGE_2_PATH = "/page2.html";
29 private static final String PAGE_2_TITLE = "Page 2 Title";
30 private static final String PAGE_WITH_HASHTAG_REDIRECT_TITLE = "Page with hashtag";
31 private static final String LOGIN_PAGE_PATH = "/login.html";
32 private static final String LOGIN_PAGE_TITLE = "Login page";
33 private static final String LOGIN_RESPONSE_PAGE_PATH = "/login-response.html";
34 private static final String LOGIN_RESPONSE_PAGE_TITLE = "Login response";
35 private static final String LOGIN_RESPONSE_PAGE_HELP_LINK_ID = "help";
37 private TestWebServer mWebServer;
38 private TestAwContentsClient mContentsClient;
39 private AwContents mAwContents;
42 public void setUp() throws Exception {
44 mContentsClient = new TestAwContentsClient();
45 final AwTestContainerView testContainerView =
46 createAwTestContainerViewOnMainSync(mContentsClient);
47 mAwContents = testContainerView.getAwContents();
48 mWebServer = new TestWebServer(false);
52 public void tearDown() throws Exception {
53 mWebServer.shutdown();
57 private NavigationHistory getNavigationHistory(final AwContents awContents)
59 return ThreadUtils.runOnUiThreadBlocking(new Callable<NavigationHistory>() {
61 public NavigationHistory call() {
62 return awContents.getContentViewCore().getNavigationHistory();
67 private void checkHistoryItem(NavigationEntry item, String url, String originalUrl,
68 String title, boolean faviconNull) {
69 assertEquals(url, item.getUrl());
70 assertEquals(originalUrl, item.getOriginalUrl());
71 assertEquals(title, item.getTitle());
73 assertNull(item.getFavicon());
75 assertNotNull(item.getFavicon());
79 private String addPage1ToServer(TestWebServer webServer) {
80 return mWebServer.setResponse(PAGE_1_PATH,
81 CommonResources.makeHtmlPageFrom(
82 "<title>" + PAGE_1_TITLE + "</title>",
83 "<div>This is test page 1.</div>"),
84 CommonResources.getTextHtmlHeaders(false));
87 private String addPage2ToServer(TestWebServer webServer) {
88 return mWebServer.setResponse(PAGE_2_PATH,
89 CommonResources.makeHtmlPageFrom(
90 "<title>" + PAGE_2_TITLE + "</title>",
91 "<div>This is test page 2.</div>"),
92 CommonResources.getTextHtmlHeaders(false));
95 private String addPageWithHashTagRedirectToServer(TestWebServer webServer) {
96 return mWebServer.setResponse(PAGE_2_PATH,
97 CommonResources.makeHtmlPageFrom(
98 "<title>" + PAGE_WITH_HASHTAG_REDIRECT_TITLE + "</title>",
99 "<iframe onLoad=\"location.replace(location.href + '#tag');\" />"),
100 CommonResources.getTextHtmlHeaders(false));
104 public void testNavigateOneUrl() throws Throwable {
105 NavigationHistory history = getNavigationHistory(mAwContents);
106 assertEquals(0, history.getEntryCount());
108 final String pageWithHashTagRedirectUrl = addPageWithHashTagRedirectToServer(mWebServer);
109 enableJavaScriptOnUiThread(mAwContents);
111 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
112 pageWithHashTagRedirectUrl);
114 history = getNavigationHistory(mAwContents);
115 checkHistoryItem(history.getEntryAtIndex(0),
116 pageWithHashTagRedirectUrl + "#tag",
117 pageWithHashTagRedirectUrl,
118 PAGE_WITH_HASHTAG_REDIRECT_TITLE,
121 assertEquals(0, history.getCurrentEntryIndex());
125 public void testNavigateTwoUrls() throws Throwable {
126 NavigationHistory list = getNavigationHistory(mAwContents);
127 assertEquals(0, list.getEntryCount());
129 final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
130 mContentsClient.getOnPageFinishedHelper();
131 final String page1Url = addPage1ToServer(mWebServer);
132 final String page2Url = addPage2ToServer(mWebServer);
134 loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
135 loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
137 list = getNavigationHistory(mAwContents);
139 // Make sure there is a new entry entry the list
140 assertEquals(2, list.getEntryCount());
142 // Make sure the first entry is still okay
143 checkHistoryItem(list.getEntryAtIndex(0),
149 // Make sure the second entry was added properly
150 checkHistoryItem(list.getEntryAtIndex(1),
156 assertEquals(1, list.getCurrentEntryIndex());
161 public void testNavigateTwoUrlsAndBack() throws Throwable {
162 final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
163 mContentsClient.getOnPageFinishedHelper();
164 NavigationHistory list = getNavigationHistory(mAwContents);
165 assertEquals(0, list.getEntryCount());
167 final String page1Url = addPage1ToServer(mWebServer);
168 final String page2Url = addPage2ToServer(mWebServer);
170 loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
171 loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
173 HistoryUtils.goBackSync(getInstrumentation(), mAwContents.getContentViewCore(),
174 onPageFinishedHelper);
175 list = getNavigationHistory(mAwContents);
177 // Make sure the first entry is still okay
178 checkHistoryItem(list.getEntryAtIndex(0),
184 // Make sure the second entry is still okay
185 checkHistoryItem(list.getEntryAtIndex(1),
191 // Make sure the current index is back to 0
192 assertEquals(0, list.getCurrentEntryIndex());
196 * Disabled until favicons are getting fetched when using ContentView.
202 public void testFavicon() throws Throwable {
203 NavigationHistory list = getNavigationHistory(mAwContents);
205 mWebServer.setResponseBase64("/" + CommonResources.FAVICON_FILENAME,
206 CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(false));
207 final String url = mWebServer.setResponse("/favicon.html",
208 CommonResources.FAVICON_STATIC_HTML, null);
210 assertEquals(0, list.getEntryCount());
211 getAwSettingsOnUiThread(mAwContents).setImagesEnabled(true);
212 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
214 list = getNavigationHistory(mAwContents);
216 // Make sure the first entry is still okay.
217 checkHistoryItem(list.getEntryAtIndex(0), url, url, "", false);
220 private String addNoncacheableLoginPageToServer(TestWebServer webServer) {
221 final String submitButtonId = "submit";
222 final String loginPageHtml =
225 " <title>" + LOGIN_PAGE_TITLE + "</title>" +
227 " function startAction() {" +
228 " button = document.getElementById('" + submitButtonId + "');" +
233 " <body onload='setTimeout(startAction, 0)'>" +
234 " <form action='" + LOGIN_RESPONSE_PAGE_PATH.substring(1) + "' method='post'>" +
235 " <input type='text' name='login'>" +
236 " <input id='" + submitButtonId + "' type='submit' value='Submit'>" +
240 return mWebServer.setResponse(LOGIN_PAGE_PATH,
242 CommonResources.getTextHtmlHeaders(true));
245 private String addNoncacheableLoginResponsePageToServer(TestWebServer webServer) {
246 final String loginResponsePageHtml =
249 " <title>" + LOGIN_RESPONSE_PAGE_TITLE + "</title>" +
253 " <div><a id='" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "' href='" +
254 PAGE_1_PATH.substring(1) + "'>Help</a></div>'" +
257 return mWebServer.setResponse(LOGIN_RESPONSE_PAGE_PATH,
258 loginResponsePageHtml,
259 CommonResources.getTextHtmlHeaders(true));
262 // This test simulates Google login page behavior. The page is non-cacheable
263 // and uses POST method for submission. It also contains a help link, leading
264 // to another page. We are verifying that it is possible to go back to the
265 // submitted login page after visiting the help page.
267 * Temporarily disabled. It is blocking a patch that fixes chromium's form
268 * resubmission defenses. This test should probably expect a modal dialog
269 * asking permission to re-post rather than expecting to just be able to navigate
270 * back to a page that specified Cache-Control: no-store.
273 * @Feature({"AndroidWebView"})
276 public void testNavigateBackToNoncacheableLoginPage() throws Throwable {
277 final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
278 mContentsClient.getOnPageFinishedHelper();
280 final String loginPageUrl = addNoncacheableLoginPageToServer(mWebServer);
281 final String loginResponsePageUrl = addNoncacheableLoginResponsePageToServer(mWebServer);
282 final String page1Url = addPage1ToServer(mWebServer);
284 getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
285 loadUrlSync(mAwContents, onPageFinishedHelper, loginPageUrl);
286 // Since the page performs an async action, we can't rely on callbacks.
287 assertTrue(pollOnUiThread(new Callable<Boolean>() {
289 public Boolean call() {
290 String title = mAwContents.getContentViewCore().getTitle();
291 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);
294 executeJavaScriptAndWaitForResult(mAwContents,
296 "link = document.getElementById('" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "');" +
298 assertTrue(pollOnUiThread(new Callable<Boolean>() {
300 public Boolean call() {
301 String title = mAwContents.getContentViewCore().getTitle();
302 return PAGE_1_TITLE.equals(title);
305 // Verify that we can still go back to the login response page despite that
306 // it is non-cacheable.
307 HistoryUtils.goBackSync(getInstrumentation(), mAwContents.getContentViewCore(),
308 onPageFinishedHelper);
309 assertTrue(pollOnUiThread(new Callable<Boolean>() {
311 public Boolean call() {
312 String title = mAwContents.getContentViewCore().getTitle();
313 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);