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