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