prerender_browsertest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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 621class PrerenderBrowserTest : virtual public InProcessBrowserTest { 622 public: 623 PrerenderBrowserTest() 624 : autostart_test_server_(true), 625 prerender_contents_factory_(NULL), 626#if defined(FULL_SAFE_BROWSING) 627 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()), 628#endif 629 use_https_src_server_(false), 630 call_javascript_(true), 631 loader_path_("files/prerender/prerender_loader.html"), 632 explicitly_set_browser_(NULL) {} 633 634 virtual ~PrerenderBrowserTest() {} 635 636 content::SessionStorageNamespace* GetSessionStorageNamespace() const { 637 WebContents* web_contents = 638 current_browser()->tab_strip_model()->GetActiveWebContents(); 639 if (!web_contents) 640 return NULL; 641 return web_contents->GetController().GetDefaultSessionStorageNamespace(); 642 } 643 644 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 645#if defined(FULL_SAFE_BROWSING) 646 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get()); 647#endif 648 } 649 650 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 651 command_line->AppendSwitchASCII(switches::kPrerenderMode, 652 switches::kPrerenderModeSwitchValueEnabled); 653#if defined(OS_MACOSX) 654 // The plugins directory isn't read by default on the Mac, so it needs to be 655 // explicitly registered. 656 base::FilePath app_dir; 657 PathService::Get(chrome::DIR_APP, &app_dir); 658 command_line->AppendSwitchPath( 659 switches::kExtraPluginDir, 660 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 661#endif 662 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins); 663 } 664 665 virtual void SetUpOnMainThread() OVERRIDE { 666 current_browser()->profile()->GetPrefs()->SetBoolean( 667 prefs::kPromptForDownload, false); 668 IncreasePrerenderMemory(); 669 if (autostart_test_server_) 670 ASSERT_TRUE(test_server()->Start()); 671 } 672 673 // Overload for a single expected final status 674 void PrerenderTestURL(const std::string& html_file, 675 FinalStatus expected_final_status, 676 int expected_number_of_loads) { 677 PrerenderTestURL(html_file, 678 expected_final_status, 679 expected_number_of_loads, 680 false); 681 } 682 683 void PrerenderTestURL(const std::string& html_file, 684 FinalStatus expected_final_status, 685 int expected_number_of_loads, 686 bool prerender_should_wait_for_ready_title) { 687 std::deque<FinalStatus> expected_final_status_queue(1, 688 expected_final_status); 689 PrerenderTestURL(html_file, 690 expected_final_status_queue, 691 expected_number_of_loads, 692 prerender_should_wait_for_ready_title); 693 } 694 695 void PrerenderTestURL( 696 const std::string& html_file, 697 const std::deque<FinalStatus>& expected_final_status_queue, 698 int expected_number_of_loads, 699 bool prerender_should_wait_for_ready_title) { 700 GURL url = test_server()->GetURL(html_file); 701 PrerenderTestURLImpl(url, url, 702 expected_final_status_queue, 703 expected_number_of_loads, 704 prerender_should_wait_for_ready_title); 705 } 706 707 void PrerenderTestURL( 708 const std::string& html_file, 709 const std::deque<FinalStatus>& expected_final_status_queue, 710 int expected_number_of_loads) { 711 PrerenderTestURL(html_file, expected_final_status_queue, 712 expected_number_of_loads, false); 713 } 714 715 void PrerenderTestURL( 716 const GURL& url, 717 FinalStatus expected_final_status, 718 int expected_number_of_loads) { 719 std::deque<FinalStatus> expected_final_status_queue(1, 720 expected_final_status); 721 PrerenderTestURLImpl(url, url, 722 expected_final_status_queue, 723 expected_number_of_loads, 724 false); 725 } 726 727 void PrerenderTestURL( 728 const GURL& prerender_url, 729 const GURL& destination_url, 730 FinalStatus expected_final_status, 731 int expected_number_of_loads) { 732 std::deque<FinalStatus> expected_final_status_queue(1, 733 expected_final_status); 734 PrerenderTestURLImpl(prerender_url, destination_url, 735 expected_final_status_queue, 736 expected_number_of_loads, 737 false); 738 } 739 740 void NavigateToDestURL() const { 741 NavigateToDestURLWithDisposition(CURRENT_TAB, true); 742 } 743 744 // Opens the url in a new tab, with no opener. 745 void NavigateToDestURLWithDisposition( 746 WindowOpenDisposition disposition, 747 bool expect_swap_to_succeed) const { 748 NavigateToURLImpl(dest_url_, disposition, expect_swap_to_succeed); 749 } 750 751 void OpenDestURLViaClick() const { 752 OpenDestURLWithJSImpl("Click()"); 753 } 754 755 void OpenDestURLViaClickTarget() const { 756 OpenDestURLWithJSImpl("ClickTarget()"); 757 } 758 759 void OpenDestURLViaClickNewWindow() const { 760 OpenDestURLWithJSImpl("ShiftClick()"); 761 } 762 763 void OpenDestURLViaClickNewForegroundTab() const { 764#if defined(OS_MACOSX) 765 OpenDestURLWithJSImpl("MetaShiftClick()"); 766#else 767 OpenDestURLWithJSImpl("CtrlShiftClick()"); 768#endif 769 } 770 771 void OpenDestURLViaClickNewBackgroundTab() const { 772 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 773 ASSERT_TRUE(prerender_contents != NULL); 774 prerender_contents->set_should_be_shown(false); 775#if defined(OS_MACOSX) 776 OpenDestURLWithJSImpl("MetaClick()"); 777#else 778 OpenDestURLWithJSImpl("CtrlClick()"); 779#endif 780 } 781 782 void OpenDestURLViaWindowOpen() const { 783 OpenDestURLWithJSImpl("WindowOpen()"); 784 } 785 786 void RemoveLinkElement(int i) const { 787 current_browser()->tab_strip_model()->GetActiveWebContents()-> 788 GetRenderViewHost()->ExecuteJavascriptInWebFrame( 789 string16(), 790 ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i))); 791 } 792 793 void ClickToNextPageAfterPrerender() { 794 content::WindowedNotificationObserver new_page_observer( 795 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 796 content::NotificationService::AllSources()); 797 RenderViewHost* render_view_host = current_browser()->tab_strip_model()-> 798 GetActiveWebContents()->GetRenderViewHost(); 799 render_view_host->ExecuteJavascriptInWebFrame( 800 string16(), 801 ASCIIToUTF16("ClickOpenLink()")); 802 new_page_observer.Wait(); 803 } 804 805 void NavigateToNextPageAfterPrerender() const { 806 ui_test_utils::NavigateToURL( 807 current_browser(), 808 test_server()->GetURL("files/prerender/prerender_page.html")); 809 } 810 811 void NavigateToDestUrlAndWaitForPassTitle() { 812 string16 expected_title = ASCIIToUTF16(kPassTitle); 813 content::TitleWatcher title_watcher( 814 GetPrerenderContents()->prerender_contents(), 815 expected_title); 816 NavigateToDestURL(); 817 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 818 } 819 820 // Called after the prerendered page has been navigated to and then away from. 821 // Navigates back through the history to the prerendered page. 822 void GoBackToPrerender() { 823 content::WindowedNotificationObserver back_nav_observer( 824 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 825 content::NotificationService::AllSources()); 826 chrome::GoBack(current_browser(), CURRENT_TAB); 827 back_nav_observer.Wait(); 828 bool original_prerender_page = false; 829 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 830 current_browser()->tab_strip_model()->GetActiveWebContents(), 831 "window.domAutomationController.send(IsOriginalPrerenderPage())", 832 &original_prerender_page)); 833 EXPECT_TRUE(original_prerender_page); 834 } 835 836 // Goes back to the page that was active before the prerender was swapped 837 // in. This must be called when the prerendered page is the current page 838 // in the active tab. 839 void GoBackToPageBeforePrerender() { 840 WebContents* tab = 841 current_browser()->tab_strip_model()->GetActiveWebContents(); 842 ASSERT_TRUE(tab); 843 EXPECT_FALSE(tab->IsLoading()); 844 content::WindowedNotificationObserver back_nav_observer( 845 content::NOTIFICATION_LOAD_STOP, 846 content::Source<NavigationController>(&tab->GetController())); 847 chrome::GoBack(current_browser(), CURRENT_TAB); 848 back_nav_observer.Wait(); 849 bool js_result; 850 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 851 tab, 852 "window.domAutomationController.send(DidBackToOriginalPagePass())", 853 &js_result)); 854 EXPECT_TRUE(js_result); 855 } 856 857 void NavigateToURL(const std::string& dest_html_file) const { 858 GURL dest_url = test_server()->GetURL(dest_html_file); 859 NavigateToURLImpl(dest_url, CURRENT_TAB, true); 860 } 861 862 bool UrlIsInPrerenderManager(const std::string& html_file) const { 863 return UrlIsInPrerenderManager(test_server()->GetURL(html_file)); 864 } 865 866 bool UrlIsInPrerenderManager(const GURL& url) const { 867 return GetPrerenderManager()->FindPrerenderData( 868 url, GetSessionStorageNamespace()) != NULL; 869 } 870 871 void set_use_https_src(bool use_https_src_server) { 872 use_https_src_server_ = use_https_src_server; 873 } 874 875 void DisableJavascriptCalls() { 876 call_javascript_ = false; 877 } 878 879 TaskManagerModel* GetModel() const { 880 return TaskManager::GetInstance()->model(); 881 } 882 883 PrerenderManager* GetPrerenderManager() const { 884 PrerenderManager* prerender_manager = 885 PrerenderManagerFactory::GetForProfile(current_browser()->profile()); 886 return prerender_manager; 887 } 888 889 const PrerenderLinkManager* GetPrerenderLinkManager() const { 890 PrerenderLinkManager* prerender_link_manager = 891 PrerenderLinkManagerFactory::GetForProfile( 892 current_browser()->profile()); 893 return prerender_link_manager; 894 } 895 896 bool DidReceivePrerenderStartEventForLinkNumber(int index) const { 897 bool received_prerender_started; 898 std::string expression = base::StringPrintf( 899 "window.domAutomationController.send(Boolean(" 900 "receivedPrerenderStartEvents[%d]))", index); 901 902 CHECK(content::ExecuteScriptAndExtractBool( 903 current_browser()->tab_strip_model()->GetActiveWebContents(), 904 expression, 905 &received_prerender_started)); 906 return received_prerender_started; 907 } 908 909 bool DidReceivePrerenderLoadEventForLinkNumber(int index) const { 910 bool received_prerender_loaded; 911 std::string expression = base::StringPrintf( 912 "window.domAutomationController.send(Boolean(" 913 "receivedPrerenderLoadEvents[%d]))", index); 914 915 CHECK(content::ExecuteScriptAndExtractBool( 916 current_browser()->tab_strip_model()->GetActiveWebContents(), 917 expression, 918 &received_prerender_loaded)); 919 return received_prerender_loaded; 920 } 921 922 bool DidReceivePrerenderStopEventForLinkNumber(int index) const { 923 bool received_prerender_stopped; 924 std::string expression = base::StringPrintf( 925 "window.domAutomationController.send(Boolean(" 926 "receivedPrerenderStopEvents[%d]))", index); 927 928 CHECK(content::ExecuteScriptAndExtractBool( 929 current_browser()->tab_strip_model()->GetActiveWebContents(), 930 expression, 931 &received_prerender_stopped)); 932 return received_prerender_stopped; 933 } 934 935 bool HadPrerenderEventErrors() const { 936 bool had_prerender_event_errors; 937 CHECK(content::ExecuteScriptAndExtractBool( 938 current_browser()->tab_strip_model()->GetActiveWebContents(), 939 "window.domAutomationController.send(Boolean(" 940 " hadPrerenderEventErrors))", 941 &had_prerender_event_errors)); 942 return had_prerender_event_errors; 943 } 944 945 // Asserting on this can result in flaky tests. PrerenderHandles are 946 // removed from the PrerenderLinkManager when the prerender is canceled from 947 // the browser, when the prerenders are cancelled from the renderer process, 948 // or the channel for the renderer process is closed on the IO thread. In the 949 // last case, the code must be careful to wait for the channel to close, as it 950 // is done asynchronously after swapping out the old process. See 951 // ChannelDestructionWatcher. 952 bool IsEmptyPrerenderLinkManager() const { 953 return GetPrerenderLinkManager()->IsEmpty(); 954 } 955 956 // Returns length of |prerender_manager_|'s history, or -1 on failure. 957 int GetHistoryLength() const { 958 scoped_ptr<DictionaryValue> prerender_dict( 959 static_cast<DictionaryValue*>(GetPrerenderManager()->GetAsValue())); 960 if (!prerender_dict.get()) 961 return -1; 962 ListValue* history_list; 963 if (!prerender_dict->GetList("history", &history_list)) 964 return -1; 965 return static_cast<int>(history_list->GetSize()); 966 } 967 968#if defined(FULL_SAFE_BROWSING) 969 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() { 970 return safe_browsing_factory_->most_recent_service()-> 971 fake_database_manager(); 972 } 973#endif 974 975 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const { 976 PrerenderManager::PrerenderData* prerender_data = 977 GetPrerenderManager()->FindPrerenderData( 978 url, GetSessionStorageNamespace()); 979 return static_cast<TestPrerenderContents*>( 980 prerender_data ? prerender_data->contents() : NULL); 981 } 982 983 TestPrerenderContents* GetPrerenderContents() const { 984 return GetPrerenderContentsFor(dest_url_); 985 } 986 987 void set_loader_path(const std::string& path) { 988 loader_path_ = path; 989 } 990 991 void set_loader_query_and_fragment(const std::string& query_and_fragment) { 992 loader_query_and_fragment_ = query_and_fragment; 993 } 994 995 GURL GetCrossDomainTestUrl(const std::string& path) { 996 static const std::string secondary_domain = "www.foo.com"; 997 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); 998 std::string url_str(base::StringPrintf( 999 "http://%s:%d/%s", 1000 secondary_domain.c_str(), 1001 test_server()->host_port_pair().port(), 1002 path.c_str())); 1003 return GURL(url_str); 1004 } 1005 1006 void set_browser(Browser* browser) { 1007 explicitly_set_browser_ = browser; 1008 } 1009 1010 Browser* current_browser() const { 1011 return explicitly_set_browser_ ? explicitly_set_browser_ : browser(); 1012 } 1013 1014 void IncreasePrerenderMemory() { 1015 // Increase the memory allowed in a prerendered page above normal settings. 1016 // Debug build bots occasionally run against the default limit, and tests 1017 // were failing because the prerender was canceled due to memory exhaustion. 1018 // http://crbug.com/93076 1019 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024; 1020 } 1021 1022 protected: 1023 bool autostart_test_server_; 1024 1025 private: 1026 void PrerenderTestURLImpl( 1027 const GURL& prerender_url, 1028 const GURL& destination_url, 1029 const std::deque<FinalStatus>& expected_final_status_queue, 1030 int expected_number_of_loads, 1031 bool prerender_should_wait_for_ready_title) { 1032 dest_url_ = destination_url; 1033 1034 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1035 replacement_text.push_back( 1036 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec())); 1037 replacement_text.push_back( 1038 make_pair("REPLACE_WITH_DESTINATION_URL", destination_url.spec())); 1039 std::string replacement_path; 1040 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1041 loader_path_, 1042 replacement_text, 1043 &replacement_path)); 1044 1045 const net::SpawnedTestServer* src_server = test_server(); 1046 scoped_ptr<net::SpawnedTestServer> https_src_server; 1047 if (use_https_src_server_) { 1048 https_src_server.reset( 1049 new net::SpawnedTestServer( 1050 net::SpawnedTestServer::TYPE_HTTPS, 1051 net::SpawnedTestServer::kLocalhost, 1052 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 1053 ASSERT_TRUE(https_src_server->Start()); 1054 src_server = https_src_server.get(); 1055 } 1056 GURL loader_url = src_server->GetURL(replacement_path + 1057 loader_query_and_fragment_); 1058 1059 PrerenderManager* prerender_manager = GetPrerenderManager(); 1060 ASSERT_TRUE(prerender_manager); 1061 prerender_manager->mutable_config().rate_limit_enabled = false; 1062 prerender_manager->mutable_config().https_allowed = true; 1063 ASSERT_TRUE(prerender_contents_factory_ == NULL); 1064 prerender_contents_factory_ = 1065 new WaitForLoadPrerenderContentsFactory( 1066 expected_number_of_loads, 1067 expected_final_status_queue, 1068 prerender_should_wait_for_ready_title); 1069 prerender_manager->SetPrerenderContentsFactory( 1070 prerender_contents_factory_); 1071 FinalStatus expected_final_status = expected_final_status_queue.front(); 1072 1073 // We construct launch_nav_observer so that we can be certain our loader 1074 // page has finished loading before continuing. This prevents ambiguous 1075 // NOTIFICATION_LOAD_STOP events from making tests flaky. 1076 WebContents* web_contents = 1077 current_browser()->tab_strip_model()->GetActiveWebContents(); 1078 content::WindowedNotificationObserver loader_nav_observer( 1079 content::NOTIFICATION_LOAD_STOP, 1080 content::Source<NavigationController>( 1081 &web_contents->GetController())); 1082 1083 // ui_test_utils::NavigateToURL uses its own observer and message loop. 1084 // Since the test needs to wait until the prerendered page has stopped 1085 // loading, rather than the page directly navigated to, need to 1086 // handle browser navigation directly. 1087 current_browser()->OpenURL(OpenURLParams( 1088 loader_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, 1089 false)); 1090 1091 content::RunMessageLoop(); 1092 // Now that we've run the prerender until it stopped loading, we can now 1093 // also make sure the launcher has finished loading. 1094 loader_nav_observer.Wait(); 1095 1096 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 1097 1098 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { 1099 ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents); 1100 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); 1101 1102 if (call_javascript_ && expected_number_of_loads > 0) { 1103 // Wait for the prerendered page to change title to signal it is ready 1104 // if required. 1105 prerender_contents->WaitForPrerenderToHaveReadyTitleIfRequired(); 1106 1107 // Check if page behaves as expected while in prerendered state. 1108 bool prerender_test_result = false; 1109 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1110 prerender_contents->GetRenderViewHostMutable(), 1111 "window.domAutomationController.send(DidPrerenderPass())", 1112 &prerender_test_result)); 1113 EXPECT_TRUE(prerender_test_result); 1114 } 1115 } else { 1116 // In the failure case, we should have removed |dest_url_| from the 1117 // prerender_manager. We ignore dummy PrerenderContents (as indicated 1118 // by not having started), and PrerenderContents that are expected to 1119 // be left in the manager until the test finishes. 1120 EXPECT_TRUE(prerender_contents == NULL || 1121 !prerender_contents->prerendering_has_started()); 1122 } 1123 } 1124 1125 void NavigateToURLImpl(const GURL& dest_url, 1126 WindowOpenDisposition disposition, 1127 bool expect_swap_to_succeed) const { 1128 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager()); 1129 // Make sure in navigating we have a URL to use in the PrerenderManager. 1130 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents()); 1131 1132 // If opening the page in a background tab, it won't be shown when swapped 1133 // in. 1134 if (disposition == NEW_BACKGROUND_TAB) 1135 GetPrerenderContents()->set_should_be_shown(false); 1136 1137 scoped_ptr<content::WindowedNotificationObserver> page_load_observer; 1138 WebContents* web_contents = NULL; 1139 1140 if (GetPrerenderContents()->prerender_contents()) { 1141 // In the case of zero loads, need to wait for the page load to complete 1142 // before running any Javascript. 1143 web_contents = GetPrerenderContents()->prerender_contents(); 1144 if (GetPrerenderContents()->number_of_loads() == 0) { 1145 page_load_observer.reset( 1146 new content::WindowedNotificationObserver( 1147 content::NOTIFICATION_LOAD_STOP, 1148 content::Source<NavigationController>( 1149 &web_contents->GetController()))); 1150 } 1151 } 1152 1153 // Navigate to the prerendered URL, but don't run the message loop. Browser 1154 // issued navigations to prerendered pages will synchronously swap in the 1155 // prerendered page. 1156 ui_test_utils::NavigateToURLWithDisposition( 1157 current_browser(), dest_url, disposition, 1158 ui_test_utils::BROWSER_TEST_NONE); 1159 1160 // Make sure the PrerenderContents found earlier was used or removed, 1161 // unless we expect the swap in to fail. 1162 EXPECT_EQ(expect_swap_to_succeed, !GetPrerenderContents()); 1163 1164 if (call_javascript_ && web_contents && expect_swap_to_succeed) { 1165 if (page_load_observer.get()) 1166 page_load_observer->Wait(); 1167 1168 bool display_test_result = false; 1169 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1170 web_contents, 1171 "window.domAutomationController.send(DidDisplayPass())", 1172 &display_test_result)); 1173 EXPECT_TRUE(display_test_result); 1174 } 1175 } 1176 1177 // Opens the prerendered page using javascript functions in the 1178 // loader page. |javascript_function_name| should be a 0 argument function 1179 // which is invoked. 1180 void OpenDestURLWithJSImpl(const std::string& javascript_function_name) 1181 const { 1182 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 1183 ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents); 1184 1185 RenderViewHost* render_view_host = current_browser()->tab_strip_model()-> 1186 GetActiveWebContents()->GetRenderViewHost(); 1187 1188 render_view_host->ExecuteJavascriptInWebFrame( 1189 string16(), ASCIIToUTF16(javascript_function_name)); 1190 1191 if (prerender_contents->quit_message_loop_on_destruction()) { 1192 // Run message loop until the prerender contents is destroyed. 1193 content::RunMessageLoop(); 1194 } else { 1195 // We don't expect to pick up a running prerender, so instead 1196 // observe one navigation. 1197 content::TestNavigationObserver observer( 1198 current_browser()->tab_strip_model()->GetActiveWebContents()); 1199 observer.StartWatchingNewWebContents(); 1200 base::RunLoop run_loop; 1201 observer.WaitForObservation( 1202 base::Bind(&content::RunThisRunLoop, 1203 base::Unretained(&run_loop)), 1204 content::GetQuitTaskForRunLoop(&run_loop)); 1205 } 1206 } 1207 1208 WaitForLoadPrerenderContentsFactory* prerender_contents_factory_; 1209#if defined(FULL_SAFE_BROWSING) 1210 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_; 1211#endif 1212 GURL dest_url_; 1213 bool use_https_src_server_; 1214 bool call_javascript_; 1215 std::string loader_path_; 1216 std::string loader_query_and_fragment_; 1217 Browser* explicitly_set_browser_; 1218}; 1219 1220// Checks that a page is correctly prerendered in the case of a 1221// <link rel=prerender> tag and then loaded into a tab in response to a 1222// navigation. 1223IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 1224 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1225 1226 ChannelDestructionWatcher channel_close_watcher; 1227 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1228 GetActiveWebContents()->GetRenderProcessHost()); 1229 NavigateToDestURL(); 1230 channel_close_watcher.WaitForChannelClose(); 1231 1232 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1233} 1234 1235// Checks that pending prerenders launch and receive proper event treatment. 1236// Disabled due to http://crbug.com/167792 1237IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderPagePending) { 1238 std::deque<FinalStatus> expected_final_status_queue; 1239 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1240 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1241 PrerenderTestURL("files/prerender/prerender_page_pending.html", 1242 expected_final_status_queue, 1); 1243 1244 ChannelDestructionWatcher first_channel_close_watcher; 1245 1246 first_channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1247 GetActiveWebContents()->GetRenderProcessHost()); 1248 NavigateToDestURL(); 1249 // NavigateToDestURL doesn't run a message loop. Normally that's fine, but in 1250 // this case, we need the pending prerenders to start. 1251 content::RunMessageLoop(); 1252 first_channel_close_watcher.WaitForChannelClose(); 1253 1254 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1255 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1256 EXPECT_FALSE(HadPrerenderEventErrors()); 1257 1258 const GURL prerender_page_url = 1259 test_server()->GetURL("files/prerender/prerender_page.html"); 1260 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1261 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL), 1262 GetPrerenderContentsFor(prerender_page_url)); 1263 1264 // Now navigate to our target page. 1265 ChannelDestructionWatcher second_channel_close_watcher; 1266 second_channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1267 GetActiveWebContents()->GetRenderProcessHost()); 1268 ui_test_utils::NavigateToURLWithDisposition( 1269 current_browser(), prerender_page_url, CURRENT_TAB, 1270 ui_test_utils::BROWSER_TEST_NONE); 1271 second_channel_close_watcher.WaitForChannelClose(); 1272 1273 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1274} 1275 1276// Checks that pending prerenders which are canceled before they are launched 1277// never get started. 1278IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) { 1279 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html", 1280 FINAL_STATUS_USED, 1); 1281 1282 ChannelDestructionWatcher channel_close_watcher; 1283 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1284 GetActiveWebContents()->GetRenderProcessHost()); 1285 NavigateToDestURL(); 1286 channel_close_watcher.WaitForChannelClose(); 1287 1288 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1)); 1289 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1290 EXPECT_FALSE(HadPrerenderEventErrors()); 1291 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1292 // calls did a thread/process hop to the renderer which insured pending 1293 // renderer events have arrived. 1294 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1295} 1296 1297// Flaky, http://crbug.com/167340. 1298IN_PROC_BROWSER_TEST_F( 1299 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLink) { 1300 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1301 set_loader_query_and_fragment("?links_to_insert=1"); 1302 PrerenderTestURL("files/prerender/prerender_page.html", 1303 FINAL_STATUS_CANCELLED, 1); 1304 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1305 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1306 1307 // No ChannelDestructionWatcher is needed here, since prerenders in the 1308 // PrerenderLinkManager should be deleted by removing the links, rather than 1309 // shutting down the renderer process. 1310 RemoveLinkElement(0); 1311 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1312 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1313 EXPECT_FALSE(HadPrerenderEventErrors()); 1314 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1315 // calls did a thread/process hop to the renderer which insured pending 1316 // renderer events have arrived. 1317 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1318} 1319 1320// Flaky, http://crbug.com/167340. 1321IN_PROC_BROWSER_TEST_F( 1322 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLinkWithTwoLinks) { 1323 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1324 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1325 1326 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1327 set_loader_query_and_fragment("?links_to_insert=2"); 1328 PrerenderTestURL("files/prerender/prerender_page.html", 1329 FINAL_STATUS_CANCELLED, 1); 1330 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1331 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1332 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1333 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1334 1335 RemoveLinkElement(0); 1336 RemoveLinkElement(1); 1337 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1338 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1339 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1340 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1341 EXPECT_FALSE(HadPrerenderEventErrors()); 1342 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1343 // calls did a thread/process hop to the renderer which insured pending 1344 // renderer events have arrived. 1345 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1346} 1347 1348#if defined(OS_WIN) 1349// TODO(gavinp): Fails on XP Rel - http://crbug.com/128841 1350#define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \ 1351 DISABLED_PrerenderPageRemovingLinkWithTwoLinksRemovingOne 1352#else 1353#define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \ 1354 PrerenderPageRemovingLinkWithTwoLinksRemovingOne 1355#endif // defined(OS_WIN) 1356IN_PROC_BROWSER_TEST_F( 1357 PrerenderBrowserTest, 1358 MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne) { 1359 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1360 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1361 set_loader_path("files/prerender/prerender_loader_removing_links.html"); 1362 set_loader_query_and_fragment("?links_to_insert=2"); 1363 PrerenderTestURL("files/prerender/prerender_page.html", 1364 FINAL_STATUS_USED, 1); 1365 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1366 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1367 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1368 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1369 1370 RemoveLinkElement(0); 1371 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1372 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1373 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1374 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1375 EXPECT_FALSE(HadPrerenderEventErrors()); 1376 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1377 // calls did a thread/process hop to the renderer which insured pending 1378 // renderer events have arrived. 1379 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1380 1381 ChannelDestructionWatcher channel_close_watcher; 1382 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 1383 GetActiveWebContents()->GetRenderProcessHost()); 1384 NavigateToDestURL(); 1385 channel_close_watcher.WaitForChannelClose(); 1386 1387 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1388} 1389 1390// Checks that prerendering works in incognito mode. 1391IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIncognito) { 1392 Profile* normal_profile = current_browser()->profile(); 1393 set_browser( 1394 ui_test_utils::OpenURLOffTheRecord(normal_profile, GURL("about:blank"))); 1395 // Increase memory expectations on the incognito PrerenderManager. 1396 IncreasePrerenderMemory(); 1397 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1398 NavigateToDestURL(); 1399} 1400 1401// Checks that the visibility API works. 1402IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) { 1403 PrerenderTestURL("files/prerender/prerender_visibility.html", 1404 FINAL_STATUS_USED, 1405 1); 1406 NavigateToDestURL(); 1407} 1408 1409// Checks that the prerendering of a page is canceled correctly if we try to 1410// swap it in before it commits. 1411IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) { 1412 // Navigate to a page that triggers a prerender for a URL that never commits. 1413 const GURL kNoCommitUrl("http://never-respond.example.com"); 1414 BrowserThread::PostTask( 1415 BrowserThread::IO, FROM_HERE, 1416 base::Bind(&CreateNeverStartProtocolHandlerOnIO, kNoCommitUrl)); 1417 PrerenderTestURL(kNoCommitUrl, 1418 FINAL_STATUS_CANCELLED, 1419 0); 1420 1421 // Navigate to the URL, but assume the contents won't be swapped in. 1422 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 1423 1424 // Confirm that the prerendered version of the URL is not swapped in, 1425 // since it never committed. 1426 EXPECT_TRUE(UrlIsInPrerenderManager(kNoCommitUrl)); 1427 1428 // Post a task to cancel all the prerenders, so that we don't wait further. 1429 base::MessageLoop::current()->PostTask( 1430 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 1431 content::RunMessageLoop(); 1432} 1433 1434// Checks that the prerendering of a page is canceled correctly when a 1435// Javascript alert is called. 1436IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 1437 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 1438 FINAL_STATUS_JAVASCRIPT_ALERT, 1439 1); 1440} 1441 1442// Checks that the prerendering of a page is canceled correctly when a 1443// Javascript alert is called. 1444IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 1445 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html", 1446 FINAL_STATUS_JAVASCRIPT_ALERT, 1447 1); 1448} 1449 1450// Checks that plugins are not loaded while a page is being preloaded, but 1451// are loaded when the page is displayed. 1452#if defined(USE_AURA) 1453// http://crbug.com/103496 1454#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1455#elif defined(OS_MACOSX) 1456// http://crbug.com/100514 1457#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1458#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1459// TODO(jschuh): Failing plugin tests. crbug.com/244653 1460#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1461#else 1462#define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin 1463#endif 1464IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) { 1465 PrerenderTestURL("files/prerender/plugin_delay_load.html", 1466 FINAL_STATUS_USED, 1467 1); 1468 NavigateToDestURL(); 1469} 1470 1471// Checks that plugins are not loaded on prerendering pages when click-to-play 1472// is enabled. 1473IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) { 1474 // Enable click-to-play. 1475 HostContentSettingsMap* content_settings_map = 1476 current_browser()->profile()->GetHostContentSettingsMap(); 1477 content_settings_map->SetDefaultContentSetting( 1478 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK); 1479 1480 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html", 1481 FINAL_STATUS_USED, 1482 1); 1483 NavigateToDestURL(); 1484} 1485 1486// Checks that we don't load a NaCl plugin when NaCl is disabled. 1487IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) { 1488 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html", 1489 FINAL_STATUS_USED, 1490 1); 1491 NavigateToDestURL(); 1492 1493 1494 // Run this check again. When we try to load aa ppapi plugin, the 1495 // "loadstart" event is asynchronously posted to a message loop. 1496 // It's possible that earlier call could have been run before the 1497 // the "loadstart" event was posted. 1498 // TODO(mmenke): While this should reliably fail on regressions, the 1499 // reliability depends on the specifics of ppapi plugin 1500 // loading. It would be great if we could avoid that. 1501 WebContents* web_contents = 1502 browser()->tab_strip_model()->GetActiveWebContents(); 1503 bool display_test_result = false; 1504 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1505 web_contents, 1506 "window.domAutomationController.send(DidDisplayPass())", 1507 &display_test_result)); 1508 EXPECT_TRUE(display_test_result); 1509} 1510 1511// Checks that plugins in an iframe are not loaded while a page is 1512// being preloaded, but are loaded when the page is displayed. 1513#if defined(USE_AURA) 1514// http://crbug.com/103496 1515#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1516 DISABLED_PrerenderIframeDelayLoadPlugin 1517#elif defined(OS_MACOSX) 1518// http://crbug.com/100514 1519#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1520 DISABLED_PrerenderIframeDelayLoadPlugin 1521#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1522// TODO(jschuh): Failing plugin tests. crbug.com/244653 1523#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1524 DISABLED_PrerenderIframeDelayLoadPlugin 1525#else 1526#define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin 1527#endif 1528IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1529 MAYBE_PrerenderIframeDelayLoadPlugin) { 1530 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html", 1531 FINAL_STATUS_USED, 1532 1); 1533 NavigateToDestURL(); 1534} 1535 1536// Renders a page that contains a prerender link to a page that contains an 1537// iframe with a source that requires http authentication. This should not 1538// prerender successfully. 1539IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) { 1540 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 1541 FINAL_STATUS_AUTH_NEEDED, 1542 1); 1543} 1544 1545// Checks that client-issued redirects work with prerendering. 1546// This version navigates to the page which issues the redirection, rather 1547// than the final destination page. 1548IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1549 PrerenderClientRedirectNavigateToFirst) { 1550 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 1551 FINAL_STATUS_USED, 1552 2); 1553 NavigateToDestURL(); 1554} 1555 1556// Checks that client-issued redirects work with prerendering. 1557// This version navigates to the final destination page, rather than the 1558// page which does the redirection. 1559IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1560 PrerenderClientRedirectNavigateToSecond) { 1561 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 1562 FINAL_STATUS_USED, 1563 2); 1564 NavigateToURL("files/prerender/prerender_page.html"); 1565} 1566 1567// Checks that client-issued redirects work with prerendering. 1568// This version navigates to the final destination page, rather than the 1569// page which does the redirection via a mouse click. 1570IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1571 PrerenderClientRedirectNavigateToSecondViaClick) { 1572 GURL prerender_url = test_server()->GetURL( 1573 CreateClientRedirect("files/prerender/prerender_page.html")); 1574 GURL destination_url = test_server()->GetURL( 1575 "files/prerender/prerender_page.html"); 1576 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 2); 1577 OpenDestURLViaClick(); 1578} 1579 1580// Checks that a prerender for an https will prevent a prerender from happening. 1581IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) { 1582 net::SpawnedTestServer https_server( 1583 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1584 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1585 ASSERT_TRUE(https_server.Start()); 1586 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1587 PrerenderTestURL(https_url, 1588 FINAL_STATUS_USED, 1589 1); 1590 NavigateToDestURL(); 1591} 1592 1593// Checks that client-issued redirects to an https page will cancel prerenders. 1594IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectToHttps) { 1595 net::SpawnedTestServer https_server( 1596 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1597 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1598 ASSERT_TRUE(https_server.Start()); 1599 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1600 PrerenderTestURL(CreateClientRedirect(https_url.spec()), 1601 FINAL_STATUS_USED, 1602 2); 1603 NavigateToDestURL(); 1604} 1605 1606// Checks that client-issued redirects within an iframe in a prerendered 1607// page will not count as an "alias" for the prerendered page. 1608IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectInIframe) { 1609 std::string redirect_path = CreateClientRedirect( 1610 "/files/prerender/prerender_embedded_content.html"); 1611 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1612 replacement_text.push_back( 1613 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1614 std::string replacement_path; 1615 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1616 "files/prerender/prerender_with_iframe.html", 1617 replacement_text, 1618 &replacement_path)); 1619 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2); 1620 EXPECT_FALSE(UrlIsInPrerenderManager( 1621 "files/prerender/prerender_embedded_content.html")); 1622 NavigateToDestURL(); 1623} 1624 1625// Checks that client-issued redirects within an iframe in a prerendered 1626// page to an https page will not cancel the prerender, nor will it 1627// count as an "alias" for the prerendered page. 1628IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1629 PrerenderClientRedirectToHttpsInIframe) { 1630 net::SpawnedTestServer https_server( 1631 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1632 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1633 ASSERT_TRUE(https_server.Start()); 1634 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1635 std::string redirect_path = CreateClientRedirect(https_url.spec()); 1636 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1637 replacement_text.push_back( 1638 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1639 std::string replacement_path; 1640 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1641 "files/prerender/prerender_with_iframe.html", 1642 replacement_text, 1643 &replacement_path)); 1644 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2); 1645 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 1646 NavigateToDestURL(); 1647} 1648 1649// Checks that server-issued redirects work with prerendering. 1650// This version navigates to the page which issues the redirection, rather 1651// than the final destination page. 1652IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1653 PrerenderServerRedirectNavigateToFirst) { 1654 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 1655 FINAL_STATUS_USED, 1656 1); 1657 NavigateToDestURL(); 1658} 1659 1660// Checks that server-issued redirects work with prerendering. 1661// This version navigates to the final destination page, rather than the 1662// page which does the redirection. 1663IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1664 PrerenderServerRedirectNavigateToSecond) { 1665 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 1666 FINAL_STATUS_USED, 1667 1); 1668 NavigateToURL("files/prerender/prerender_page.html"); 1669} 1670 1671// Checks that server-issued redirects work with prerendering. 1672// This version navigates to the final destination page, rather than the 1673// page which does the redirection via a mouse click. 1674IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1675 PrerenderServerRedirectNavigateToSecondViaClick) { 1676 GURL prerender_url = test_server()->GetURL( 1677 CreateServerRedirect("files/prerender/prerender_page.html")); 1678 GURL destination_url = test_server()->GetURL( 1679 "files/prerender/prerender_page.html"); 1680 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 1); 1681 OpenDestURLViaClick(); 1682} 1683 1684// Checks that server-issued redirects from an http to an https 1685// location will cancel prerendering. 1686IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1687 PrerenderServerRedirectToHttps) { 1688 net::SpawnedTestServer https_server( 1689 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1690 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1691 ASSERT_TRUE(https_server.Start()); 1692 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1693 PrerenderTestURL(CreateServerRedirect(https_url.spec()), 1694 FINAL_STATUS_USED, 1695 1); 1696 NavigateToDestURL(); 1697} 1698 1699// Checks that server-issued redirects within an iframe in a prerendered 1700// page will not count as an "alias" for the prerendered page. 1701IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) { 1702 std::string redirect_path = CreateServerRedirect( 1703 "/files/prerender/prerender_embedded_content.html"); 1704 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1705 replacement_text.push_back( 1706 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1707 std::string replacement_path; 1708 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1709 "files/prerender/prerender_with_iframe.html", 1710 replacement_text, 1711 &replacement_path)); 1712 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 1713 EXPECT_FALSE(UrlIsInPrerenderManager( 1714 "files/prerender/prerender_embedded_content.html")); 1715 NavigateToDestURL(); 1716} 1717 1718// Checks that server-issued redirects within an iframe in a prerendered 1719// page to an https page will not cancel the prerender, nor will it 1720// count as an "alias" for the prerendered page. 1721IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1722 PrerenderServerRedirectToHttpsInIframe) { 1723 net::SpawnedTestServer https_server( 1724 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 1725 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1726 ASSERT_TRUE(https_server.Start()); 1727 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 1728 std::string redirect_path = CreateServerRedirect(https_url.spec()); 1729 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1730 replacement_text.push_back( 1731 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 1732 std::string replacement_path; 1733 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 1734 "files/prerender/prerender_with_iframe.html", 1735 replacement_text, 1736 &replacement_path)); 1737 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 1738 EXPECT_FALSE(UrlIsInPrerenderManager(https_url)); 1739 NavigateToDestURL(); 1740} 1741 1742// Prerenders a page that contains an automatic download triggered through an 1743// iframe. This should not prerender successfully. 1744IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) { 1745 PrerenderTestURL("files/prerender/prerender_download_iframe.html", 1746 FINAL_STATUS_DOWNLOAD, 1747 1); 1748} 1749 1750// Prerenders a page that contains an automatic download triggered through 1751// Javascript changing the window.location. This should not prerender 1752// successfully 1753IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) { 1754 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"), 1755 FINAL_STATUS_DOWNLOAD, 1756 1); 1757} 1758 1759// Prerenders a page that contains an automatic download triggered through a 1760// client-issued redirect. This should not prerender successfully. 1761IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) { 1762 PrerenderTestURL("files/prerender/prerender_download_refresh.html", 1763 FINAL_STATUS_DOWNLOAD, 1764 1); 1765} 1766 1767// Checks that the referrer is set when prerendering. 1768IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) { 1769 PrerenderTestURL("files/prerender/prerender_referrer.html", 1770 FINAL_STATUS_USED, 1771 1); 1772 NavigateToDestURL(); 1773} 1774 1775// Checks that the referrer is not set when prerendering and the source page is 1776// HTTPS. 1777IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoSSLReferrer) { 1778 set_use_https_src(true); 1779 PrerenderTestURL("files/prerender/prerender_no_referrer.html", 1780 FINAL_STATUS_USED, 1781 1); 1782 NavigateToDestURL(); 1783} 1784 1785// Checks that popups on a prerendered page cause cancellation. 1786IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) { 1787 PrerenderTestURL("files/prerender/prerender_popup.html", 1788 FINAL_STATUS_CREATE_NEW_WINDOW, 1789 1); 1790} 1791 1792// Checks that registering a protocol handler causes cancellation. 1793IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) { 1794 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html", 1795 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER, 1796 1); 1797} 1798 1799// Checks that renderers using excessive memory will be terminated. 1800IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) { 1801 ASSERT_TRUE(GetPrerenderManager()); 1802 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024; 1803 PrerenderTestURL("files/prerender/prerender_excessive_memory.html", 1804 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 1805 1); 1806} 1807 1808// Checks shutdown code while a prerender is active. 1809IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) { 1810 PrerenderTestURL("files/prerender/prerender_page.html", 1811 FINAL_STATUS_APP_TERMINATING, 1812 0); 1813} 1814 1815// TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test. 1816// Checks that we don't prerender in an infinite loop. 1817IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) { 1818 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html"; 1819 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html"; 1820 1821 std::deque<FinalStatus> expected_final_status_queue; 1822 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1823 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1824 1825 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 1826 ASSERT_TRUE(GetPrerenderContents()); 1827 GetPrerenderContents()->WaitForPendingPrerenders(1u); 1828 1829 // Next url should be in pending list but not an active entry. 1830 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 1831 1832 NavigateToDestURL(); 1833 1834 // Make sure the PrerenderContents for the next url is now in the manager 1835 // and not pending. 1836 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB)); 1837} 1838 1839// TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test. 1840// Checks that we don't prerender in an infinite loop and multiple links are 1841// handled correctly. 1842IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1843 DISABLED_PrerenderInfiniteLoopMultiple) { 1844 const char* const kHtmlFileA = 1845 "files/prerender/prerender_infinite_a_multiple.html"; 1846 const char* const kHtmlFileB = 1847 "files/prerender/prerender_infinite_b_multiple.html"; 1848 const char* const kHtmlFileC = 1849 "files/prerender/prerender_infinite_c_multiple.html"; 1850 1851 // This test is conceptually simplest if concurrency is at two, since we 1852 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted. 1853 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1854 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1855 1856 std::deque<FinalStatus> expected_final_status_queue; 1857 expected_final_status_queue.push_back(FINAL_STATUS_USED); 1858 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1859 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 1860 1861 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 1862 ASSERT_TRUE(GetPrerenderContents()); 1863 GetPrerenderContents()->WaitForPendingPrerenders(2u); 1864 1865 // Next url should be in pending list but not an active entry. 1866 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 1867 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC)); 1868 1869 NavigateToDestURL(); 1870 1871 // Make sure the PrerenderContents for the next urls are now in the manager 1872 // and not pending. One and only one of the URLs (the last seen) should be the 1873 // active entry. 1874 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB); 1875 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC); 1876 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender); 1877} 1878 1879// See crbug.com/131836. 1880IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderTaskManager) { 1881 // Show the task manager. This populates the model. 1882 chrome::OpenTaskManager(current_browser(), false); 1883 // Wait for the model of task manager to start. 1884 TaskManagerBrowserTestUtil::WaitForWebResourceChange(1); 1885 1886 // Start with two resources. 1887 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1888 1889 // One of the resources that has a WebContents associated with it should have 1890 // the Prerender prefix. 1891 const string16 prefix = 1892 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX, string16()); 1893 string16 prerender_title; 1894 int num_prerender_tabs = 0; 1895 1896 const TaskManagerModel* model = GetModel(); 1897 for (int i = 0; i < model->ResourceCount(); ++i) { 1898 if (model->GetResourceWebContents(i)) { 1899 prerender_title = model->GetResourceTitle(i); 1900 if (StartsWith(prerender_title, prefix, true)) 1901 ++num_prerender_tabs; 1902 } 1903 } 1904 EXPECT_EQ(1, num_prerender_tabs); 1905 const string16 prerender_page_title = prerender_title.substr(prefix.length()); 1906 1907 NavigateToDestURL(); 1908 1909 // There should be no tabs with the Prerender prefix. 1910 const string16 tab_prefix = 1911 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, string16()); 1912 num_prerender_tabs = 0; 1913 int num_tabs_with_prerender_page_title = 0; 1914 for (int i = 0; i < model->ResourceCount(); ++i) { 1915 if (model->GetResourceWebContents(i)) { 1916 string16 tab_title = model->GetResourceTitle(i); 1917 if (StartsWith(tab_title, prefix, true)) { 1918 ++num_prerender_tabs; 1919 } else { 1920 EXPECT_TRUE(StartsWith(tab_title, tab_prefix, true)); 1921 1922 // The prerender tab should now be a normal tab but the title should be 1923 // the same. Depending on timing, there may be more than one of these. 1924 const string16 tab_page_title = tab_title.substr(tab_prefix.length()); 1925 if (prerender_page_title.compare(tab_page_title) == 0) 1926 ++num_tabs_with_prerender_page_title; 1927 } 1928 } 1929 } 1930 EXPECT_EQ(0, num_prerender_tabs); 1931 1932 // We may have deleted the prerender tab, but the swapped in tab should be 1933 // active. 1934 EXPECT_GE(num_tabs_with_prerender_page_title, 1); 1935 EXPECT_LE(num_tabs_with_prerender_page_title, 2); 1936} 1937 1938// Checks that audio loads are deferred on prerendering. 1939// Times out under AddressSanitizer, see http://crbug.com/108402 1940#if defined(ADDRESS_SANITIZER) 1941#define MAYBE_PrerenderHTML5Audio DISABLED_PrerenderHTML5Audio 1942#else 1943#define MAYBE_PrerenderHTML5Audio PrerenderHTML5Audio 1944#endif 1945IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_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 1955#if defined(OS_CHROMEOS) 1956#define MAYBE_PrerenderHTML5AudioAutoplay DISABLED_PrerenderHTML5AudioAutoplay 1957#else 1958#define MAYBE_PrerenderHTML5AudioAutoplay PrerenderHTML5AudioAutoplay 1959#endif 1960IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1961 MAYBE_PrerenderHTML5AudioAutoplay) { 1962 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html", 1963 FINAL_STATUS_USED, 1964 1); 1965 NavigateToDestUrlAndWaitForPassTitle(); 1966} 1967 1968// Checks that audio loads are deferred on prerendering and played back when 1969// the prerender is swapped in if js starts playing. 1970IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioJsplay) { 1971 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html", 1972 FINAL_STATUS_USED, 1973 1); 1974 NavigateToDestUrlAndWaitForPassTitle(); 1975} 1976 1977// Checks that video loads are deferred on prerendering. 1978IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) { 1979 PrerenderTestURL("files/prerender/prerender_html5_video.html", 1980 FINAL_STATUS_USED, 1981 1); 1982 NavigateToDestUrlAndWaitForPassTitle(); 1983} 1984 1985// Checks that video tags inserted by javascript are deferred and played 1986// correctly on swap in. 1987IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) { 1988 PrerenderTestURL("files/prerender/prerender_html5_video_script.html", 1989 FINAL_STATUS_USED, 1990 1); 1991 NavigateToDestUrlAndWaitForPassTitle(); 1992} 1993 1994// Checks for correct network events by using a busy sleep the javascript. 1995IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoNetwork) { 1996 PrerenderTestURL("files/prerender/prerender_html5_video_network.html", 1997 FINAL_STATUS_USED, 1998 1, 1999 true); 2000 NavigateToDestUrlAndWaitForPassTitle(); 2001} 2002 2003// Checks that scripts can retrieve the correct window size while prerendering. 2004#if defined(TOOLKIT_VIEWS) 2005// TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363 2006IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) { 2007#else 2008IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) { 2009#endif 2010 PrerenderTestURL("files/prerender/prerender_size.html", 2011 FINAL_STATUS_USED, 2012 1); 2013 NavigateToDestURL(); 2014} 2015 2016#if defined(OS_CHROMEOS) 2017// Flakily times out: http://crbug.com/171546 2018#define MAYBE_PrerenderRendererCrash DISABLED_PrerenderRendererCrash 2019#else 2020#define MAYBE_PrerenderRendererCrash PrerenderRendererCrash 2021#endif 2022 2023// Checks that prerenderers will terminate when the RenderView crashes. 2024IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderRendererCrash) { 2025 PrerenderTestURL("files/prerender/prerender_page.html", 2026 FINAL_STATUS_RENDERER_CRASHED, 2027 1); 2028 2029 // Navigate to about:crash and then wait for the renderer to crash. 2030 ASSERT_TRUE(GetPrerenderContents()); 2031 ASSERT_TRUE(GetPrerenderContents()->prerender_contents()); 2032 GetPrerenderContents()->prerender_contents()->GetController(). 2033 LoadURL( 2034 GURL(content::kChromeUICrashURL), 2035 content::Referrer(), 2036 content::PAGE_TRANSITION_TYPED, 2037 std::string()); 2038 content::RunMessageLoop(); 2039} 2040 2041IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2042 PrerenderPageWithFragment) { 2043 PrerenderTestURL("files/prerender/prerender_page.html#fragment", 2044 FINAL_STATUS_USED, 2045 1); 2046 2047 ChannelDestructionWatcher channel_close_watcher; 2048 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2049 GetActiveWebContents()->GetRenderProcessHost()); 2050 NavigateToDestURL(); 2051 channel_close_watcher.WaitForChannelClose(); 2052 2053 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2054} 2055 2056// Checks that we correctly use a prerendered page when navigating to a 2057// fragment. 2058// DISABLED: http://crbug.com/84154 2059IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2060 DISABLED_PrerenderPageNavigateFragment) { 2061 PrerenderTestURL("files/prerender/no_prerender_page.html", 2062 FINAL_STATUS_APP_TERMINATING, 2063 1); 2064 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2065} 2066 2067// Checks that we correctly use a prerendered page when we prerender a fragment 2068// but navigate to the main page. 2069// http://crbug.com/83901 2070IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2071 DISABLED_PrerenderFragmentNavigatePage) { 2072 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment", 2073 FINAL_STATUS_APP_TERMINATING, 2074 1); 2075 NavigateToURL("files/prerender/no_prerender_page.html"); 2076} 2077 2078// Checks that we correctly use a prerendered page when we prerender a fragment 2079// but navigate to a different fragment on the same page. 2080// DISABLED: http://crbug.com/84154 2081IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2082 DISABLED_PrerenderFragmentNavigateFragment) { 2083 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment", 2084 FINAL_STATUS_APP_TERMINATING, 2085 1); 2086 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2087} 2088 2089// Checks that we correctly use a prerendered page when the page uses a client 2090// redirect to refresh from a fragment on the same page. 2091// http://crbug.com/83901 2092IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2093 DISABLED_PrerenderClientRedirectFromFragment) { 2094 PrerenderTestURL( 2095 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"), 2096 FINAL_STATUS_APP_TERMINATING, 2097 2); 2098 NavigateToURL("files/prerender/no_prerender_page.html"); 2099} 2100 2101// Checks that we correctly use a prerendered page when the page uses a client 2102// redirect to refresh to a fragment on the same page. 2103// DISABLED: http://crbug.com/84154 2104IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2105 DISABLED_PrerenderClientRedirectToFragment) { 2106 PrerenderTestURL( 2107 CreateClientRedirect("files/prerender/no_prerender_page.html"), 2108 FINAL_STATUS_APP_TERMINATING, 2109 2); 2110 NavigateToURL("files/prerender/no_prerender_page.html#fragment"); 2111} 2112 2113// Checks that we correctly use a prerendered page when the page uses JS to set 2114// the window.location.hash to a fragment on the same page. 2115IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2116 PrerenderPageChangeFragmentLocationHash) { 2117 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html", 2118 FINAL_STATUS_USED, 2119 1); 2120 NavigateToURL("files/prerender/prerender_fragment_location_hash.html"); 2121} 2122 2123// Checks that prerendering a PNG works correctly. 2124IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) { 2125 DisableJavascriptCalls(); 2126 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1); 2127 NavigateToDestURL(); 2128} 2129 2130// Checks that prerendering a JPG works correctly. 2131IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) { 2132 DisableJavascriptCalls(); 2133 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1); 2134 NavigateToDestURL(); 2135} 2136 2137// Checks that a prerender of a CRX will result in a cancellation due to 2138// download. 2139IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) { 2140 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 1); 2141} 2142 2143// Checks that xhr GET requests allow prerenders. 2144IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) { 2145 PrerenderTestURL("files/prerender/prerender_xhr_get.html", 2146 FINAL_STATUS_USED, 2147 1); 2148 NavigateToDestURL(); 2149} 2150 2151// Checks that xhr HEAD requests allow prerenders. 2152IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) { 2153 PrerenderTestURL("files/prerender/prerender_xhr_head.html", 2154 FINAL_STATUS_USED, 2155 1); 2156 NavigateToDestURL(); 2157} 2158 2159// Checks that xhr OPTIONS requests allow prerenders. 2160IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) { 2161 PrerenderTestURL("files/prerender/prerender_xhr_options.html", 2162 FINAL_STATUS_USED, 2163 1); 2164 NavigateToDestURL(); 2165} 2166 2167// Checks that xhr TRACE requests allow prerenders. 2168IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) { 2169 PrerenderTestURL("files/prerender/prerender_xhr_trace.html", 2170 FINAL_STATUS_USED, 2171 1); 2172 NavigateToDestURL(); 2173} 2174 2175// Checks that xhr POST requests allow prerenders. 2176IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) { 2177 PrerenderTestURL("files/prerender/prerender_xhr_post.html", 2178 FINAL_STATUS_USED, 2179 1); 2180 NavigateToDestURL(); 2181} 2182 2183// Checks that xhr PUT cancels prerenders. 2184IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) { 2185 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 2186 FINAL_STATUS_INVALID_HTTP_METHOD, 2187 1); 2188} 2189 2190// Checks that xhr DELETE cancels prerenders. 2191IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) { 2192 PrerenderTestURL("files/prerender/prerender_xhr_delete.html", 2193 FINAL_STATUS_INVALID_HTTP_METHOD, 2194 1); 2195} 2196 2197// Checks that a top-level page which would trigger an SSL error is canceled. 2198IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) { 2199 net::SpawnedTestServer::SSLOptions ssl_options; 2200 ssl_options.server_certificate = 2201 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2202 net::SpawnedTestServer https_server( 2203 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2204 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2205 ASSERT_TRUE(https_server.Start()); 2206 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2207 PrerenderTestURL(https_url, 2208 FINAL_STATUS_SSL_ERROR, 2209 1); 2210} 2211 2212// Checks that an SSL error that comes from a subresource does not cancel 2213// the page. Non-main-frame requests are simply cancelled if they run into 2214// an SSL problem. 2215IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) { 2216 net::SpawnedTestServer::SSLOptions ssl_options; 2217 ssl_options.server_certificate = 2218 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2219 net::SpawnedTestServer https_server( 2220 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2221 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2222 ASSERT_TRUE(https_server.Start()); 2223 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2224 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2225 replacement_text.push_back( 2226 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2227 std::string replacement_path; 2228 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2229 "files/prerender/prerender_with_image.html", 2230 replacement_text, 2231 &replacement_path)); 2232 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2233 NavigateToDestURL(); 2234} 2235 2236// Checks that an SSL error that comes from an iframe does not cancel 2237// the page. Non-main-frame requests are simply cancelled if they run into 2238// an SSL problem. 2239IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) { 2240 net::SpawnedTestServer::SSLOptions ssl_options; 2241 ssl_options.server_certificate = 2242 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2243 net::SpawnedTestServer https_server( 2244 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2245 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2246 ASSERT_TRUE(https_server.Start()); 2247 GURL https_url = https_server.GetURL( 2248 "files/prerender/prerender_embedded_content.html"); 2249 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2250 replacement_text.push_back( 2251 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2252 std::string replacement_path; 2253 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2254 "files/prerender/prerender_with_iframe.html", 2255 replacement_text, 2256 &replacement_path)); 2257 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2258 NavigateToDestURL(); 2259} 2260 2261// Checks that we cancel correctly when window.print() is called. 2262IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) { 2263 PrerenderTestURL("files/prerender/prerender_print.html", 2264 FINAL_STATUS_WINDOW_PRINT, 2265 1); 2266} 2267 2268// Checks that if a page is opened in a new window by javascript and both the 2269// pages are in the same domain, the prerendered page is not used. 2270IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2271 PrerenderSameDomainWindowOpenerWindowOpen) { 2272 PrerenderTestURL("files/prerender/prerender_page.html", 2273 FINAL_STATUS_APP_TERMINATING, 2274 1); 2275 OpenDestURLViaWindowOpen(); 2276} 2277 2278// Checks that if a page is opened due to click on a href with target="_blank" 2279// and both pages are in the same domain the prerendered page is not used. 2280IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2281 PrerenderSameDomainWindowOpenerClickTarget) { 2282 PrerenderTestURL("files/prerender/prerender_page.html", 2283 FINAL_STATUS_APP_TERMINATING, 2284 1); 2285 OpenDestURLViaClickTarget(); 2286} 2287 2288// Checks that a top-level page which would normally request an SSL client 2289// certificate will never be seen since it's an https top-level resource. 2290IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertTopLevel) { 2291 net::SpawnedTestServer::SSLOptions ssl_options; 2292 ssl_options.request_client_certificate = true; 2293 net::SpawnedTestServer https_server( 2294 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2295 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2296 ASSERT_TRUE(https_server.Start()); 2297 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2298 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 1); 2299} 2300 2301// Checks that an SSL Client Certificate request that originates from a 2302// subresource will cancel the prerendered page. 2303IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2304 PrerenderSSLClientCertSubresource) { 2305 net::SpawnedTestServer::SSLOptions ssl_options; 2306 ssl_options.request_client_certificate = true; 2307 net::SpawnedTestServer https_server( 2308 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2309 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2310 ASSERT_TRUE(https_server.Start()); 2311 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2312 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2313 replacement_text.push_back( 2314 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2315 std::string replacement_path; 2316 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2317 "files/prerender/prerender_with_image.html", 2318 replacement_text, 2319 &replacement_path)); 2320 PrerenderTestURL(replacement_path, 2321 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2322 1); 2323} 2324 2325// Checks that an SSL Client Certificate request that originates from an 2326// iframe will cancel the prerendered page. 2327IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) { 2328 net::SpawnedTestServer::SSLOptions ssl_options; 2329 ssl_options.request_client_certificate = true; 2330 net::SpawnedTestServer https_server( 2331 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2332 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2333 ASSERT_TRUE(https_server.Start()); 2334 GURL https_url = https_server.GetURL( 2335 "files/prerender/prerender_embedded_content.html"); 2336 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2337 replacement_text.push_back( 2338 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2339 std::string replacement_path; 2340 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2341 "files/prerender/prerender_with_iframe.html", 2342 replacement_text, 2343 &replacement_path)); 2344 PrerenderTestURL(replacement_path, 2345 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2346 1); 2347} 2348 2349#if defined(FULL_SAFE_BROWSING) 2350// Ensures that we do not prerender pages with a safe browsing 2351// interstitial. 2352IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) { 2353 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2354 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2355 url, SB_THREAT_TYPE_URL_MALWARE); 2356 PrerenderTestURL("files/prerender/prerender_page.html", 2357 FINAL_STATUS_SAFE_BROWSING, 1); 2358} 2359 2360// Ensures that server redirects to a malware page will cancel prerenders. 2361IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2362 PrerenderSafeBrowsingServerRedirect) { 2363 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2364 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2365 url, SB_THREAT_TYPE_URL_MALWARE); 2366 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 2367 FINAL_STATUS_SAFE_BROWSING, 2368 1); 2369} 2370 2371// Ensures that client redirects to a malware page will cancel prerenders. 2372IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2373 PrerenderSafeBrowsingClientRedirect) { 2374 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2375 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2376 url, SB_THREAT_TYPE_URL_MALWARE); 2377 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 2378 FINAL_STATUS_SAFE_BROWSING, 2379 1); 2380} 2381 2382// Ensures that we do not prerender pages which have a malware subresource. 2383IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) { 2384 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg"); 2385 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2386 image_url, SB_THREAT_TYPE_URL_MALWARE); 2387 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2388 replacement_text.push_back( 2389 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2390 std::string replacement_path; 2391 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2392 "files/prerender/prerender_with_image.html", 2393 replacement_text, 2394 &replacement_path)); 2395 PrerenderTestURL(replacement_path, 2396 FINAL_STATUS_SAFE_BROWSING, 2397 1); 2398} 2399 2400// Ensures that we do not prerender pages which have a malware iframe. 2401IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) { 2402 GURL iframe_url = test_server()->GetURL( 2403 "files/prerender/prerender_embedded_content.html"); 2404 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2405 iframe_url, SB_THREAT_TYPE_URL_MALWARE); 2406 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2407 replacement_text.push_back( 2408 std::make_pair("REPLACE_WITH_URL", iframe_url.spec())); 2409 std::string replacement_path; 2410 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2411 "files/prerender/prerender_with_iframe.html", 2412 replacement_text, 2413 &replacement_path)); 2414 PrerenderTestURL(replacement_path, 2415 FINAL_STATUS_SAFE_BROWSING, 2416 1); 2417} 2418 2419#endif 2420 2421// Checks that a local storage read will not cause prerender to fail. 2422IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) { 2423 PrerenderTestURL("files/prerender/prerender_localstorage_read.html", 2424 FINAL_STATUS_USED, 2425 1); 2426 NavigateToDestURL(); 2427} 2428 2429// Checks that a local storage write will not cause prerender to fail. 2430IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) { 2431 PrerenderTestURL("files/prerender/prerender_localstorage_write.html", 2432 FINAL_STATUS_USED, 2433 1); 2434 NavigateToDestURL(); 2435} 2436 2437// Checks that the favicon is properly loaded on prerender. 2438IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) { 2439 PrerenderTestURL("files/prerender/prerender_favicon.html", 2440 FINAL_STATUS_USED, 2441 1); 2442 TestPrerenderContents* prerender_contents = GetPrerenderContents(); 2443 ASSERT_TRUE(prerender_contents != NULL); 2444 content::WindowedNotificationObserver favicon_update_watcher( 2445 chrome::NOTIFICATION_FAVICON_UPDATED, 2446 content::Source<WebContents>(prerender_contents->prerender_contents())); 2447 NavigateToDestURL(); 2448 favicon_update_watcher.Wait(); 2449} 2450 2451// Checks that when a prerendered page is swapped in to a referring page, the 2452// unload handlers on the referring page are executed. 2453// Fails about 50% on CrOS, 5-10% on linux, win, mac. http://crbug.com/128986 2454IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderUnload) { 2455 set_loader_path("files/prerender/prerender_loader_with_unload.html"); 2456 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2457 string16 expected_title = ASCIIToUTF16("Unloaded"); 2458 content::TitleWatcher title_watcher( 2459 current_browser()->tab_strip_model()->GetActiveWebContents(), 2460 expected_title); 2461 NavigateToDestURL(); 2462 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 2463} 2464 2465// Checks that when the history is cleared, prerendering is cancelled and 2466// prerendering history is cleared. 2467IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) { 2468 PrerenderTestURL("files/prerender/prerender_page.html", 2469 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 2470 1); 2471 2472 // Post a task to clear the history, and run the message loop until it 2473 // destroys the prerender. 2474 base::MessageLoop::current()->PostTask( 2475 FROM_HERE, 2476 base::Bind(&ClearBrowsingData, current_browser(), 2477 BrowsingDataRemover::REMOVE_HISTORY)); 2478 content::RunMessageLoop(); 2479 2480 // Make sure prerender history was cleared. 2481 EXPECT_EQ(0, GetHistoryLength()); 2482} 2483 2484// Checks that when the cache is cleared, prerenders are cancelled but 2485// prerendering history is not cleared. 2486IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearCache) { 2487 PrerenderTestURL("files/prerender/prerender_page.html", 2488 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 2489 1); 2490 2491 // Post a task to clear the cache, and run the message loop until it 2492 // destroys the prerender. 2493 base::MessageLoop::current()->PostTask(FROM_HERE, 2494 base::Bind(&ClearBrowsingData, current_browser(), 2495 BrowsingDataRemover::REMOVE_CACHE)); 2496 content::RunMessageLoop(); 2497 2498 // Make sure prerender history was not cleared. Not a vital behavior, but 2499 // used to compare with PrerenderClearHistory test. 2500 EXPECT_EQ(1, GetHistoryLength()); 2501} 2502 2503IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) { 2504 PrerenderTestURL("files/prerender/prerender_page.html", 2505 FINAL_STATUS_CANCELLED, 2506 1); 2507 // Post a task to cancel all the prerenders. 2508 base::MessageLoop::current()->PostTask( 2509 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2510 content::RunMessageLoop(); 2511 EXPECT_TRUE(GetPrerenderContents() == NULL); 2512} 2513 2514IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) { 2515 PrerenderTestURL("files/prerender/prerender_page.html", 2516 FINAL_STATUS_CANCELLED, 1); 2517 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2518 EXPECT_TRUE(DidReceivePrerenderLoadEventForLinkNumber(0)); 2519 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 2520 2521 base::MessageLoop::current()->PostTask( 2522 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2523 content::RunMessageLoop(); 2524 2525 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2526 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0)); 2527 EXPECT_FALSE(HadPrerenderEventErrors()); 2528} 2529 2530// Cancels the prerender of a page with its own prerender. The second prerender 2531// should never be started. 2532IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2533 PrerenderCancelPrerenderWithPrerender) { 2534 PrerenderTestURL("files/prerender/prerender_infinite_a.html", 2535 FINAL_STATUS_CANCELLED, 2536 1); 2537 // Post a task to cancel all the prerenders. 2538 base::MessageLoop::current()->PostTask( 2539 FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager())); 2540 content::RunMessageLoop(); 2541 EXPECT_TRUE(GetPrerenderContents() == NULL); 2542} 2543 2544// PrerenderBrowserTest.PrerenderEventsNoLoad may pass flakily on regression, 2545// so please be aggressive about filing bugs when this test is failing. 2546IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEventsNoLoad) { 2547 // This should be canceled. 2548 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 2549 FINAL_STATUS_AUTH_NEEDED, 2550 1); 2551 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 2552 EXPECT_FALSE(DidReceivePrerenderLoadEventForLinkNumber(0)); 2553 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 2554 EXPECT_FALSE(HadPrerenderEventErrors()); 2555} 2556 2557// Prerendering and history tests. 2558// The prerendered page is navigated to in several ways [navigate via 2559// omnibox, click on link, key-modified click to open in background tab, etc], 2560// followed by a navigation to another page from the prerendered page, followed 2561// by a back navigation. 2562 2563IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) { 2564 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2565 FINAL_STATUS_USED, 2566 1); 2567 NavigateToDestURL(); 2568 ClickToNextPageAfterPrerender(); 2569 GoBackToPrerender(); 2570} 2571 2572// Disabled due to timeouts on commit queue. 2573// http://crbug.com/121130 2574IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2575 DISABLED_PrerenderNavigateNavigateGoBack) { 2576 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2577 FINAL_STATUS_USED, 2578 1); 2579 NavigateToDestURL(); 2580 NavigateToNextPageAfterPrerender(); 2581 GoBackToPrerender(); 2582} 2583 2584IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) { 2585 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2586 FINAL_STATUS_USED, 2587 1); 2588 OpenDestURLViaClick(); 2589 ClickToNextPageAfterPrerender(); 2590 GoBackToPrerender(); 2591} 2592 2593// Disabled due to timeouts on commit queue. 2594// http://crbug.com/121130 2595IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2596 DISABLED_PrerenderClickNavigateGoBack) { 2597 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2598 FINAL_STATUS_USED, 2599 1); 2600 OpenDestURLViaClick(); 2601 NavigateToNextPageAfterPrerender(); 2602 GoBackToPrerender(); 2603} 2604 2605IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) { 2606 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2607 FINAL_STATUS_APP_TERMINATING, 2608 1); 2609 OpenDestURLViaClickNewWindow(); 2610} 2611 2612IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) { 2613 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2614 FINAL_STATUS_APP_TERMINATING, 2615 1); 2616 OpenDestURLViaClickNewForegroundTab(); 2617} 2618 2619IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) { 2620 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 2621 FINAL_STATUS_APP_TERMINATING, 2622 1); 2623 OpenDestURLViaClickNewBackgroundTab(); 2624} 2625 2626IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2627 NavigateToPrerenderedPageWhenDevToolsAttached) { 2628 DisableJavascriptCalls(); 2629 WebContents* web_contents = 2630 current_browser()->tab_strip_model()->GetActiveWebContents(); 2631 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( 2632 web_contents->GetRenderViewHost())); 2633 DevToolsManager* manager = DevToolsManager::GetInstance(); 2634 FakeDevToolsClientHost client_host; 2635 manager->RegisterDevToolsClientHostFor(agent.get(), &client_host); 2636 const char* url = "files/prerender/prerender_page.html"; 2637 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1); 2638 NavigateToURL(url); 2639 manager->ClientHostClosing(&client_host); 2640} 2641 2642// Validate that the sessionStorage namespace remains the same when swapping 2643// in a prerendered page. 2644IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) { 2645 set_loader_path("files/prerender/prerender_loader_with_session_storage.html"); 2646 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"), 2647 FINAL_STATUS_USED, 2648 1); 2649 NavigateToDestURL(); 2650 GoBackToPageBeforePrerender(); 2651} 2652 2653#if defined(OS_MACOSX) 2654// http://crbug.com/142535 - Times out on Chrome Mac release builder 2655#define MAYBE_ControlGroup DISABLED_ControlGroup 2656#else 2657#define MAYBE_ControlGroup ControlGroup 2658#endif 2659// Checks that the control group works. A JS alert cannot be detected in the 2660// control group. 2661IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_ControlGroup) { 2662 RestorePrerenderMode restore_prerender_mode; 2663 PrerenderManager::SetMode( 2664 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP); 2665 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 2666 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0); 2667 NavigateToDestURL(); 2668} 2669 2670// Make sure that the MatchComplete dummy works in the normal case. Once 2671// a prerender is cancelled because of a script, a dummy must be created to 2672// account for the MatchComplete case, and it must have a final status of 2673// FINAL_STATUS_WOULD_HAVE_BEEN_USED. 2674#if defined(OS_MACOSX) 2675// http://crbug.com/142912 - Times out on Chrome Mac release builder 2676#define MAYBE_MatchCompleteDummy DISABLED_MatchCompleteDummy 2677#else 2678#define MAYBE_MatchCompleteDummy MatchCompleteDummy 2679#endif 2680IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_MatchCompleteDummy) { 2681 std::deque<FinalStatus> expected_final_status_queue; 2682 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT); 2683 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 2684 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 2685 expected_final_status_queue, 1); 2686 NavigateToDestURL(); 2687} 2688 2689class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest { 2690 public: 2691 PrerenderBrowserTestWithNaCl() {} 2692 virtual ~PrerenderBrowserTestWithNaCl() {} 2693 2694 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2695 PrerenderBrowserTest::SetUpCommandLine(command_line); 2696 command_line->AppendSwitch(switches::kEnableNaCl); 2697 } 2698}; 2699 2700// Check that NaCl plugins work when enabled, with prerendering. 2701IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl, 2702 PrerenderNaClPluginEnabled) { 2703 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html", 2704 FINAL_STATUS_USED, 2705 1); 2706 NavigateToDestURL(); 2707 2708 // To avoid any chance of a race, we have to let the script send its response 2709 // asynchronously. 2710 WebContents* web_contents = 2711 browser()->tab_strip_model()->GetActiveWebContents(); 2712 bool display_test_result = false; 2713 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, 2714 "DidDisplayReallyPass()", 2715 &display_test_result)); 2716 ASSERT_TRUE(display_test_result); 2717} 2718 2719// Checks that the referrer policy is used when prerendering. 2720IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) { 2721 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 2722 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 2723 FINAL_STATUS_USED, 2724 1); 2725 NavigateToDestURL(); 2726} 2727 2728// Checks that the referrer policy is used when prerendering on HTTPS. 2729IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLReferrerPolicy) { 2730 set_use_https_src(true); 2731 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 2732 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 2733 FINAL_STATUS_USED, 2734 1); 2735 NavigateToDestURL(); 2736} 2737 2738// Test interaction of the webNavigation and tabs API with prerender. 2739class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest, 2740 public ExtensionApiTest { 2741 public: 2742 PrerenderBrowserTestWithExtensions() { 2743 autostart_test_server_ = false; 2744 } 2745 virtual ~PrerenderBrowserTestWithExtensions() {} 2746 2747 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2748 PrerenderBrowserTest::SetUpCommandLine(command_line); 2749 ExtensionApiTest::SetUpCommandLine(command_line); 2750 } 2751 2752 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 2753 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture(); 2754 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); 2755 } 2756 2757 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 2758 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture(); 2759 ExtensionApiTest::TearDownInProcessBrowserTestFixture(); 2760 } 2761 2762 virtual void SetUpOnMainThread() OVERRIDE { 2763 PrerenderBrowserTest::SetUpOnMainThread(); 2764 } 2765}; 2766 2767// http://crbug.com/177163 2768#if defined(OS_WIN) && !defined(NDEBUG) 2769#define MAYBE_WebNavigation DISABLED_WebNavigation 2770#else 2771#define MAYBE_WebNavigation WebNavigation 2772#endif 2773IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, 2774 MAYBE_WebNavigation) { 2775 ASSERT_TRUE(StartTestServer()); 2776 extensions::FrameNavigationState::set_allow_extension_scheme(true); 2777 2778 CommandLine::ForCurrentProcess()->AppendSwitch( 2779 switches::kAllowLegacyExtensionManifests); 2780 2781 // Wait for the extension to set itself up and return control to us. 2782 ASSERT_TRUE( 2783 RunExtensionSubtest("webnavigation", "test_prerender.html")) << message_; 2784 2785 ResultCatcher catcher; 2786 2787 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2788 2789 ChannelDestructionWatcher channel_close_watcher; 2790 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2791 GetActiveWebContents()->GetRenderProcessHost()); 2792 NavigateToDestURL(); 2793 channel_close_watcher.WaitForChannelClose(); 2794 2795 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2796 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 2797} 2798 2799// Fails often on Windows dbg bots. http://crbug.com/177163 2800#if defined(OS_WIN) 2801#define MAYBE_TabsApi DISABLED_TabsApi 2802#else 2803#define MAYBE_TabsApi TabsApi 2804#endif // defined(OS_WIN) 2805IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, MAYBE_TabsApi) { 2806 ASSERT_TRUE(StartTestServer()); 2807 extensions::FrameNavigationState::set_allow_extension_scheme(true); 2808 2809 // Wait for the extension to set itself up and return control to us. 2810 ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html")) 2811 << message_; 2812 2813 ResultCatcher catcher; 2814 2815 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2816 2817 ChannelDestructionWatcher channel_close_watcher; 2818 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2819 GetActiveWebContents()->GetRenderProcessHost()); 2820 NavigateToDestURL(); 2821 channel_close_watcher.WaitForChannelClose(); 2822 2823 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2824 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 2825} 2826 2827// Checks that non-http/https/chrome-extension subresource cancels the 2828// prerender. 2829IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2830 PrerenderCancelSubresourceUnsupportedScheme) { 2831 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg"); 2832 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2833 replacement_text.push_back( 2834 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2835 std::string replacement_path; 2836 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2837 "files/prerender/prerender_with_image.html", 2838 replacement_text, 2839 &replacement_path)); 2840 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2841 NavigateToDestURL(); 2842} 2843 2844// Checks that non-http/https/chrome-extension subresource cancels the prerender 2845// on redirect. 2846IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2847 PrerenderCancelSubresourceRedirectUnsupportedScheme) { 2848 GURL image_url = test_server()->GetURL( 2849 CreateServerRedirect("invalidscheme://www.google.com/test.jpg")); 2850 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2851 replacement_text.push_back( 2852 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2853 std::string replacement_path; 2854 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2855 "files/prerender/prerender_with_image.html", 2856 replacement_text, 2857 &replacement_path)); 2858 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2859 NavigateToDestURL(); 2860} 2861 2862// Checks that chrome-extension subresource does not cancel the prerender. 2863IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2864 PrerenderKeepSubresourceExtensionScheme) { 2865 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg"); 2866 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2867 replacement_text.push_back( 2868 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2869 std::string replacement_path; 2870 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2871 "files/prerender/prerender_with_image.html", 2872 replacement_text, 2873 &replacement_path)); 2874 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2875 NavigateToDestURL(); 2876} 2877 2878// Checks that redirect to chrome-extension subresource does not cancel the 2879// prerender. 2880IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2881 PrerenderKeepSubresourceRedirectExtensionScheme) { 2882 GURL image_url = test_server()->GetURL( 2883 CreateServerRedirect("chrome-extension://abcdefg/test.jpg")); 2884 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2885 replacement_text.push_back( 2886 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 2887 std::string replacement_path; 2888 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2889 "files/prerender/prerender_with_image.html", 2890 replacement_text, 2891 &replacement_path)); 2892 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2893 NavigateToDestURL(); 2894} 2895 2896 2897// Checks that non-http/https main page redirects cancel the prerender. 2898IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2899 PrerenderCancelMainFrameRedirectUnsupportedScheme) { 2900 GURL url = test_server()->GetURL( 2901 CreateServerRedirect("invalidscheme://www.google.com/test.html")); 2902 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 1); 2903 NavigateToDestURL(); 2904} 2905 2906} // namespace prerender 2907