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 | |
dominich
2011/05/16 22:21:12
nit: 'if'
| |
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 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1067 std::make_pair("REPLACE_WITH_URL", https_url.spec())); | 1101 std::make_pair("REPLACE_WITH_URL", https_url.spec())); |
1068 std::string replacement_path; | 1102 std::string replacement_path; |
1069 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( | 1103 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( |
1070 "files/prerender/prerender_with_iframe.html", | 1104 "files/prerender/prerender_with_iframe.html", |
1071 replacement_text, | 1105 replacement_text, |
1072 &replacement_path)); | 1106 &replacement_path)); |
1073 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); | 1107 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); |
1074 NavigateToDestURL(); | 1108 NavigateToDestURL(); |
1075 } | 1109 } |
1076 | 1110 |
1111 // Checks that if a page is opened in a new window by javascript the | |
1112 // prerendered page is not used. | |
1113 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, | |
1114 PrerenderWindowOpenerJsOpenInNewPageTest) { | |
1115 PrerenderTestURL("files/prerender/prerender_page.html", | |
1116 FINAL_STATUS_WINDOW_OPENER, | |
1117 1); | |
1118 OpenDestUrlInNewWindowViaJs(); | |
1119 } | |
1120 | |
1121 // Checks that if a page is opened due to click on a href with target="_blank" | |
1122 // the prerendered page is not used. | |
1123 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, | |
1124 PrerenderWindowOpenerClickOpenInNewPageTest) { | |
1125 PrerenderTestURL("files/prerender/prerender_page.html", | |
1126 FINAL_STATUS_WINDOW_OPENER, | |
1127 1); | |
1128 OpenDestUrlInNewWindowViaClick(); | |
1129 } | |
1130 | |
1131 // TODO(shishir): Add a test for the case when the page having the | |
1132 // prerendering link already has an opener set. | |
1133 | |
1077 } // namespace prerender | 1134 } // namespace prerender |
OLD | NEW |