[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / content / browser / session_history_browsertest.cc
blob232ad17756af2b481d956546eabe6cd87f887606
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 #include "base/string_util.h"
6 #include "base/utf_string_conversions.h"
7 #include "content/public/browser/navigation_controller.h"
8 #include "content/public/browser/notification_service.h"
9 #include "content/public/browser/notification_types.h"
10 #include "content/public/browser/web_contents.h"
11 #include "content/public/common/url_constants.h"
12 #include "content/public/test/browser_test_utils.h"
13 #include "content/public/test/test_utils.h"
14 #include "content/shell/shell.h"
15 #include "content/test/content_browser_test.h"
16 #include "content/test/content_browser_test_utils.h"
17 #include "net/test/test_server.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace content {
22 class SessionHistoryTest : public ContentBrowserTest {
23 protected:
24 SessionHistoryTest() {}
26 virtual void SetUpOnMainThread() {
27 ASSERT_TRUE(test_server()->Start());
28 NavigateToURL(shell(), GURL(chrome::kAboutBlankURL));
31 // Simulate clicking a link. Only works on the frames.html testserver page.
32 void ClickLink(std::string node_id) {
33 GURL url("javascript:clickLink('" + node_id + "')");
34 NavigateToURL(shell(), url);
37 // Simulate filling in form data. Only works on the frames.html page with
38 // subframe = form.html, and on form.html itself.
39 void FillForm(std::string node_id, std::string value) {
40 GURL url("javascript:fillForm('" + node_id + "', '" + value + "')");
41 // This will return immediately, but since the JS executes synchronously
42 // on the renderer, it will complete before the next navigate message is
43 // processed.
44 NavigateToURL(shell(), url);
47 // Simulate submitting a form. Only works on the frames.html page with
48 // subframe = form.html, and on form.html itself.
49 void SubmitForm(std::string node_id) {
50 GURL url("javascript:submitForm('" + node_id + "')");
51 NavigateToURL(shell(), url);
54 // Navigate session history using history.go(distance).
55 void JavascriptGo(std::string distance) {
56 GURL url("javascript:history.go('" + distance + "')");
57 NavigateToURL(shell(), url);
60 std::string GetTabTitle() {
61 return UTF16ToASCII(shell()->web_contents()->GetTitle());
64 GURL GetTabURL() {
65 return shell()->web_contents()->GetURL();
68 GURL GetURL(const std::string file) {
69 return test_server()->GetURL(std::string("files/session_history/") + file);
72 void NavigateAndCheckTitle(const char* filename,
73 const std::string& expected_title) {
74 string16 expected_title16(ASCIIToUTF16(expected_title));
75 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
76 NavigateToURL(shell(), GetURL(filename));
77 ASSERT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
80 bool CanGoBack() {
81 return shell()->web_contents()->GetController().CanGoBack();
84 bool CanGoForward() {
85 return shell()->web_contents()->GetController().CanGoForward();
88 void GoBack() {
89 WindowedNotificationObserver load_stop_observer(
90 NOTIFICATION_LOAD_STOP,
91 NotificationService::AllSources());
92 shell()->web_contents()->GetController().GoBack();
93 load_stop_observer.Wait();
96 void GoForward() {
97 WindowedNotificationObserver load_stop_observer(
98 NOTIFICATION_LOAD_STOP,
99 NotificationService::AllSources());
100 shell()->web_contents()->GetController().GoForward();
101 load_stop_observer.Wait();
105 // If this flakes, use http://crbug.com/61619 on windows and
106 // http://crbug.com/102094 on mac.
107 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, BasicBackForward) {
108 ASSERT_FALSE(CanGoBack());
110 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot1.html", "bot1"));
111 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot2.html", "bot2"));
112 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot3.html", "bot3"));
114 // history is [blank, bot1, bot2, *bot3]
116 GoBack();
117 EXPECT_EQ("bot2", GetTabTitle());
119 GoBack();
120 EXPECT_EQ("bot1", GetTabTitle());
122 GoForward();
123 EXPECT_EQ("bot2", GetTabTitle());
125 GoBack();
126 EXPECT_EQ("bot1", GetTabTitle());
128 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot3.html", "bot3"));
130 // history is [blank, bot1, *bot3]
132 ASSERT_FALSE(CanGoForward());
133 EXPECT_EQ("bot3", GetTabTitle());
135 GoBack();
136 EXPECT_EQ("bot1", GetTabTitle());
138 GoBack();
139 EXPECT_EQ("about:blank", GetTabTitle());
141 ASSERT_FALSE(CanGoBack());
142 EXPECT_EQ("about:blank", GetTabTitle());
144 GoForward();
145 EXPECT_EQ("bot1", GetTabTitle());
147 GoForward();
148 EXPECT_EQ("bot3", GetTabTitle());
151 // Test that back/forward works when navigating in subframes.
152 // If this flakes, use http://crbug.com/48833
153 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, FrameBackForward) {
154 ASSERT_FALSE(CanGoBack());
156 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("frames.html", "bot1"));
158 ClickLink("abot2");
159 EXPECT_EQ("bot2", GetTabTitle());
160 GURL frames(GetURL("frames.html"));
161 EXPECT_EQ(frames, GetTabURL());
163 ClickLink("abot3");
164 EXPECT_EQ("bot3", GetTabTitle());
165 EXPECT_EQ(frames, GetTabURL());
167 // history is [blank, bot1, bot2, *bot3]
169 GoBack();
170 EXPECT_EQ("bot2", GetTabTitle());
171 EXPECT_EQ(frames, GetTabURL());
173 GoBack();
174 EXPECT_EQ("bot1", GetTabTitle());
175 EXPECT_EQ(frames, GetTabURL());
177 GoBack();
178 EXPECT_EQ("about:blank", GetTabTitle());
179 EXPECT_EQ(GURL(chrome::kAboutBlankURL), GetTabURL());
181 GoForward();
182 EXPECT_EQ("bot1", GetTabTitle());
183 EXPECT_EQ(frames, GetTabURL());
185 GoForward();
186 EXPECT_EQ("bot2", GetTabTitle());
187 EXPECT_EQ(frames, GetTabURL());
189 ClickLink("abot1");
190 EXPECT_EQ("bot1", GetTabTitle());
191 EXPECT_EQ(frames, GetTabURL());
193 // history is [blank, bot1, bot2, *bot1]
195 ASSERT_FALSE(CanGoForward());
196 EXPECT_EQ("bot1", GetTabTitle());
197 EXPECT_EQ(frames, GetTabURL());
199 GoBack();
200 EXPECT_EQ("bot2", GetTabTitle());
201 EXPECT_EQ(frames, GetTabURL());
203 GoBack();
204 EXPECT_EQ("bot1", GetTabTitle());
205 EXPECT_EQ(frames, GetTabURL());
208 // Test that back/forward preserves POST data and document state in subframes.
209 // If this flakes use http://crbug.com/61619
210 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, FrameFormBackForward) {
211 ASSERT_FALSE(CanGoBack());
213 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("frames.html", "bot1"));
215 ClickLink("aform");
216 EXPECT_EQ("form", GetTabTitle());
217 GURL frames(GetURL("frames.html"));
218 EXPECT_EQ(frames, GetTabURL());
220 SubmitForm("isubmit");
221 EXPECT_EQ("text=&select=a", GetTabTitle());
222 EXPECT_EQ(frames, GetTabURL());
224 GoBack();
225 EXPECT_EQ("form", GetTabTitle());
226 EXPECT_EQ(frames, GetTabURL());
228 // history is [blank, bot1, *form, post]
230 ClickLink("abot2");
231 EXPECT_EQ("bot2", GetTabTitle());
232 EXPECT_EQ(frames, GetTabURL());
234 // history is [blank, bot1, form, *bot2]
236 GoBack();
237 EXPECT_EQ("form", GetTabTitle());
238 EXPECT_EQ(frames, GetTabURL());
240 SubmitForm("isubmit");
241 EXPECT_EQ("text=&select=a", GetTabTitle());
242 EXPECT_EQ(frames, GetTabURL());
244 // history is [blank, bot1, form, *post]
246 // TODO(mpcomplete): reenable this when WebKit bug 10199 is fixed:
247 // "returning to a POST result within a frame does a GET instead of a POST"
248 ClickLink("abot2");
249 EXPECT_EQ("bot2", GetTabTitle());
250 EXPECT_EQ(frames, GetTabURL());
252 GoBack();
253 EXPECT_EQ("text=&select=a", GetTabTitle());
254 EXPECT_EQ(frames, GetTabURL());
257 // TODO(mpcomplete): enable this when Bug 734372 is fixed:
258 // "Doing a session history navigation does not restore newly-created subframe
259 // document state"
260 // Test that back/forward preserves POST data and document state when navigating
261 // across frames (ie, from frame -> nonframe).
262 // Hangs, see http://crbug.com/45058.
263 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, CrossFrameFormBackForward) {
264 ASSERT_FALSE(CanGoBack());
266 GURL frames(GetURL("frames.html"));
267 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("frames.html", "bot1"));
269 ClickLink("aform");
270 EXPECT_EQ("form", GetTabTitle());
271 EXPECT_EQ(frames, GetTabURL());
273 SubmitForm("isubmit");
274 EXPECT_EQ("text=&select=a", GetTabTitle());
275 EXPECT_EQ(frames, GetTabURL());
277 GoBack();
278 EXPECT_EQ("form", GetTabTitle());
279 EXPECT_EQ(frames, GetTabURL());
281 // history is [blank, bot1, *form, post]
283 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot2.html", "bot2"));
285 // history is [blank, bot1, form, *bot2]
287 GoBack();
288 EXPECT_EQ("bot1", GetTabTitle());
289 EXPECT_EQ(frames, GetTabURL());
291 SubmitForm("isubmit");
292 EXPECT_EQ("text=&select=a", GetTabTitle());
293 EXPECT_EQ(frames, GetTabURL());
296 // Test that back/forward entries are created for reference fragment
297 // navigations. Bug 730379.
298 // If this flakes use http://crbug.com/61619.
299 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, FragmentBackForward) {
300 ASSERT_FALSE(CanGoBack());
302 GURL fragment(GetURL("fragment.html"));
303 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("fragment.html", "fragment"));
305 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("fragment.html#a", "fragment"));
306 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("fragment.html#b", "fragment"));
307 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("fragment.html#c", "fragment"));
309 // history is [blank, fragment, fragment#a, fragment#b, *fragment#c]
311 GoBack();
312 EXPECT_EQ(GetURL("fragment.html#b"), GetTabURL());
314 GoBack();
315 EXPECT_EQ(GetURL("fragment.html#a"), GetTabURL());
317 GoBack();
318 EXPECT_EQ(GetURL("fragment.html"), GetTabURL());
320 GoForward();
321 EXPECT_EQ(GetURL("fragment.html#a"), GetTabURL());
323 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot3.html", "bot3"));
325 // history is [blank, fragment, fragment#a, bot3]
327 ASSERT_FALSE(CanGoForward());
328 EXPECT_EQ(GetURL("bot3.html"), GetTabURL());
330 GoBack();
331 EXPECT_EQ(GetURL("fragment.html#a"), GetTabURL());
333 GoBack();
334 EXPECT_EQ(GetURL("fragment.html"), GetTabURL());
337 // Test that the javascript window.history object works.
338 // NOTE: history.go(N) does not do anything if N is outside the bounds of the
339 // back/forward list (such as trigger our start/stop loading events). This
340 // means the test will hang if it attempts to navigate too far forward or back,
341 // since we'll be waiting forever for a load stop event.
343 // TODO(brettw) bug 50648: fix flakyness. This test seems like it was failing
344 // about 1/4 of the time on Vista by failing to execute JavascriptGo (see bug).
345 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, JavascriptHistory) {
346 ASSERT_FALSE(CanGoBack());
348 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot1.html", "bot1"));
349 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot2.html", "bot2"));
350 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot3.html", "bot3"));
352 // history is [blank, bot1, bot2, *bot3]
354 JavascriptGo("-1");
355 EXPECT_EQ("bot2", GetTabTitle());
357 JavascriptGo("-1");
358 EXPECT_EQ("bot1", GetTabTitle());
360 JavascriptGo("1");
361 EXPECT_EQ("bot2", GetTabTitle());
363 JavascriptGo("-1");
364 EXPECT_EQ("bot1", GetTabTitle());
366 JavascriptGo("2");
367 EXPECT_EQ("bot3", GetTabTitle());
369 // history is [blank, bot1, bot2, *bot3]
371 JavascriptGo("-3");
372 EXPECT_EQ("about:blank", GetTabTitle());
374 ASSERT_FALSE(CanGoBack());
375 EXPECT_EQ("about:blank", GetTabTitle());
377 JavascriptGo("1");
378 EXPECT_EQ("bot1", GetTabTitle());
380 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle("bot3.html", "bot3"));
382 // history is [blank, bot1, *bot3]
384 ASSERT_FALSE(CanGoForward());
385 EXPECT_EQ("bot3", GetTabTitle());
387 JavascriptGo("-1");
388 EXPECT_EQ("bot1", GetTabTitle());
390 JavascriptGo("-1");
391 EXPECT_EQ("about:blank", GetTabTitle());
393 ASSERT_FALSE(CanGoBack());
394 EXPECT_EQ("about:blank", GetTabTitle());
396 JavascriptGo("1");
397 EXPECT_EQ("bot1", GetTabTitle());
399 JavascriptGo("1");
400 EXPECT_EQ("bot3", GetTabTitle());
402 // TODO(creis): Test that JavaScript history navigations work across tab
403 // types. For example, load about:network in a tab, then a real page, then
404 // try to go back and forward with JavaScript. Bug 1136715.
405 // (Hard to test right now, because pages like about:network cause the
406 // TabProxy to hang. This is because they do not appear to use the
407 // NotificationService.)
410 // This test is failing consistently. See http://crbug.com/22560
411 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, LocationReplace) {
412 // Test that using location.replace doesn't leave the title of the old page
413 // visible.
414 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle(
415 "replace.html?bot1.html", "bot1"));
418 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, LocationChangeInSubframe) {
419 ASSERT_NO_FATAL_FAILURE(NavigateAndCheckTitle(
420 "location_redirect.html", "Default Title"));
422 NavigateToURL(shell(), GURL("javascript:void(frames[0].navigate())"));
423 EXPECT_EQ("foo", GetTabTitle());
425 GoBack();
426 EXPECT_EQ("Default Title", GetTabTitle());
429 // http://code.google.com/p/chromium/issues/detail?id=56267
430 IN_PROC_BROWSER_TEST_F(SessionHistoryTest, HistoryLength) {
431 int length;
432 ASSERT_TRUE(ExecuteJavaScriptAndExtractInt(
433 shell()->web_contents()->GetRenderViewHost(),
434 L"", L"domAutomationController.send(history.length)", &length));
435 EXPECT_EQ(1, length);
437 NavigateToURL(shell(), GetURL("title1.html"));
439 ASSERT_TRUE(ExecuteJavaScriptAndExtractInt(
440 shell()->web_contents()->GetRenderViewHost(),
441 L"", L"domAutomationController.send(history.length)", &length));
442 EXPECT_EQ(2, length);
444 // Now test that history.length is updated when the navigation is committed.
445 NavigateToURL(shell(), GetURL("record_length.html"));
447 ASSERT_TRUE(ExecuteJavaScriptAndExtractInt(
448 shell()->web_contents()->GetRenderViewHost(),
449 L"", L"domAutomationController.send(history.length)", &length));
450 EXPECT_EQ(3, length);
452 GoBack();
453 GoBack();
455 // Ensure history.length is properly truncated.
456 NavigateToURL(shell(), GetURL("title2.html"));
458 ASSERT_TRUE(ExecuteJavaScriptAndExtractInt(
459 shell()->web_contents()->GetRenderViewHost(),
460 L"", L"domAutomationController.send(history.length)", &length));
461 EXPECT_EQ(2, length);
464 } // namespace content