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 36namespace prerender { 37 38namespace { 39 40std::string CreateClientRedirect(const std::string& dest_url) { 41 const char* const kClientRedirectBase = "client-redirect?"; 42 return kClientRedirectBase + dest_url; 43} 44 45std::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(). 51class 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. 90class 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 128class 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. 296IN_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. 303IN_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. 311IN_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. 319IN_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. 328IN_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. 338IN_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. 347IN_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. 359IN_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. 370IN_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. 382IN_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. 402IN_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. 425IN_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. 437IN_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. 452IN_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. 472IN_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. 494IN_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. 503IN_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. 511IN_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. 518IN_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. 527IN_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. 536IN_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. 546IN_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. 555IN_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. 579IN_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 617IN_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. 644IN_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. 651IN_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. 659IN_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