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