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