- add sources.
[platform/framework/web/crosswalk.git] / src / android_webview / javatests / src / org / chromium / android_webview / test / NavigationHistoryTest.java
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.
4
5 package org.chromium.android_webview.test;
6
7 import android.test.FlakyTest;
8 import android.test.suitebuilder.annotation.MediumTest;
9 import android.test.suitebuilder.annotation.SmallTest;
10
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;
21
22 import java.util.concurrent.Callable;
23
24 public class NavigationHistoryTest extends AwTestBase {
25
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";
36
37     private TestWebServer mWebServer;
38     private TestAwContentsClient mContentsClient;
39     private AwContents mAwContents;
40
41     @Override
42     public void setUp() throws Exception {
43         super.setUp();
44         mContentsClient = new TestAwContentsClient();
45         final AwTestContainerView testContainerView =
46             createAwTestContainerViewOnMainSync(mContentsClient);
47         mAwContents = testContainerView.getAwContents();
48         mWebServer = new TestWebServer(false);
49     }
50
51     @Override
52     public void tearDown() throws Exception {
53         mWebServer.shutdown();
54         super.tearDown();
55     }
56
57     private NavigationHistory getNavigationHistory(final AwContents awContents)
58             throws Exception {
59         return ThreadUtils.runOnUiThreadBlocking(new Callable<NavigationHistory>() {
60             @Override
61             public NavigationHistory call() {
62                 return awContents.getContentViewCore().getNavigationHistory();
63             }
64         });
65     }
66
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());
72         if (faviconNull) {
73             assertNull(item.getFavicon());
74         } else {
75             assertNotNull(item.getFavicon());
76         }
77     }
78
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));
85     }
86
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));
93     }
94
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));
101     }
102
103     @SmallTest
104     public void testNavigateOneUrl() throws Throwable {
105         NavigationHistory history = getNavigationHistory(mAwContents);
106         assertEquals(0, history.getEntryCount());
107
108         final String pageWithHashTagRedirectUrl = addPageWithHashTagRedirectToServer(mWebServer);
109         enableJavaScriptOnUiThread(mAwContents);
110
111         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
112                 pageWithHashTagRedirectUrl);
113
114         history = getNavigationHistory(mAwContents);
115         checkHistoryItem(history.getEntryAtIndex(0),
116                 pageWithHashTagRedirectUrl + "#tag",
117                 pageWithHashTagRedirectUrl,
118                 PAGE_WITH_HASHTAG_REDIRECT_TITLE,
119                 true);
120
121         assertEquals(0, history.getCurrentEntryIndex());
122     }
123
124     @SmallTest
125     public void testNavigateTwoUrls() throws Throwable {
126         NavigationHistory list = getNavigationHistory(mAwContents);
127         assertEquals(0, list.getEntryCount());
128
129         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
130                 mContentsClient.getOnPageFinishedHelper();
131         final String page1Url = addPage1ToServer(mWebServer);
132         final String page2Url = addPage2ToServer(mWebServer);
133
134         loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
135         loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
136
137         list = getNavigationHistory(mAwContents);
138
139         // Make sure there is a new entry entry the list
140         assertEquals(2, list.getEntryCount());
141
142         // Make sure the first entry is still okay
143         checkHistoryItem(list.getEntryAtIndex(0),
144                 page1Url,
145                 page1Url,
146                 PAGE_1_TITLE,
147                 true);
148
149         // Make sure the second entry was added properly
150         checkHistoryItem(list.getEntryAtIndex(1),
151                 page2Url,
152                 page2Url,
153                 PAGE_2_TITLE,
154                 true);
155
156         assertEquals(1, list.getCurrentEntryIndex());
157
158     }
159
160     @SmallTest
161     public void testNavigateTwoUrlsAndBack() throws Throwable {
162         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
163                 mContentsClient.getOnPageFinishedHelper();
164         NavigationHistory list = getNavigationHistory(mAwContents);
165         assertEquals(0, list.getEntryCount());
166
167         final String page1Url = addPage1ToServer(mWebServer);
168         final String page2Url = addPage2ToServer(mWebServer);
169
170         loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
171         loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
172
173         HistoryUtils.goBackSync(getInstrumentation(), mAwContents.getContentViewCore(),
174                 onPageFinishedHelper);
175         list = getNavigationHistory(mAwContents);
176
177         // Make sure the first entry is still okay
178         checkHistoryItem(list.getEntryAtIndex(0),
179                 page1Url,
180                 page1Url,
181                 PAGE_1_TITLE,
182                 true);
183
184         // Make sure the second entry is still okay
185         checkHistoryItem(list.getEntryAtIndex(1),
186                 page2Url,
187                 page2Url,
188                 PAGE_2_TITLE,
189                 true);
190
191         // Make sure the current index is back to 0
192         assertEquals(0, list.getCurrentEntryIndex());
193     }
194
195     /**
196      * Disabled until favicons are getting fetched when using ContentView.
197      *
198      * @SmallTest
199      * @throws Throwable
200      */
201     @DisabledTest
202     public void testFavicon() throws Throwable {
203         NavigationHistory list = getNavigationHistory(mAwContents);
204
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);
209
210         assertEquals(0, list.getEntryCount());
211         getAwSettingsOnUiThread(mAwContents).setImagesEnabled(true);
212         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
213
214         list = getNavigationHistory(mAwContents);
215
216         // Make sure the first entry is still okay.
217         checkHistoryItem(list.getEntryAtIndex(0), url, url, "", false);
218     }
219
220     private String addNoncacheableLoginPageToServer(TestWebServer webServer) {
221         final String submitButtonId = "submit";
222         final String loginPageHtml =
223                 "<html>" +
224                 "  <head>" +
225                 "    <title>" + LOGIN_PAGE_TITLE + "</title>" +
226                 "    <script>" +
227                 "      function startAction() {" +
228                 "        button = document.getElementById('" + submitButtonId + "');" +
229                 "        button.click();" +
230                 "      }" +
231                 "    </script>" +
232                 "  </head>" +
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'>" +
237                 "    </form>" +
238                 "  </body>" +
239                 "</html>";
240         return mWebServer.setResponse(LOGIN_PAGE_PATH,
241                 loginPageHtml,
242                 CommonResources.getTextHtmlHeaders(true));
243     }
244
245     private String addNoncacheableLoginResponsePageToServer(TestWebServer webServer) {
246         final String loginResponsePageHtml =
247                 "<html>" +
248                 "  <head>" +
249                 "    <title>" + LOGIN_RESPONSE_PAGE_TITLE + "</title>" +
250                 "  </head>" +
251                 "  <body>" +
252                 "    Login incorrect" +
253                 "    <div><a id='" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "' href='" +
254                 PAGE_1_PATH.substring(1) + "'>Help</a></div>'" +
255                 "  </body>" +
256                 "</html>";
257         return mWebServer.setResponse(LOGIN_RESPONSE_PAGE_PATH,
258                 loginResponsePageHtml,
259                 CommonResources.getTextHtmlHeaders(true));
260     }
261
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.
266     /**
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.
271      *
272      * @MediumTest
273      * @Feature({"AndroidWebView"})
274      */
275     @DisabledTest
276     public void testNavigateBackToNoncacheableLoginPage() throws Throwable {
277         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
278                 mContentsClient.getOnPageFinishedHelper();
279
280         final String loginPageUrl = addNoncacheableLoginPageToServer(mWebServer);
281         final String loginResponsePageUrl = addNoncacheableLoginResponsePageToServer(mWebServer);
282         final String page1Url = addPage1ToServer(mWebServer);
283
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>() {
288             @Override
289             public Boolean call() {
290                 String title = mAwContents.getContentViewCore().getTitle();
291                 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);
292             }
293         }));
294         executeJavaScriptAndWaitForResult(mAwContents,
295                 mContentsClient,
296                 "link = document.getElementById('" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "');" +
297                 "link.click();");
298         assertTrue(pollOnUiThread(new Callable<Boolean>() {
299             @Override
300             public Boolean call() {
301                 String title = mAwContents.getContentViewCore().getTitle();
302                 return PAGE_1_TITLE.equals(title);
303             }
304         }));
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>() {
310             @Override
311             public Boolean call() {
312                 String title = mAwContents.getContentViewCore().getTitle();
313                 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);
314             }
315         }));
316     }
317 }