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