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. 4 5 #include <deque> 6 #include <vector> 7 8 #include "base/command_line.h" 9 #include "base/path_service.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/stringprintf.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "base/test/test_timeouts.h" 15 #include "base/values.h" 16 #include "chrome/browser/browsing_data/browsing_data_helper.h" 17 #include "chrome/browser/browsing_data/browsing_data_remover.h" 18 #include "chrome/browser/chrome_notification_types.h" 19 #include "chrome/browser/content_settings/host_content_settings_map.h" 20 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" 21 #include "chrome/browser/extensions/extension_apitest.h" 22 #include "chrome/browser/favicon/favicon_tab_helper.h" 23 #include "chrome/browser/prerender/prerender_contents.h" 24 #include "chrome/browser/prerender/prerender_handle.h" 25 #include "chrome/browser/prerender/prerender_link_manager.h" 26 #include "chrome/browser/prerender/prerender_link_manager_factory.h" 27 #include "chrome/browser/prerender/prerender_manager.h" 28 #include "chrome/browser/prerender/prerender_manager_factory.h" 29 #include "chrome/browser/profiles/profile.h" 30 #include "chrome/browser/safe_browsing/database_manager.h" 31 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 32 #include "chrome/browser/safe_browsing/safe_browsing_util.h" 33 #include "chrome/browser/task_manager/task_manager.h" 34 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" 35 #include "chrome/browser/ui/browser.h" 36 #include "chrome/browser/ui/browser_commands.h" 37 #include "chrome/browser/ui/browser_finder.h" 38 #include "chrome/browser/ui/browser_window.h" 39 #include "chrome/browser/ui/tabs/tab_strip_model.h" 40 #include "chrome/common/chrome_paths.h" 41 #include "chrome/common/chrome_switches.h" 42 #include "chrome/common/pref_names.h" 43 #include "chrome/test/base/in_process_browser_test.h" 44 #include "chrome/test/base/test_switches.h" 45 #include "chrome/test/base/ui_test_utils.h" 46 #include "content/public/browser/browser_message_filter.h" 47 #include "content/public/browser/devtools_agent_host.h" 48 #include "content/public/browser/devtools_client_host.h" 49 #include "content/public/browser/devtools_manager.h" 50 #include "content/public/browser/notification_service.h" 51 #include "content/public/browser/render_process_host.h" 52 #include "content/public/browser/render_view_host.h" 53 #include "content/public/browser/web_contents.h" 54 #include "content/public/common/url_constants.h" 55 #include "content/public/test/browser_test_utils.h" 56 #include "content/public/test/test_navigation_observer.h" 57 #include "content/public/test/test_utils.h" 58 #include "extensions/common/switches.h" 59 #include "grit/generated_resources.h" 60 #include "net/dns/mock_host_resolver.h" 61 #include "net/url_request/url_request_context.h" 62 #include "net/url_request/url_request_context_getter.h" 63 #include "net/url_request/url_request_filter.h" 64 #include "net/url_request/url_request_job.h" 65 #include "ui/base/l10n/l10n_util.h" 66 #include "url/gurl.h" 67 68 using content::BrowserThread; 69 using content::DevToolsAgentHost; 70 using content::DevToolsClientHost; 71 using content::DevToolsManager; 72 using content::NavigationController; 73 using content::OpenURLParams; 74 using content::Referrer; 75 using content::RenderViewHost; 76 using content::RenderWidgetHost; 77 using content::WebContents; 78 79 // Prerender tests work as follows: 80 // 81 // A page with a prefetch link to the test page is loaded. Once prerendered, 82 // its Javascript function DidPrerenderPass() is called, which returns true if 83 // the page behaves as expected when prerendered. 84 // 85 // The prerendered page is then displayed on a tab. The Javascript function 86 // DidDisplayPass() is called, and returns true if the page behaved as it 87 // should while being displayed. 88 89 namespace prerender { 90 91 namespace { 92 93 // Constants used in the test HTML files. 94 static const char* kReadyTitle = "READY"; 95 static const char* kPassTitle = "PASS"; 96 97 std::string CreateClientRedirect(const std::string& dest_url) { 98 const char* const kClientRedirectBase = "client-redirect?"; 99 return kClientRedirectBase + dest_url; 100 } 101 102 std::string CreateServerRedirect(const std::string& dest_url) { 103 const char* const kServerRedirectBase = "server-redirect?"; 104 return kServerRedirectBase + dest_url; 105 } 106 107 // Clears the specified data using BrowsingDataRemover. 108 void ClearBrowsingData(Browser* browser, int remove_mask) { 109 BrowsingDataRemover* remover = 110 BrowsingDataRemover::CreateForUnboundedRange(browser->profile()); 111 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB); 112 // BrowsingDataRemover deletes itself. 113 } 114 115 void CancelAllPrerenders(PrerenderManager* prerender_manager) { 116 prerender_manager->CancelAllPrerenders(); 117 } 118 119 // Returns true if and only if the final status is one in which the prerendered 120 // page should prerender correctly. The page still may not be used. 121 bool ShouldRenderPrerenderedPageCorrectly(FinalStatus status) { 122 switch (status) { 123 case FINAL_STATUS_USED: 124 case FINAL_STATUS_WINDOW_OPENER: 125 case FINAL_STATUS_APP_TERMINATING: 126 case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED: 127 // We'll crash the renderer after it's loaded. 128 case FINAL_STATUS_RENDERER_CRASHED: 129 case FINAL_STATUS_CANCELLED: 130 case FINAL_STATUS_DEVTOOLS_ATTACHED: 131 case FINAL_STATUS_PAGE_BEING_CAPTURED: 132 return true; 133 default: 134 return false; 135 } 136 } 137 138 // Waits for the destruction of a RenderProcessHost's IPC channel. 139 // Used to make sure the PrerenderLinkManager's OnChannelClosed function has 140 // been called, before checking its state. 141 class ChannelDestructionWatcher { 142 public: 143 ChannelDestructionWatcher() : channel_destroyed_(false), 144 waiting_for_channel_destruction_(false) { 145 } 146 147 ~ChannelDestructionWatcher() { 148 } 149 150 void WatchChannel(content::RenderProcessHost* host) { 151 host->GetChannel()->AddFilter(new DestructionMessageFilter(this)); 152 } 153 154 void WaitForChannelClose() { 155 ASSERT_FALSE(waiting_for_channel_destruction_); 156 157 if (channel_destroyed_) 158 return; 159 waiting_for_channel_destruction_ = true; 160 content::RunMessageLoop(); 161 162 EXPECT_FALSE(waiting_for_channel_destruction_); 163 EXPECT_TRUE(channel_destroyed_); 164 } 165 166 private: 167 // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed. 168 // Ignores all messages. 169 class DestructionMessageFilter : public content::BrowserMessageFilter { 170 public: 171 explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher) 172 : watcher_(watcher) { 173 } 174 175 private: 176 virtual ~DestructionMessageFilter() { 177 content::BrowserThread::PostTask( 178 content::BrowserThread::UI, FROM_HERE, 179 base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed, 180 base::Unretained(watcher_))); 181 } 182 183 virtual bool OnMessageReceived(const IPC::Message& message, 184 bool* message_was_ok) OVERRIDE { 185 return false; 186 } 187 188 ChannelDestructionWatcher* watcher_; 189 190 DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter); 191 }; 192 193 void OnChannelDestroyed() { 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 195 196 EXPECT_FALSE(channel_destroyed_); 197 channel_destroyed_ = true; 198 if (waiting_for_channel_destruction_) { 199 waiting_for_channel_destruction_ = false; 200 base::MessageLoop::current()->Quit(); 201 } 202 } 203 204 bool channel_destroyed_; 205 bool waiting_for_channel_destruction_; 206 207 DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher); 208 }; 209 210 // PrerenderContents that stops the UI message loop on DidStopLoading(). 211 class TestPrerenderContents : public PrerenderContents { 212 public: 213 TestPrerenderContents( 214 PrerenderManager* prerender_manager, 215 Profile* profile, 216 const GURL& url, 217 const content::Referrer& referrer, 218 Origin origin, 219 int expected_number_of_loads, 220 FinalStatus expected_final_status, 221 bool prerender_should_wait_for_ready_title) 222 : PrerenderContents(prerender_manager, profile, url, 223 referrer, origin, PrerenderManager::kNoExperiment), 224 number_of_loads_(0), 225 expected_number_of_loads_(expected_number_of_loads), 226 expected_final_status_(expected_final_status), 227 new_render_view_host_(NULL), 228 was_hidden_(false), 229 was_shown_(false), 230 should_be_shown_(expected_final_status == FINAL_STATUS_USED), 231 quit_message_loop_on_destruction_( 232 expected_final_status != FINAL_STATUS_APP_TERMINATING && 233 expected_final_status != FINAL_STATUS_MAX), 234 expected_pending_prerenders_(0), 235 prerender_should_wait_for_ready_title_( 236 prerender_should_wait_for_ready_title) { 237 if (expected_number_of_loads == 0) 238 base::MessageLoopForUI::current()->Quit(); 239 } 240 241 virtual ~TestPrerenderContents() { 242 if (expected_final_status_ == FINAL_STATUS_MAX) { 243 EXPECT_EQ(match_complete_status(), MATCH_COMPLETE_REPLACEMENT); 244 } else { 245 EXPECT_EQ(expected_final_status_, final_status()) << 246 " when testing URL " << prerender_url().path() << 247 " (Expected: " << NameFromFinalStatus(expected_final_status_) << 248 ", Actual: " << NameFromFinalStatus(final_status()) << ")"; 249 } 250 // Prerendering RenderViewHosts should be hidden before the first 251 // navigation, so this should be happen for every PrerenderContents for 252 // which a RenderViewHost is created, regardless of whether or not it's 253 // used. 254 if (new_render_view_host_) 255 EXPECT_TRUE(was_hidden_); 256 257 // A used PrerenderContents will only be destroyed when we swap out 258 // WebContents, at the end of a navigation caused by a call to 259 // NavigateToURLImpl(). 260 if (final_status() == FINAL_STATUS_USED) 261 EXPECT_TRUE(new_render_view_host_); 262 263 EXPECT_EQ(should_be_shown_, was_shown_); 264 265 // When the PrerenderContents is destroyed, quit the UI message loop. 266 // This happens on navigation to used prerendered pages, and soon 267 // after cancellation of unused prerendered pages. 268 if (quit_message_loop_on_destruction_) { 269 // The message loop may not be running if this is swapped in 270 // synchronously on a Navigation. 271 base::MessageLoop* loop = base::MessageLoopForUI::current(); 272 if (loop->is_running()) 273 loop->Quit(); 274 } 275 } 276 277 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE { 278 // On quit, it's possible to end up here when render processes are closed 279 // before the PrerenderManager is destroyed. As a result, it's possible to 280 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED 281 // on quit. 282 // 283 // It's also possible for this to be called after we've been notified of 284 // app termination, but before we've been deleted, which is why the second 285 // check is needed. 286 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING && 287 final_status() != expected_final_status_) { 288 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED; 289 } 290 291 PrerenderContents::RenderProcessGone(status); 292 } 293 294 virtual bool AddAliasURL(const GURL& url) OVERRIDE { 295 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in 296 // the PrerenderRendererCrash test. 297 if (url.spec() != content::kChromeUICrashURL) 298 return PrerenderContents::AddAliasURL(url); 299 return true; 300 } 301 302 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE { 303 PrerenderContents::DidStopLoading(render_view_host); 304 ++number_of_loads_; 305 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status_) && 306 number_of_loads_ == expected_number_of_loads_) { 307 base::MessageLoopForUI::current()->Quit(); 308 } 309 } 310 311 virtual void AddPendingPrerender( 312 scoped_ptr<PendingPrerenderInfo> pending_prerender_info) OVERRIDE { 313 PrerenderContents::AddPendingPrerender(pending_prerender_info.Pass()); 314 if (expected_pending_prerenders_ > 0 && 315 pending_prerender_count() == expected_pending_prerenders_) { 316 base::MessageLoop::current()->Quit(); 317 } 318 } 319 320 virtual WebContents* CreateWebContents( 321 content::SessionStorageNamespace* session_storage_namespace) OVERRIDE { 322 WebContents* web_contents = PrerenderContents::CreateWebContents( 323 session_storage_namespace); 324 string16 ready_title = ASCIIToUTF16(kReadyTitle); 325 if (prerender_should_wait_for_ready_title_) 326 ready_title_watcher_.reset(new content::TitleWatcher( 327 web_contents, ready_title)); 328 return web_contents; 329 } 330 331 void WaitForPrerenderToHaveReadyTitleIfRequired() { 332 if (ready_title_watcher_.get()) { 333 string16 ready_title = ASCIIToUTF16(kReadyTitle); 334 ASSERT_EQ(ready_title, ready_title_watcher_->WaitAndGetTitle()); 335 } 336 } 337 338 // Waits until the prerender has |expected_pending_prerenders| pending 339 // prerenders. 340 void WaitForPendingPrerenders(size_t expected_pending_prerenders) { 341 if (pending_prerender_count() < expected_pending_prerenders) { 342 expected_pending_prerenders_ = expected_pending_prerenders; 343 content::RunMessageLoop(); 344 expected_pending_prerenders_ = 0; 345 } 346 347 EXPECT_EQ(expected_pending_prerenders, pending_prerender_count()); 348 } 349 350 // For tests that open the prerender in a new background tab, the RenderView 351 // will not have been made visible when the PrerenderContents is destroyed 352 // even though it is used. 353 void set_should_be_shown(bool value) { should_be_shown_ = value; } 354 355 int number_of_loads() const { return number_of_loads_; } 356 357 FinalStatus expected_final_status() const { return expected_final_status_; } 358 359 bool quit_message_loop_on_destruction() const { 360 return quit_message_loop_on_destruction_; 361 } 362 363 private: 364 virtual void OnRenderViewHostCreated( 365 RenderViewHost* new_render_view_host) OVERRIDE { 366 // Used to make sure the RenderViewHost is hidden and, if used, 367 // subsequently shown. 368 notification_registrar().Add( 369 this, 370 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 371 content::Source<RenderWidgetHost>(new_render_view_host)); 372 373 new_render_view_host_ = new_render_view_host; 374 375 PrerenderContents::OnRenderViewHostCreated(new_render_view_host); 376 } 377 378 virtual void Observe(int type, 379 const content::NotificationSource& source, 380 const content::NotificationDetails& details) OVERRIDE { 381 if (type == 382 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) { 383 EXPECT_EQ(new_render_view_host_, 384 content::Source<RenderWidgetHost>(source).ptr()); 385 bool is_visible = *content::Details<bool>(details).ptr(); 386 387 if (!is_visible) { 388 was_hidden_ = true; 389 } else if (is_visible && was_hidden_) { 390 // Once hidden, a prerendered RenderViewHost should only be shown after 391 // being removed from the PrerenderContents for display. 392 EXPECT_FALSE(GetRenderViewHost()); 393 was_shown_ = true; 394 } 395 return; 396 } 397 PrerenderContents::Observe(type, source, details); 398 } 399 400 int number_of_loads_; 401 int expected_number_of_loads_; 402 FinalStatus expected_final_status_; 403 404 // The RenderViewHost created for the prerender, if any. 405 RenderViewHost* new_render_view_host_; 406 // Set to true when the prerendering RenderWidget is hidden. 407 bool was_hidden_; 408 // Set to true when the prerendering RenderWidget is shown, after having been 409 // hidden. 410 bool was_shown_; 411 // Expected final value of was_shown_. Defaults to true for 412 // FINAL_STATUS_USED, and false otherwise. 413 bool should_be_shown_; 414 415 // If true, quits message loop on destruction of |this|. 416 bool quit_message_loop_on_destruction_; 417 418 // Total number of pending prerenders we're currently waiting for. Zero 419 // indicates we currently aren't waiting for any. 420 size_t expected_pending_prerenders_; 421 422 // If true, before calling DidPrerenderPass, will wait for the title of the 423 // prerendered page to turn to "READY". 424 bool prerender_should_wait_for_ready_title_; 425 scoped_ptr<content::TitleWatcher> ready_title_watcher_; 426 }; 427 428 // PrerenderManager that uses TestPrerenderContents. 429 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { 430 public: 431 WaitForLoadPrerenderContentsFactory( 432 int expected_number_of_loads, 433 const std::deque<FinalStatus>& expected_final_status_queue, 434 bool prerender_should_wait_for_ready_title) 435 : expected_number_of_loads_(expected_number_of_loads), 436 expected_final_status_queue_(expected_final_status_queue), 437 prerender_should_wait_for_ready_title_( 438 prerender_should_wait_for_ready_title) { 439 VLOG(1) << "Factory created with queue length " << 440 expected_final_status_queue_.size(); 441 } 442 443 virtual PrerenderContents* CreatePrerenderContents( 444 PrerenderManager* prerender_manager, 445 Profile* profile, 446 const GURL& url, 447 const content::Referrer& referrer, 448 Origin origin, 449 uint8 experiment_id) OVERRIDE { 450 FinalStatus expected_final_status = FINAL_STATUS_MAX; 451 if (!expected_final_status_queue_.empty()) { 452 expected_final_status = expected_final_status_queue_.front(); 453 expected_final_status_queue_.pop_front(); 454 } 455 VLOG(1) << "Creating prerender contents for " << url.path() << 456 " with expected final status " << expected_final_status; 457 VLOG(1) << expected_final_status_queue_.size() << " left in the queue."; 458 return new TestPrerenderContents(prerender_manager, 459 profile, url, referrer, origin, 460 expected_number_of_loads_, 461 expected_final_status, 462 prerender_should_wait_for_ready_title_); 463 } 464 465 private: 466 int expected_number_of_loads_; 467 std::deque<FinalStatus> expected_final_status_queue_; 468 bool prerender_should_wait_for_ready_title_; 469 }; 470 471 #if defined(FULL_SAFE_BROWSING) 472 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for 473 // a given URL. 474 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { 475 public: 476 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service) 477 : SafeBrowsingDatabaseManager(service), 478 threat_type_(SB_THREAT_TYPE_SAFE) { } 479 480 // Called on the IO thread to check if the given url is safe or not. If we 481 // can synchronously determine that the url is safe, CheckUrl returns true. 482 // Otherwise it returns false, and "client" is called asynchronously with the 483 // result when it is ready. 484 // Returns true, indicating a SAFE result, unless the URL is the fixed URL 485 // specified by the user, and the user-specified result is not SAFE 486 // (in which that result will be communicated back via a call into the 487 // client, and false will be returned). 488 // Overrides SafeBrowsingService::CheckBrowseUrl. 489 virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE { 490 if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE) 491 return true; 492 493 BrowserThread::PostTask( 494 BrowserThread::IO, FROM_HERE, 495 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone, 496 this, gurl, client)); 497 return false; 498 } 499 500 void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) { 501 url_ = url; 502 threat_type_ = threat_type; 503 } 504 505 private: 506 virtual ~FakeSafeBrowsingDatabaseManager() {} 507 508 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) { 509 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check( 510 std::vector<GURL>(1, gurl), 511 std::vector<SBFullHash>(), 512 client, 513 safe_browsing_util::MALWARE); 514 sb_check.url_results[0] = threat_type_; 515 client->OnSafeBrowsingResult(sb_check); 516 } 517 518 GURL url_; 519 SBThreatType threat_type_; 520 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager); 521 }; 522 523 class FakeSafeBrowsingService : public SafeBrowsingService { 524 public: 525 FakeSafeBrowsingService() { } 526 527 // Returned pointer has the same lifespan as the database_manager_ refcounted 528 // object. 529 FakeSafeBrowsingDatabaseManager* fake_database_manager() { 530 return fake_database_manager_; 531 } 532 533 protected: 534 virtual ~FakeSafeBrowsingService() { } 535 536 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE { 537 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this); 538 return fake_database_manager_; 539 } 540 541 private: 542 FakeSafeBrowsingDatabaseManager* fake_database_manager_; 543 544 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService); 545 }; 546 547 // Factory that creates FakeSafeBrowsingService instances. 548 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory { 549 public: 550 TestSafeBrowsingServiceFactory() : 551 most_recent_service_(NULL) { } 552 virtual ~TestSafeBrowsingServiceFactory() { } 553 554 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE { 555 most_recent_service_ = new FakeSafeBrowsingService(); 556 return most_recent_service_; 557 } 558 559 FakeSafeBrowsingService* most_recent_service() const { 560 return most_recent_service_; 561 } 562 563 private: 564 FakeSafeBrowsingService* most_recent_service_; 565 }; 566 #endif 567 568 class FakeDevToolsClientHost : public DevToolsClientHost { 569 public: 570 FakeDevToolsClientHost() {} 571 virtual ~FakeDevToolsClientHost() {} 572 virtual void InspectedContentsClosing() OVERRIDE {} 573 virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {} 574 virtual void ReplacedWithAnotherClient() OVERRIDE {} 575 }; 576 577 class RestorePrerenderMode { 578 public: 579 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) { 580 } 581 582 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); } 583 private: 584 PrerenderManager::PrerenderManagerMode prev_mode_; 585 }; 586 587 // URLRequestJob (and associated handler) which never starts. 588 class NeverStartURLRequestJob : public net::URLRequestJob { 589 public: 590 NeverStartURLRequestJob(net::URLRequest* request, 591 net::NetworkDelegate* network_delegate) 592 : net::URLRequestJob(request, network_delegate) { 593 } 594 595 virtual void Start() OVERRIDE {} 596 597 private: 598 virtual ~NeverStartURLRequestJob() {} 599 }; 600 601 class NeverStartProtocolHandler 602 : public net::URLRequestJobFactory::ProtocolHandler { 603 public: 604 NeverStartProtocolHandler() {} 605 virtual ~NeverStartProtocolHandler() {} 606 607 virtual net::URLRequestJob* MaybeCreateJob( 608 net::URLRequest* request, 609 net::NetworkDelegate* network_delegate) const OVERRIDE { 610 return new NeverStartURLRequestJob(request, network_delegate); 611 } 612 }; 613 614 void CreateNeverStartProtocolHandlerOnIO(const GURL& url) { 615 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 616 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler( 617 new NeverStartProtocolHandler()); 618 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( 619 url, never_respond_handler.Pass()); 620 } 621 622 } // namespace 623 624 // Many of these tests are flaky. See http://crbug.com/249179 625 class PrerenderBrowserTest : virtual public InProcessBrowserTest { 626 public: 627 PrerenderBrowserTest() 628 : autostart_test_server_(true), 629 prerender_contents_factory_(NULL), 630 #if defined(FULL_SAFE_BROWSING) 631 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()), 632 #endif 633 use_https_src_server_(false), 634 call_javascript_(true), 635 loader_path_("files/prerender/prerender_loader.html"), 636 explicitly_set_browser_(NULL) {} 637 638 virtual ~PrerenderBrowserTest() {} 639 640 content::SessionStorageNamespace* GetSessionStorageNamespace() const { 641 WebContents* web_contents = 642 current_browser()->tab_strip_model()->GetActiveWebContents(); 643 if (!web_contents) 644 return NULL; 645 return web_contents->GetController().GetDefaultSessionStorageNamespace(); 646 } 647 648 virtual void SetUp() OVERRIDE { 649 // TODO(danakj): The GPU Video Decoder needs real GL bindings. 650 // crbug.com/269087 651 UseRealGLBindings(); 652 653 InProcessBrowserTest::SetUp(); 654 } 655 656 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 657 #if defined(FULL_SAFE_BROWSING) 658 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get()); 659 #endif 660 } 661 662 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 663 command_line->AppendSwitchASCII(switches::kPrerenderMode, 664 switches::kPrerenderModeSwitchValueEnabled); 665 #if defined(OS_MACOSX) 666 // The plugins directory isn't read by default on the Mac, so it needs to be 667 // explicitly registered. 668 base::FilePath app_dir; 669 PathService::Get(chrome::DIR_APP, &app_dir); 670 command_line->AppendSwitchPath( 671 switches::kExtraPluginDir, 672 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 673 #endif 674 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins); 675 } 676 677 virtual void SetUpOnMainThread() OVERRIDE { 678 current_browser()->profile()->GetPrefs()->SetBoolean( 679 prefs::kPromptForDownload, false); 680 IncreasePrerenderMemory(); 681 if (autostart_test_server_) 682 ASSERT_TRUE(test_server()->Start()); 683 } 684 685 // Overload for a single expected final status 686 void PrerenderTestURL(const std::string& html_file, 687 FinalStatus expected_final_status, 688 int expected_number_of_loads) { 689 PrerenderTestURL(html_file, 690 expected_final_status, 691 expected_number_of_loads, 692 false); 693 } 694 695 void PrerenderTestURL(const std::string& html_file, 696 FinalStatus expected_final_status, 697 int expected_number_of_loads, 698 bool prerender_should_wait_for_ready_title) { 699 std::deque<FinalStatus> expected_final_status_queue(1, 700 expected_final_status); 701 PrerenderTestURL(html_file, 702 expected_final_status_queue, 703 expected_number_of_loads, 704 prerender_should_wait_for_ready_title); 705 } 706 707 void PrerenderTestURL( 708 const std::string& html_file, 709 const std::deque<FinalStatus>& expected_final_status_queue, 710 int expected_number_of_loads, 711 bool prerender_should_wait_for_ready_title) { 712 GURL url = test_server()->GetURL(html_file); 713 PrerenderTestURLImpl(url, url, 714 expected_final_status_queue, 715 expected_number_of_loads, 716 prerender_should_wait_for_ready_title); 717 } 718 719 void PrerenderTestURL( 720 const std::string& html_file, 721 const std::deque<FinalStatus>& expected_final_status_queue, 722 int expected_number_of_loads) { 723 PrerenderTestURL(html_file, expected_final_status_queue, 724 expected_number_of_loads, false); 725 } 726 727 void PrerenderTestURL( 728 const GURL& url, 729 FinalStatus expected_final_status, 730 int expected_number_of_loads) { 731 std::deque<FinalStatus> expected_final_status_queue(1, 732 expected_final_status); 733 PrerenderTestURLImpl(url, url, 734 expected_final_status_queue, 735 expected_number_of_loads, 736 false); 737 } 738 739 void PrerenderTestURL( 740 const GURL& prerender_url, 741 const GURL& destination_url, 742 FinalStatus expected_final_status, 743 int expected_number_of_loads) { 744 std::deque<FinalStatus> expected_final_status_queue(1, 745 expected_final_status); 746 PrerenderTestURLImpl(prerender_url, destination_url, 747 expected_final_status_queue, 748 expected_number_of_loads, 749 false); 750 } 751 752 void NavigateToDestURL() const { 753 NavigateToDestURLWithDisposition(CURRENT_TAB, true); 754 } 755 756 // Opens the url in a new tab, with no opener. 757 void NavigateToDestURLWithDisposition( 758 WindowOpenDisposition disposition, 759 bool expect_swap_to_succeed) const { 760 NavigateToURLImpl(dest_url_, disposition, expect_swap_to_succeed); 761 } 762 763 void OpenDestURLViaClick() const { 764 OpenDestURLWithJSImpl("Click()"); 765 } 766 767 void OpenDestURLViaClickTarget() const { 768 OpenDestURLWithJSImpl("ClickTarget()"); 769 } 770 771 void OpenDestURLViaClickNewWindow() const { 772 OpenDestURLWithJSImpl("ShiftClick()"); 773 } 774 775 void OpenDestURLViaClickNewForegroundTab() const { 776 #if defined(OS_MACOSX) 777 OpenDestURLWithJSImpl("MetaShiftClick()"); 778 #else 779 OpenDestURLWithJSImpl("CtrlShiftClick()"); 780 #endif 781 } 782 783 void OpenDestURLViaClickNewBackgroundTab() const { 784 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 785 ASSERT_TRUE(prerender_contents != NULL); 786 prerender_contents->set_should_be_shown(false); 787 #if defined(OS_MACOSX) 788 OpenDestURLWithJSImpl("MetaClick()"); 789 #else 790 OpenDestURLWithJSImpl("CtrlClick()"); 791 #endif 792 } 793 794 void OpenDestURLViaWindowOpen() const { 795 OpenDestURLWithJSImpl("WindowOpen()"); 796 } 797 798 void RemoveLinkElement(int i) const { 799 current_browser()->tab_strip_model()->GetActiveWebContents()-> 800 GetRenderViewHost()->ExecuteJavascriptInWebFrame( 801 string16(), 802 ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i))); 803 } 804 805 void ClickToNextPageAfterPrerender() { 806 content::WindowedNotificationObserver new_page_observer( 807 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 808 content::NotificationService::AllSources()); 809 RenderViewHost* render_view_host = current_browser()->tab_strip_model()-> 810 GetActiveWebContents()->GetRenderViewHost(); 811 render_view_host->ExecuteJavascriptInWebFrame( 812 string16(), 813 ASCIIToUTF16("ClickOpenLink()")); 814 new_page_observer.Wait(); 815 } 816 817 void NavigateToNextPageAfterPrerender() const { 818 ui_test_utils::NavigateToURL( 819 current_browser(), 820 test_server()->GetURL("files/prerender/prerender_page.html")); 821 } 822 823 void NavigateToDestUrlAndWaitForPassTitle() { 824 string16 expected_title = ASCIIToUTF16(kPassTitle); 825 content::TitleWatcher title_watcher( 826 GetPrerenderContents()->prerender_contents(), 827 expected_title); 828 NavigateToDestURL(); 829 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 830 } 831 832 // Called after the prerendered page has been navigated to and then away from. 833 // Navigates back through the history to the prerendered page. 834 void GoBackToPrerender() { 835 content::WindowedNotificationObserver back_nav_observer( 836 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 837 content::NotificationService::AllSources()); 838 chrome::GoBack(current_browser(), CURRENT_TAB); 839 back_nav_observer.Wait(); 840 bool original_prerender_page = false; 841 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 842 current_browser()->tab_strip_model()->GetActiveWebContents(), 843 "window.domAutomationController.send(IsOriginalPrerenderPage())", 844 &original_prerender_page)); 845 EXPECT_TRUE(original_prerender_page); 846 } 847 848 // Goes back to the page that was active before the prerender was swapped 849 // in. This must be called when the prerendered page is the current page 850 // in the active tab. 851 void GoBackToPageBeforePrerender() { 852 WebContents* tab = 853 current_browser()->tab_strip_model()->GetActiveWebContents(); 854 ASSERT_TRUE(tab); 855 EXPECT_FALSE(tab->IsLoading()); 856 content::WindowedNotificationObserver back_nav_observer( 857 content::NOTIFICATION_LOAD_STOP, 858 content::Source<NavigationController>(&tab->GetController())); 859 chrome::GoBack(current_browser(), CURRENT_TAB); 860 back_nav_observer.Wait(); 861 bool js_result; 862 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 863 tab, 864 "window.domAutomationController.send(DidBackToOriginalPagePass())", 865 &js_result)); 866 EXPECT_TRUE(js_result); 867 } 868 869 void NavigateToURL(const std::string& dest_html_file) const { 870 GURL dest_url = test_server()->GetURL(dest_html_file); 871 NavigateToURLImpl(dest_url, CURRENT_TAB, true); 872 } 873 874 bool UrlIsInPrerenderManager(const std::string& html_file) const { 875 return UrlIsInPrerenderManager(test_server()->GetURL(html_file)); 876 } 877 878 bool UrlIsInPrerenderManager(const GURL& url) const { 879 return GetPrerenderManager()->FindPrerenderData( 880 url, GetSessionStorageNamespace()) != NULL; 881 } 882 883 void set_use_https_src(bool use_https_src_server) { 884 use_https_src_server_ = use_https_src_server; 885 } 886 887 void DisableJavascriptCalls() { 888 call_javascript_ = false; 889 } 890 891 TaskManagerModel* GetModel() const { 892 return TaskManager::GetInstance()->model(); 893 } 894 895 PrerenderManager* GetPrerenderManager() const { 896 PrerenderManager* prerender_manager = 897 PrerenderManagerFactory::GetForProfile(current_browser()->profile()); 898 return prerender_manager; 899 } 900 901 const PrerenderLinkManager* GetPrerenderLinkManager() const { 902 PrerenderLinkManager* prerender_link_manager = 903 PrerenderLinkManagerFactory::GetForProfile( 904 current_browser()->profile()); 905 return prerender_link_manager; 906 } 907 908 bool DidReceivePrerenderStartEventForLinkNumber(int index) const { 909 bool received_prerender_started; 910 std::string expression = base::StringPrintf( 911 "window.domAutomationController.send(Boolean(" 912 "receivedPrerenderStartEvents[%d]))", index); 913 914 CHECK(content::ExecuteScriptAndExtractBool( 915 current_browser()->tab_strip_model()->GetActiveWebContents(), 916 expression, 917 &received_prerender_started)); 918 return received_prerender_started; 919 } 920 921 bool DidReceivePrerenderLoadEventForLinkNumber(int index) const { 922 bool received_prerender_loaded; 923 std::string expression = base::StringPrintf( 924 "window.domAutomationController.send(Boolean(" 925 "receivedPrerenderLoadEvents[%d]))", index); 926 927 CHECK(content::ExecuteScriptAndExtractBool( 928 current_browser()->tab_strip_model()->GetActiveWebContents(), 929 expression, 930 &received_prerender_loaded)); 931 return received_prerender_loaded; 932 } 933 934 bool DidReceivePrerenderStopEventForLinkNumber(int index) const { 935 bool received_prerender_stopped; 936 std::string expression = base::StringPrintf( 937 "window.domAutomationController.send(Boolean(" 938 "receivedPrerenderStopEvents[%d]))", index); 939 940 CHECK(content::ExecuteScriptAndExtractBool( 941 current_browser()->tab_strip_model()->GetActiveWebContents(), 942 expression, 943 &received_prerender_stopped)); 944 return received_prerender_stopped; 945 } 946 947 bool HadPrerenderEventErrors() const { 948 bool had_prerender_event_errors; 949 CHECK(content::ExecuteScriptAndExtractBool( 950 current_browser()->tab_strip_model()->GetActiveWebContents(), 951 "window.domAutomationController.send(Boolean(" 952 " hadPrerenderEventErrors))", 953 &had_prerender_event_errors)); 954 return had_prerender_event_errors; 955 } 956 957 // Asserting on this can result in flaky tests. PrerenderHandles are 958 // removed from the PrerenderLinkManager when the prerender is canceled from 959 // the browser, when the prerenders are cancelled from the renderer process, 960 // or the channel for the renderer process is closed on the IO thread. In the 961 // last case, the code must be careful to wait for the channel to close, as it 962 // is done asynchronously after swapping out the old process. See 963 // ChannelDestructionWatcher. 964 bool IsEmptyPrerenderLinkManager() const { 965 return GetPrerenderLinkManager()->IsEmpty(); 966 } 967 968 // Returns length of |prerender_manager_|'s history, or -1 on failure. 969 int GetHistoryLength() const { 970 scoped_ptr<DictionaryValue> prerender_dict( 971 static_cast<DictionaryValue*>(GetPrerenderManager()->GetAsValue())); 972 if (!prerender_dict.get()) 973 return -1; 974 ListValue* history_list; 975 if (!prerender_dict->GetList("history", &history_list)) 976 return -1; 977 return static_cast<int>(history_list->GetSize()); 978 } 979 980 #if defined(FULL_SAFE_BROWSING) 981 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() { 982 return safe_browsing_factory_->most_recent_service()-> 983 fake_database_manager(); 984 } 985 #endif 986 987 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const { 988 PrerenderManager::PrerenderData* prerender_data = 989 GetPrerenderManager()->FindPrerenderData( 990 url, GetSessionStorageNamespace()); 991 return static_cast<TestPrerenderContents*>( 992 prerender_data ? prerender_data->contents() : NULL); 993 } 994 995 TestPrerenderContents* GetPrerenderContents() const { 996 return GetPrerenderContentsFor(dest_url_); 997 } 998 999 void set_loader_path(const std::string& path) { 1000 loader_path_ = path; 1001 } 1002 1003 void set_loader_query_and_fragment(const std::string& query_and_fragment) { 1004 loader_query_and_fragment_ = query_and_fragment; 1005 } 1006 1007 GURL GetCrossDomainTestUrl(const std::string& path) { 1008 static const std::string secondary_domain = "www.foo.com"; 1009 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); 1010 std::string url_str(base::StringPrintf( 1011 "http://%s:%d/%s", 1012 secondary_domain.c_str(), 1013 test_server()->host_port_pair().port(), 1014 path.c_str())); 1015 return GURL(url_str); 1016 } 1017 1018 void set_browser(Browser* browser) { 1019 explicitly_set_browser_ = browser; 1020 } 1021 1022 Browser* current_browser() const { 1023 return explicitly_set_browser_ ? explicitly_set_browser_ : browser(); 1024 } 1025 1026 void IncreasePrerenderMemory() { 1027 // Increase the memory allowed in a prerendered page above normal settings. 1028 // Debug build bots occasionally run against the default limit, and tests 1029 // were failing because the prerender was canceled due to memory exhaustion. 1030 // http://crbug.com/93076 1031 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024; 1032 } 1033 1034 protected: 1035 bool autostart_test_server_; 1036 1037 private: 1038 void PrerenderTestURLImpl( 1039 const GURL& prerender_url, 1040 const GURL& destination_url, 1041 const std::deque<FinalStatus>& expected_final_status_queue, 1042 int expected_number_of_loads, 1043 bool prerender_should_wait_for_ready_title) { 1044 dest_url_ = destination_url; 1045 1046 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1047 replacement_text.push_back( 1048 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec())); 1049 replacement_text.push_back( 1050 make_pair("REPLACE_WITH_DESTINATION_URL", destination_url.spec())); 1051 std::string replacement_path; 1052 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1053 loader_path_, 1054 replacement_text, 1055 &replacement_path)); 1056 1057 const net::SpawnedTestServer* src_server = test_server(); 1058 scoped_ptr<net::SpawnedTestServer> https_src_server; 1059 if (use_https_src_server_) { 1060 https_src_server.reset( 1061 new net::SpawnedTestServer( 1062 net::SpawnedTestServer::TYPE_HTTPS, 1063 net::SpawnedTestServer::kLocalhost, 1064 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 1065 ASSERT_TRUE(https_src_server->Start()); 1066 src_server = https_src_server.get(); 1067 } 1068 GURL loader_url = src_server->GetURL(replacement_path + 1069 loader_query_and_fragment_); 1070 1071 PrerenderManager* prerender_manager = GetPrerenderManager(); 1072 ASSERT_TRUE(prerender_manager); 1073 prerender_manager->mutable_config().rate_limit_enabled = false; 1074 prerender_manager->mutable_config().https_allowed = true; 1075 ASSERT_TRUE(prerender_contents_factory_ == NULL); 1076 prerender_contents_factory_ = 1077 new WaitForLoadPrerenderContentsFactory( 1078 expected_number_of_loads, 1079 expected_final_status_queue, 1080 prerender_should_wait_for_ready_title); 1081 prerender_manager->SetPrerenderContentsFactory( 1082 prerender_contents_factory_); 1083 FinalStatus expected_final_status = expected_final_status_queue.front(); 1084 1085 // We construct launch_nav_observer so that we can be certain our loader 1086 // page has finished loading before continuing. This prevents ambiguous 1087 // NOTIFICATION_LOAD_STOP events from making tests flaky. 1088 WebContents* web_contents = 1089 current_browser()->tab_strip_model()->GetActiveWebContents(); 1090 content::WindowedNotificationObserver loader_nav_observer( 1091 content::NOTIFICATION_LOAD_STOP, 1092 content::Source<NavigationController>( 1093 &web_contents->GetController())); 1094 1095 // ui_test_utils::NavigateToURL uses its own observer and message loop. 1096 // Since the test needs to wait until the prerendered page has stopped 1097 // loading, rather than the page directly navigated to, need to 1098 // handle browser navigation directly. 1099 current_browser()->OpenURL(OpenURLParams( 1100 loader_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, 1101 false)); 1102 1103 content::RunMessageLoop(); 1104 // Now that we've run the prerender until it stopped loading, we can now 1105 // also make sure the launcher has finished loading. 1106 loader_nav_observer.Wait(); 1107 1108 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 1109 1110 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { 1111 ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents); 1112 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); 1113 1114 if (call_javascript_ && expected_number_of_loads > 0) { 1115 // Wait for the prerendered page to change title to signal it is ready 1116 // if required. 1117 prerender_contents->WaitForPrerenderToHaveReadyTitleIfRequired(); 1118 1119 // Check if page behaves as expected while in prerendered state. 1120 bool prerender_test_result = false; 1121 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1122 prerender_contents->GetRenderViewHostMutable(), 1123 "window.domAutomationController.send(DidPrerenderPass())", 1124 &prerender_test_result)); 1125 EXPECT_TRUE(prerender_test_result); 1126 } 1127 } else { 1128 // In the failure case, we should have removed |dest_url_| from the 1129 // prerender_manager. We ignore dummy PrerenderContents (as indicated 1130 // by not having started), and PrerenderContents that are expected to 1131 // be left in the manager until the test finishes. 1132 EXPECT_TRUE(prerender_contents == NULL || 1133 !prerender_contents->prerendering_has_started()); 1134 } 1135 } 1136 1137 void NavigateToURLImpl(const GURL& dest_url, 1138 WindowOpenDisposition disposition, 1139 bool expect_swap_to_succeed) const { 1140 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager()); 1141 // Make sure in navigating we have a URL to use in the PrerenderManager. 1142 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents()); 1143 1144 // If opening the page in a background tab, it won't be shown when swapped 1145 // in. 1146 if (disposition == NEW_BACKGROUND_TAB) 1147 GetPrerenderContents()->set_should_be_shown(false); 1148 1149 scoped_ptr<content::WindowedNotificationObserver> page_load_observer; 1150 WebContents* web_contents = NULL; 1151 1152 if (GetPrerenderContents()->prerender_contents()) { 1153 // In the case of zero loads, need to wait for the page load to complete 1154 // before running any Javascript. 1155 web_contents = GetPrerenderContents()->prerender_contents(); 1156 if (GetPrerenderContents()->number_of_loads() == 0) { 1157 page_load_observer.reset( 1158 new content::WindowedNotificationObserver( 1159 content::NOTIFICATION_LOAD_STOP, 1160 content::Source<NavigationController>( 1161 &web_contents->GetController()))); 1162 } 1163 } 1164 1165 // Navigate to the prerendered URL, but don't run the message loop. Browser 1166 // issued navigations to prerendered pages will synchronously swap in the 1167 // prerendered page. 1168 ui_test_utils::NavigateToURLWithDisposition( 1169 current_browser(), dest_url, disposition, 1170 ui_test_utils::BROWSER_TEST_NONE); 1171 1172 if (call_javascript_ && web_contents && expect_swap_to_succeed) { 1173 if (page_load_observer.get()) 1174 page_load_observer->Wait(); 1175 1176 bool display_test_result = false; 1177 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1178 web_contents, 1179 "window.domAutomationController.send(DidDisplayPass())", 1180 &display_test_result)); 1181 EXPECT_TRUE(display_test_result); 1182 } 1183 } 1184 1185 // Opens the prerendered page using javascript functions in the 1186 // loader page. |javascript_function_name| should be a 0 argument function 1187 // which is invoked. 1188 void OpenDestURLWithJSImpl(const std::string& javascript_function_name) 1189 const { 1190 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 1191 ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents); 1192 1193 RenderViewHost* render_view_host = current_browser()->tab_strip_model()-> 1194 GetActiveWebContents()->GetRenderViewHost(); 1195 1196 render_view_host->ExecuteJavascriptInWebFrame( 1197 string16(), ASCIIToUTF16(javascript_function_name)); 1198 1199 if (prerender_contents->quit_message_loop_on_destruction()) { 1200 // Run message loop until the prerender contents is destroyed. 1201 content::RunMessageLoop(); 1202 } else { 1203 // We don't expect to pick up a running prerender, so instead 1204 // observe one navigation. 1205 content::TestNavigationObserver observer( 1206 current_browser()->tab_strip_model()->GetActiveWebContents()); 1207 observer.StartWatchingNewWebContents(); 1208 base::RunLoop run_loop; 1209 observer.WaitForObservation( 1210 base::Bind(&content::RunThisRunLoop, 1211 base::Unretained(&run_loop)), 1212 content::GetQuitTaskForRunLoop(&run_loop)); 1213 } 1214 } 1215 1216 WaitForLoadPrerenderContentsFactory* prerender_contents_factory_; 1217 #if defined(FULL_SAFE_BROWSING) 1218 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_; 1219 #endif 1220 GURL dest_url_; 1221 bool use_https_src_server_; 1222 bool call_javascript_; 1223 std::string loader_path_; 1224 std::string loader_query_and_fragment_; 1225 Browser* explicitly_set_browser_; 1226 }; 1227 1228 // Checks that a page is correctly prerendered in the case of a 1229 // <link rel=prerender> tag and then loaded into a tab in response to a 1230 // navigation. 1231 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 1232 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1233 1234 ChannelDestructionWatcher channel_close_watcher; 1235 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1236 GetActiveWebContents()->GetRenderProcessHost()); 1237 NavigateToDestURL(); 1238 channel_close_watcher.WaitForChannelClose(); 1239 1240 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1241 } 1242 1243 // Checks that pending prerenders launch and receive proper event treatment. 1244 // Disabled due to http://crbug.com/167792 1245 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderPagePending) { 1246 std::deque<FinalStatus> expected_final_status_queue; 1247 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1248 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1249 PrerenderTestURL("files/prerender/prerender_page_pending.html", 1250 expected_final_status_queue, 1); 1251 1252 ChannelDestructionWatcher first_channel_close_watcher; 1253 1254 first_channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1255 GetActiveWebContents()->GetRenderProcessHost()); 1256 NavigateToDestURL(); 1257 // NavigateToDestURL doesn't run a message loop. Normally that's fine, but in 1258 // this case, we need the pending prerenders to start. 1259 content::RunMessageLoop(); 1260 first_channel_close_watcher.WaitForChannelClose(); 1261 1262 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1263 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1264 EXPECT_FALSE(HadPrerenderEventErrors()); 1265 1266 const GURL prerender_page_url = 1267 test_server()->GetURL("files/prerender/prerender_page.html"); 1268 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1269 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL), 1270 GetPrerenderContentsFor(prerender_page_url)); 1271 1272 // Now navigate to our target page. 1273 ChannelDestructionWatcher second_channel_close_watcher; 1274 second_channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1275 GetActiveWebContents()->GetRenderProcessHost()); 1276 ui_test_utils::NavigateToURLWithDisposition( 1277 current_browser(), prerender_page_url, CURRENT_TAB, 1278 ui_test_utils::BROWSER_TEST_NONE); 1279 second_channel_close_watcher.WaitForChannelClose(); 1280 1281 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1282 } 1283 1284 // Checks that pending prerenders which are canceled before they are launched 1285 // never get started. 1286 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) { 1287 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html", 1288 FINAL_STATUS_USED, 1); 1289 1290 ChannelDestructionWatcher channel_close_watcher; 1291 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1292 GetActiveWebContents()->GetRenderProcessHost()); 1293 NavigateToDestURL(); 1294 channel_close_watcher.WaitForChannelClose(); 1295 1296 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1)); 1297 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1298 EXPECT_FALSE(HadPrerenderEventErrors()); 1299 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1300 // calls did a thread/process hop to the renderer which insured pending 1301 // renderer events have arrived. 1302 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1303 } 1304 1305 // Flaky, http://crbug.com/167340. 1306 IN_PROC_BROWSER_TEST_F( 1307 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLink) { 1308 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1309 set_loader_query_and_fragment("?links_to_insert=1"); 1310 PrerenderTestURL("files/prerender/prerender_page.html", 1311 FINAL_STATUS_CANCELLED, 1); 1312 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1313 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1314 1315 // No ChannelDestructionWatcher is needed here, since prerenders in the 1316 // PrerenderLinkManager should be deleted by removing the links, rather than 1317 // shutting down the renderer process. 1318 RemoveLinkElement(0); 1319 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1320 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1321 EXPECT_FALSE(HadPrerenderEventErrors()); 1322 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1323 // calls did a thread/process hop to the renderer which insured pending 1324 // renderer events have arrived. 1325 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1326 } 1327 1328 // Flaky, http://crbug.com/167340. 1329 IN_PROC_BROWSER_TEST_F( 1330 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLinkWithTwoLinks) { 1331 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1332 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1333 1334 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1335 set_loader_query_and_fragment("?links_to_insert=2"); 1336 PrerenderTestURL("files/prerender/prerender_page.html", 1337 FINAL_STATUS_CANCELLED, 1); 1338 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1339 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1340 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1341 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1342 1343 RemoveLinkElement(0); 1344 RemoveLinkElement(1); 1345 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1346 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1347 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1348 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1349 EXPECT_FALSE(HadPrerenderEventErrors()); 1350 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1351 // calls did a thread/process hop to the renderer which insured pending 1352 // renderer events have arrived. 1353 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1354 } 1355 1356 #if defined(OS_WIN) 1357 // TODO(gavinp): Fails on XP Rel - http://crbug.com/128841 1358 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \ 1359 DISABLED_PrerenderPageRemovingLinkWithTwoLinksRemovingOne 1360 #else 1361 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \ 1362 PrerenderPageRemovingLinkWithTwoLinksRemovingOne 1363 #endif // defined(OS_WIN) 1364 IN_PROC_BROWSER_TEST_F( 1365 PrerenderBrowserTest, 1366 MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne) { 1367 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1368 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1369 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1370 set_loader_query_and_fragment("?links_to_insert=2"); 1371 PrerenderTestURL("files/prerender/prerender_page.html", 1372 FINAL_STATUS_USED, 1); 1373 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1374 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1375 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1376 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1377 1378 RemoveLinkElement(0); 1379 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1380 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1381 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1382 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1383 EXPECT_FALSE(HadPrerenderEventErrors()); 1384 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1385 // calls did a thread/process hop to the renderer which insured pending 1386 // renderer events have arrived. 1387 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1388 1389 ChannelDestructionWatcher channel_close_watcher; 1390 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1391 GetActiveWebContents()->GetRenderProcessHost()); 1392 NavigateToDestURL(); 1393 channel_close_watcher.WaitForChannelClose(); 1394 1395 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1396 } 1397 1398 // Checks that prerendering works in incognito mode. 1399 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIncognito) { 1400 Profile* normal_profile = current_browser()->profile(); 1401 set_browser( 1402 ui_test_utils::OpenURLOffTheRecord(normal_profile, GURL("about:blank"))); 1403 // Increase memory expectations on the incognito PrerenderManager. 1404 IncreasePrerenderMemory(); 1405 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1406 NavigateToDestURL(); 1407 } 1408 1409 // Checks that the visibility API works. 1410 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1411 DISABLED_PrerenderVisibility) { 1412 PrerenderTestURL("files/prerender/prerender_visibility.html", 1413 FINAL_STATUS_USED, 1414 1); 1415 NavigateToDestURL(); 1416 } 1417 1418 // Checks that the prerendering of a page is canceled correctly if we try to 1419 // swap it in before it commits. 1420 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) { 1421 // Navigate to a page that triggers a prerender for a URL that never commits. 1422 const GURL kNoCommitUrl("http://never-respond.example.com"); 1423 BrowserThread::PostTask( 1424 BrowserThread::IO, FROM_HERE, 1425 base::Bind(&CreateNeverStartProtocolHandlerOnIO, kNoCommitUrl)); 1426 PrerenderTestURL(kNoCommitUrl, 1427 FINAL_STATUS_CANCELLED, 1428 0); 1429 1430 // Navigate to the URL, but assume the contents won't be swapped in. 1431 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 1432 1433 // Confirm that the prerendered version of the URL is not swapped in, 1434 // since it never committed. 1435 EXPECT_TRUE(UrlIsInPrerenderManager(kNoCommitUrl)); 1436 1437 // Post a task to cancel all the prerenders, so that we don't wait further. 1438 base::MessageLoop::current()->PostTask( 1439 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 1440 content::RunMessageLoop(); 1441 } 1442 1443 // Checks that the prerendering of a page is canceled correctly when a 1444 // Javascript alert is called. 1445 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 1446 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 1447 FINAL_STATUS_JAVASCRIPT_ALERT, 1448 1); 1449 } 1450 1451 // Checks that the prerendering of a page is canceled correctly when a 1452 // Javascript alert is called. 1453 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 1454 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html", 1455 FINAL_STATUS_JAVASCRIPT_ALERT, 1456 1); 1457 } 1458 1459 // Checks that plugins are not loaded while a page is being preloaded, but 1460 // are loaded when the page is displayed. 1461 #if defined(USE_AURA) 1462 // http://crbug.com/103496 1463 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1464 #elif defined(OS_MACOSX) 1465 // http://crbug.com/100514 1466 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1467 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1468 // TODO(jschuh): Failing plugin tests. crbug.com/244653 1469 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1470 #else 1471 #define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin 1472 #endif 1473 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) { 1474 PrerenderTestURL("files/prerender/plugin_delay_load.html", 1475 FINAL_STATUS_USED, 1476 1); 1477 NavigateToDestURL(); 1478 } 1479 1480 // Checks that plugins are not loaded on prerendering pages when click-to-play 1481 // is enabled. 1482 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) { 1483 // Enable click-to-play. 1484 HostContentSettingsMap* content_settings_map = 1485 current_browser()->profile()->GetHostContentSettingsMap(); 1486 content_settings_map->SetDefaultContentSetting( 1487 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK); 1488 1489 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html", 1490 FINAL_STATUS_USED, 1491 1); 1492 NavigateToDestURL(); 1493 } 1494 1495 // Checks that we don't load a NaCl plugin when NaCl is disabled. 1496 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) { 1497 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html", 1498 FINAL_STATUS_USED, 1499 1); 1500 NavigateToDestURL(); 1501 1502 1503 // Run this check again. When we try to load aa ppapi plugin, the 1504 // "loadstart" event is asynchronously posted to a message loop. 1505 // It's possible that earlier call could have been run before the 1506 // the "loadstart" event was posted. 1507 // TODO(mmenke): While this should reliably fail on regressions, the 1508 // reliability depends on the specifics of ppapi plugin 1509 // loading. It would be great if we could avoid that. 1510 WebContents* web_contents = 1511 browser()->tab_strip_model()->GetActiveWebContents(); 1512 bool display_test_result = false; 1513 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1514 web_contents, 1515 "window.domAutomationController.send(DidDisplayPass())", 1516 &display_test_result)); 1517 EXPECT_TRUE(display_test_result); 1518 } 1519 1520 // Checks that plugins in an iframe are not loaded while a page is 1521 // being preloaded, but are loaded when the page is displayed. 1522 #if defined(USE_AURA) 1523 // http://crbug.com/103496 1524 #define MAYBE_PrerenderIframeDelayLoadPlugin \ 1525 DISABLED_PrerenderIframeDelayLoadPlugin 1526 #elif defined(OS_MACOSX) 1527 // http://crbug.com/100514 1528 #define MAYBE_PrerenderIframeDelayLoadPlugin \ 1529 DISABLED_PrerenderIframeDelayLoadPlugin 1530 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1531 // TODO(jschuh): Failing plugin tests. crbug.com/244653 1532 #define MAYBE_PrerenderIframeDelayLoadPlugin \ 1533 DISABLED_PrerenderIframeDelayLoadPlugin 1534 #else 1535 #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin 1536 #endif 1537 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1538 MAYBE_PrerenderIframeDelayLoadPlugin) { 1539 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html", 1540 FINAL_STATUS_USED, 1541 1); 1542 NavigateToDestURL(); 1543 } 1544 1545 // Renders a page that contains a prerender link to a page that contains an 1546 // iframe with a source that requires http authentication. This should not 1547 // prerender successfully. 1548 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) { 1549 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 1550 FINAL_STATUS_AUTH_NEEDED, 1551 1); 1552 } 1553 1554 // Checks that client-issued redirects work with prerendering. 1555 // This version navigates to the page which issues the redirection, rather 1556 // than the final destination page. 1557 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1558 DISABLED_PrerenderClientRedirectNavigateToFirst) { 1559 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 1560 FINAL_STATUS_USED, 1561 2); 1562 NavigateToDestURL(); 1563 } 1564 1565 // Checks that client-issued redirects work with prerendering. 1566 // This version navigates to the final destination page, rather than the 1567 // page which does the redirection. 1568 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1569 PrerenderClientRedirectNavigateToSecond) { 1570 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 1571 FINAL_STATUS_USED, 1572 2); 1573 NavigateToURL("files/prerender/prerender_page.html"); 1574 } 1575 1576 // Checks that client-issued redirects work with prerendering. 1577 // This version navigates to the final destination page, rather than the 1578 // page which does the redirection via a mouse click. 1579 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1580 DISABLED_PrerenderClientRedirectNavigateToSecondViaClick) { 1581 GURL prerender_url = test_server()->GetURL( 1582 CreateClientRedirect("files/prerender/prerender_page.html")); 1583 GURL destination_url = test_server()->GetURL( 1584 "files/prerender/prerender_page.html"); 1585 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 2); 1586 OpenDestURLViaClick(); 1587 } 1588 1589 // Checks that a prerender for an https will prevent a prerender from happening. 1590 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) { 1591 net::SpawnedTestServer https_server( 1592 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1593 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1594 ASSERT_TRUE(https_server.Start()); 1595 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1596 PrerenderTestURL(https_url, 1597 FINAL_STATUS_USED, 1598 1); 1599 NavigateToDestURL(); 1600 } 1601 1602 // Checks that client-issued redirects to an https page will cancel prerenders. 1603 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1604 DISABLED_PrerenderClientRedirectToHttps) { 1605 net::SpawnedTestServer https_server( 1606 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1607 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1608 ASSERT_TRUE(https_server.Start()); 1609 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1610 PrerenderTestURL(CreateClientRedirect(https_url.spec()), 1611 FINAL_STATUS_USED, 1612 2); 1613 NavigateToDestURL(); 1614 } 1615 1616 // Checks that client-issued redirects within an iframe in a prerendered 1617 // page will not count as an "alias" for the prerendered page. 1618 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1619 DISABLED_PrerenderClientRedirectInIframe) { 1620 std::string redirect_path = CreateClientRedirect( 1621 "/files/prerender/prerender_embedded_content.html"); 1622 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1623 replacement_text.push_back( 1624 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1625 std::string replacement_path; 1626 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1627 "files/prerender/prerender_with_iframe.html", 1628 replacement_text, 1629 &replacement_path)); 1630 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2); 1631 EXPECT_FALSE(UrlIsInPrerenderManager( 1632 "files/prerender/prerender_embedded_content.html")); 1633 NavigateToDestURL(); 1634 } 1635 1636 // Checks that client-issued redirects within an iframe in a prerendered 1637 // page to an https page will not cancel the prerender, nor will it 1638 // count as an "alias" for the prerendered page. 1639 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1640 DISABLED_PrerenderClientRedirectToHttpsInIframe) { 1641 net::SpawnedTestServer https_server( 1642 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1643 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1644 ASSERT_TRUE(https_server.Start()); 1645 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1646 std::string redirect_path = CreateClientRedirect(https_url.spec()); 1647 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1648 replacement_text.push_back( 1649 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1650 std::string replacement_path; 1651 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1652 "files/prerender/prerender_with_iframe.html", 1653 replacement_text, 1654 &replacement_path)); 1655 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2); 1656 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 1657 NavigateToDestURL(); 1658 } 1659 1660 // Checks that server-issued redirects work with prerendering. 1661 // This version navigates to the page which issues the redirection, rather 1662 // than the final destination page. 1663 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1664 PrerenderServerRedirectNavigateToFirst) { 1665 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 1666 FINAL_STATUS_USED, 1667 1); 1668 NavigateToDestURL(); 1669 } 1670 1671 // Checks that server-issued redirects work with prerendering. 1672 // This version navigates to the final destination page, rather than the 1673 // page which does the redirection. 1674 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1675 PrerenderServerRedirectNavigateToSecond) { 1676 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 1677 FINAL_STATUS_USED, 1678 1); 1679 NavigateToURL("files/prerender/prerender_page.html"); 1680 } 1681 1682 // Checks that server-issued redirects work with prerendering. 1683 // This version navigates to the final destination page, rather than the 1684 // page which does the redirection via a mouse click. 1685 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1686 PrerenderServerRedirectNavigateToSecondViaClick) { 1687 GURL prerender_url = test_server()->GetURL( 1688 CreateServerRedirect("files/prerender/prerender_page.html")); 1689 GURL destination_url = test_server()->GetURL( 1690 "files/prerender/prerender_page.html"); 1691 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 1); 1692 OpenDestURLViaClick(); 1693 } 1694 1695 // Checks that server-issued redirects from an http to an https 1696 // location will cancel prerendering. 1697 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1698 PrerenderServerRedirectToHttps) { 1699 net::SpawnedTestServer https_server( 1700 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1701 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1702 ASSERT_TRUE(https_server.Start()); 1703 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1704 PrerenderTestURL(CreateServerRedirect(https_url.spec()), 1705 FINAL_STATUS_USED, 1706 1); 1707 NavigateToDestURL(); 1708 } 1709 1710 // Checks that server-issued redirects within an iframe in a prerendered 1711 // page will not count as an "alias" for the prerendered page. 1712 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) { 1713 std::string redirect_path = CreateServerRedirect( 1714 "/files/prerender/prerender_embedded_content.html"); 1715 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1716 replacement_text.push_back( 1717 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1718 std::string replacement_path; 1719 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1720 "files/prerender/prerender_with_iframe.html", 1721 replacement_text, 1722 &replacement_path)); 1723 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 1724 EXPECT_FALSE(UrlIsInPrerenderManager( 1725 "files/prerender/prerender_embedded_content.html")); 1726 NavigateToDestURL(); 1727 } 1728 1729 // Checks that server-issued redirects within an iframe in a prerendered 1730 // page to an https page will not cancel the prerender, nor will it 1731 // count as an "alias" for the prerendered page. 1732 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1733 DISABLED_PrerenderServerRedirectToHttpsInIframe) { 1734 net::SpawnedTestServer https_server( 1735 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1736 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1737 ASSERT_TRUE(https_server.Start()); 1738 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1739 std::string redirect_path = CreateServerRedirect(https_url.spec()); 1740 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1741 replacement_text.push_back( 1742 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1743 std::string replacement_path; 1744 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1745 "files/prerender/prerender_with_iframe.html", 1746 replacement_text, 1747 &replacement_path)); 1748 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 1749 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 1750 NavigateToDestURL(); 1751 } 1752 1753 // Prerenders a page that contains an automatic download triggered through an 1754 // iframe. This should not prerender successfully. 1755 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) { 1756 PrerenderTestURL("files/prerender/prerender_download_iframe.html", 1757 FINAL_STATUS_DOWNLOAD, 1758 1); 1759 } 1760 1761 // Prerenders a page that contains an automatic download triggered through 1762 // Javascript changing the window.location. This should not prerender 1763 // successfully 1764 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) { 1765 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"), 1766 FINAL_STATUS_DOWNLOAD, 1767 1); 1768 } 1769 1770 // Prerenders a page that contains an automatic download triggered through a 1771 // client-issued redirect. This should not prerender successfully. 1772 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) { 1773 PrerenderTestURL("files/prerender/prerender_download_refresh.html", 1774 FINAL_STATUS_DOWNLOAD, 1775 1); 1776 } 1777 1778 // Checks that the referrer is set when prerendering. 1779 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) { 1780 PrerenderTestURL("files/prerender/prerender_referrer.html", 1781 FINAL_STATUS_USED, 1782 1); 1783 NavigateToDestURL(); 1784 } 1785 1786 // Checks that the referrer is not set when prerendering and the source page is 1787 // HTTPS. 1788 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1789 DISABLED_PrerenderNoSSLReferrer) { 1790 set_use_https_src(true); 1791 PrerenderTestURL("files/prerender/prerender_no_referrer.html", 1792 FINAL_STATUS_USED, 1793 1); 1794 NavigateToDestURL(); 1795 } 1796 1797 // Checks that popups on a prerendered page cause cancellation. 1798 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) { 1799 PrerenderTestURL("files/prerender/prerender_popup.html", 1800 FINAL_STATUS_CREATE_NEW_WINDOW, 1801 1); 1802 } 1803 1804 // Checks that registering a protocol handler causes cancellation. 1805 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) { 1806 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html", 1807 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER, 1808 1); 1809 } 1810 1811 // Checks that renderers using excessive memory will be terminated. 1812 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) { 1813 ASSERT_TRUE(GetPrerenderManager()); 1814 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024; 1815 PrerenderTestURL("files/prerender/prerender_excessive_memory.html", 1816 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1817 1); 1818 } 1819 1820 // Checks shutdown code while a prerender is active. 1821 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) { 1822 PrerenderTestURL("files/prerender/prerender_page.html", 1823 FINAL_STATUS_APP_TERMINATING, 1824 0); 1825 } 1826 1827 // TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test. 1828 // Checks that we don't prerender in an infinite loop. 1829 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) { 1830 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html"; 1831 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html"; 1832 1833 std::deque<FinalStatus> expected_final_status_queue; 1834 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1835 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1836 1837 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 1838 ASSERT_TRUE(GetPrerenderContents()); 1839 GetPrerenderContents()->WaitForPendingPrerenders(1u); 1840 1841 // Next url should be in pending list but not an active entry. 1842 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 1843 1844 NavigateToDestURL(); 1845 1846 // Make sure the PrerenderContents for the next url is now in the manager 1847 // and not pending. 1848 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB)); 1849 } 1850 1851 // TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test. 1852 // Checks that we don't prerender in an infinite loop and multiple links are 1853 // handled correctly. 1854 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1855 DISABLED_PrerenderInfiniteLoopMultiple) { 1856 const char* const kHtmlFileA = 1857 "files/prerender/prerender_infinite_a_multiple.html"; 1858 const char* const kHtmlFileB = 1859 "files/prerender/prerender_infinite_b_multiple.html"; 1860 const char* const kHtmlFileC = 1861 "files/prerender/prerender_infinite_c_multiple.html"; 1862 1863 // This test is conceptually simplest if concurrency is at two, since we 1864 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted. 1865 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1866 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1867 1868 std::deque<FinalStatus> expected_final_status_queue; 1869 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1870 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1871 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1872 1873 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 1874 ASSERT_TRUE(GetPrerenderContents()); 1875 GetPrerenderContents()->WaitForPendingPrerenders(2u); 1876 1877 // Next url should be in pending list but not an active entry. 1878 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 1879 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC)); 1880 1881 NavigateToDestURL(); 1882 1883 // Make sure the PrerenderContents for the next urls are now in the manager 1884 // and not pending. One and only one of the URLs (the last seen) should be the 1885 // active entry. 1886 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB); 1887 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC); 1888 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender); 1889 } 1890 1891 // See crbug.com/131836. 1892 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderTaskManager) { 1893 // Show the task manager. This populates the model. 1894 chrome::OpenTaskManager(current_browser()); 1895 // Wait for the model of task manager to start. 1896 TaskManagerBrowserTestUtil::WaitForWebResourceChange(1); 1897 1898 // Start with two resources. 1899 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1900 1901 // One of the resources that has a WebContents associated with it should have 1902 // the Prerender prefix. 1903 const string16 prefix = 1904 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX, string16()); 1905 string16 prerender_title; 1906 int num_prerender_tabs = 0; 1907 1908 const TaskManagerModel* model = GetModel(); 1909 for (int i = 0; i < model->ResourceCount(); ++i) { 1910 if (model->GetResourceWebContents(i)) { 1911 prerender_title = model->GetResourceTitle(i); 1912 if (StartsWith(prerender_title, prefix, true)) 1913 ++num_prerender_tabs; 1914 } 1915 } 1916 EXPECT_EQ(1, num_prerender_tabs); 1917 const string16 prerender_page_title = prerender_title.substr(prefix.length()); 1918 1919 NavigateToDestURL(); 1920 1921 // There should be no tabs with the Prerender prefix. 1922 const string16 tab_prefix = 1923 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, string16()); 1924 num_prerender_tabs = 0; 1925 int num_tabs_with_prerender_page_title = 0; 1926 for (int i = 0; i < model->ResourceCount(); ++i) { 1927 if (model->GetResourceWebContents(i)) { 1928 string16 tab_title = model->GetResourceTitle(i); 1929 if (StartsWith(tab_title, prefix, true)) { 1930 ++num_prerender_tabs; 1931 } else { 1932 EXPECT_TRUE(StartsWith(tab_title, tab_prefix, true)); 1933 1934 // The prerender tab should now be a normal tab but the title should be 1935 // the same. Depending on timing, there may be more than one of these. 1936 const string16 tab_page_title = tab_title.substr(tab_prefix.length()); 1937 if (prerender_page_title.compare(tab_page_title) == 0) 1938 ++num_tabs_with_prerender_page_title; 1939 } 1940 } 1941 } 1942 EXPECT_EQ(0, num_prerender_tabs); 1943 1944 // We may have deleted the prerender tab, but the swapped in tab should be 1945 // active. 1946 EXPECT_GE(num_tabs_with_prerender_page_title, 1); 1947 EXPECT_LE(num_tabs_with_prerender_page_title, 2); 1948 } 1949 1950 // Checks that audio loads are deferred on prerendering. 1951 // Times out under AddressSanitizer, see http://crbug.com/108402 1952 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Audio) { 1953 PrerenderTestURL("files/prerender/prerender_html5_audio.html", 1954 FINAL_STATUS_USED, 1955 1); 1956 NavigateToDestUrlAndWaitForPassTitle(); 1957 } 1958 1959 // Checks that audio loads are deferred on prerendering and played back when 1960 // the prerender is swapped in if autoplay is set. 1961 // Periodically fails on chrome-os. See http://crbug.com/145263 1962 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1963 DISABLED_PrerenderHTML5AudioAutoplay) { 1964 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html", 1965 FINAL_STATUS_USED, 1966 1); 1967 NavigateToDestUrlAndWaitForPassTitle(); 1968 } 1969 1970 // Checks that audio loads are deferred on prerendering and played back when 1971 // the prerender is swapped in if js starts playing. 1972 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1973 DISABLED_PrerenderHTML5AudioJsplay) { 1974 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html", 1975 FINAL_STATUS_USED, 1976 1); 1977 NavigateToDestUrlAndWaitForPassTitle(); 1978 } 1979 1980 // Checks that video loads are deferred on prerendering. 1981 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Video) { 1982 PrerenderTestURL("files/prerender/prerender_html5_video.html", 1983 FINAL_STATUS_USED, 1984 1); 1985 NavigateToDestUrlAndWaitForPassTitle(); 1986 } 1987 1988 // Checks that video tags inserted by javascript are deferred and played 1989 // correctly on swap in. 1990 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1991 DISABLED_PrerenderHTML5VideoJs) { 1992 PrerenderTestURL("files/prerender/prerender_html5_video_script.html", 1993 FINAL_STATUS_USED, 1994 1); 1995 NavigateToDestUrlAndWaitForPassTitle(); 1996 } 1997 1998 // Checks for correct network events by using a busy sleep the javascript. 1999 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2000 DISABLED_PrerenderHTML5VideoNetwork) { 2001 PrerenderTestURL("files/prerender/prerender_html5_video_network.html", 2002 FINAL_STATUS_USED, 2003 1, 2004 true); 2005 NavigateToDestUrlAndWaitForPassTitle(); 2006 } 2007 2008 // Checks that scripts can retrieve the correct window size while prerendering. 2009 #if defined(TOOLKIT_VIEWS) 2010 // TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363 2011 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) { 2012 #else 2013 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) { 2014 #endif 2015 PrerenderTestURL("files/prerender/prerender_size.html", 2016 FINAL_STATUS_USED, 2017 1); 2018 NavigateToDestURL(); 2019 } 2020 2021 // Flakily times out: http://crbug.com/171546 2022 // Checks that prerenderers will terminate when the RenderView crashes. 2023 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderRendererCrash) { 2024 PrerenderTestURL("files/prerender/prerender_page.html", 2025 FINAL_STATUS_RENDERER_CRASHED, 2026 1); 2027 2028 // Navigate to about:crash and then wait for the renderer to crash. 2029 ASSERT_TRUE(GetPrerenderContents()); 2030 ASSERT_TRUE(GetPrerenderContents()->prerender_contents()); 2031 GetPrerenderContents()->prerender_contents()->GetController(). 2032 LoadURL( 2033 GURL(content::kChromeUICrashURL), 2034 content::Referrer(), 2035 content::PAGE_TRANSITION_TYPED, 2036 std::string()); 2037 content::RunMessageLoop(); 2038 } 2039 2040 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2041 PrerenderPageWithFragment) { 2042 PrerenderTestURL("files/prerender/prerender_page.html#fragment", 2043 FINAL_STATUS_USED, 2044 1); 2045 2046 ChannelDestructionWatcher channel_close_watcher; 2047 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2048 GetActiveWebContents()->GetRenderProcessHost()); 2049 NavigateToDestURL(); 2050 channel_close_watcher.WaitForChannelClose(); 2051 2052 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2053 } 2054 2055 // Checks that we correctly use a prerendered page when navigating to a 2056 // fragment. 2057 // DISABLED: http://crbug.com/84154 2058 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2059 DISABLED_PrerenderPageNavigateFragment) { 2060 PrerenderTestURL("files/prerender/no_prerender_page.html", 2061 FINAL_STATUS_APP_TERMINATING, 2062 1); 2063 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2064 } 2065 2066 // Checks that we correctly use a prerendered page when we prerender a fragment 2067 // but navigate to the main page. 2068 // http://crbug.com/83901 2069 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2070 DISABLED_PrerenderFragmentNavigatePage) { 2071 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment", 2072 FINAL_STATUS_APP_TERMINATING, 2073 1); 2074 NavigateToURL("files/prerender/no_prerender_page.html"); 2075 } 2076 2077 // Checks that we correctly use a prerendered page when we prerender a fragment 2078 // but navigate to a different fragment on the same page. 2079 // DISABLED: http://crbug.com/84154 2080 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2081 DISABLED_PrerenderFragmentNavigateFragment) { 2082 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment", 2083 FINAL_STATUS_APP_TERMINATING, 2084 1); 2085 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2086 } 2087 2088 // Checks that we correctly use a prerendered page when the page uses a client 2089 // redirect to refresh from a fragment on the same page. 2090 // http://crbug.com/83901 2091 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2092 DISABLED_PrerenderClientRedirectFromFragment) { 2093 PrerenderTestURL( 2094 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"), 2095 FINAL_STATUS_APP_TERMINATING, 2096 2); 2097 NavigateToURL("files/prerender/no_prerender_page.html"); 2098 } 2099 2100 // Checks that we correctly use a prerendered page when the page uses a client 2101 // redirect to refresh to a fragment on the same page. 2102 // DISABLED: http://crbug.com/84154 2103 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2104 DISABLED_PrerenderClientRedirectToFragment) { 2105 PrerenderTestURL( 2106 CreateClientRedirect("files/prerender/no_prerender_page.html"), 2107 FINAL_STATUS_APP_TERMINATING, 2108 2); 2109 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2110 } 2111 2112 // Checks that we correctly use a prerendered page when the page uses JS to set 2113 // the window.location.hash to a fragment on the same page. 2114 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2115 PrerenderPageChangeFragmentLocationHash) { 2116 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html", 2117 FINAL_STATUS_USED, 2118 1); 2119 NavigateToURL("files/prerender/prerender_fragment_location_hash.html"); 2120 } 2121 2122 // Checks that prerendering a PNG works correctly. 2123 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) { 2124 DisableJavascriptCalls(); 2125 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1); 2126 NavigateToDestURL(); 2127 } 2128 2129 // Checks that prerendering a JPG works correctly. 2130 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) { 2131 DisableJavascriptCalls(); 2132 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1); 2133 NavigateToDestURL(); 2134 } 2135 2136 // Checks that a prerender of a CRX will result in a cancellation due to 2137 // download. 2138 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) { 2139 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 1); 2140 } 2141 2142 // Checks that xhr GET requests allow prerenders. 2143 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) { 2144 PrerenderTestURL("files/prerender/prerender_xhr_get.html", 2145 FINAL_STATUS_USED, 2146 1); 2147 NavigateToDestURL(); 2148 } 2149 2150 // Checks that xhr HEAD requests allow prerenders. 2151 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) { 2152 PrerenderTestURL("files/prerender/prerender_xhr_head.html", 2153 FINAL_STATUS_USED, 2154 1); 2155 NavigateToDestURL(); 2156 } 2157 2158 // Checks that xhr OPTIONS requests allow prerenders. 2159 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) { 2160 PrerenderTestURL("files/prerender/prerender_xhr_options.html", 2161 FINAL_STATUS_USED, 2162 1); 2163 NavigateToDestURL(); 2164 } 2165 2166 // Checks that xhr TRACE requests allow prerenders. 2167 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) { 2168 PrerenderTestURL("files/prerender/prerender_xhr_trace.html", 2169 FINAL_STATUS_USED, 2170 1); 2171 NavigateToDestURL(); 2172 } 2173 2174 // Checks that xhr POST requests allow prerenders. 2175 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderXhrPost) { 2176 PrerenderTestURL("files/prerender/prerender_xhr_post.html", 2177 FINAL_STATUS_USED, 2178 1); 2179 NavigateToDestURL(); 2180 } 2181 2182 // Checks that xhr PUT cancels prerenders. 2183 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) { 2184 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 2185 FINAL_STATUS_INVALID_HTTP_METHOD, 2186 1); 2187 } 2188 2189 // Checks that xhr DELETE cancels prerenders. 2190 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) { 2191 PrerenderTestURL("files/prerender/prerender_xhr_delete.html", 2192 FINAL_STATUS_INVALID_HTTP_METHOD, 2193 1); 2194 } 2195 2196 // Checks that a top-level page which would trigger an SSL error is canceled. 2197 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) { 2198 net::SpawnedTestServer::SSLOptions ssl_options; 2199 ssl_options.server_certificate = 2200 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2201 net::SpawnedTestServer https_server( 2202 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2203 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2204 ASSERT_TRUE(https_server.Start()); 2205 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2206 PrerenderTestURL(https_url, 2207 FINAL_STATUS_SSL_ERROR, 2208 1); 2209 } 2210 2211 // Checks that an SSL error that comes from a subresource does not cancel 2212 // the page. Non-main-frame requests are simply cancelled if they run into 2213 // an SSL problem. 2214 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) { 2215 net::SpawnedTestServer::SSLOptions ssl_options; 2216 ssl_options.server_certificate = 2217 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2218 net::SpawnedTestServer https_server( 2219 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2220 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2221 ASSERT_TRUE(https_server.Start()); 2222 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2223 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2224 replacement_text.push_back( 2225 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2226 std::string replacement_path; 2227 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2228 "files/prerender/prerender_with_image.html", 2229 replacement_text, 2230 &replacement_path)); 2231 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2232 NavigateToDestURL(); 2233 } 2234 2235 // Checks that an SSL error that comes from an iframe does not cancel 2236 // the page. Non-main-frame requests are simply cancelled if they run into 2237 // an SSL problem. 2238 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) { 2239 net::SpawnedTestServer::SSLOptions ssl_options; 2240 ssl_options.server_certificate = 2241 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2242 net::SpawnedTestServer https_server( 2243 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2244 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2245 ASSERT_TRUE(https_server.Start()); 2246 GURL https_url = https_server.GetURL( 2247 "files/prerender/prerender_embedded_content.html"); 2248 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2249 replacement_text.push_back( 2250 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2251 std::string replacement_path; 2252 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2253 "files/prerender/prerender_with_iframe.html", 2254 replacement_text, 2255 &replacement_path)); 2256 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2257 NavigateToDestURL(); 2258 } 2259 2260 // Checks that we cancel correctly when window.print() is called. 2261 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) { 2262 PrerenderTestURL("files/prerender/prerender_print.html", 2263 FINAL_STATUS_WINDOW_PRINT, 2264 1); 2265 } 2266 2267 // Checks that if a page is opened in a new window by javascript and both the 2268 // pages are in the same domain, the prerendered page is not used. 2269 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2270 PrerenderSameDomainWindowOpenerWindowOpen) { 2271 PrerenderTestURL("files/prerender/prerender_page.html", 2272 FINAL_STATUS_APP_TERMINATING, 2273 1); 2274 OpenDestURLViaWindowOpen(); 2275 } 2276 2277 // Checks that if a page is opened due to click on a href with target="_blank" 2278 // and both pages are in the same domain the prerendered page is not used. 2279 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2280 PrerenderSameDomainWindowOpenerClickTarget) { 2281 PrerenderTestURL("files/prerender/prerender_page.html", 2282 FINAL_STATUS_APP_TERMINATING, 2283 1); 2284 OpenDestURLViaClickTarget(); 2285 } 2286 2287 // Checks that a top-level page which would normally request an SSL client 2288 // certificate will never be seen since it's an https top-level resource. 2289 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertTopLevel) { 2290 net::SpawnedTestServer::SSLOptions ssl_options; 2291 ssl_options.request_client_certificate = true; 2292 net::SpawnedTestServer https_server( 2293 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2294 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2295 ASSERT_TRUE(https_server.Start()); 2296 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2297 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 1); 2298 } 2299 2300 // Checks that an SSL Client Certificate request that originates from a 2301 // subresource will cancel the prerendered page. 2302 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2303 PrerenderSSLClientCertSubresource) { 2304 net::SpawnedTestServer::SSLOptions ssl_options; 2305 ssl_options.request_client_certificate = true; 2306 net::SpawnedTestServer https_server( 2307 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2308 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2309 ASSERT_TRUE(https_server.Start()); 2310 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2311 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2312 replacement_text.push_back( 2313 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2314 std::string replacement_path; 2315 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2316 "files/prerender/prerender_with_image.html", 2317 replacement_text, 2318 &replacement_path)); 2319 PrerenderTestURL(replacement_path, 2320 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2321 1); 2322 } 2323 2324 // Checks that an SSL Client Certificate request that originates from an 2325 // iframe will cancel the prerendered page. 2326 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) { 2327 net::SpawnedTestServer::SSLOptions ssl_options; 2328 ssl_options.request_client_certificate = true; 2329 net::SpawnedTestServer https_server( 2330 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2331 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2332 ASSERT_TRUE(https_server.Start()); 2333 GURL https_url = https_server.GetURL( 2334 "files/prerender/prerender_embedded_content.html"); 2335 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2336 replacement_text.push_back( 2337 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2338 std::string replacement_path; 2339 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2340 "files/prerender/prerender_with_iframe.html", 2341 replacement_text, 2342 &replacement_path)); 2343 PrerenderTestURL(replacement_path, 2344 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2345 1); 2346 } 2347 2348 #if defined(FULL_SAFE_BROWSING) 2349 // Ensures that we do not prerender pages with a safe browsing 2350 // interstitial. 2351 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) { 2352 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2353 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2354 url, SB_THREAT_TYPE_URL_MALWARE); 2355 PrerenderTestURL("files/prerender/prerender_page.html", 2356 FINAL_STATUS_SAFE_BROWSING, 1); 2357 } 2358 2359 // Ensures that server redirects to a malware page will cancel prerenders. 2360 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2361 PrerenderSafeBrowsingServerRedirect) { 2362 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2363 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2364 url, SB_THREAT_TYPE_URL_MALWARE); 2365 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 2366 FINAL_STATUS_SAFE_BROWSING, 2367 1); 2368 } 2369 2370 // Ensures that client redirects to a malware page will cancel prerenders. 2371 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2372 PrerenderSafeBrowsingClientRedirect) { 2373 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2374 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2375 url, SB_THREAT_TYPE_URL_MALWARE); 2376 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 2377 FINAL_STATUS_SAFE_BROWSING, 2378 1); 2379 } 2380 2381 // Ensures that we do not prerender pages which have a malware subresource. 2382 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) { 2383 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg"); 2384 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2385 image_url, SB_THREAT_TYPE_URL_MALWARE); 2386 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2387 replacement_text.push_back( 2388 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2389 std::string replacement_path; 2390 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2391 "files/prerender/prerender_with_image.html", 2392 replacement_text, 2393 &replacement_path)); 2394 PrerenderTestURL(replacement_path, 2395 FINAL_STATUS_SAFE_BROWSING, 2396 1); 2397 } 2398 2399 // Ensures that we do not prerender pages which have a malware iframe. 2400 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) { 2401 GURL iframe_url = test_server()->GetURL( 2402 "files/prerender/prerender_embedded_content.html"); 2403 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2404 iframe_url, SB_THREAT_TYPE_URL_MALWARE); 2405 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2406 replacement_text.push_back( 2407 std::make_pair("REPLACE_WITH_URL", iframe_url.spec())); 2408 std::string replacement_path; 2409 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2410 "files/prerender/prerender_with_iframe.html", 2411 replacement_text, 2412 &replacement_path)); 2413 PrerenderTestURL(replacement_path, 2414 FINAL_STATUS_SAFE_BROWSING, 2415 1); 2416 } 2417 2418 #endif 2419 2420 // Checks that a local storage read will not cause prerender to fail. 2421 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) { 2422 PrerenderTestURL("files/prerender/prerender_localstorage_read.html", 2423 FINAL_STATUS_USED, 2424 1); 2425 NavigateToDestURL(); 2426 } 2427 2428 // Checks that a local storage write will not cause prerender to fail. 2429 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) { 2430 PrerenderTestURL("files/prerender/prerender_localstorage_write.html", 2431 FINAL_STATUS_USED, 2432 1); 2433 NavigateToDestURL(); 2434 } 2435 2436 // Checks that the favicon is properly loaded on prerender. 2437 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2438 DISABLED_PrerenderFavicon) { 2439 PrerenderTestURL("files/prerender/prerender_favicon.html", 2440 FINAL_STATUS_USED, 2441 1); 2442 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 2443 ASSERT_TRUE(prerender_contents != NULL); 2444 content::WindowedNotificationObserver favicon_update_watcher( 2445 chrome::NOTIFICATION_FAVICON_UPDATED, 2446 content::Source<WebContents>(prerender_contents->prerender_contents())); 2447 NavigateToDestURL(); 2448 favicon_update_watcher.Wait(); 2449 } 2450 2451 // Checks that when a prerendered page is swapped in to a referring page, the 2452 // unload handlers on the referring page are executed. 2453 // Fails about 50% on CrOS, 5-10% on linux, win, mac. http://crbug.com/128986 2454 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderUnload) { 2455 set_loader_path("files/prerender/prerender_loader_with_unload.html"); 2456 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2457 string16 expected_title = ASCIIToUTF16("Unloaded"); 2458 content::TitleWatcher title_watcher( 2459 current_browser()->tab_strip_model()->GetActiveWebContents(), 2460 expected_title); 2461 NavigateToDestURL(); 2462 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 2463 } 2464 2465 // Checks that when the history is cleared, prerendering is cancelled and 2466 // prerendering history is cleared. 2467 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) { 2468 PrerenderTestURL("files/prerender/prerender_page.html", 2469 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 2470 1); 2471 2472 // Post a task to clear the history, and run the message loop until it 2473 // destroys the prerender. 2474 base::MessageLoop::current()->PostTask( 2475 FROM_HERE, 2476 base::Bind(&ClearBrowsingData, current_browser(), 2477 BrowsingDataRemover::REMOVE_HISTORY)); 2478 content::RunMessageLoop(); 2479 2480 // Make sure prerender history was cleared. 2481 EXPECT_EQ(0, GetHistoryLength()); 2482 } 2483 2484 // Checks that when the cache is cleared, prerenders are cancelled but 2485 // prerendering history is not cleared. 2486 // Flaky/times out on linux_aura, win, mac - http://crbug.com/270948 2487 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderClearCache) { 2488 PrerenderTestURL("files/prerender/prerender_page.html", 2489 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 2490 1); 2491 2492 // Post a task to clear the cache, and run the message loop until it 2493 // destroys the prerender. 2494 base::MessageLoop::current()->PostTask(FROM_HERE, 2495 base::Bind(&ClearBrowsingData, current_browser(), 2496 BrowsingDataRemover::REMOVE_CACHE)); 2497 content::RunMessageLoop(); 2498 2499 // Make sure prerender history was not cleared. Not a vital behavior, but 2500 // used to compare with PrerenderClearHistory test. 2501 EXPECT_EQ(1, GetHistoryLength()); 2502 } 2503 2504 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) { 2505 PrerenderTestURL("files/prerender/prerender_page.html", 2506 FINAL_STATUS_CANCELLED, 2507 1); 2508 // Post a task to cancel all the prerenders. 2509 base::MessageLoop::current()->PostTask( 2510 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2511 content::RunMessageLoop(); 2512 EXPECT_TRUE(GetPrerenderContents() == NULL); 2513 } 2514 2515 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) { 2516 PrerenderTestURL("files/prerender/prerender_page.html", 2517 FINAL_STATUS_CANCELLED, 1); 2518 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2519 EXPECT_TRUE(DidReceivePrerenderLoadEventForLinkNumber(0)); 2520 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 2521 2522 base::MessageLoop::current()->PostTask( 2523 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2524 content::RunMessageLoop(); 2525 2526 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2527 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0)); 2528 EXPECT_FALSE(HadPrerenderEventErrors()); 2529 } 2530 2531 // Cancels the prerender of a page with its own prerender. The second prerender 2532 // should never be started. 2533 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2534 PrerenderCancelPrerenderWithPrerender) { 2535 PrerenderTestURL("files/prerender/prerender_infinite_a.html", 2536 FINAL_STATUS_CANCELLED, 2537 1); 2538 // Post a task to cancel all the prerenders. 2539 base::MessageLoop::current()->PostTask( 2540 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2541 content::RunMessageLoop(); 2542 EXPECT_TRUE(GetPrerenderContents() == NULL); 2543 } 2544 2545 // PrerenderBrowserTest.PrerenderEventsNoLoad may pass flakily on regression, 2546 // so please be aggressive about filing bugs when this test is failing. 2547 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEventsNoLoad) { 2548 // This should be canceled. 2549 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 2550 FINAL_STATUS_AUTH_NEEDED, 2551 1); 2552 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2553 EXPECT_FALSE(DidReceivePrerenderLoadEventForLinkNumber(0)); 2554 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 2555 EXPECT_FALSE(HadPrerenderEventErrors()); 2556 } 2557 2558 // Prerendering and history tests. 2559 // The prerendered page is navigated to in several ways [navigate via 2560 // omnibox, click on link, key-modified click to open in background tab, etc], 2561 // followed by a navigation to another page from the prerendered page, followed 2562 // by a back navigation. 2563 2564 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2565 DISABLED_PrerenderNavigateClickGoBack) { 2566 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2567 FINAL_STATUS_USED, 2568 1); 2569 NavigateToDestURL(); 2570 ClickToNextPageAfterPrerender(); 2571 GoBackToPrerender(); 2572 } 2573 2574 // Disabled due to timeouts on commit queue. 2575 // http://crbug.com/121130 2576 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2577 DISABLED_PrerenderNavigateNavigateGoBack) { 2578 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2579 FINAL_STATUS_USED, 2580 1); 2581 NavigateToDestURL(); 2582 NavigateToNextPageAfterPrerender(); 2583 GoBackToPrerender(); 2584 } 2585 2586 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2587 DISABLED_PrerenderClickClickGoBack) { 2588 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2589 FINAL_STATUS_USED, 2590 1); 2591 OpenDestURLViaClick(); 2592 ClickToNextPageAfterPrerender(); 2593 GoBackToPrerender(); 2594 } 2595 2596 // Disabled due to timeouts on commit queue. 2597 // http://crbug.com/121130 2598 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2599 DISABLED_PrerenderClickNavigateGoBack) { 2600 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2601 FINAL_STATUS_USED, 2602 1); 2603 OpenDestURLViaClick(); 2604 NavigateToNextPageAfterPrerender(); 2605 GoBackToPrerender(); 2606 } 2607 2608 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) { 2609 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2610 FINAL_STATUS_APP_TERMINATING, 2611 1); 2612 OpenDestURLViaClickNewWindow(); 2613 } 2614 2615 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) { 2616 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2617 FINAL_STATUS_APP_TERMINATING, 2618 1); 2619 OpenDestURLViaClickNewForegroundTab(); 2620 } 2621 2622 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2623 DISABLED_PrerenderClickNewBackgroundTab) { 2624 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2625 FINAL_STATUS_APP_TERMINATING, 2626 1); 2627 OpenDestURLViaClickNewBackgroundTab(); 2628 } 2629 2630 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2631 NavigateToPrerenderedPageWhenDevToolsAttached) { 2632 DisableJavascriptCalls(); 2633 WebContents* web_contents = 2634 current_browser()->tab_strip_model()->GetActiveWebContents(); 2635 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( 2636 web_contents->GetRenderViewHost())); 2637 DevToolsManager* manager = DevToolsManager::GetInstance(); 2638 FakeDevToolsClientHost client_host; 2639 manager->RegisterDevToolsClientHostFor(agent.get(), &client_host); 2640 const char* url = "files/prerender/prerender_page.html"; 2641 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1); 2642 NavigateToURL(url); 2643 manager->ClientHostClosing(&client_host); 2644 } 2645 2646 // Validate that the sessionStorage namespace remains the same when swapping 2647 // in a prerendered page. 2648 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2649 DISABLED_PrerenderSessionStorage) { 2650 set_loader_path("files/prerender/prerender_loader_with_session_storage.html"); 2651 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"), 2652 FINAL_STATUS_USED, 2653 1); 2654 NavigateToDestURL(); 2655 GoBackToPageBeforePrerender(); 2656 } 2657 2658 #if defined(OS_MACOSX) 2659 // http://crbug.com/142535 - Times out on Chrome Mac release builder 2660 #define MAYBE_ControlGroup DISABLED_ControlGroup 2661 #else 2662 #define MAYBE_ControlGroup ControlGroup 2663 #endif 2664 // Checks that the control group works. A JS alert cannot be detected in the 2665 // control group. 2666 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_ControlGroup) { 2667 RestorePrerenderMode restore_prerender_mode; 2668 PrerenderManager::SetMode( 2669 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP); 2670 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 2671 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0); 2672 NavigateToDestURL(); 2673 } 2674 2675 // Make sure that the MatchComplete dummy works in the normal case. Once 2676 // a prerender is cancelled because of a script, a dummy must be created to 2677 // account for the MatchComplete case, and it must have a final status of 2678 // FINAL_STATUS_WOULD_HAVE_BEEN_USED. 2679 #if defined(OS_MACOSX) 2680 // http://crbug.com/142912 - Times out on Chrome Mac release builder 2681 #define MAYBE_MatchCompleteDummy DISABLED_MatchCompleteDummy 2682 #else 2683 #define MAYBE_MatchCompleteDummy MatchCompleteDummy 2684 #endif 2685 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_MatchCompleteDummy) { 2686 std::deque<FinalStatus> expected_final_status_queue; 2687 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT); 2688 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 2689 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 2690 expected_final_status_queue, 1); 2691 NavigateToDestURL(); 2692 } 2693 2694 class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest { 2695 public: 2696 PrerenderBrowserTestWithNaCl() {} 2697 virtual ~PrerenderBrowserTestWithNaCl() {} 2698 2699 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2700 PrerenderBrowserTest::SetUpCommandLine(command_line); 2701 command_line->AppendSwitch(switches::kEnableNaCl); 2702 } 2703 }; 2704 2705 // Check that NaCl plugins work when enabled, with prerendering. 2706 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl, 2707 PrerenderNaClPluginEnabled) { 2708 #if defined(OS_WIN) && defined(USE_ASH) 2709 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 2710 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 2711 return; 2712 #endif 2713 2714 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html", 2715 FINAL_STATUS_USED, 2716 1); 2717 NavigateToDestURL(); 2718 2719 // To avoid any chance of a race, we have to let the script send its response 2720 // asynchronously. 2721 WebContents* web_contents = 2722 browser()->tab_strip_model()->GetActiveWebContents(); 2723 bool display_test_result = false; 2724 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, 2725 "DidDisplayReallyPass()", 2726 &display_test_result)); 2727 ASSERT_TRUE(display_test_result); 2728 } 2729 2730 // Checks that the referrer policy is used when prerendering. 2731 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) { 2732 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 2733 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 2734 FINAL_STATUS_USED, 2735 1); 2736 NavigateToDestURL(); 2737 } 2738 2739 // Checks that the referrer policy is used when prerendering on HTTPS. 2740 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2741 DISABLED_PrerenderSSLReferrerPolicy) { 2742 set_use_https_src(true); 2743 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 2744 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 2745 FINAL_STATUS_USED, 2746 1); 2747 NavigateToDestURL(); 2748 } 2749 2750 // Test interaction of the webNavigation and tabs API with prerender. 2751 class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest, 2752 public ExtensionApiTest { 2753 public: 2754 virtual void SetUp() OVERRIDE { 2755 PrerenderBrowserTest::SetUp(); 2756 } 2757 2758 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2759 PrerenderBrowserTest::SetUpCommandLine(command_line); 2760 ExtensionApiTest::SetUpCommandLine(command_line); 2761 } 2762 2763 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 2764 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture(); 2765 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); 2766 } 2767 2768 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 2769 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture(); 2770 ExtensionApiTest::TearDownInProcessBrowserTestFixture(); 2771 } 2772 2773 virtual void SetUpOnMainThread() OVERRIDE { 2774 PrerenderBrowserTest::SetUpOnMainThread(); 2775 } 2776 }; 2777 2778 // http://crbug.com/177163 2779 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, 2780 DISABLED_WebNavigation) { 2781 ASSERT_TRUE(StartEmbeddedTestServer()); 2782 extensions::FrameNavigationState::set_allow_extension_scheme(true); 2783 2784 CommandLine::ForCurrentProcess()->AppendSwitch( 2785 extensions::switches::kAllowLegacyExtensionManifests); 2786 2787 // Wait for the extension to set itself up and return control to us. 2788 ASSERT_TRUE( 2789 RunExtensionSubtest("webnavigation", "test_prerender.html")) << message_; 2790 2791 ResultCatcher catcher; 2792 2793 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2794 2795 ChannelDestructionWatcher channel_close_watcher; 2796 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2797 GetActiveWebContents()->GetRenderProcessHost()); 2798 NavigateToDestURL(); 2799 channel_close_watcher.WaitForChannelClose(); 2800 2801 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2802 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 2803 } 2804 2805 // Fails often on Windows dbg bots. http://crbug.com/177163 2806 #if defined(OS_WIN) 2807 #define MAYBE_TabsApi DISABLED_TabsApi 2808 #else 2809 #define MAYBE_TabsApi TabsApi 2810 #endif // defined(OS_WIN) 2811 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, MAYBE_TabsApi) { 2812 ASSERT_TRUE(StartEmbeddedTestServer()); 2813 extensions::FrameNavigationState::set_allow_extension_scheme(true); 2814 2815 // Wait for the extension to set itself up and return control to us. 2816 ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html")) 2817 << message_; 2818 2819 ResultCatcher catcher; 2820 2821 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2822 2823 ChannelDestructionWatcher channel_close_watcher; 2824 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2825 GetActiveWebContents()->GetRenderProcessHost()); 2826 NavigateToDestURL(); 2827 channel_close_watcher.WaitForChannelClose(); 2828 2829 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2830 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 2831 } 2832 2833 // Checks that non-http/https/chrome-extension subresource cancels the 2834 // prerender. 2835 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2836 DISABLED_PrerenderCancelSubresourceUnsupportedScheme) { 2837 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg"); 2838 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2839 replacement_text.push_back( 2840 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2841 std::string replacement_path; 2842 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2843 "files/prerender/prerender_with_image.html", 2844 replacement_text, 2845 &replacement_path)); 2846 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2847 NavigateToDestURL(); 2848 } 2849 2850 // Ensure that about:blank is permitted for any subresource. 2851 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2852 PrerenderAllowAboutBlankSubresource) { 2853 GURL image_url = GURL("about:blank"); 2854 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2855 replacement_text.push_back( 2856 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2857 std::string replacement_path; 2858 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2859 "files/prerender/prerender_with_image.html", 2860 replacement_text, 2861 &replacement_path)); 2862 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2863 NavigateToDestURL(); 2864 } 2865 2866 // Checks that non-http/https/chrome-extension subresource cancels the prerender 2867 // on redirect. 2868 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2869 PrerenderCancelSubresourceRedirectUnsupportedScheme) { 2870 GURL image_url = test_server()->GetURL( 2871 CreateServerRedirect("invalidscheme://www.google.com/test.jpg")); 2872 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2873 replacement_text.push_back( 2874 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2875 std::string replacement_path; 2876 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2877 "files/prerender/prerender_with_image.html", 2878 replacement_text, 2879 &replacement_path)); 2880 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2881 NavigateToDestURL(); 2882 } 2883 2884 // Checks that chrome-extension subresource does not cancel the prerender. 2885 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2886 PrerenderKeepSubresourceExtensionScheme) { 2887 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg"); 2888 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2889 replacement_text.push_back( 2890 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2891 std::string replacement_path; 2892 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2893 "files/prerender/prerender_with_image.html", 2894 replacement_text, 2895 &replacement_path)); 2896 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2897 NavigateToDestURL(); 2898 } 2899 2900 // Checks that redirect to chrome-extension subresource does not cancel the 2901 // prerender. 2902 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2903 PrerenderKeepSubresourceRedirectExtensionScheme) { 2904 GURL image_url = test_server()->GetURL( 2905 CreateServerRedirect("chrome-extension://abcdefg/test.jpg")); 2906 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2907 replacement_text.push_back( 2908 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2909 std::string replacement_path; 2910 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2911 "files/prerender/prerender_with_image.html", 2912 replacement_text, 2913 &replacement_path)); 2914 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2915 NavigateToDestURL(); 2916 } 2917 2918 2919 // Checks that non-http/https main page redirects cancel the prerender. 2920 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2921 PrerenderCancelMainFrameRedirectUnsupportedScheme) { 2922 GURL url = test_server()->GetURL( 2923 CreateServerRedirect("invalidscheme://www.google.com/test.html")); 2924 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2925 NavigateToDestURL(); 2926 } 2927 2928 // Checks that media source video loads are deferred on prerendering. 2929 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) { 2930 PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html", 2931 FINAL_STATUS_USED, 2932 1); 2933 NavigateToDestUrlAndWaitForPassTitle(); 2934 } 2935 2936 // Checks that a prerender that creates an audio stream (via a WebAudioDevice) 2937 // is cancelled. 2938 // http://crbug.com/261489 2939 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWebAudioDevice) { 2940 PrerenderTestURL("files/prerender/prerender_web_audio_device.html", 2941 FINAL_STATUS_CREATING_AUDIO_STREAM, 1); 2942 } 2943 2944 // Checks that prerenders do not swap in to WebContents being captured. 2945 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) { 2946 PrerenderTestURL("files/prerender/prerender_page.html", 2947 FINAL_STATUS_PAGE_BEING_CAPTURED, 1); 2948 WebContents* web_contents = 2949 current_browser()->tab_strip_model()->GetActiveWebContents(); 2950 web_contents->IncrementCapturerCount(); 2951 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 2952 web_contents->DecrementCapturerCount(); 2953 } 2954 2955 } // namespace prerender 2956