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