OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/memory/scoped_temp_dir.h" | 8 #include "base/memory/scoped_temp_dir.h" |
9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 std::string CreateClientRedirect(const std::string& dest_url) { | 46 std::string CreateClientRedirect(const std::string& dest_url) { |
47 const char* const kClientRedirectBase = "client-redirect?"; | 47 const char* const kClientRedirectBase = "client-redirect?"; |
48 return kClientRedirectBase + dest_url; | 48 return kClientRedirectBase + dest_url; |
49 } | 49 } |
50 | 50 |
51 std::string CreateServerRedirect(const std::string& dest_url) { | 51 std::string CreateServerRedirect(const std::string& dest_url) { |
52 const char* const kServerRedirectBase = "server-redirect?"; | 52 const char* const kServerRedirectBase = "server-redirect?"; |
53 return kServerRedirectBase + dest_url; | 53 return kServerRedirectBase + dest_url; |
54 } | 54 } |
55 | 55 |
| 56 // Returns true iff the final status is one in which the prerendered |
| 57 // page should prerender correctly. The page still may not be used. |
| 58 bool ShouldRenderPrerenderedPageCorrectly(FinalStatus status) { |
| 59 switch (status) { |
| 60 case FINAL_STATUS_USED: |
| 61 case FINAL_STATUS_WINDOW_OPENER: |
| 62 return true; |
| 63 default: |
| 64 return false; |
| 65 } |
| 66 } |
| 67 |
56 // PrerenderContents that stops the UI message loop on DidStopLoading(). | 68 // PrerenderContents that stops the UI message loop on DidStopLoading(). |
57 class TestPrerenderContents : public PrerenderContents { | 69 class TestPrerenderContents : public PrerenderContents { |
58 public: | 70 public: |
59 TestPrerenderContents( | 71 TestPrerenderContents( |
60 PrerenderManager* prerender_manager, | 72 PrerenderManager* prerender_manager, |
61 Profile* profile, | 73 Profile* profile, |
62 const GURL& url, | 74 const GURL& url, |
63 const GURL& referrer, | 75 const GURL& referrer, |
64 int number_of_loads, | 76 int number_of_loads, |
65 FinalStatus expected_final_status) | 77 FinalStatus expected_final_status) |
(...skipping 23 matching lines...) Expand all Loading... |
89 if (final_status() == FINAL_STATUS_USED) { | 101 if (final_status() == FINAL_STATUS_USED) { |
90 EXPECT_TRUE(new_render_view_host_); | 102 EXPECT_TRUE(new_render_view_host_); |
91 EXPECT_TRUE(was_shown_); | 103 EXPECT_TRUE(was_shown_); |
92 } else { | 104 } else { |
93 EXPECT_FALSE(was_shown_); | 105 EXPECT_FALSE(was_shown_); |
94 } | 106 } |
95 | 107 |
96 // When the PrerenderContents is destroyed, quit the UI message loop. | 108 // When the PrerenderContents is destroyed, quit the UI message loop. |
97 // This happens on navigation to used prerendered pages, and soon | 109 // This happens on navigation to used prerendered pages, and soon |
98 // after cancellation of unused prerendered pages. | 110 // after cancellation of unused prerendered pages. |
| 111 MessageLoopForUI::current()->RunAllPending(); |
99 MessageLoopForUI::current()->Quit(); | 112 MessageLoopForUI::current()->Quit(); |
100 } | 113 } |
101 | 114 |
102 virtual void OnRenderViewGone(int status, int exit_code) OVERRIDE { | 115 virtual void OnRenderViewGone(int status, int exit_code) OVERRIDE { |
103 // On quit, it's possible to end up here when render processes are closed | 116 // On quit, it's possible to end up here when render processes are closed |
104 // before the PrerenderManager is destroyed. As a result, it's possible to | 117 // before the PrerenderManager is destroyed. As a result, it's possible to |
105 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED | 118 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED |
106 // on quit. | 119 // on quit. |
107 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING) | 120 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING) |
108 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED; | 121 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED; |
109 | 122 |
110 PrerenderContents::OnRenderViewGone(status, exit_code); | 123 PrerenderContents::OnRenderViewGone(status, exit_code); |
111 } | 124 } |
112 | 125 |
113 virtual void DidStopLoading() OVERRIDE { | 126 virtual void DidStopLoading() OVERRIDE { |
114 PrerenderContents::DidStopLoading(); | 127 PrerenderContents::DidStopLoading(); |
115 ++number_of_loads_; | 128 ++number_of_loads_; |
116 if (expected_final_status_ == FINAL_STATUS_USED && | 129 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status_) && |
117 number_of_loads_ >= expected_number_of_loads_) { | 130 number_of_loads_ >= expected_number_of_loads_) { |
118 MessageLoopForUI::current()->Quit(); | 131 MessageLoopForUI::current()->Quit(); |
119 } else if (expected_final_status_ == FINAL_STATUS_RENDERER_CRASHED) { | 132 } else if (expected_final_status_ == FINAL_STATUS_RENDERER_CRASHED) { |
120 // Crash the render process. This has to be done here because | 133 // Crash the render process. This has to be done here because |
121 // a prerender navigating to about:crash is cancelled with | 134 // a prerender navigating to about:crash is cancelled with |
122 // "FINAL_STATUS_HTTPS". Even if this were worked around, | 135 // "FINAL_STATUS_HTTPS". Even if this were worked around, |
123 // about:crash can't be navigated to by a normal webpage. | 136 // about:crash can't be navigated to by a normal webpage. |
124 render_view_host_mutable()->NavigateToURL(GURL("about:crash")); | 137 render_view_host_mutable()->NavigateToURL(GURL("about:crash")); |
125 } | 138 } |
126 } | 139 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 ASSERT_TRUE(test_server()->Start()); | 290 ASSERT_TRUE(test_server()->Start()); |
278 std::deque<FinalStatus> expected_final_status_queue(1, | 291 std::deque<FinalStatus> expected_final_status_queue(1, |
279 expected_final_status); | 292 expected_final_status); |
280 PrerenderTestURLImpl(url, expected_final_status_queue, total_navigations); | 293 PrerenderTestURLImpl(url, expected_final_status_queue, total_navigations); |
281 } | 294 } |
282 | 295 |
283 void NavigateToDestURL() const { | 296 void NavigateToDestURL() const { |
284 NavigateToURLImpl(dest_url_); | 297 NavigateToURLImpl(dest_url_); |
285 } | 298 } |
286 | 299 |
| 300 void OpenDestUrlInNewWindowViaJs() const { |
| 301 // Make sure in navigating we have a URL to use in the PrerenderManager. |
| 302 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) != NULL); |
| 303 |
| 304 bool open_window_result = false; |
| 305 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
| 306 browser()->GetSelectedTabContents()->render_view_host(), L"", |
| 307 L"window.domAutomationController.send(JsOpenLinkInNewWindow())", |
| 308 &open_window_result)); |
| 309 EXPECT_TRUE(open_window_result); |
| 310 } |
| 311 |
| 312 void OpenDestUrlInNewWindowViaClick() const { |
| 313 // Make sure in navigating we have a URL to use in the PrerenderManager. |
| 314 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) != NULL); |
| 315 |
| 316 bool click_prerendered_link_result = false; |
| 317 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
| 318 browser()->GetSelectedTabContents()->render_view_host(), L"", |
| 319 L"window.domAutomationController.send(ClickOpenLinkInNewWindow())", |
| 320 &click_prerendered_link_result)); |
| 321 EXPECT_TRUE(click_prerendered_link_result); |
| 322 } |
| 323 |
287 // Should be const but test_server()->GetURL(...) is not const. | 324 // Should be const but test_server()->GetURL(...) is not const. |
288 void NavigateToURL(const std::string& dest_html_file) { | 325 void NavigateToURL(const std::string& dest_html_file) { |
289 GURL dest_url = test_server()->GetURL(dest_html_file); | 326 GURL dest_url = test_server()->GetURL(dest_html_file); |
290 NavigateToURLImpl(dest_url); | 327 NavigateToURLImpl(dest_url); |
291 } | 328 } |
292 | 329 |
293 bool UrlIsInPrerenderManager(const std::string& html_file) { | 330 bool UrlIsInPrerenderManager(const std::string& html_file) { |
294 GURL dest_url = test_server()->GetURL(html_file); | 331 GURL dest_url = test_server()->GetURL(html_file); |
295 return (prerender_manager()->FindEntry(dest_url) != NULL); | 332 return (prerender_manager()->FindEntry(dest_url) != NULL); |
296 } | 333 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // handle browser navigation directly. | 404 // handle browser navigation directly. |
368 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); | 405 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); |
369 | 406 |
370 TestPrerenderContents* prerender_contents = NULL; | 407 TestPrerenderContents* prerender_contents = NULL; |
371 ui_test_utils::RunMessageLoop(); | 408 ui_test_utils::RunMessageLoop(); |
372 | 409 |
373 prerender_contents = | 410 prerender_contents = |
374 static_cast<TestPrerenderContents*>( | 411 static_cast<TestPrerenderContents*>( |
375 prerender_manager()->FindEntry(dest_url_)); | 412 prerender_manager()->FindEntry(dest_url_)); |
376 | 413 |
377 switch (expected_final_status) { | 414 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { |
378 case FINAL_STATUS_USED: { | 415 ASSERT_TRUE(prerender_contents != NULL); |
379 ASSERT_TRUE(prerender_contents != NULL); | 416 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); |
380 | 417 |
381 if (call_javascript_) { | 418 if (call_javascript_) { |
382 // Check if page behaves as expected while in prerendered state. | 419 // Check if page behaves as expected while in prerendered state. |
383 bool prerender_test_result = false; | 420 bool prerender_test_result = false; |
384 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( | 421 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
385 prerender_contents->render_view_host_mutable(), L"", | 422 prerender_contents->render_view_host_mutable(), L"", |
386 L"window.domAutomationController.send(DidPrerenderPass())", | 423 L"window.domAutomationController.send(DidPrerenderPass())", |
387 &prerender_test_result)); | 424 &prerender_test_result)); |
388 EXPECT_TRUE(prerender_test_result); | 425 EXPECT_TRUE(prerender_test_result); |
389 } | |
390 break; | |
391 } | 426 } |
392 default: | 427 } else { |
393 // In the failure case, we should have removed dest_url_ from the | 428 // In the failure case, we should have removed dest_url_ from the |
394 // prerender_manager. | 429 // prerender_manager. |
395 EXPECT_TRUE(prerender_contents == NULL); | 430 EXPECT_TRUE(prerender_contents == NULL); |
396 break; | |
397 } | 431 } |
398 } | 432 } |
399 | 433 |
400 void NavigateToURLImpl(const GURL& dest_url) const { | 434 void NavigateToURLImpl(const GURL& dest_url) const { |
401 // Make sure in navigating we have a URL to use in the PrerenderManager. | 435 // Make sure in navigating we have a URL to use in the PrerenderManager. |
402 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) != NULL); | 436 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) != NULL); |
403 | 437 |
404 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on | 438 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on |
405 // the current tab. As that tab is going to end up deleted, and may never | 439 // the current tab. As that tab is going to end up deleted, and may never |
406 // finish loading before that happens, exit the message loop on the deletion | 440 // finish loading before that happens, exit the message loop on the deletion |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 NavigateToDestURL(); | 1108 NavigateToDestURL(); |
1075 } | 1109 } |
1076 | 1110 |
1077 // Checks that we cancel correctly when window.print() is called. | 1111 // Checks that we cancel correctly when window.print() is called. |
1078 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) { | 1112 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) { |
1079 PrerenderTestURL("files/prerender/prerender_print.html", | 1113 PrerenderTestURL("files/prerender/prerender_print.html", |
1080 FINAL_STATUS_WINDOW_PRINT, | 1114 FINAL_STATUS_WINDOW_PRINT, |
1081 1); | 1115 1); |
1082 } | 1116 } |
1083 | 1117 |
| 1118 // Checks that if a page is opened in a new window by javascript the |
| 1119 // prerendered page is not used. |
| 1120 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, |
| 1121 PrerenderWindowOpenerJsOpenInNewPageTest) { |
| 1122 PrerenderTestURL("files/prerender/prerender_page.html", |
| 1123 FINAL_STATUS_WINDOW_OPENER, |
| 1124 1); |
| 1125 OpenDestUrlInNewWindowViaJs(); |
| 1126 } |
| 1127 |
| 1128 // Checks that if a page is opened due to click on a href with target="_blank" |
| 1129 // the prerendered page is not used. |
| 1130 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, |
| 1131 PrerenderWindowOpenerClickOpenInNewPageTest) { |
| 1132 PrerenderTestURL("files/prerender/prerender_page.html", |
| 1133 FINAL_STATUS_WINDOW_OPENER, |
| 1134 1); |
| 1135 OpenDestUrlInNewWindowViaClick(); |
| 1136 } |
| 1137 |
| 1138 // TODO(shishir): Add a test for the case when the page having the |
| 1139 // prerendering link already has an opener set. |
| 1140 |
1084 } // namespace prerender | 1141 } // namespace prerender |
OLD | NEW |