Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / android_webview / javatests / src / org / chromium / android_webview / test / NavigationHistoryTest.java
1 // Copyright 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.suitebuilder.annotation.SmallTest;
8
9 import org.chromium.android_webview.AwContents;
10 import org.chromium.android_webview.test.util.CommonResources;
11 import org.chromium.base.ThreadUtils;
12 import org.chromium.base.test.util.DisabledTest;
13 import org.chromium.content.browser.test.util.HistoryUtils;
14 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
15 import org.chromium.content_public.browser.NavigationEntry;
16 import org.chromium.content_public.browser.NavigationHistory;
17 import org.chromium.net.test.util.TestWebServer;
18
19 import java.util.concurrent.Callable;
20
21 /**
22  * Navigation history tests.
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         AwContents.setShouldDownloadFavicons();
45         mContentsClient = new TestAwContentsClient();
46         final AwTestContainerView testContainerView =
47             createAwTestContainerViewOnMainSync(mContentsClient);
48         mAwContents = testContainerView.getAwContents();
49         mWebServer = TestWebServer.start();
50     }
51
52     @Override
53     public void tearDown() throws Exception {
54         mWebServer.shutdown();
55         super.tearDown();
56     }
57
58     private NavigationHistory getNavigationHistory(final AwContents awContents)
59             throws Exception {
60         return ThreadUtils.runOnUiThreadBlocking(new Callable<NavigationHistory>() {
61             @Override
62             public NavigationHistory call() {
63                 return awContents.getNavigationController().getNavigationHistory();
64             }
65         });
66     }
67
68     private void checkHistoryItem(NavigationEntry item, String url, String originalUrl,
69             String title, boolean faviconNull) {
70         assertEquals(url, item.getUrl());
71         assertEquals(originalUrl, item.getOriginalUrl());
72         assertEquals(title, item.getTitle());
73         if (faviconNull) {
74             assertNull(item.getFavicon());
75         } else {
76             assertNotNull(item.getFavicon());
77         }
78     }
79
80     private String addPage1ToServer(TestWebServer webServer) {
81         return mWebServer.setResponse(PAGE_1_PATH,
82                 CommonResources.makeHtmlPageFrom(
83                         "<title>" + PAGE_1_TITLE + "</title>",
84                         "<div>This is test page 1.</div>"),
85                 CommonResources.getTextHtmlHeaders(false));
86     }
87
88     private String addPage2ToServer(TestWebServer webServer) {
89         return mWebServer.setResponse(PAGE_2_PATH,
90                 CommonResources.makeHtmlPageFrom(
91                         "<title>" + PAGE_2_TITLE + "</title>",
92                         "<div>This is test page 2.</div>"),
93                 CommonResources.getTextHtmlHeaders(false));
94     }
95
96     private String addPageWithHashTagRedirectToServer(TestWebServer webServer) {
97         return mWebServer.setResponse(PAGE_2_PATH,
98                 CommonResources.makeHtmlPageFrom(
99                         "<title>" + PAGE_WITH_HASHTAG_REDIRECT_TITLE + "</title>",
100                         "<iframe onLoad=\"location.replace(location.href + '#tag');\" />"),
101                 CommonResources.getTextHtmlHeaders(false));
102     }
103
104     @SmallTest
105     public void testNavigateOneUrl() throws Throwable {
106         NavigationHistory history = getNavigationHistory(mAwContents);
107         assertEquals(0, history.getEntryCount());
108
109         final String pageWithHashTagRedirectUrl = addPageWithHashTagRedirectToServer(mWebServer);
110         enableJavaScriptOnUiThread(mAwContents);
111
112         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
113                 pageWithHashTagRedirectUrl);
114
115         history = getNavigationHistory(mAwContents);
116         checkHistoryItem(history.getEntryAtIndex(0),
117                 pageWithHashTagRedirectUrl + "#tag",
118                 pageWithHashTagRedirectUrl,
119                 PAGE_WITH_HASHTAG_REDIRECT_TITLE,
120                 true);
121
122         assertEquals(0, history.getCurrentEntryIndex());
123     }
124
125     @SmallTest
126     public void testNavigateTwoUrls() throws Throwable {
127         NavigationHistory list = getNavigationHistory(mAwContents);
128         assertEquals(0, list.getEntryCount());
129
130         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
131                 mContentsClient.getOnPageFinishedHelper();
132         final String page1Url = addPage1ToServer(mWebServer);
133         final String page2Url = addPage2ToServer(mWebServer);
134
135         loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
136         loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
137
138         list = getNavigationHistory(mAwContents);
139
140         // Make sure there is a new entry entry the list
141         assertEquals(2, list.getEntryCount());
142
143         // Make sure the first entry is still okay
144         checkHistoryItem(list.getEntryAtIndex(0),
145                 page1Url,
146                 page1Url,
147                 PAGE_1_TITLE,
148                 true);
149
150         // Make sure the second entry was added properly
151         checkHistoryItem(list.getEntryAtIndex(1),
152                 page2Url,
153                 page2Url,
154                 PAGE_2_TITLE,
155                 true);
156
157         assertEquals(1, list.getCurrentEntryIndex());
158
159     }
160
161     @SmallTest
162     public void testNavigateTwoUrlsAndBack() throws Throwable {
163         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
164                 mContentsClient.getOnPageFinishedHelper();
165         NavigationHistory list = getNavigationHistory(mAwContents);
166         assertEquals(0, list.getEntryCount());
167
168         final String page1Url = addPage1ToServer(mWebServer);
169         final String page2Url = addPage2ToServer(mWebServer);
170
171         loadUrlSync(mAwContents, onPageFinishedHelper, page1Url);
172         loadUrlSync(mAwContents, onPageFinishedHelper, page2Url);
173
174         HistoryUtils.goBackSync(getInstrumentation(), mAwContents.getWebContents(),
175                 onPageFinishedHelper);
176         list = getNavigationHistory(mAwContents);
177
178         // Make sure the first entry is still okay
179         checkHistoryItem(list.getEntryAtIndex(0),
180                 page1Url,
181                 page1Url,
182                 PAGE_1_TITLE,
183                 true);
184
185         // Make sure the second entry is still okay
186         checkHistoryItem(list.getEntryAtIndex(1),
187                 page2Url,
188                 page2Url,
189                 PAGE_2_TITLE,
190                 true);
191
192         // Make sure the current index is back to 0
193         assertEquals(0, list.getCurrentEntryIndex());
194     }
195
196     /**
197      * Disabled until favicons are getting fetched when using ContentView.
198      *
199      * @SmallTest
200      * @throws Throwable
201      */
202     @DisabledTest
203     public void testFavicon() throws Throwable {
204         NavigationHistory list = getNavigationHistory(mAwContents);
205
206         mWebServer.setResponseBase64("/" + CommonResources.FAVICON_FILENAME,
207                 CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(false));
208         final String url = mWebServer.setResponse("/favicon.html",
209                 CommonResources.FAVICON_STATIC_HTML, null);
210
211         assertEquals(0, list.getEntryCount());
212         getAwSettingsOnUiThread(mAwContents).setImagesEnabled(true);
213         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
214
215         list = getNavigationHistory(mAwContents);
216
217         // Make sure the first entry is still okay.
218         checkHistoryItem(list.getEntryAtIndex(0), url, url, "", false);
219     }
220
221     private String addNoncacheableLoginPageToServer(TestWebServer webServer) {
222         final String submitButtonId = "submit";
223         final String loginPageHtml =
224                 "<html>" +
225                 "  <head>" +
226                 "    <title>" + LOGIN_PAGE_TITLE + "</title>" +
227                 "    <script>" +
228                 "      function startAction() {" +
229                 "        button = document.getElementById('" + submitButtonId + "');" +
230                 "        button.click();" +
231                 "      }" +
232                 "    </script>" +
233                 "  </head>" +
234                 "  <body onload='setTimeout(startAction, 0)'>" +
235                 "    <form action='" + LOGIN_RESPONSE_PAGE_PATH.substring(1) + "' method='post'>" +
236                 "      <input type='text' name='login'>" +
237                 "      <input id='" + submitButtonId + "' type='submit' value='Submit'>" +
238                 "    </form>" +
239                 "  </body>" +
240                 "</html>";
241         return mWebServer.setResponse(LOGIN_PAGE_PATH,
242                 loginPageHtml,
243                 CommonResources.getTextHtmlHeaders(true));
244     }
245
246     private String addNoncacheableLoginResponsePageToServer(TestWebServer webServer) {
247         final String loginResponsePageHtml =
248                 "<html>" +
249                 "  <head>" +
250                 "    <title>" + LOGIN_RESPONSE_PAGE_TITLE + "</title>" +
251                 "  </head>" +
252                 "  <body>" +
253                 "    Login incorrect" +
254                 "    <div><a id='" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "' href='" +
255                 PAGE_1_PATH.substring(1) + "'>Help</a></div>'" +
256                 "  </body>" +
257                 "</html>";
258         return mWebServer.setResponse(LOGIN_RESPONSE_PAGE_PATH,
259                 loginResponsePageHtml,
260                 CommonResources.getTextHtmlHeaders(true));
261     }
262
263     // This test simulates Google login page behavior. The page is non-cacheable
264     // and uses POST method for submission. It also contains a help link, leading
265     // to another page. We are verifying that it is possible to go back to the
266     // submitted login page after visiting the help page.
267     /**
268      * Temporarily disabled. It is blocking a patch that fixes chromium's form
269      * resubmission defenses. This test should probably expect a modal dialog
270      * asking permission to re-post rather than expecting to just be able to navigate
271      * back to a page that specified Cache-Control: no-store.
272      *
273      * @MediumTest
274      * @Feature({"AndroidWebView"})
275      */
276     @DisabledTest
277     public void testNavigateBackToNoncacheableLoginPage() throws Throwable {
278         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
279                 mContentsClient.getOnPageFinishedHelper();
280
281         final String loginPageUrl = addNoncacheableLoginPageToServer(mWebServer);
282         final String loginResponsePageUrl = addNoncacheableLoginResponsePageToServer(mWebServer);
283         final String page1Url = addPage1ToServer(mWebServer);
284
285         getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
286         loadUrlSync(mAwContents, onPageFinishedHelper, loginPageUrl);
287         // Since the page performs an async action, we can't rely on callbacks.
288         pollOnUiThread(new Callable<Boolean>() {
289             @Override
290             public Boolean call() {
291                 String title = mAwContents.getTitle();
292                 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);
293             }
294         });
295         executeJavaScriptAndWaitForResult(mAwContents,
296                 mContentsClient,
297                 "link = document.getElementById('" + LOGIN_RESPONSE_PAGE_HELP_LINK_ID + "');" +
298                 "link.click();");
299         pollOnUiThread(new Callable<Boolean>() {
300             @Override
301             public Boolean call() {
302                 String title = mAwContents.getTitle();
303                 return PAGE_1_TITLE.equals(title);
304             }
305         });
306         // Verify that we can still go back to the login response page despite that
307         // it is non-cacheable.
308         HistoryUtils.goBackSync(getInstrumentation(), mAwContents.getWebContents(),
309                 onPageFinishedHelper);
310         pollOnUiThread(new Callable<Boolean>() {
311             @Override
312             public Boolean call() {
313                 String title = mAwContents.getTitle();
314                 return LOGIN_RESPONSE_PAGE_TITLE.equals(title);
315             }
316         });
317     }
318 }