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 3 // found in the LICENSE file. 4 5 #include "base/command_line.h" 6 #include "base/path_service.h" 7 #include "base/string_util.h" 8 #include "chrome/browser/prerender/prerender_contents.h" 9 #include "chrome/browser/prerender/prerender_manager.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/task_manager/task_manager.h" 12 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser_window.h" 14 #include "chrome/common/chrome_paths.h" 15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/test/in_process_browser_test.h" 17 #include "chrome/test/ui_test_utils.h" 18 #include "content/browser/tab_contents/tab_contents.h" 19 #include "grit/generated_resources.h" 20 #include "net/url_request/url_request_context.h" 21 #include "net/url_request/url_request_context_getter.h" 22 #include "ui/base/l10n/l10n_util.h" 23 24 #include <deque> 25 26 // Prerender tests work as follows: 27 // 28 // A page with a prefetch link to the test page is loaded. Once prerendered, 29 // its Javascript function DidPrerenderPass() is called, which returns true if 30 // the page behaves as expected when prerendered. 31 // 32 // The prerendered page is then displayed on a tab. The Javascript function 33 // DidDisplayPass() is called, and returns true if the page behaved as it 34 // should while being displayed. 35 36 namespace prerender { 37 38 namespace { 39 40 std::string CreateClientRedirect(const std::string& dest_url) { 41 const char* const kClientRedirectBase = "client-redirect?"; 42 return kClientRedirectBase + dest_url; 43 } 44 45 std::string CreateServerRedirect(const std::string& dest_url) { 46 const char* const kServerRedirectBase = "server-redirect?"; 47 return kServerRedirectBase + dest_url; 48 } 49 50 // PrerenderContents that stops the UI message loop on DidStopLoading(). 51 class TestPrerenderContents : public PrerenderContents { 52 public: 53 TestPrerenderContents( 54 PrerenderManager* prerender_manager, Profile* profile, const GURL& url, 55 const std::vector<GURL>& alias_urls, 56 const GURL& referrer, 57 int number_of_loads, 58 FinalStatus expected_final_status) 59 : PrerenderContents(prerender_manager, profile, url, alias_urls, 60 referrer), 61 number_of_loads_(0), 62 expected_number_of_loads_(number_of_loads), 63 expected_final_status_(expected_final_status) { 64 } 65 66 virtual ~TestPrerenderContents() { 67 EXPECT_EQ(expected_final_status_, final_status()) << 68 " when testing URL " << prerender_url().path(); 69 // In the event we are destroyed, say if the prerender was canceled, quit 70 // the UI message loop. 71 MessageLoopForUI::current()->Quit(); 72 } 73 74 virtual void DidStopLoading() { 75 PrerenderContents::DidStopLoading(); 76 ++number_of_loads_; 77 if (expected_final_status_ == FINAL_STATUS_USED && 78 number_of_loads_ >= expected_number_of_loads_) { 79 MessageLoopForUI::current()->Quit(); 80 } 81 } 82 83 private: 84 int number_of_loads_; 85 int expected_number_of_loads_; 86 FinalStatus expected_final_status_; 87 }; 88 89 // PrerenderManager that uses TestPrerenderContents. 90 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { 91 public: 92 WaitForLoadPrerenderContentsFactory( 93 int number_of_loads, 94 const std::deque<FinalStatus>& expected_final_status_queue) 95 : number_of_loads_(number_of_loads) { 96 expected_final_status_queue_.resize(expected_final_status_queue.size()); 97 std::copy(expected_final_status_queue.begin(), 98 expected_final_status_queue.end(), 99 expected_final_status_queue_.begin()); 100 LOG(INFO) << "Factory created with queue length " << 101 expected_final_status_queue_.size(); 102 } 103 104 virtual PrerenderContents* CreatePrerenderContents( 105 PrerenderManager* prerender_manager, Profile* profile, const GURL& url, 106 const std::vector<GURL>& alias_urls, const GURL& referrer) { 107 CHECK(!expected_final_status_queue_.empty()) << 108 "Creating prerender contents for " << url.path() << 109 " with no expected final status"; 110 FinalStatus expected_final_status = expected_final_status_queue_.front(); 111 expected_final_status_queue_.pop_front(); 112 LOG(INFO) << "Creating prerender contents for " << url.path() << 113 " with expected final status " << expected_final_status; 114 LOG(INFO) << expected_final_status_queue_.size() << " left in the queue."; 115 return new TestPrerenderContents(prerender_manager, profile, url, 116 alias_urls, referrer, 117 number_of_loads_, 118 expected_final_status); 119 } 120 121 private: 122 int number_of_loads_; 123 std::deque<FinalStatus> expected_final_status_queue_; 124 }; 125 126 } // namespace 127 128 class PrerenderBrowserTest : public InProcessBrowserTest { 129 public: 130 PrerenderBrowserTest() 131 : prc_factory_(NULL), 132 use_https_src_server_(false) { 133 EnableDOMAutomation(); 134 } 135 136 virtual void SetUpCommandLine(CommandLine* command_line) { 137 command_line->AppendSwitchASCII(switches::kPrerender, 138 switches::kPrerenderSwitchValueEnabled); 139 #if defined(OS_MACOSX) 140 // The plugins directory isn't read by default on the Mac, so it needs to be 141 // explicitly registered. 142 FilePath app_dir; 143 PathService::Get(chrome::DIR_APP, &app_dir); 144 command_line->AppendSwitchPath( 145 switches::kExtraPluginDir, 146 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 147 #endif 148 } 149 150 // Overload for a single expected final status 151 void PrerenderTestURL(const std::string& html_file, 152 FinalStatus expected_final_status, 153 int total_navigations) { 154 std::deque<FinalStatus> expected_final_status_queue(1, 155 expected_final_status); 156 PrerenderTestURLImpl(html_file, 157 expected_final_status_queue, 158 total_navigations); 159 } 160 161 void PrerenderTestURL( 162 const std::string& html_file, 163 const std::deque<FinalStatus>& expected_final_status_queue, 164 int total_navigations) { 165 PrerenderTestURLImpl(html_file, 166 expected_final_status_queue, 167 total_navigations); 168 } 169 170 void NavigateToDestURL() const { 171 ui_test_utils::NavigateToURL(browser(), dest_url_); 172 173 // Make sure the PrerenderContents found earlier was used or removed 174 EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) == NULL); 175 176 // Check if page behaved as expected when actually displayed. 177 bool display_test_result = false; 178 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 179 browser()->GetSelectedTabContents()->render_view_host(), L"", 180 L"window.domAutomationController.send(DidDisplayPass())", 181 &display_test_result)); 182 EXPECT_TRUE(display_test_result); 183 } 184 185 bool UrlIsInPrerenderManager(const std::string& html_file) { 186 GURL dest_url = test_server()->GetURL(html_file); 187 return (prerender_manager()->FindEntry(dest_url) != NULL); 188 } 189 190 bool UrlIsInPrerenderManager(const GURL& url) { 191 return (prerender_manager()->FindEntry(url) != NULL); 192 } 193 194 bool UrlIsPendingInPrerenderManager(const std::string& html_file) { 195 GURL dest_url = test_server()->GetURL(html_file); 196 return (prerender_manager()->FindPendingEntry(dest_url) != NULL); 197 } 198 199 void set_use_https_src(bool use_https_src_server) { 200 use_https_src_server_ = use_https_src_server; 201 } 202 203 TaskManagerModel* model() const { 204 return TaskManager::GetInstance()->model(); 205 } 206 207 void set_dest_url(const GURL& dest_url) { dest_url_ = dest_url; } 208 209 private: 210 void PrerenderTestURLImpl( 211 const std::string& html_file, 212 const std::deque<FinalStatus>& expected_final_status_queue, 213 int total_navigations) { 214 ASSERT_TRUE(test_server()->Start()); 215 dest_url_ = test_server()->GetURL(html_file); 216 217 std::vector<net::TestServer::StringPair> replacement_text; 218 replacement_text.push_back( 219 make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec())); 220 std::string replacement_path; 221 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 222 "files/prerender/prerender_loader.html", 223 replacement_text, 224 &replacement_path)); 225 226 net::TestServer* src_server = test_server(); 227 scoped_ptr<net::TestServer> https_src_server; 228 if (use_https_src_server_) { 229 https_src_server.reset( 230 new net::TestServer(net::TestServer::TYPE_HTTPS, 231 FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 232 ASSERT_TRUE(https_src_server->Start()); 233 src_server = https_src_server.get(); 234 } 235 GURL src_url = src_server->GetURL(replacement_path); 236 237 // This is needed to exit the event loop once the prerendered page has 238 // stopped loading or was cancelled. 239 ASSERT_TRUE(prerender_manager()); 240 prerender_manager()->rate_limit_enabled_ = false; 241 ASSERT_TRUE(prc_factory_ == NULL); 242 prc_factory_ = 243 new WaitForLoadPrerenderContentsFactory(total_navigations, 244 expected_final_status_queue); 245 prerender_manager()->SetPrerenderContentsFactory(prc_factory_); 246 FinalStatus expected_final_status = expected_final_status_queue.front(); 247 248 // ui_test_utils::NavigateToURL uses its own observer and message loop. 249 // Since the test needs to wait until the prerendered page has stopped 250 // loading, rathather than the page directly navigated to, need to 251 // handle browser navigation directly. 252 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 253 254 TestPrerenderContents* prerender_contents = NULL; 255 ui_test_utils::RunMessageLoop(); 256 257 prerender_contents = 258 static_cast<TestPrerenderContents*>( 259 prerender_manager()->FindEntry(dest_url_)); 260 261 switch (expected_final_status) { 262 case FINAL_STATUS_USED: { 263 ASSERT_TRUE(prerender_contents != NULL); 264 265 // Check if page behaves as expected while in prerendered state. 266 bool prerender_test_result = false; 267 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 268 prerender_contents->render_view_host(), L"", 269 L"window.domAutomationController.send(DidPrerenderPass())", 270 &prerender_test_result)); 271 EXPECT_TRUE(prerender_test_result); 272 break; 273 } 274 default: 275 // In the failure case, we should have removed dest_url_ from the 276 // prerender_manager. 277 EXPECT_TRUE(prerender_contents == NULL); 278 break; 279 } 280 } 281 282 PrerenderManager* prerender_manager() const { 283 Profile* profile = browser()->GetSelectedTabContents()->profile(); 284 PrerenderManager* prerender_manager = profile->GetPrerenderManager(); 285 return prerender_manager; 286 } 287 288 WaitForLoadPrerenderContentsFactory* prc_factory_; 289 GURL dest_url_; 290 bool use_https_src_server_; 291 }; 292 293 // Checks that a page is correctly prerendered in the case of a 294 // <link rel=prefetch> tag and then loaded into a tab in response to a 295 // navigation. 296 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 297 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 298 NavigateToDestURL(); 299 } 300 301 // Checks that the prerendering of a page is canceled correctly when a 302 // Javascript alert is called. 303 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 304 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 305 FINAL_STATUS_JAVASCRIPT_ALERT, 306 1); 307 } 308 309 // Checks that the prerendering of a page is canceled correctly when a 310 // Javascript alert is called. 311 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 312 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html", 313 FINAL_STATUS_JAVASCRIPT_ALERT, 314 1); 315 } 316 317 // Checks that plugins are not loaded while a page is being preloaded, but 318 // are loaded when the page is displayed. 319 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) { 320 PrerenderTestURL("files/prerender/plugin_delay_load.html", 321 FINAL_STATUS_USED, 322 1); 323 NavigateToDestURL(); 324 } 325 326 // Checks that plugins in an iframe are not loaded while a page is 327 // being preloaded, but are loaded when the page is displayed. 328 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIframeDelayLoadPlugin) { 329 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html", 330 FINAL_STATUS_USED, 331 1); 332 NavigateToDestURL(); 333 } 334 335 // Renders a page that contains a prerender link to a page that contains an 336 // iframe with a source that requires http authentication. This should not 337 // prerender successfully. 338 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) { 339 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 340 FINAL_STATUS_AUTH_NEEDED, 341 1); 342 } 343 344 // Checks that client-issued redirects work with prerendering. 345 // This version navigates to the page which issues the redirection, rather 346 // than the final destination page. 347 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 348 PrerenderClientRedirectNavigateToFirst) { 349 PrerenderTestURL( 350 CreateClientRedirect("files/prerender/prerender_page.html"), 351 FINAL_STATUS_USED, 352 2); 353 NavigateToDestURL(); 354 } 355 356 // Checks that client-issued redirects work with prerendering. 357 // This version navigates to the final destination page, rather than the 358 // page which does the redirection. 359 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 360 PrerenderClientRedirectNavigateToSecond) { 361 PrerenderTestURL( 362 CreateClientRedirect("files/prerender/prerender_page.html"), 363 FINAL_STATUS_USED, 364 2); 365 set_dest_url(test_server()->GetURL("files/prerender/prerender_page.html")); 366 NavigateToDestURL(); 367 } 368 369 // Checks that client-issued redirects to an https page will cancel prerenders. 370 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectToHttps) { 371 net::TestServer https_server(net::TestServer::TYPE_HTTPS, 372 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 373 ASSERT_TRUE(https_server.Start()); 374 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 375 PrerenderTestURL(CreateClientRedirect(https_url.spec()), 376 FINAL_STATUS_HTTPS, 377 1); 378 } 379 380 // Checks that client-issued redirects within an iframe in a prerendered 381 // page will not count as an "alias" for the prerendered page. 382 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectInIframe) { 383 std::string redirect_path = CreateClientRedirect( 384 "/files/prerender/prerender_embedded_content.html"); 385 std::vector<net::TestServer::StringPair> replacement_text; 386 replacement_text.push_back( 387 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 388 std::string replacement_path; 389 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 390 "files/prerender/prerender_with_iframe.html", 391 replacement_text, 392 &replacement_path)); 393 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 394 EXPECT_FALSE(UrlIsInPrerenderManager( 395 "files/prerender/prerender_embedded_content.html")); 396 NavigateToDestURL(); 397 } 398 399 // Checks that client-issued redirects within an iframe in a prerendered 400 // page to an https page will not cancel the prerender, nor will it 401 // count as an "alias" for the prerendered page. 402 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 403 PrerenderClientRedirectToHttpsInIframe) { 404 net::TestServer https_server(net::TestServer::TYPE_HTTPS, 405 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 406 ASSERT_TRUE(https_server.Start()); 407 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 408 std::string redirect_path = CreateClientRedirect(https_url.spec()); 409 std::vector<net::TestServer::StringPair> replacement_text; 410 replacement_text.push_back( 411 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 412 std::string replacement_path; 413 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 414 "files/prerender/prerender_with_iframe.html", 415 replacement_text, 416 &replacement_path)); 417 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 418 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 419 NavigateToDestURL(); 420 } 421 422 // Checks that server-issued redirects work with prerendering. 423 // This version navigates to the page which issues the redirection, rather 424 // than the final destination page. 425 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 426 PrerenderServerRedirectNavigateToFirst) { 427 PrerenderTestURL( 428 CreateServerRedirect("files/prerender/prerender_page.html"), 429 FINAL_STATUS_USED, 430 1); 431 NavigateToDestURL(); 432 } 433 434 // Checks that server-issued redirects work with prerendering. 435 // This version navigates to the final destination page, rather than the 436 // page which does the redirection. 437 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 438 PrerenderServerRedirectNavigateToSecond) { 439 std::string redirect_path; 440 PrerenderTestURL( 441 CreateServerRedirect("files/prerender/prerender_page.html"), 442 FINAL_STATUS_USED, 443 1); 444 set_dest_url(test_server()->GetURL("files/prerender/prerender_page.html")); 445 NavigateToDestURL(); 446 } 447 448 // TODO(cbentzel): Add server-redirect-to-https test. http://crbug.com/79182 449 450 // Checks that server-issued redirects within an iframe in a prerendered 451 // page will not count as an "alias" for the prerendered page. 452 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) { 453 std::string redirect_path = CreateServerRedirect( 454 "/files/prerender/prerender_embedded_content.html"); 455 std::vector<net::TestServer::StringPair> replacement_text; 456 replacement_text.push_back( 457 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 458 std::string replacement_path; 459 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 460 "files/prerender/prerender_with_iframe.html", 461 replacement_text, 462 &replacement_path)); 463 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 464 EXPECT_FALSE(UrlIsInPrerenderManager( 465 "files/prerender/prerender_embedded_content.html")); 466 NavigateToDestURL(); 467 } 468 469 // Checks that server-issued redirects within an iframe in a prerendered 470 // page to an https page will not cancel the prerender, nor will it 471 // count as an "alias" for the prerendered page. 472 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 473 PrerenderServerRedirectToHttpsInIframe) { 474 net::TestServer https_server(net::TestServer::TYPE_HTTPS, 475 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 476 ASSERT_TRUE(https_server.Start()); 477 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 478 std::string redirect_path = CreateServerRedirect(https_url.spec()); 479 std::vector<net::TestServer::StringPair> replacement_text; 480 replacement_text.push_back( 481 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 482 std::string replacement_path; 483 ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( 484 "files/prerender/prerender_with_iframe.html", 485 replacement_text, 486 &replacement_path)); 487 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 488 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 489 NavigateToDestURL(); 490 } 491 492 // Prerenders a page that contains an automatic download triggered through an 493 // iframe. This should not prerender successfully. 494 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIFrame) { 495 PrerenderTestURL("files/prerender/prerender_download_iframe.html", 496 FINAL_STATUS_DOWNLOAD, 497 1); 498 } 499 500 // Prerenders a page that contains an automatic download triggered through 501 // Javascript changing the window.location. This should not prerender 502 // successfully. 503 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) { 504 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"), 505 FINAL_STATUS_DOWNLOAD, 506 1); 507 } 508 509 // Prerenders a page that contains an automatic download triggered through a 510 // client-issued redirect. This should not prerender successfully. 511 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) { 512 PrerenderTestURL("files/prerender/prerender_download_refresh.html", 513 FINAL_STATUS_DOWNLOAD, 514 1); 515 } 516 517 // Checks that the referrer is set when prerendering. 518 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) { 519 PrerenderTestURL("files/prerender/prerender_referrer.html", 520 FINAL_STATUS_USED, 521 1); 522 NavigateToDestURL(); 523 } 524 525 // Checks that the referrer is not set when prerendering and the source page is 526 // HTTPS. 527 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoSSLReferrer) { 528 set_use_https_src(true); 529 PrerenderTestURL("files/prerender/prerender_no_referrer.html", 530 FINAL_STATUS_USED, 531 1); 532 NavigateToDestURL(); 533 } 534 535 // Checks that popups on a prerendered page cause cancellation. 536 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) { 537 PrerenderTestURL("files/prerender/prerender_popup.html", 538 FINAL_STATUS_CREATE_NEW_WINDOW, 539 1); 540 } 541 542 543 544 // Checks that renderers using excessive memory will be terminated. 545 // Disabled, http://crbug.com/77870. 546 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 547 DISABLED_PrerenderExcessiveMemory) { 548 PrerenderTestURL("files/prerender/prerender_excessive_memory.html", 549 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 550 1); 551 } 552 553 // Checks that we don't prerender in an infinite loop. 554 // Disabled, http://crbug.com/77870. 555 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) { 556 const char* const kHtmlFileA = "prerender_infinite_a.html"; 557 const char* const kHtmlFileB = "prerender_infinite_b.html"; 558 559 std::deque<FinalStatus> expected_final_status_queue; 560 expected_final_status_queue.push_back(FINAL_STATUS_USED); 561 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 562 563 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 564 565 // Next url should be in pending list but not an active entry. 566 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 567 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB)); 568 569 NavigateToDestURL(); 570 571 // Make sure the PrerenderContents for the next url is now in the manager 572 // and not pending. 573 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB)); 574 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB)); 575 } 576 577 // Checks that we don't prerender in an infinite loop and multiple links are 578 // handled correctly. 579 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 580 FLAKY_PrerenderInfiniteLoopMultiple) { 581 const char* const kHtmlFileA = 582 "files/prerender/prerender_infinite_a_multiple.html"; 583 const char* const kHtmlFileB = 584 "files/prerender/prerender_infinite_b_multiple.html"; 585 const char* const kHtmlFileC = 586 "files/prerender/prerender_infinite_c_multiple.html"; 587 588 // We need to set the final status to expect here before starting any 589 // prerenders. We set them on a queue so whichever we see first is expected to 590 // be evicted, and the second should stick around until we exit. 591 std::deque<FinalStatus> expected_final_status_queue; 592 expected_final_status_queue.push_back(FINAL_STATUS_USED); 593 expected_final_status_queue.push_back(FINAL_STATUS_EVICTED); 594 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 595 596 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 597 598 // Next url should be in pending list but not an active entry. 599 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 600 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC)); 601 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB)); 602 EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileC)); 603 604 NavigateToDestURL(); 605 606 // Make sure the PrerenderContents for the next urls are now in the manager 607 // and not pending. One and only one of the URLs (the last seen) should be the 608 // active entry. 609 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB); 610 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC); 611 EXPECT_TRUE((url_b_is_active_prerender || url_c_is_active_prerender) && 612 !(url_b_is_active_prerender && url_c_is_active_prerender)); 613 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB)); 614 EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileC)); 615 } 616 617 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TaskManager) { 618 // Show the task manager. This populates the model. 619 browser()->window()->ShowTaskManager(); 620 621 // Start with two resources. 622 EXPECT_EQ(2, model()->ResourceCount()); 623 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 624 625 // The prerender makes three. 626 EXPECT_EQ(3, model()->ResourceCount()); 627 628 // It shouldn't have a TabContents associated with it. 629 ASSERT_TRUE(model()->GetResourceTabContents(1) == NULL); 630 631 // The prefix should be "Prerender:" 632 string16 prefix = 633 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX, 634 string16()); 635 ASSERT_TRUE(StartsWith(model()->GetResourceTitle(1), prefix, true)); 636 637 NavigateToDestURL(); 638 639 // Prerender task should be killed and removed from the Task Manager. 640 EXPECT_EQ(2, model()->ResourceCount()); 641 } 642 643 // Checks that prerenderers will terminate when an audio tag is encountered. 644 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Audio) { 645 PrerenderTestURL("files/prerender/prerender_html5_audio.html", 646 FINAL_STATUS_HTML5_MEDIA, 647 1); 648 } 649 650 // Checks that prerenderers will terminate when a video tag is encountered. 651 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) { 652 PrerenderTestURL("files/prerender/prerender_html5_video.html", 653 FINAL_STATUS_HTML5_MEDIA, 654 1); 655 } 656 657 // Checks that prerenderers will terminate when a video tag is inserted via 658 // javascript. 659 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) { 660 PrerenderTestURL("files/prerender/prerender_html5_video_script.html", 661 FINAL_STATUS_HTML5_MEDIA, 662 1); 663 } 664 665 } // namespace prerender 666