prerender_browsertest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <deque> 6#include <vector> 7 8#include "base/bind.h" 9#include "base/command_line.h" 10#include "base/files/file_path.h" 11#include "base/memory/ref_counted_memory.h" 12#include "base/memory/scoped_vector.h" 13#include "base/memory/weak_ptr.h" 14#include "base/path_service.h" 15#include "base/prefs/pref_service.h" 16#include "base/run_loop.h" 17#include "base/strings/string_util.h" 18#include "base/strings/stringprintf.h" 19#include "base/strings/utf_string_conversions.h" 20#include "base/test/test_timeouts.h" 21#include "base/values.h" 22#include "chrome/browser/browsing_data/browsing_data_helper.h" 23#include "chrome/browser/browsing_data/browsing_data_remover.h" 24#include "chrome/browser/chrome_content_browser_client.h" 25#include "chrome/browser/chrome_notification_types.h" 26#include "chrome/browser/content_settings/host_content_settings_map.h" 27#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" 28#include "chrome/browser/extensions/extension_apitest.h" 29#include "chrome/browser/external_protocol/external_protocol_handler.h" 30#include "chrome/browser/favicon/favicon_tab_helper.h" 31#include "chrome/browser/prerender/prerender_contents.h" 32#include "chrome/browser/prerender/prerender_handle.h" 33#include "chrome/browser/prerender/prerender_link_manager.h" 34#include "chrome/browser/prerender/prerender_link_manager_factory.h" 35#include "chrome/browser/prerender/prerender_manager.h" 36#include "chrome/browser/prerender/prerender_manager_factory.h" 37#include "chrome/browser/profiles/profile.h" 38#include "chrome/browser/profiles/profile_io_data.h" 39#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h" 40#include "chrome/browser/safe_browsing/database_manager.h" 41#include "chrome/browser/safe_browsing/safe_browsing_service.h" 42#include "chrome/browser/safe_browsing/safe_browsing_util.h" 43#include "chrome/browser/task_manager/task_manager.h" 44#include "chrome/browser/task_manager/task_manager_browsertest_util.h" 45#include "chrome/browser/ui/browser.h" 46#include "chrome/browser/ui/browser_commands.h" 47#include "chrome/browser/ui/browser_finder.h" 48#include "chrome/browser/ui/browser_navigator.h" 49#include "chrome/browser/ui/browser_window.h" 50#include "chrome/browser/ui/tabs/tab_strip_model.h" 51#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" 52#include "chrome/common/chrome_paths.h" 53#include "chrome/common/chrome_switches.h" 54#include "chrome/common/extensions/extension_constants.h" 55#include "chrome/common/extensions/mime_types_handler.h" 56#include "chrome/common/pref_names.h" 57#include "chrome/test/base/in_process_browser_test.h" 58#include "chrome/test/base/test_switches.h" 59#include "chrome/test/base/ui_test_utils.h" 60#include "chrome/test/base/uma_histogram_helper.h" 61#include "content/public/browser/browser_message_filter.h" 62#include "content/public/browser/devtools_agent_host.h" 63#include "content/public/browser/devtools_client_host.h" 64#include "content/public/browser/devtools_manager.h" 65#include "content/public/browser/navigation_controller.h" 66#include "content/public/browser/navigation_entry.h" 67#include "content/public/browser/notification_service.h" 68#include "content/public/browser/render_frame_host.h" 69#include "content/public/browser/render_process_host.h" 70#include "content/public/browser/render_view_host.h" 71#include "content/public/browser/site_instance.h" 72#include "content/public/browser/web_contents.h" 73#include "content/public/browser/web_contents_observer.h" 74#include "content/public/common/url_constants.h" 75#include "content/public/test/browser_test_utils.h" 76#include "content/public/test/test_navigation_observer.h" 77#include "content/public/test/test_utils.h" 78#include "content/test/net/url_request_mock_http_job.h" 79#include "extensions/common/switches.h" 80#include "grit/generated_resources.h" 81#include "net/base/escape.h" 82#include "net/cert/x509_certificate.h" 83#include "net/dns/mock_host_resolver.h" 84#include "net/ssl/client_cert_store.h" 85#include "net/ssl/ssl_cert_request_info.h" 86#include "net/url_request/url_request_context.h" 87#include "net/url_request/url_request_context_getter.h" 88#include "net/url_request/url_request_filter.h" 89#include "net/url_request/url_request_job.h" 90#include "ui/base/l10n/l10n_util.h" 91#include "url/gurl.h" 92 93using content::BrowserThread; 94using content::DevToolsAgentHost; 95using content::DevToolsClientHost; 96using content::DevToolsManager; 97using content::NavigationController; 98using content::OpenURLParams; 99using content::Referrer; 100using content::RenderFrameHost; 101using content::RenderViewHost; 102using content::RenderWidgetHost; 103using content::TestNavigationObserver; 104using content::WebContents; 105using content::WebContentsObserver; 106using task_manager::browsertest_util::WaitForTaskManagerRows; 107 108// Prerender tests work as follows: 109// 110// A page with a prefetch link to the test page is loaded. Once prerendered, 111// its Javascript function DidPrerenderPass() is called, which returns true if 112// the page behaves as expected when prerendered. 113// 114// The prerendered page is then displayed on a tab. The Javascript function 115// DidDisplayPass() is called, and returns true if the page behaved as it 116// should while being displayed. 117 118namespace prerender { 119 120namespace { 121 122// Constants used in the test HTML files. 123const char* kReadyTitle = "READY"; 124const char* kPassTitle = "PASS"; 125 126std::string CreateClientRedirect(const std::string& dest_url) { 127 const char* const kClientRedirectBase = "client-redirect?"; 128 return kClientRedirectBase + net::EscapeQueryParamValue(dest_url, false); 129} 130 131std::string CreateServerRedirect(const std::string& dest_url) { 132 const char* const kServerRedirectBase = "server-redirect?"; 133 return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false); 134} 135 136// Clears the specified data using BrowsingDataRemover. 137void ClearBrowsingData(Browser* browser, int remove_mask) { 138 BrowsingDataRemover* remover = 139 BrowsingDataRemover::CreateForUnboundedRange(browser->profile()); 140 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB); 141 // BrowsingDataRemover deletes itself. 142} 143 144// Returns true if the prerender is expected to abort on its own, before 145// attempting to swap it. 146bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) { 147 switch (status) { 148 case FINAL_STATUS_USED: 149 case FINAL_STATUS_WINDOW_OPENER: 150 case FINAL_STATUS_APP_TERMINATING: 151 case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED: 152 // We'll crash the renderer after it's loaded. 153 case FINAL_STATUS_RENDERER_CRASHED: 154 case FINAL_STATUS_CANCELLED: 155 case FINAL_STATUS_DEVTOOLS_ATTACHED: 156 case FINAL_STATUS_PAGE_BEING_CAPTURED: 157 case FINAL_STATUS_NAVIGATION_UNCOMMITTED: 158 case FINAL_STATUS_WOULD_HAVE_BEEN_USED: 159 return false; 160 default: 161 return true; 162 } 163} 164 165// Convenience function to wait for a title. Handles the case when the 166// WebContents already has the expected title. 167void WaitForASCIITitle(WebContents* web_contents, 168 const char* expected_title_ascii) { 169 base::string16 expected_title = base::ASCIIToUTF16(expected_title_ascii); 170 if (web_contents->GetTitle() == expected_title) 171 return; 172 content::TitleWatcher title_watcher(web_contents, expected_title); 173 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 174} 175 176// Waits for the destruction of a RenderProcessHost's IPC channel. 177// Used to make sure the PrerenderLinkManager's OnChannelClosed function has 178// been called, before checking its state. 179class ChannelDestructionWatcher { 180 public: 181 ChannelDestructionWatcher() : channel_destroyed_(false) { 182 } 183 184 ~ChannelDestructionWatcher() { 185 } 186 187 void WatchChannel(content::RenderProcessHost* host) { 188 host->AddFilter(new DestructionMessageFilter(this)); 189 } 190 191 void WaitForChannelClose() { 192 run_loop_.Run(); 193 EXPECT_TRUE(channel_destroyed_); 194 } 195 196 private: 197 // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed. 198 // Ignores all messages. 199 class DestructionMessageFilter : public content::BrowserMessageFilter { 200 public: 201 explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher) 202 : BrowserMessageFilter(0), 203 watcher_(watcher) { 204 } 205 206 private: 207 virtual ~DestructionMessageFilter() { 208 content::BrowserThread::PostTask( 209 content::BrowserThread::UI, FROM_HERE, 210 base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed, 211 base::Unretained(watcher_))); 212 } 213 214 virtual bool OnMessageReceived(const IPC::Message& message, 215 bool* message_was_ok) OVERRIDE { 216 return false; 217 } 218 219 ChannelDestructionWatcher* watcher_; 220 221 DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter); 222 }; 223 224 void OnChannelDestroyed() { 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 226 227 EXPECT_FALSE(channel_destroyed_); 228 channel_destroyed_ = true; 229 run_loop_.Quit(); 230 } 231 232 bool channel_destroyed_; 233 base::RunLoop run_loop_; 234 235 DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher); 236}; 237 238// A navigation observer to wait on either a new load or a swap of a 239// WebContents. On swap, if the new WebContents is still loading, wait for that 240// load to complete as well. Note that the load must begin after the observer is 241// attached. 242class NavigationOrSwapObserver : public WebContentsObserver, 243 public TabStripModelObserver { 244 public: 245 // Waits for either a new load or a swap of |tab_strip_model|'s active 246 // WebContents. 247 NavigationOrSwapObserver(TabStripModel* tab_strip_model, 248 WebContents* web_contents) 249 : WebContentsObserver(web_contents), 250 tab_strip_model_(tab_strip_model), 251 did_start_loading_(false), 252 number_of_loads_(1) { 253 CHECK_NE(TabStripModel::kNoTab, 254 tab_strip_model->GetIndexOfWebContents(web_contents)); 255 tab_strip_model_->AddObserver(this); 256 } 257 258 // Waits for either |number_of_loads| loads or a swap of |tab_strip_model|'s 259 // active WebContents. 260 NavigationOrSwapObserver(TabStripModel* tab_strip_model, 261 WebContents* web_contents, 262 int number_of_loads) 263 : WebContentsObserver(web_contents), 264 tab_strip_model_(tab_strip_model), 265 did_start_loading_(false), 266 number_of_loads_(number_of_loads) { 267 CHECK_NE(TabStripModel::kNoTab, 268 tab_strip_model->GetIndexOfWebContents(web_contents)); 269 tab_strip_model_->AddObserver(this); 270 } 271 272 virtual ~NavigationOrSwapObserver() { 273 tab_strip_model_->RemoveObserver(this); 274 } 275 276 void Wait() { 277 loop_.Run(); 278 } 279 280 // WebContentsObserver implementation: 281 virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE { 282 did_start_loading_ = true; 283 } 284 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE { 285 if (!did_start_loading_) 286 return; 287 number_of_loads_--; 288 if (number_of_loads_ == 0) 289 loop_.Quit(); 290 } 291 292 // TabStripModelObserver implementation: 293 virtual void TabReplacedAt(TabStripModel* tab_strip_model, 294 WebContents* old_contents, 295 WebContents* new_contents, 296 int index) OVERRIDE { 297 if (old_contents != web_contents()) 298 return; 299 // Switch to observing the new WebContents. 300 Observe(new_contents); 301 if (new_contents->IsLoading()) { 302 // If the new WebContents is still loading, wait for it to complete. Only 303 // one load post-swap is supported. 304 did_start_loading_ = true; 305 number_of_loads_ = 1; 306 } else { 307 loop_.Quit(); 308 } 309 } 310 311 private: 312 TabStripModel* tab_strip_model_; 313 bool did_start_loading_; 314 int number_of_loads_; 315 base::RunLoop loop_; 316}; 317 318// Waits for a new tab to open and a navigation or swap in it. 319class NewTabNavigationOrSwapObserver { 320 public: 321 NewTabNavigationOrSwapObserver() 322 : new_tab_observer_( 323 chrome::NOTIFICATION_TAB_ADDED, 324 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded, 325 base::Unretained(this))) { 326 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the 327 // NavigationOrSwapObserver can be attached synchronously and no events are 328 // missed. 329 } 330 331 void Wait() { 332 new_tab_observer_.Wait(); 333 swap_observer_->Wait(); 334 } 335 336 bool OnTabAdded(const content::NotificationSource& source, 337 const content::NotificationDetails& details) { 338 if (swap_observer_) 339 return true; 340 WebContents* new_tab = content::Details<WebContents>(details).ptr(); 341 // Get the TabStripModel. Assume this is attached to a Browser. 342 TabStripModel* tab_strip_model = 343 static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model(); 344 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model, 345 new_tab)); 346 return true; 347 } 348 349 private: 350 content::WindowedNotificationObserver new_tab_observer_; 351 scoped_ptr<NavigationOrSwapObserver> swap_observer_; 352}; 353 354// PrerenderContents that stops the UI message loop on DidStopLoading(). 355class TestPrerenderContents : public PrerenderContents { 356 public: 357 TestPrerenderContents( 358 PrerenderManager* prerender_manager, 359 Profile* profile, 360 const GURL& url, 361 const content::Referrer& referrer, 362 Origin origin, 363 FinalStatus expected_final_status) 364 : PrerenderContents(prerender_manager, profile, url, 365 referrer, origin, PrerenderManager::kNoExperiment), 366 expected_final_status_(expected_final_status), 367 new_render_view_host_(NULL), 368 was_hidden_(false), 369 was_shown_(false), 370 should_be_shown_(expected_final_status == FINAL_STATUS_USED), 371 skip_final_checks_(false) { 372 } 373 374 virtual ~TestPrerenderContents() { 375 if (skip_final_checks_) 376 return; 377 378 if (expected_final_status_ == FINAL_STATUS_MAX) { 379 EXPECT_EQ(MATCH_COMPLETE_REPLACEMENT, match_complete_status()); 380 } else { 381 EXPECT_EQ(expected_final_status_, final_status()) << 382 " when testing URL " << prerender_url().path() << 383 " (Expected: " << NameFromFinalStatus(expected_final_status_) << 384 ", Actual: " << NameFromFinalStatus(final_status()) << ")"; 385 } 386 // Prerendering RenderViewHosts should be hidden before the first 387 // navigation, so this should be happen for every PrerenderContents for 388 // which a RenderViewHost is created, regardless of whether or not it's 389 // used. 390 if (new_render_view_host_) 391 EXPECT_TRUE(was_hidden_); 392 393 // A used PrerenderContents will only be destroyed when we swap out 394 // WebContents, at the end of a navigation caused by a call to 395 // NavigateToURLImpl(). 396 if (final_status() == FINAL_STATUS_USED) 397 EXPECT_TRUE(new_render_view_host_); 398 399 EXPECT_EQ(should_be_shown_, was_shown_); 400 } 401 402 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE { 403 // On quit, it's possible to end up here when render processes are closed 404 // before the PrerenderManager is destroyed. As a result, it's possible to 405 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED 406 // on quit. 407 // 408 // It's also possible for this to be called after we've been notified of 409 // app termination, but before we've been deleted, which is why the second 410 // check is needed. 411 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING && 412 final_status() != expected_final_status_) { 413 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED; 414 } 415 416 PrerenderContents::RenderProcessGone(status); 417 } 418 419 virtual bool CheckURL(const GURL& url) OVERRIDE { 420 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in 421 // the PrerenderRendererCrash test. 422 if (url.spec() != content::kChromeUICrashURL) 423 return PrerenderContents::CheckURL(url); 424 return true; 425 } 426 427 // For tests that open the prerender in a new background tab, the RenderView 428 // will not have been made visible when the PrerenderContents is destroyed 429 // even though it is used. 430 void set_should_be_shown(bool value) { should_be_shown_ = value; } 431 432 // For tests which do not know whether the prerender will be used. 433 void set_skip_final_checks(bool value) { skip_final_checks_ = value; } 434 435 FinalStatus expected_final_status() const { return expected_final_status_; } 436 437 private: 438 virtual void OnRenderViewHostCreated( 439 RenderViewHost* new_render_view_host) OVERRIDE { 440 // Used to make sure the RenderViewHost is hidden and, if used, 441 // subsequently shown. 442 notification_registrar().Add( 443 this, 444 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 445 content::Source<RenderWidgetHost>(new_render_view_host)); 446 447 new_render_view_host_ = new_render_view_host; 448 449 PrerenderContents::OnRenderViewHostCreated(new_render_view_host); 450 } 451 452 virtual void Observe(int type, 453 const content::NotificationSource& source, 454 const content::NotificationDetails& details) OVERRIDE { 455 if (type == 456 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) { 457 EXPECT_EQ(new_render_view_host_, 458 content::Source<RenderWidgetHost>(source).ptr()); 459 bool is_visible = *content::Details<bool>(details).ptr(); 460 461 if (!is_visible) { 462 was_hidden_ = true; 463 } else if (is_visible && was_hidden_) { 464 // Once hidden, a prerendered RenderViewHost should only be shown after 465 // being removed from the PrerenderContents for display. 466 EXPECT_FALSE(GetRenderViewHost()); 467 was_shown_ = true; 468 } 469 return; 470 } 471 PrerenderContents::Observe(type, source, details); 472 } 473 474 FinalStatus expected_final_status_; 475 476 // The RenderViewHost created for the prerender, if any. 477 RenderViewHost* new_render_view_host_; 478 // Set to true when the prerendering RenderWidget is hidden. 479 bool was_hidden_; 480 // Set to true when the prerendering RenderWidget is shown, after having been 481 // hidden. 482 bool was_shown_; 483 // Expected final value of was_shown_. Defaults to true for 484 // FINAL_STATUS_USED, and false otherwise. 485 bool should_be_shown_; 486 // If true, |expected_final_status_| and other shutdown checks are skipped. 487 bool skip_final_checks_; 488}; 489 490// A handle to a TestPrerenderContents whose lifetime is under the caller's 491// control. A PrerenderContents may be destroyed at any point. This allows 492// tracking the final status, etc. 493class TestPrerender : public PrerenderContents::Observer, 494 public base::SupportsWeakPtr<TestPrerender> { 495 public: 496 TestPrerender() 497 : contents_(NULL), 498 number_of_loads_(0), 499 expected_number_of_loads_(0) { 500 } 501 virtual ~TestPrerender() { 502 if (contents_) 503 contents_->RemoveObserver(this); 504 } 505 506 TestPrerenderContents* contents() const { return contents_; } 507 int number_of_loads() const { return number_of_loads_; } 508 509 void WaitForCreate() { create_loop_.Run(); } 510 void WaitForStart() { start_loop_.Run(); } 511 void WaitForStop() { stop_loop_.Run(); } 512 513 // Waits for |number_of_loads()| to be at least |expected_number_of_loads| OR 514 // for the prerender to stop running (just to avoid a timeout if the prerender 515 // dies). Note: this does not assert equality on the number of loads; the 516 // caller must do it instead. 517 void WaitForLoads(int expected_number_of_loads) { 518 DCHECK(!load_waiter_); 519 DCHECK(!expected_number_of_loads_); 520 if (number_of_loads_ < expected_number_of_loads) { 521 load_waiter_.reset(new base::RunLoop); 522 expected_number_of_loads_ = expected_number_of_loads; 523 load_waiter_->Run(); 524 load_waiter_.reset(); 525 expected_number_of_loads_ = 0; 526 } 527 EXPECT_LE(expected_number_of_loads, number_of_loads_); 528 } 529 530 void OnPrerenderCreated(TestPrerenderContents* contents) { 531 DCHECK(!contents_); 532 contents_ = contents; 533 contents_->AddObserver(this); 534 create_loop_.Quit(); 535 } 536 537 // PrerenderContents::Observer implementation: 538 virtual void OnPrerenderStart(PrerenderContents* contents) OVERRIDE { 539 start_loop_.Quit(); 540 } 541 542 virtual void OnPrerenderStopLoading(PrerenderContents* contents) OVERRIDE { 543 number_of_loads_++; 544 if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_) 545 load_waiter_->Quit(); 546 } 547 548 virtual void OnPrerenderStop(PrerenderContents* contents) OVERRIDE { 549 DCHECK(contents_); 550 contents_ = NULL; 551 stop_loop_.Quit(); 552 // If there is a WaitForLoads call and it has yet to see the expected number 553 // of loads, stop the loop so the test fails instead of timing out. 554 if (load_waiter_) 555 load_waiter_->Quit(); 556 } 557 558 virtual void OnPrerenderCreatedMatchCompleteReplacement( 559 PrerenderContents* contents, PrerenderContents* replacement) OVERRIDE { 560 } 561 562 private: 563 TestPrerenderContents* contents_; 564 int number_of_loads_; 565 566 int expected_number_of_loads_; 567 scoped_ptr<base::RunLoop> load_waiter_; 568 569 base::RunLoop create_loop_; 570 base::RunLoop start_loop_; 571 base::RunLoop stop_loop_; 572 573 DISALLOW_COPY_AND_ASSIGN(TestPrerender); 574}; 575 576// PrerenderManager that uses TestPrerenderContents. 577class TestPrerenderContentsFactory : public PrerenderContents::Factory { 578 public: 579 TestPrerenderContentsFactory() {} 580 581 virtual ~TestPrerenderContentsFactory() { 582 EXPECT_TRUE(expected_contents_queue_.empty()); 583 } 584 585 scoped_ptr<TestPrerender> ExpectPrerenderContents(FinalStatus final_status) { 586 scoped_ptr<TestPrerender> handle(new TestPrerender()); 587 expected_contents_queue_.push_back( 588 ExpectedContents(final_status, handle->AsWeakPtr())); 589 return handle.Pass(); 590 } 591 592 virtual PrerenderContents* CreatePrerenderContents( 593 PrerenderManager* prerender_manager, 594 Profile* profile, 595 const GURL& url, 596 const content::Referrer& referrer, 597 Origin origin, 598 uint8 experiment_id) OVERRIDE { 599 ExpectedContents expected; 600 if (!expected_contents_queue_.empty()) { 601 expected = expected_contents_queue_.front(); 602 expected_contents_queue_.pop_front(); 603 } 604 VLOG(1) << "Creating prerender contents for " << url.path() << 605 " with expected final status " << expected.final_status; 606 VLOG(1) << expected_contents_queue_.size() << " left in the queue."; 607 TestPrerenderContents* contents = 608 new TestPrerenderContents(prerender_manager, 609 profile, url, referrer, origin, 610 expected.final_status); 611 if (expected.handle) 612 expected.handle->OnPrerenderCreated(contents); 613 return contents; 614 } 615 616 private: 617 struct ExpectedContents { 618 ExpectedContents() : final_status(FINAL_STATUS_MAX) { } 619 ExpectedContents(FinalStatus final_status, 620 const base::WeakPtr<TestPrerender>& handle) 621 : final_status(final_status), 622 handle(handle) { 623 } 624 625 FinalStatus final_status; 626 base::WeakPtr<TestPrerender> handle; 627 }; 628 629 std::deque<ExpectedContents> expected_contents_queue_; 630}; 631 632#if defined(FULL_SAFE_BROWSING) 633// A SafeBrowsingDatabaseManager implementation that returns a fixed result for 634// a given URL. 635class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { 636 public: 637 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service) 638 : SafeBrowsingDatabaseManager(service), 639 threat_type_(SB_THREAT_TYPE_SAFE) { } 640 641 // Called on the IO thread to check if the given url is safe or not. If we 642 // can synchronously determine that the url is safe, CheckUrl returns true. 643 // Otherwise it returns false, and "client" is called asynchronously with the 644 // result when it is ready. 645 // Returns true, indicating a SAFE result, unless the URL is the fixed URL 646 // specified by the user, and the user-specified result is not SAFE 647 // (in which that result will be communicated back via a call into the 648 // client, and false will be returned). 649 // Overrides SafeBrowsingService::CheckBrowseUrl. 650 virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE { 651 if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE) 652 return true; 653 654 BrowserThread::PostTask( 655 BrowserThread::IO, FROM_HERE, 656 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone, 657 this, gurl, client)); 658 return false; 659 } 660 661 void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) { 662 url_ = url; 663 threat_type_ = threat_type; 664 } 665 666 private: 667 virtual ~FakeSafeBrowsingDatabaseManager() {} 668 669 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) { 670 std::vector<SBThreatType> expected_threats; 671 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE); 672 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING); 673 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check( 674 std::vector<GURL>(1, gurl), 675 std::vector<SBFullHash>(), 676 client, 677 safe_browsing_util::MALWARE, 678 expected_threats); 679 sb_check.url_results[0] = threat_type_; 680 client->OnSafeBrowsingResult(sb_check); 681 } 682 683 GURL url_; 684 SBThreatType threat_type_; 685 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager); 686}; 687 688class FakeSafeBrowsingService : public SafeBrowsingService { 689 public: 690 FakeSafeBrowsingService() { } 691 692 // Returned pointer has the same lifespan as the database_manager_ refcounted 693 // object. 694 FakeSafeBrowsingDatabaseManager* fake_database_manager() { 695 return fake_database_manager_; 696 } 697 698 protected: 699 virtual ~FakeSafeBrowsingService() { } 700 701 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE { 702 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this); 703 return fake_database_manager_; 704 } 705 706 private: 707 FakeSafeBrowsingDatabaseManager* fake_database_manager_; 708 709 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService); 710}; 711 712// Factory that creates FakeSafeBrowsingService instances. 713class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory { 714 public: 715 TestSafeBrowsingServiceFactory() : 716 most_recent_service_(NULL) { } 717 virtual ~TestSafeBrowsingServiceFactory() { } 718 719 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE { 720 most_recent_service_ = new FakeSafeBrowsingService(); 721 return most_recent_service_; 722 } 723 724 FakeSafeBrowsingService* most_recent_service() const { 725 return most_recent_service_; 726 } 727 728 private: 729 FakeSafeBrowsingService* most_recent_service_; 730}; 731#endif 732 733class FakeDevToolsClientHost : public DevToolsClientHost { 734 public: 735 FakeDevToolsClientHost() {} 736 virtual ~FakeDevToolsClientHost() {} 737 virtual void InspectedContentsClosing() OVERRIDE {} 738 virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {} 739 virtual void ReplacedWithAnotherClient() OVERRIDE {} 740}; 741 742class RestorePrerenderMode { 743 public: 744 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) { 745 } 746 747 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); } 748 private: 749 PrerenderManager::PrerenderManagerMode prev_mode_; 750}; 751 752// URLRequestJob (and associated handler) which hangs. 753class HangingURLRequestJob : public net::URLRequestJob { 754 public: 755 HangingURLRequestJob(net::URLRequest* request, 756 net::NetworkDelegate* network_delegate) 757 : net::URLRequestJob(request, network_delegate) { 758 } 759 760 virtual void Start() OVERRIDE {} 761 762 private: 763 virtual ~HangingURLRequestJob() {} 764}; 765 766class HangingFirstRequestProtocolHandler 767 : public net::URLRequestJobFactory::ProtocolHandler { 768 public: 769 HangingFirstRequestProtocolHandler(const base::FilePath& file, 770 base::Closure callback) 771 : file_(file), 772 callback_(callback), 773 first_run_(true) { 774 } 775 virtual ~HangingFirstRequestProtocolHandler() {} 776 777 virtual net::URLRequestJob* MaybeCreateJob( 778 net::URLRequest* request, 779 net::NetworkDelegate* network_delegate) const OVERRIDE { 780 if (first_run_) { 781 first_run_ = false; 782 if (!callback_.is_null()) { 783 BrowserThread::PostTask( 784 BrowserThread::UI, FROM_HERE, callback_); 785 } 786 return new HangingURLRequestJob(request, network_delegate); 787 } 788 return new content::URLRequestMockHTTPJob(request, network_delegate, file_); 789 } 790 791 private: 792 base::FilePath file_; 793 base::Closure callback_; 794 mutable bool first_run_; 795}; 796 797// Makes |url| never respond on the first load, and then with the contents of 798// |file| afterwards. When the first load has been scheduled, runs |callback| on 799// the UI thread. 800void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url, 801 const base::FilePath& file, 802 base::Closure callback) { 803 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 804 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler( 805 new HangingFirstRequestProtocolHandler(file, callback)); 806 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( 807 url, never_respond_handler.Pass()); 808} 809 810// Wrapper over URLRequestMockHTTPJob that exposes extra callbacks. 811class MockHTTPJob : public content::URLRequestMockHTTPJob { 812 public: 813 MockHTTPJob(net::URLRequest* request, 814 net::NetworkDelegate* delegate, 815 const base::FilePath& file) 816 : content::URLRequestMockHTTPJob(request, delegate, file) { 817 } 818 819 void set_start_callback(const base::Closure& start_callback) { 820 start_callback_ = start_callback; 821 } 822 823 virtual void Start() OVERRIDE { 824 if (!start_callback_.is_null()) 825 start_callback_.Run(); 826 content::URLRequestMockHTTPJob::Start(); 827 } 828 829 private: 830 virtual ~MockHTTPJob() {} 831 832 base::Closure start_callback_; 833}; 834 835// Dummy counter class to live on the UI thread for counting requests. 836class RequestCounter : public base::SupportsWeakPtr<RequestCounter> { 837 public: 838 RequestCounter() : count_(0), expected_count_(-1) {} 839 int count() const { return count_; } 840 841 void RequestStarted() { 842 count_++; 843 if (loop_ && count_ == expected_count_) 844 loop_->Quit(); 845 } 846 847 void WaitForCount(int expected_count) { 848 ASSERT_TRUE(!loop_); 849 ASSERT_EQ(-1, expected_count_); 850 if (count_ < expected_count) { 851 expected_count_ = expected_count; 852 loop_.reset(new base::RunLoop); 853 loop_->Run(); 854 expected_count_ = -1; 855 loop_.reset(); 856 } 857 858 EXPECT_EQ(expected_count, count_); 859 } 860 private: 861 int count_; 862 int expected_count_; 863 scoped_ptr<base::RunLoop> loop_; 864}; 865 866// Protocol handler which counts the number of requests that start. 867class CountingProtocolHandler 868 : public net::URLRequestJobFactory::ProtocolHandler { 869 public: 870 CountingProtocolHandler(const base::FilePath& file, 871 const base::WeakPtr<RequestCounter>& counter) 872 : file_(file), 873 counter_(counter), 874 weak_factory_(this) { 875 } 876 virtual ~CountingProtocolHandler() {} 877 878 virtual net::URLRequestJob* MaybeCreateJob( 879 net::URLRequest* request, 880 net::NetworkDelegate* network_delegate) const OVERRIDE { 881 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_); 882 job->set_start_callback(base::Bind(&CountingProtocolHandler::RequestStarted, 883 weak_factory_.GetWeakPtr())); 884 return job; 885 } 886 887 void RequestStarted() { 888 BrowserThread::PostTask( 889 BrowserThread::UI, FROM_HERE, 890 base::Bind(&RequestCounter::RequestStarted, counter_)); 891 } 892 893 private: 894 base::FilePath file_; 895 base::WeakPtr<RequestCounter> counter_; 896 mutable base::WeakPtrFactory<CountingProtocolHandler> weak_factory_; 897}; 898 899// Makes |url| respond to requests with the contents of |file|, counting the 900// number that start in |counter|. 901void CreateCountingProtocolHandlerOnIO( 902 const GURL& url, 903 const base::FilePath& file, 904 const base::WeakPtr<RequestCounter>& counter) { 905 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 906 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> protocol_handler( 907 new CountingProtocolHandler(file, counter)); 908 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( 909 url, protocol_handler.Pass()); 910} 911 912// Makes |url| respond to requests with the contents of |file|. 913void CreateMockProtocolHandlerOnIO(const GURL& url, 914 const base::FilePath& file) { 915 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 916 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( 917 url, content::URLRequestMockHTTPJob::CreateProtocolHandlerForSingleFile( 918 file)); 919} 920 921// A ContentBrowserClient that cancels all prerenderers on OpenURL. 922class TestContentBrowserClient : public chrome::ChromeContentBrowserClient { 923 public: 924 TestContentBrowserClient() {} 925 virtual ~TestContentBrowserClient() {} 926 927 // chrome::ChromeContentBrowserClient implementation. 928 virtual bool ShouldAllowOpenURL(content::SiteInstance* site_instance, 929 const GURL& url) OVERRIDE { 930 PrerenderManagerFactory::GetForProfile( 931 Profile::FromBrowserContext(site_instance->GetBrowserContext())) 932 ->CancelAllPrerenders(); 933 return chrome::ChromeContentBrowserClient::ShouldAllowOpenURL(site_instance, 934 url); 935 } 936 937 private: 938 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient); 939}; 940 941// A ContentBrowserClient that forces cross-process navigations. 942class SwapProcessesContentBrowserClient 943 : public chrome::ChromeContentBrowserClient { 944 public: 945 SwapProcessesContentBrowserClient() {} 946 virtual ~SwapProcessesContentBrowserClient() {} 947 948 // chrome::ChromeContentBrowserClient implementation. 949 virtual bool ShouldSwapProcessesForRedirect( 950 content::ResourceContext* resource_context, 951 const GURL& current_url, 952 const GURL& new_url) OVERRIDE { 953 return true; 954 } 955 956 private: 957 DISALLOW_COPY_AND_ASSIGN(SwapProcessesContentBrowserClient); 958}; 959 960// An ExternalProtocolHandler that blocks everything and asserts it never is 961// called. 962class NeverRunsExternalProtocolHandlerDelegate 963 : public ExternalProtocolHandler::Delegate { 964 public: 965 // ExternalProtocolHandler::Delegate implementation. 966 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( 967 ShellIntegration::DefaultWebClientObserver* observer, 968 const std::string& protocol) OVERRIDE { 969 NOTREACHED(); 970 // This will crash, but it shouldn't get this far with BlockState::BLOCK 971 // anyway. 972 return NULL; 973 } 974 virtual ExternalProtocolHandler::BlockState GetBlockState( 975 const std::string& scheme, 976 bool initiated_by_user_gesture) OVERRIDE { 977 // Block everything and fail the test. 978 ADD_FAILURE(); 979 return ExternalProtocolHandler::BLOCK; 980 } 981 virtual void BlockRequest() OVERRIDE { } 982 virtual void RunExternalProtocolDialog(const GURL& url, 983 int render_process_host_id, 984 int routing_id) OVERRIDE { 985 NOTREACHED(); 986 } 987 virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE { 988 NOTREACHED(); 989 } 990 virtual void FinishedProcessingCheck() OVERRIDE { 991 NOTREACHED(); 992 } 993}; 994 995base::FilePath GetTestPath(const std::string& file_name) { 996 return ui_test_utils::GetTestFilePath( 997 base::FilePath(FILE_PATH_LITERAL("prerender")), 998 base::FilePath().AppendASCII(file_name)); 999} 1000 1001} // namespace 1002 1003// Many of these tests are flaky. See http://crbug.com/249179 1004class PrerenderBrowserTest : virtual public InProcessBrowserTest { 1005 public: 1006 PrerenderBrowserTest() 1007 : autostart_test_server_(true), 1008 prerender_contents_factory_(NULL), 1009#if defined(FULL_SAFE_BROWSING) 1010 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()), 1011#endif 1012 call_javascript_(true), 1013 check_load_events_(true), 1014 loader_path_("files/prerender/prerender_loader.html"), 1015 explicitly_set_browser_(NULL) {} 1016 1017 virtual ~PrerenderBrowserTest() {} 1018 1019 content::SessionStorageNamespace* GetSessionStorageNamespace() const { 1020 WebContents* web_contents = GetActiveWebContents(); 1021 if (!web_contents) 1022 return NULL; 1023 return web_contents->GetController().GetDefaultSessionStorageNamespace(); 1024 } 1025 1026 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 1027#if defined(FULL_SAFE_BROWSING) 1028 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get()); 1029#endif 1030 } 1031 1032 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 1033#if defined(FULL_SAFE_BROWSING) 1034 SafeBrowsingService::RegisterFactory(NULL); 1035#endif 1036 } 1037 1038 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1039 command_line->AppendSwitchASCII(switches::kPrerenderMode, 1040 switches::kPrerenderModeSwitchValueEnabled); 1041#if defined(OS_MACOSX) 1042 // The plugins directory isn't read by default on the Mac, so it needs to be 1043 // explicitly registered. 1044 base::FilePath app_dir; 1045 PathService::Get(chrome::DIR_APP, &app_dir); 1046 command_line->AppendSwitchPath( 1047 switches::kExtraPluginDir, 1048 app_dir.Append(FILE_PATH_LITERAL("plugins"))); 1049#endif 1050 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins); 1051 } 1052 1053 virtual void SetUpOnMainThread() OVERRIDE { 1054 current_browser()->profile()->GetPrefs()->SetBoolean( 1055 prefs::kPromptForDownload, false); 1056 IncreasePrerenderMemory(); 1057 if (autostart_test_server_) 1058 ASSERT_TRUE(test_server()->Start()); 1059 ChromeResourceDispatcherHostDelegate:: 1060 SetExternalProtocolHandlerDelegateForTesting( 1061 &external_protocol_handler_delegate_); 1062 1063 PrerenderManager* prerender_manager = GetPrerenderManager(); 1064 ASSERT_TRUE(prerender_manager); 1065 prerender_manager->mutable_config().rate_limit_enabled = false; 1066 ASSERT_TRUE(prerender_contents_factory_ == NULL); 1067 prerender_contents_factory_ = new TestPrerenderContentsFactory; 1068 prerender_manager->SetPrerenderContentsFactory(prerender_contents_factory_); 1069 } 1070 1071 // Convenience function to get the currently active WebContents in 1072 // current_browser(). 1073 WebContents* GetActiveWebContents() const { 1074 return current_browser()->tab_strip_model()->GetActiveWebContents(); 1075 } 1076 1077 // Overload for a single expected final status 1078 scoped_ptr<TestPrerender> PrerenderTestURL( 1079 const std::string& html_file, 1080 FinalStatus expected_final_status, 1081 int expected_number_of_loads) { 1082 GURL url = test_server()->GetURL(html_file); 1083 return PrerenderTestURL(url, 1084 expected_final_status, 1085 expected_number_of_loads); 1086 } 1087 1088 ScopedVector<TestPrerender> PrerenderTestURL( 1089 const std::string& html_file, 1090 const std::vector<FinalStatus>& expected_final_status_queue, 1091 int expected_number_of_loads) { 1092 GURL url = test_server()->GetURL(html_file); 1093 return PrerenderTestURLImpl(url, 1094 expected_final_status_queue, 1095 expected_number_of_loads); 1096 } 1097 1098 scoped_ptr<TestPrerender> PrerenderTestURL( 1099 const GURL& url, 1100 FinalStatus expected_final_status, 1101 int expected_number_of_loads) { 1102 std::vector<FinalStatus> expected_final_status_queue( 1103 1, expected_final_status); 1104 std::vector<TestPrerender*> prerenders; 1105 PrerenderTestURLImpl(url, 1106 expected_final_status_queue, 1107 expected_number_of_loads).release(&prerenders); 1108 CHECK_EQ(1u, prerenders.size()); 1109 return scoped_ptr<TestPrerender>(prerenders[0]); 1110 } 1111 1112 void NavigateToDestURL() const { 1113 NavigateToDestURLWithDisposition(CURRENT_TAB, true); 1114 } 1115 1116 // Opens the url in a new tab, with no opener. 1117 void NavigateToDestURLWithDisposition( 1118 WindowOpenDisposition disposition, 1119 bool expect_swap_to_succeed) const { 1120 NavigateToURLWithParams( 1121 content::OpenURLParams(dest_url_, Referrer(), disposition, 1122 content::PAGE_TRANSITION_TYPED, false), 1123 expect_swap_to_succeed); 1124 } 1125 1126 void NavigateToURL(const std::string& dest_html_file) const { 1127 NavigateToURLWithDisposition(dest_html_file, CURRENT_TAB, true); 1128 } 1129 1130 void NavigateToURLWithDisposition(const std::string& dest_html_file, 1131 WindowOpenDisposition disposition, 1132 bool expect_swap_to_succeed) const { 1133 GURL dest_url = test_server()->GetURL(dest_html_file); 1134 NavigateToURLWithDisposition(dest_url, disposition, expect_swap_to_succeed); 1135 } 1136 1137 void NavigateToURLWithDisposition(const GURL& dest_url, 1138 WindowOpenDisposition disposition, 1139 bool expect_swap_to_succeed) const { 1140 NavigateToURLWithParams( 1141 content::OpenURLParams(dest_url, Referrer(), disposition, 1142 content::PAGE_TRANSITION_TYPED, false), 1143 expect_swap_to_succeed); 1144 } 1145 1146 void NavigateToURLWithParams(const content::OpenURLParams& params, 1147 bool expect_swap_to_succeed) const { 1148 NavigateToURLImpl(params, expect_swap_to_succeed); 1149 } 1150 1151 void OpenDestURLViaClick() const { 1152 OpenURLViaClick(dest_url_); 1153 } 1154 1155 void OpenURLViaClick(const GURL& url) const { 1156 OpenURLWithJSImpl("Click", url, GURL(), false); 1157 } 1158 1159 void OpenDestURLViaClickTarget() const { 1160 OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true); 1161 } 1162 1163 void OpenDestURLViaClickPing(const GURL& ping_url) const { 1164 OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false); 1165 } 1166 1167 void OpenDestURLViaClickNewWindow() const { 1168 OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true); 1169 } 1170 1171 void OpenDestURLViaClickNewForegroundTab() const { 1172#if defined(OS_MACOSX) 1173 OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true); 1174#else 1175 OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true); 1176#endif 1177 } 1178 1179 void OpenDestURLViaClickNewBackgroundTab() const { 1180#if defined(OS_MACOSX) 1181 OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true); 1182#else 1183 OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true); 1184#endif 1185 } 1186 1187 void OpenDestURLViaWindowOpen() const { 1188 OpenURLWithJSImpl("WindowOpen", dest_url_, GURL(), true); 1189 } 1190 1191 void RemoveLinkElement(int i) const { 1192 GetActiveWebContents()->GetMainFrame()->ExecuteJavaScript( 1193 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i))); 1194 } 1195 1196 void ClickToNextPageAfterPrerender() { 1197 TestNavigationObserver nav_observer(GetActiveWebContents()); 1198 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame(); 1199 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("ClickOpenLink()")); 1200 nav_observer.Wait(); 1201 } 1202 1203 void NavigateToNextPageAfterPrerender() const { 1204 ui_test_utils::NavigateToURL( 1205 current_browser(), 1206 test_server()->GetURL("files/prerender/prerender_page.html")); 1207 } 1208 1209 // Called after the prerendered page has been navigated to and then away from. 1210 // Navigates back through the history to the prerendered page. 1211 void GoBackToPrerender() { 1212 TestNavigationObserver back_nav_observer(GetActiveWebContents()); 1213 chrome::GoBack(current_browser(), CURRENT_TAB); 1214 back_nav_observer.Wait(); 1215 bool original_prerender_page = false; 1216 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1217 GetActiveWebContents(), 1218 "window.domAutomationController.send(IsOriginalPrerenderPage())", 1219 &original_prerender_page)); 1220 EXPECT_TRUE(original_prerender_page); 1221 } 1222 1223 // Goes back to the page that was active before the prerender was swapped 1224 // in. This must be called when the prerendered page is the current page 1225 // in the active tab. 1226 void GoBackToPageBeforePrerender() { 1227 WebContents* tab = GetActiveWebContents(); 1228 ASSERT_TRUE(tab); 1229 EXPECT_FALSE(tab->IsLoading()); 1230 TestNavigationObserver back_nav_observer(tab); 1231 chrome::GoBack(current_browser(), CURRENT_TAB); 1232 back_nav_observer.Wait(); 1233 bool js_result; 1234 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 1235 tab, 1236 "window.domAutomationController.send(DidBackToOriginalPagePass())", 1237 &js_result)); 1238 EXPECT_TRUE(js_result); 1239 } 1240 1241 bool UrlIsInPrerenderManager(const std::string& html_file) const { 1242 return UrlIsInPrerenderManager(test_server()->GetURL(html_file)); 1243 } 1244 1245 bool UrlIsInPrerenderManager(const GURL& url) const { 1246 return GetPrerenderManager()->FindPrerenderData( 1247 url, GetSessionStorageNamespace()) != NULL; 1248 } 1249 1250 void UseHttpsSrcServer() { 1251 if (https_src_server_) 1252 return; 1253 https_src_server_.reset( 1254 new net::SpawnedTestServer( 1255 net::SpawnedTestServer::TYPE_HTTPS, 1256 net::SpawnedTestServer::kLocalhost, 1257 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 1258 CHECK(https_src_server_->Start()); 1259 } 1260 1261 void DisableJavascriptCalls() { 1262 call_javascript_ = false; 1263 } 1264 1265 void DisableLoadEventCheck() { 1266 check_load_events_ = false; 1267 } 1268 1269 TaskManagerModel* GetModel() const { 1270 return TaskManager::GetInstance()->model(); 1271 } 1272 1273 PrerenderManager* GetPrerenderManager() const { 1274 PrerenderManager* prerender_manager = 1275 PrerenderManagerFactory::GetForProfile(current_browser()->profile()); 1276 return prerender_manager; 1277 } 1278 1279 const PrerenderLinkManager* GetPrerenderLinkManager() const { 1280 PrerenderLinkManager* prerender_link_manager = 1281 PrerenderLinkManagerFactory::GetForProfile( 1282 current_browser()->profile()); 1283 return prerender_link_manager; 1284 } 1285 1286 int GetPrerenderEventCount(int index, const std::string& type) const { 1287 int event_count; 1288 std::string expression = base::StringPrintf( 1289 "window.domAutomationController.send(" 1290 " GetPrerenderEventCount(%d, '%s'))", index, type.c_str()); 1291 1292 CHECK(content::ExecuteScriptAndExtractInt( 1293 GetActiveWebContents(), expression, &event_count)); 1294 return event_count; 1295 } 1296 1297 bool DidReceivePrerenderStartEventForLinkNumber(int index) const { 1298 return GetPrerenderEventCount(index, "webkitprerenderstart") > 0; 1299 } 1300 1301 int GetPrerenderLoadEventCountForLinkNumber(int index) const { 1302 return GetPrerenderEventCount(index, "webkitprerenderload"); 1303 } 1304 1305 int GetPrerenderDomContentLoadedEventCountForLinkNumber(int index) const { 1306 return GetPrerenderEventCount(index, "webkitprerenderdomcontentloaded"); 1307 } 1308 1309 bool DidReceivePrerenderStopEventForLinkNumber(int index) const { 1310 return GetPrerenderEventCount(index, "webkitprerenderstop") > 0; 1311 } 1312 1313 void WaitForPrerenderEventCount(int index, 1314 const std::string& type, 1315 int count) const { 1316 int dummy; 1317 std::string expression = base::StringPrintf( 1318 "WaitForPrerenderEventCount(%d, '%s', %d," 1319 " window.domAutomationController.send.bind(" 1320 " window.domAutomationController, 0))", 1321 index, type.c_str(), count); 1322 1323 CHECK(content::ExecuteScriptAndExtractInt( 1324 GetActiveWebContents(), expression, &dummy)); 1325 CHECK_EQ(0, dummy); 1326 } 1327 1328 bool HadPrerenderEventErrors() const { 1329 bool had_prerender_event_errors; 1330 CHECK(content::ExecuteScriptAndExtractBool( 1331 GetActiveWebContents(), 1332 "window.domAutomationController.send(Boolean(" 1333 " hadPrerenderEventErrors))", 1334 &had_prerender_event_errors)); 1335 return had_prerender_event_errors; 1336 } 1337 1338 // Asserting on this can result in flaky tests. PrerenderHandles are 1339 // removed from the PrerenderLinkManager when the prerender is canceled from 1340 // the browser, when the prerenders are cancelled from the renderer process, 1341 // or the channel for the renderer process is closed on the IO thread. In the 1342 // last case, the code must be careful to wait for the channel to close, as it 1343 // is done asynchronously after swapping out the old process. See 1344 // ChannelDestructionWatcher. 1345 bool IsEmptyPrerenderLinkManager() const { 1346 return GetPrerenderLinkManager()->IsEmpty(); 1347 } 1348 1349 size_t GetLinkPrerenderCount() const { 1350 return GetPrerenderLinkManager()->prerenders_.size(); 1351 } 1352 1353 size_t GetRunningLinkPrerenderCount() const { 1354 return GetPrerenderLinkManager()->CountRunningPrerenders(); 1355 } 1356 1357 // Returns length of |prerender_manager_|'s history, or -1 on failure. 1358 int GetHistoryLength() const { 1359 scoped_ptr<base::DictionaryValue> prerender_dict( 1360 static_cast<base::DictionaryValue*>( 1361 GetPrerenderManager()->GetAsValue())); 1362 if (!prerender_dict.get()) 1363 return -1; 1364 base::ListValue* history_list; 1365 if (!prerender_dict->GetList("history", &history_list)) 1366 return -1; 1367 return static_cast<int>(history_list->GetSize()); 1368 } 1369 1370#if defined(FULL_SAFE_BROWSING) 1371 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() { 1372 return safe_browsing_factory_->most_recent_service()-> 1373 fake_database_manager(); 1374 } 1375#endif 1376 1377 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const { 1378 PrerenderManager::PrerenderData* prerender_data = 1379 GetPrerenderManager()->FindPrerenderData(url, NULL); 1380 return static_cast<TestPrerenderContents*>( 1381 prerender_data ? prerender_data->contents() : NULL); 1382 } 1383 1384 void SetLoaderHostOverride(const std::string& host) { 1385 loader_host_override_ = host; 1386 host_resolver()->AddRule(host, "127.0.0.1"); 1387 } 1388 1389 void set_loader_path(const std::string& path) { 1390 loader_path_ = path; 1391 } 1392 1393 void set_loader_query(const std::string& query) { 1394 loader_query_ = query; 1395 } 1396 1397 GURL GetCrossDomainTestUrl(const std::string& path) { 1398 static const std::string secondary_domain = "www.foo.com"; 1399 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); 1400 std::string url_str(base::StringPrintf( 1401 "http://%s:%d/%s", 1402 secondary_domain.c_str(), 1403 test_server()->host_port_pair().port(), 1404 path.c_str())); 1405 return GURL(url_str); 1406 } 1407 1408 void set_browser(Browser* browser) { 1409 explicitly_set_browser_ = browser; 1410 } 1411 1412 Browser* current_browser() const { 1413 return explicitly_set_browser_ ? explicitly_set_browser_ : browser(); 1414 } 1415 1416 const GURL& dest_url() const { 1417 return dest_url_; 1418 } 1419 1420 void IncreasePrerenderMemory() { 1421 // Increase the memory allowed in a prerendered page above normal settings. 1422 // Debug build bots occasionally run against the default limit, and tests 1423 // were failing because the prerender was canceled due to memory exhaustion. 1424 // http://crbug.com/93076 1425 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024; 1426 } 1427 1428 bool DidPrerenderPass(WebContents* web_contents) const { 1429 bool prerender_test_result = false; 1430 if (!content::ExecuteScriptAndExtractBool( 1431 web_contents, 1432 "window.domAutomationController.send(DidPrerenderPass())", 1433 &prerender_test_result)) 1434 return false; 1435 return prerender_test_result; 1436 } 1437 1438 bool DidDisplayPass(WebContents* web_contents) const { 1439 bool display_test_result = false; 1440 if (!content::ExecuteScriptAndExtractBool( 1441 web_contents, 1442 "window.domAutomationController.send(DidDisplayPass())", 1443 &display_test_result)) 1444 return false; 1445 return display_test_result; 1446 } 1447 1448 scoped_ptr<TestPrerender> ExpectPrerender(FinalStatus expected_final_status) { 1449 return prerender_contents_factory_->ExpectPrerenderContents( 1450 expected_final_status); 1451 } 1452 1453 void AddPrerender(const GURL& url, int index) { 1454 std::string javascript = base::StringPrintf( 1455 "AddPrerender('%s', %d)", url.spec().c_str(), index); 1456 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame(); 1457 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); 1458 } 1459 1460 // Returns a string for pattern-matching TaskManager tab entries. 1461 base::string16 MatchTaskManagerTab(const char* page_title) { 1462 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, 1463 base::ASCIIToUTF16(page_title)); 1464 } 1465 1466 // Returns a string for pattern-matching TaskManager prerender entries. 1467 base::string16 MatchTaskManagerPrerender(const char* page_title) { 1468 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX, 1469 base::ASCIIToUTF16(page_title)); 1470 } 1471 1472 protected: 1473 bool autostart_test_server_; 1474 1475 private: 1476 // TODO(davidben): Remove this altogether so the tests don't globally assume 1477 // only one prerender. 1478 TestPrerenderContents* GetPrerenderContents() const { 1479 return GetPrerenderContentsFor(dest_url_); 1480 } 1481 1482 ScopedVector<TestPrerender> PrerenderTestURLImpl( 1483 const GURL& prerender_url, 1484 const std::vector<FinalStatus>& expected_final_status_queue, 1485 int expected_number_of_loads) { 1486 dest_url_ = prerender_url; 1487 1488 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 1489 replacement_text.push_back( 1490 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec())); 1491 std::string replacement_path; 1492 CHECK(net::SpawnedTestServer::GetFilePathWithReplacements( 1493 loader_path_, 1494 replacement_text, 1495 &replacement_path)); 1496 1497 const net::SpawnedTestServer* src_server = test_server(); 1498 if (https_src_server_) 1499 src_server = https_src_server_.get(); 1500 GURL loader_url = src_server->GetURL( 1501 replacement_path + "&" + loader_query_); 1502 1503 GURL::Replacements loader_replacements; 1504 if (!loader_host_override_.empty()) 1505 loader_replacements.SetHostStr(loader_host_override_); 1506 loader_url = loader_url.ReplaceComponents(loader_replacements); 1507 1508 VLOG(1) << "Running test with queue length " << 1509 expected_final_status_queue.size(); 1510 CHECK(!expected_final_status_queue.empty()); 1511 ScopedVector<TestPrerender> prerenders; 1512 for (size_t i = 0; i < expected_final_status_queue.size(); i++) { 1513 prerenders.push_back( 1514 prerender_contents_factory_->ExpectPrerenderContents( 1515 expected_final_status_queue[i]).release()); 1516 } 1517 1518 FinalStatus expected_final_status = expected_final_status_queue.front(); 1519 1520 // Navigate to the loader URL and then wait for the first prerender to be 1521 // created. 1522 ui_test_utils::NavigateToURL(current_browser(), loader_url); 1523 prerenders[0]->WaitForCreate(); 1524 prerenders[0]->WaitForLoads(expected_number_of_loads); 1525 1526 if (ShouldAbortPrerenderBeforeSwap(expected_final_status)) { 1527 // The prerender will abort on its own. Assert it does so correctly. 1528 prerenders[0]->WaitForStop(); 1529 EXPECT_FALSE(prerenders[0]->contents()); 1530 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0)); 1531 } else { 1532 // Otherwise, check that it prerendered correctly. 1533 TestPrerenderContents* prerender_contents = prerenders[0]->contents(); 1534 1535 CHECK_NE(static_cast<PrerenderContents*>(NULL), prerender_contents); 1536 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); 1537 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1538 1539 if (call_javascript_) { 1540 // Check if page behaves as expected while in prerendered state. 1541 EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents())); 1542 } 1543 } 1544 1545 // Test that the referring page received the right start and load events. 1546 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1547 if (check_load_events_) { 1548 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads()); 1549 EXPECT_EQ(expected_number_of_loads, 1550 GetPrerenderLoadEventCountForLinkNumber(0)); 1551 } 1552 EXPECT_FALSE(HadPrerenderEventErrors()); 1553 1554 return prerenders.Pass(); 1555 } 1556 1557 void NavigateToURLImpl(const content::OpenURLParams& params, 1558 bool expect_swap_to_succeed) const { 1559 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager()); 1560 // Make sure in navigating we have a URL to use in the PrerenderManager. 1561 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents()); 1562 1563 WebContents* web_contents = GetPrerenderContents()->prerender_contents(); 1564 1565 // Navigate and wait for either the load to finish normally or for a swap to 1566 // occur. 1567 // TODO(davidben): The only handles CURRENT_TAB navigations, which is the 1568 // only case tested or prerendered right now. 1569 CHECK_EQ(CURRENT_TAB, params.disposition); 1570 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(), 1571 GetActiveWebContents()); 1572 WebContents* target_web_contents = current_browser()->OpenURL(params); 1573 swap_observer.Wait(); 1574 1575 if (web_contents && expect_swap_to_succeed) { 1576 EXPECT_EQ(web_contents, target_web_contents); 1577 if (call_javascript_) 1578 EXPECT_TRUE(DidDisplayPass(web_contents)); 1579 } 1580 } 1581 1582 // Opens the prerendered page using javascript functions in the loader 1583 // page. |javascript_function_name| should be a 0 argument function which is 1584 // invoked. |new_web_contents| is true if the navigation is expected to 1585 // happen in a new WebContents via OpenURL. 1586 void OpenURLWithJSImpl(const std::string& javascript_function_name, 1587 const GURL& url, 1588 const GURL& ping_url, 1589 bool new_web_contents) const { 1590 WebContents* web_contents = GetActiveWebContents(); 1591 RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); 1592 // Extra arguments in JS are ignored. 1593 std::string javascript = base::StringPrintf( 1594 "%s('%s', '%s')", javascript_function_name.c_str(), 1595 url.spec().c_str(), ping_url.spec().c_str()); 1596 1597 if (new_web_contents) { 1598 NewTabNavigationOrSwapObserver observer; 1599 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); 1600 observer.Wait(); 1601 } else { 1602 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(), 1603 web_contents); 1604 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript)); 1605 observer.Wait(); 1606 } 1607 } 1608 1609 TestPrerenderContentsFactory* prerender_contents_factory_; 1610#if defined(FULL_SAFE_BROWSING) 1611 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_; 1612#endif 1613 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_; 1614 GURL dest_url_; 1615 scoped_ptr<net::SpawnedTestServer> https_src_server_; 1616 bool call_javascript_; 1617 bool check_load_events_; 1618 std::string loader_host_override_; 1619 std::string loader_path_; 1620 std::string loader_query_; 1621 Browser* explicitly_set_browser_; 1622}; 1623 1624// Checks that a page is correctly prerendered in the case of a 1625// <link rel=prerender> tag and then loaded into a tab in response to a 1626// navigation. 1627IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) { 1628 UMAHistogramHelper histograms; 1629 1630 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 1631 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0)); 1632 histograms.Fetch(); 1633 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 1634 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 1635 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 1636 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1); 1637 1638 ChannelDestructionWatcher channel_close_watcher; 1639 channel_close_watcher.WatchChannel( 1640 GetActiveWebContents()->GetRenderProcessHost()); 1641 NavigateToDestURL(); 1642 channel_close_watcher.WaitForChannelClose(); 1643 1644 histograms.Fetch(); 1645 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1); 1646 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1); 1647 histograms.ExpectTotalCount( 1648 "Prerender.websame_PerceivedPLTMatchedComplete", 1); 1649 1650 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1651} 1652 1653// Checks that cross-domain prerenders emit the correct histograms. 1654IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageCrossDomain) { 1655 UMAHistogramHelper histograms; 1656 1657 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"), 1658 FINAL_STATUS_USED, 1); 1659 histograms.Fetch(); 1660 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 1661 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 1662 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 1663 histograms.ExpectTotalCount("Prerender.webcross_PrerenderNotSwappedInPLT", 1); 1664 1665 NavigateToDestURL(); 1666 histograms.Fetch(); 1667 histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLT", 1); 1668 histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLTMatched", 1); 1669 histograms.ExpectTotalCount( 1670 "Prerender.webcross_PerceivedPLTMatchedComplete", 1); 1671} 1672 1673// Checks that pending prerenders launch and receive proper event treatment. 1674IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPagePending) { 1675 scoped_ptr<TestPrerender> prerender = 1676 PrerenderTestURL("files/prerender/prerender_page_pending.html", 1677 FINAL_STATUS_USED, 1); 1678 1679 // Navigate to the prerender. 1680 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED); 1681 NavigateToDestURL(); 1682 // Abort early if the original prerender didn't swap, so as not to hang. 1683 ASSERT_FALSE(prerender->contents()); 1684 1685 // Wait for the new prerender to be ready. 1686 prerender2->WaitForStart(); 1687 prerender2->WaitForLoads(1); 1688 1689 const GURL prerender_page_url = 1690 test_server()->GetURL("files/prerender/prerender_page.html"); 1691 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1692 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL), 1693 GetPrerenderContentsFor(prerender_page_url)); 1694 1695 // Now navigate to our target page. 1696 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(), 1697 GetActiveWebContents()); 1698 ui_test_utils::NavigateToURLWithDisposition( 1699 current_browser(), prerender_page_url, CURRENT_TAB, 1700 ui_test_utils::BROWSER_TEST_NONE); 1701 swap_observer.Wait(); 1702 1703 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1704} 1705 1706// Checks that pending prerenders which are canceled before they are launched 1707// never get started. 1708IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) { 1709 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html", 1710 FINAL_STATUS_USED, 1); 1711 1712 ChannelDestructionWatcher channel_close_watcher; 1713 channel_close_watcher.WatchChannel( 1714 GetActiveWebContents()->GetRenderProcessHost()); 1715 NavigateToDestURL(); 1716 channel_close_watcher.WaitForChannelClose(); 1717 1718 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1)); 1719 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1720 EXPECT_FALSE(HadPrerenderEventErrors()); 1721 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1722 // calls did a thread/process hop to the renderer which insured pending 1723 // renderer events have arrived. 1724 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 1725} 1726 1727IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovingLink) { 1728 scoped_ptr<TestPrerender> prerender = 1729 PrerenderTestURL("files/prerender/prerender_page.html", 1730 FINAL_STATUS_CANCELLED, 1); 1731 1732 // No ChannelDestructionWatcher is needed here, since prerenders in the 1733 // PrerenderLinkManager should be deleted by removing the links, rather than 1734 // shutting down the renderer process. 1735 RemoveLinkElement(0); 1736 prerender->WaitForStop(); 1737 1738 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1739 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1740 EXPECT_FALSE(HadPrerenderEventErrors()); 1741 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1742 // calls did a thread/process hop to the renderer which insured pending 1743 // renderer events have arrived. 1744 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1745} 1746 1747IN_PROC_BROWSER_TEST_F( 1748 PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinks) { 1749 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1750 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1751 1752 set_loader_query("links_to_insert=2"); 1753 scoped_ptr<TestPrerender> prerender = 1754 PrerenderTestURL("files/prerender/prerender_page.html", 1755 FINAL_STATUS_CANCELLED, 1); 1756 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1757 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1758 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1759 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1760 1761 RemoveLinkElement(0); 1762 RemoveLinkElement(1); 1763 prerender->WaitForStop(); 1764 1765 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1766 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1767 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1768 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1769 EXPECT_FALSE(HadPrerenderEventErrors()); 1770 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1771 // calls did a thread/process hop to the renderer which insured pending 1772 // renderer events have arrived. 1773 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1774} 1775 1776IN_PROC_BROWSER_TEST_F( 1777 PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinksOneLate) { 1778 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1779 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1780 1781 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 1782 scoped_ptr<TestPrerender> prerender = 1783 PrerenderTestURL(url, FINAL_STATUS_CANCELLED, 1); 1784 1785 // Add a second prerender for the same link. It reuses the prerender, so only 1786 // the start event fires here. 1787 AddPrerender(url, 1); 1788 WaitForPrerenderEventCount(1, "webkitprerenderstart", 1); 1789 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1790 EXPECT_EQ(0, GetPrerenderLoadEventCountForLinkNumber(1)); 1791 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1792 1793 RemoveLinkElement(0); 1794 RemoveLinkElement(1); 1795 prerender->WaitForStop(); 1796 1797 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1798 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1799 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1800 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1801 EXPECT_FALSE(HadPrerenderEventErrors()); 1802 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1803 // calls did a thread/process hop to the renderer which insured pending 1804 // renderer events have arrived. 1805 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1806} 1807 1808IN_PROC_BROWSER_TEST_F( 1809 PrerenderBrowserTest, 1810 PrerenderPageRemovingLinkWithTwoLinksRemovingOne) { 1811 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 1812 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 1813 set_loader_query("links_to_insert=2"); 1814 PrerenderTestURL("files/prerender/prerender_page.html", 1815 FINAL_STATUS_USED, 1); 1816 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1817 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1818 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1819 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1820 1821 RemoveLinkElement(0); 1822 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 1823 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0)); 1824 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1)); 1825 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1)); 1826 EXPECT_FALSE(HadPrerenderEventErrors()); 1827 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive* 1828 // calls did a thread/process hop to the renderer which insured pending 1829 // renderer events have arrived. 1830 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1831 1832 ChannelDestructionWatcher channel_close_watcher; 1833 channel_close_watcher.WatchChannel( 1834 GetActiveWebContents()->GetRenderProcessHost()); 1835 NavigateToDestURL(); 1836 channel_close_watcher.WaitForChannelClose(); 1837 1838 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1839} 1840 1841// Checks that the visibility API works. 1842IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) { 1843 PrerenderTestURL("files/prerender/prerender_visibility.html", 1844 FINAL_STATUS_USED, 1845 1); 1846 NavigateToDestURL(); 1847} 1848 1849// Checks that the prerendering of a page is canceled correctly if we try to 1850// swap it in before it commits. 1851IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) { 1852 // Navigate to a page that triggers a prerender for a URL that never commits. 1853 const GURL kNoCommitUrl("http://never-respond.example.com"); 1854 base::FilePath file(GetTestPath("prerender_page.html")); 1855 1856 base::RunLoop prerender_start_loop; 1857 BrowserThread::PostTask( 1858 BrowserThread::IO, FROM_HERE, 1859 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, 1860 kNoCommitUrl, file, prerender_start_loop.QuitClosure())); 1861 DisableJavascriptCalls(); 1862 PrerenderTestURL(kNoCommitUrl, 1863 FINAL_STATUS_NAVIGATION_UNCOMMITTED, 1864 0); 1865 // Wait for the hanging request to be scheduled. 1866 prerender_start_loop.Run(); 1867 1868 // Navigate to the URL, but assume the contents won't be swapped in. 1869 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 1870} 1871 1872// Checks that client redirects don't add alias URLs until after they commit. 1873IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) { 1874 // Navigate to a page that then navigates to a URL that never commits. 1875 const GURL kNoCommitUrl("http://never-respond.example.com"); 1876 base::FilePath file(GetTestPath("prerender_page.html")); 1877 1878 base::RunLoop prerender_start_loop; 1879 BrowserThread::PostTask( 1880 BrowserThread::IO, FROM_HERE, 1881 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, 1882 kNoCommitUrl, file, prerender_start_loop.QuitClosure())); 1883 DisableJavascriptCalls(); 1884 PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()), 1885 FINAL_STATUS_APP_TERMINATING, 1); 1886 // Wait for the hanging request to be scheduled. 1887 prerender_start_loop.Run(); 1888 1889 // Navigating to the second URL should not swap. 1890 NavigateToURLWithDisposition(kNoCommitUrl, CURRENT_TAB, false); 1891} 1892 1893// Checks that the prerendering of a page is canceled correctly when a 1894// Javascript alert is called. 1895IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { 1896 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 1897 FINAL_STATUS_JAVASCRIPT_ALERT, 1898 0); 1899} 1900 1901// Checks that the prerendering of a page is canceled correctly when a 1902// Javascript alert is called. 1903IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) { 1904 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html", 1905 FINAL_STATUS_JAVASCRIPT_ALERT, 1906 1); 1907} 1908 1909// Checks that plugins are not loaded while a page is being preloaded, but 1910// are loaded when the page is displayed. 1911#if defined(USE_AURA) && !defined(OS_WIN) 1912// http://crbug.com/103496 1913#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1914#elif defined(OS_MACOSX) 1915// http://crbug.com/100514 1916#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1917#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1918// TODO(jschuh): Failing plugin tests. crbug.com/244653 1919#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1920#elif defined(OS_LINUX) 1921// http://crbug.com/306715 1922#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin 1923#else 1924#define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin 1925#endif 1926// http://crbug.com/306715 1927IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) { 1928 PrerenderTestURL("files/prerender/plugin_delay_load.html", 1929 FINAL_STATUS_USED, 1930 1); 1931 NavigateToDestURL(); 1932} 1933 1934// Checks that plugins are not loaded on prerendering pages when click-to-play 1935// is enabled. 1936IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) { 1937 // Enable click-to-play. 1938 HostContentSettingsMap* content_settings_map = 1939 current_browser()->profile()->GetHostContentSettingsMap(); 1940 content_settings_map->SetDefaultContentSetting( 1941 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK); 1942 1943 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html", 1944 FINAL_STATUS_USED, 1945 1); 1946 NavigateToDestURL(); 1947} 1948 1949// Checks that we don't load a NaCl plugin when NaCl is disabled. 1950IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) { 1951 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html", 1952 FINAL_STATUS_USED, 1953 1); 1954 NavigateToDestURL(); 1955 1956 1957 // Run this check again. When we try to load aa ppapi plugin, the 1958 // "loadstart" event is asynchronously posted to a message loop. 1959 // It's possible that earlier call could have been run before the 1960 // the "loadstart" event was posted. 1961 // TODO(mmenke): While this should reliably fail on regressions, the 1962 // reliability depends on the specifics of ppapi plugin 1963 // loading. It would be great if we could avoid that. 1964 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 1965} 1966 1967// Checks that plugins in an iframe are not loaded while a page is 1968// being preloaded, but are loaded when the page is displayed. 1969#if defined(USE_AURA) && !defined(OS_WIN) 1970// http://crbug.com/103496 1971#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1972 DISABLED_PrerenderIframeDelayLoadPlugin 1973#elif defined(OS_MACOSX) 1974// http://crbug.com/100514 1975#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1976 DISABLED_PrerenderIframeDelayLoadPlugin 1977#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 1978// TODO(jschuh): Failing plugin tests. crbug.com/244653 1979#define MAYBE_PrerenderIframeDelayLoadPlugin \ 1980 DISABLED_PrerenderIframeDelayLoadPlugin 1981#else 1982#define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin 1983#endif 1984IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 1985 MAYBE_PrerenderIframeDelayLoadPlugin) { 1986 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html", 1987 FINAL_STATUS_USED, 1988 1); 1989 NavigateToDestURL(); 1990} 1991 1992// Renders a page that contains a prerender link to a page that contains an 1993// iframe with a source that requires http authentication. This should not 1994// prerender successfully. 1995IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) { 1996 PrerenderTestURL("files/prerender/prerender_http_auth_container.html", 1997 FINAL_STATUS_AUTH_NEEDED, 1998 0); 1999} 2000 2001// Checks that client-issued redirects work with prerendering. 2002// This version navigates to the page which issues the redirection, rather 2003// than the final destination page. 2004IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2005 PrerenderClientRedirectNavigateToFirst) { 2006 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 2007 FINAL_STATUS_USED, 2008 2); 2009 NavigateToDestURL(); 2010} 2011 2012// Checks that client-issued redirects work with prerendering. 2013// This version navigates to the final destination page, rather than the 2014// page which does the redirection. 2015IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2016 PrerenderClientRedirectNavigateToSecond) { 2017 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 2018 FINAL_STATUS_USED, 2019 2); 2020 NavigateToURL("files/prerender/prerender_page.html"); 2021} 2022 2023// Checks that redirects with location.replace do not cancel a prerender and 2024// and swap when navigating to the first page. 2025IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2026 PrerenderLocationReplaceNavigateToFirst) { 2027 PrerenderTestURL("files/prerender/prerender_location_replace.html", 2028 FINAL_STATUS_USED, 2029 2); 2030 NavigateToDestURL(); 2031} 2032 2033// Checks that redirects with location.replace do not cancel a prerender and 2034// and swap when navigating to the second. 2035IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2036 PrerenderLocationReplaceNavigateToSecond) { 2037 PrerenderTestURL("files/prerender/prerender_location_replace.html", 2038 FINAL_STATUS_USED, 2039 2); 2040 NavigateToURL("files/prerender/prerender_page.html"); 2041} 2042 2043// Checks that we get the right PPLT histograms for client redirect prerenders 2044// and navigations when the referring page is Google. 2045IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2046 PrerenderLocationReplaceGWSHistograms) { 2047 DisableJavascriptCalls(); 2048 UMAHistogramHelper histograms; 2049 2050 // The loader page should look like Google. 2051 const std::string kGoogleDotCom("www.google.com"); 2052 SetLoaderHostOverride(kGoogleDotCom); 2053 set_loader_path("files/prerender/prerender_loader_with_replace_state.html"); 2054 2055 GURL dest_url = GetCrossDomainTestUrl( 2056 "files/prerender/prerender_deferred_image.html"); 2057 2058 GURL prerender_url = test_server()->GetURL( 2059 "files/prerender/prerender_location_replace.html?" + 2060 net::EscapeQueryParamValue(dest_url.spec(), false) + 2061 "#prerender"); 2062 GURL::Replacements replacements; 2063 replacements.SetHostStr(kGoogleDotCom); 2064 prerender_url = prerender_url.ReplaceComponents(replacements); 2065 2066 // The prerender will not completely load until after the swap, so wait for a 2067 // title change before calling DidPrerenderPass. 2068 scoped_ptr<TestPrerender> prerender = 2069 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1); 2070 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle); 2071 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents())); 2072 EXPECT_EQ(1, prerender->number_of_loads()); 2073 2074 histograms.Fetch(); 2075 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 2076 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 2077 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 2078 // Although there is a client redirect, it is dropped from histograms because 2079 // it is a Google URL. The target page itself does not load until after the 2080 // swap. 2081 histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0); 2082 2083 GURL navigate_url = test_server()->GetURL( 2084 "files/prerender/prerender_location_replace.html?" + 2085 net::EscapeQueryParamValue(dest_url.spec(), false) + 2086 "#navigate"); 2087 navigate_url = navigate_url.ReplaceComponents(replacements); 2088 2089 NavigationOrSwapObserver swap_observer( 2090 current_browser()->tab_strip_model(), 2091 GetActiveWebContents(), 2); 2092 current_browser()->OpenURL(OpenURLParams( 2093 navigate_url, Referrer(), CURRENT_TAB, 2094 content::PAGE_TRANSITION_TYPED, false)); 2095 swap_observer.Wait(); 2096 2097 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 2098 2099 histograms.Fetch(); 2100 histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0); 2101 histograms.ExpectTotalCount("Prerender.gws_PerceivedPLT", 1); 2102 histograms.ExpectTotalCount("Prerender.gws_PerceivedPLTMatched", 1); 2103 histograms.ExpectTotalCount( 2104 "Prerender.gws_PerceivedPLTMatchedComplete", 1); 2105 2106 // The client redirect does /not/ count as a miss because it's a Google URL. 2107 histograms.ExpectTotalCount("Prerender.PerceivedPLTFirstAfterMiss", 0); 2108} 2109 2110// Checks that client-issued redirects work with prerendering. 2111// This version navigates to the final destination page, rather than the 2112// page which does the redirection via a mouse click. 2113IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2114 PrerenderClientRedirectNavigateToSecondViaClick) { 2115 GURL prerender_url = test_server()->GetURL( 2116 CreateClientRedirect("files/prerender/prerender_page.html")); 2117 GURL destination_url = test_server()->GetURL( 2118 "files/prerender/prerender_page.html"); 2119 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 2); 2120 OpenURLViaClick(destination_url); 2121} 2122 2123// Checks that a page served over HTTPS is correctly prerendered. 2124IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) { 2125 net::SpawnedTestServer https_server( 2126 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 2127 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2128 ASSERT_TRUE(https_server.Start()); 2129 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2130 PrerenderTestURL(https_url, 2131 FINAL_STATUS_USED, 2132 1); 2133 NavigateToDestURL(); 2134} 2135 2136// Checks that client-issued redirects within an iframe in a prerendered 2137// page will not count as an "alias" for the prerendered page. 2138IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2139 PrerenderClientRedirectInIframe) { 2140 std::string redirect_path = CreateClientRedirect( 2141 "/files/prerender/prerender_embedded_content.html"); 2142 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2143 replacement_text.push_back( 2144 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 2145 std::string replacement_path; 2146 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2147 "files/prerender/prerender_with_iframe.html", 2148 replacement_text, 2149 &replacement_path)); 2150 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2); 2151 EXPECT_FALSE(UrlIsInPrerenderManager( 2152 "files/prerender/prerender_embedded_content.html")); 2153 NavigateToDestURL(); 2154} 2155 2156// Checks that server-issued redirects work with prerendering. 2157// This version navigates to the page which issues the redirection, rather 2158// than the final destination page. 2159IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2160 PrerenderServerRedirectNavigateToFirst) { 2161 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 2162 FINAL_STATUS_USED, 2163 1); 2164 NavigateToDestURL(); 2165} 2166 2167// Checks that server-issued redirects work with prerendering. 2168// This version navigates to the final destination page, rather than the 2169// page which does the redirection. 2170IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2171 PrerenderServerRedirectNavigateToSecond) { 2172 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 2173 FINAL_STATUS_USED, 2174 1); 2175 NavigateToURL("files/prerender/prerender_page.html"); 2176} 2177 2178// Checks that server-issued redirects work with prerendering. 2179// This version navigates to the final destination page, rather than the 2180// page which does the redirection via a mouse click. 2181IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2182 PrerenderServerRedirectNavigateToSecondViaClick) { 2183 GURL prerender_url = test_server()->GetURL( 2184 CreateServerRedirect("files/prerender/prerender_page.html")); 2185 GURL destination_url = test_server()->GetURL( 2186 "files/prerender/prerender_page.html"); 2187 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1); 2188 OpenURLViaClick(destination_url); 2189} 2190 2191// Checks that server-issued redirects within an iframe in a prerendered 2192// page will not count as an "alias" for the prerendered page. 2193IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) { 2194 std::string redirect_path = CreateServerRedirect( 2195 "/files/prerender/prerender_embedded_content.html"); 2196 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2197 replacement_text.push_back( 2198 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path)); 2199 std::string replacement_path; 2200 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2201 "files/prerender/prerender_with_iframe.html", 2202 replacement_text, 2203 &replacement_path)); 2204 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2205 EXPECT_FALSE(UrlIsInPrerenderManager( 2206 "files/prerender/prerender_embedded_content.html")); 2207 NavigateToDestURL(); 2208} 2209 2210// Prerenders a page that contains an automatic download triggered through an 2211// iframe. This should not prerender successfully. 2212IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) { 2213 PrerenderTestURL("files/prerender/prerender_download_iframe.html", 2214 FINAL_STATUS_DOWNLOAD, 2215 0); 2216} 2217 2218// Prerenders a page that contains an automatic download triggered through 2219// Javascript changing the window.location. This should not prerender 2220// successfully 2221IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) { 2222 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"), 2223 FINAL_STATUS_DOWNLOAD, 2224 1); 2225} 2226 2227// Prerenders a page that contains an automatic download triggered through a 2228// client-issued redirect. This should not prerender successfully. 2229IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) { 2230 PrerenderTestURL("files/prerender/prerender_download_refresh.html", 2231 FINAL_STATUS_DOWNLOAD, 2232 1); 2233} 2234 2235// Checks that the referrer is set when prerendering. 2236IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) { 2237 PrerenderTestURL("files/prerender/prerender_referrer.html", 2238 FINAL_STATUS_USED, 2239 1); 2240 NavigateToDestURL(); 2241} 2242 2243// Checks that the referrer is not set when prerendering and the source page is 2244// HTTPS. 2245IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2246 PrerenderNoSSLReferrer) { 2247 UseHttpsSrcServer(); 2248 PrerenderTestURL("files/prerender/prerender_no_referrer.html", 2249 FINAL_STATUS_USED, 2250 1); 2251 NavigateToDestURL(); 2252} 2253 2254// Checks that the referrer is set when prerendering is cancelled. 2255IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrer) { 2256 scoped_ptr<TestContentBrowserClient> test_content_browser_client( 2257 new TestContentBrowserClient); 2258 content::ContentBrowserClient* original_browser_client = 2259 content::SetBrowserClientForTesting(test_content_browser_client.get()); 2260 2261 PrerenderTestURL("files/prerender/prerender_referrer.html", 2262 FINAL_STATUS_CANCELLED, 2263 1); 2264 OpenDestURLViaClick(); 2265 2266 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 2267 2268 content::SetBrowserClientForTesting(original_browser_client); 2269} 2270 2271// Checks that popups on a prerendered page cause cancellation. 2272IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) { 2273 PrerenderTestURL("files/prerender/prerender_popup.html", 2274 FINAL_STATUS_CREATE_NEW_WINDOW, 2275 0); 2276} 2277 2278// Checks that registering a protocol handler causes cancellation. 2279IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) { 2280 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html", 2281 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER, 2282 0); 2283} 2284 2285// Checks that renderers using excessive memory will be terminated. 2286IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) { 2287 ASSERT_TRUE(GetPrerenderManager()); 2288 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024; 2289 // The excessive memory kill may happen before or after the load event as it 2290 // happens asynchronously with IPC calls. Even if the test does not start 2291 // allocating until after load, the browser process might notice before the 2292 // message gets through. This happens on XP debug bots because they're so 2293 // slow. Instead, don't bother checking the load event count. 2294 DisableLoadEventCheck(); 2295 PrerenderTestURL("files/prerender/prerender_excessive_memory.html", 2296 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 0); 2297} 2298 2299// Checks shutdown code while a prerender is active. 2300IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) { 2301 DisableJavascriptCalls(); 2302 DisableLoadEventCheck(); 2303 PrerenderTestURL("files/prerender/prerender_page.html", 2304 FINAL_STATUS_APP_TERMINATING, 2305 0); 2306} 2307 2308// Checks that we don't prerender in an infinite loop. 2309IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) { 2310 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html"; 2311 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html"; 2312 2313 std::vector<FinalStatus> expected_final_status_queue; 2314 expected_final_status_queue.push_back(FINAL_STATUS_USED); 2315 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 2316 2317 ScopedVector<TestPrerender> prerenders = 2318 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 2319 ASSERT_TRUE(prerenders[0]->contents()); 2320 // Assert that the pending prerender is in there already. This relies on the 2321 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending 2322 // the page load one. 2323 EXPECT_EQ(2U, GetLinkPrerenderCount()); 2324 EXPECT_EQ(1U, GetRunningLinkPrerenderCount()); 2325 2326 // Next url should be in pending list but not an active entry. 2327 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 2328 2329 NavigateToDestURL(); 2330 2331 // Make sure the PrerenderContents for the next url is now in the manager and 2332 // not pending. This relies on pending prerenders being resolved in the same 2333 // event loop iteration as OnPrerenderStop. 2334 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB)); 2335 EXPECT_EQ(1U, GetLinkPrerenderCount()); 2336 EXPECT_EQ(1U, GetRunningLinkPrerenderCount()); 2337} 2338 2339// Checks that we don't prerender in an infinite loop and multiple links are 2340// handled correctly. 2341IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2342 PrerenderInfiniteLoopMultiple) { 2343 const char* const kHtmlFileA = 2344 "files/prerender/prerender_infinite_a_multiple.html"; 2345 const char* const kHtmlFileB = 2346 "files/prerender/prerender_infinite_b_multiple.html"; 2347 const char* const kHtmlFileC = 2348 "files/prerender/prerender_infinite_c_multiple.html"; 2349 2350 // This test is conceptually simplest if concurrency is at two, since we 2351 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted. 2352 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 2353 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 2354 2355 std::vector<FinalStatus> expected_final_status_queue; 2356 expected_final_status_queue.push_back(FINAL_STATUS_USED); 2357 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 2358 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING); 2359 2360 ScopedVector<TestPrerender> prerenders = 2361 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1); 2362 ASSERT_TRUE(prerenders[0]->contents()); 2363 2364 // Next url should be in pending list but not an active entry. This relies on 2365 // the fact that the renderer sends out the AddLinkRelPrerender IPC before 2366 // sending the page load one. 2367 EXPECT_EQ(3U, GetLinkPrerenderCount()); 2368 EXPECT_EQ(1U, GetRunningLinkPrerenderCount()); 2369 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 2370 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC)); 2371 2372 NavigateToDestURL(); 2373 2374 // Make sure the PrerenderContents for the next urls are now in the manager 2375 // and not pending. One and only one of the URLs (the last seen) should be the 2376 // active entry. This relies on pending prerenders being resolved in the same 2377 // event loop iteration as OnPrerenderStop. 2378 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB); 2379 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC); 2380 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender); 2381 EXPECT_EQ(2U, GetLinkPrerenderCount()); 2382 EXPECT_EQ(2U, GetRunningLinkPrerenderCount()); 2383} 2384 2385// Checks that pending prerenders are aborted (and never launched) when launched 2386// by a prerender that itself gets aborted. 2387IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) { 2388 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html"; 2389 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html"; 2390 2391 scoped_ptr<TestPrerender> prerender = 2392 PrerenderTestURL(kHtmlFileA, FINAL_STATUS_CANCELLED, 1); 2393 ASSERT_TRUE(prerender->contents()); 2394 // Assert that the pending prerender is in there already. This relies on the 2395 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending 2396 // the page load one. 2397 EXPECT_EQ(2U, GetLinkPrerenderCount()); 2398 EXPECT_EQ(1U, GetRunningLinkPrerenderCount()); 2399 2400 // Next url should be in pending list but not an active entry. 2401 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB)); 2402 2403 // Cancel the prerender. 2404 GetPrerenderManager()->CancelAllPrerenders(); 2405 prerender->WaitForStop(); 2406 2407 // All prerenders are now gone. 2408 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 2409} 2410 2411IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerBeforePrerender) { 2412 const base::string16 any_prerender = MatchTaskManagerPrerender("*"); 2413 const base::string16 any_tab = MatchTaskManagerTab("*"); 2414 const base::string16 original = MatchTaskManagerTab("Preloader"); 2415 const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page"); 2416 const base::string16 final = MatchTaskManagerTab("Prerender Page"); 2417 2418 // Show the task manager. This populates the model. 2419 chrome::OpenTaskManager(current_browser()); 2420 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2421 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); 2422 2423 // Prerender a page in addition to the original tab. 2424 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2425 2426 // A TaskManager entry should appear like "Prerender: Prerender Page" 2427 // alongside the original tab entry. There should be just these two entries. 2428 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender)); 2429 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original)); 2430 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final)); 2431 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender)); 2432 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2433 2434 // Swap in the prerendered content. 2435 NavigateToDestURL(); 2436 2437 // The "Prerender: " TaskManager entry should disappear, being replaced by a 2438 // "Tab: Prerender Page" entry, and nothing else. 2439 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender)); 2440 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original)); 2441 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final)); 2442 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2443 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); 2444} 2445 2446IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterPrerender) { 2447 const base::string16 any_prerender = MatchTaskManagerPrerender("*"); 2448 const base::string16 any_tab = MatchTaskManagerTab("*"); 2449 const base::string16 original = MatchTaskManagerTab("Preloader"); 2450 const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page"); 2451 const base::string16 final = MatchTaskManagerTab("Prerender Page"); 2452 2453 // Start with two resources. 2454 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2455 2456 // Show the task manager. This populates the model. Importantly, we're doing 2457 // this after the prerender WebContents already exists - the task manager 2458 // needs to find it, it can't just listen for creation. 2459 chrome::OpenTaskManager(current_browser()); 2460 2461 // A TaskManager entry should appear like "Prerender: Prerender Page" 2462 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender)); 2463 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original)); 2464 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final)); 2465 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender)); 2466 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2467 2468 // Swap in the tab. 2469 NavigateToDestURL(); 2470 2471 // The "Prerender: Prerender Page" TaskManager row should disappear, being 2472 // replaced by "Tab: Prerender Page" 2473 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender)); 2474 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original)); 2475 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final)); 2476 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2477 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); 2478} 2479 2480IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterSwapIn) { 2481 const base::string16 any_prerender = MatchTaskManagerPrerender("*"); 2482 const base::string16 any_tab = MatchTaskManagerTab("*"); 2483 const base::string16 final = MatchTaskManagerTab("Prerender Page"); 2484 2485 // Prerender, and swap it in. 2486 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 2487 NavigateToDestURL(); 2488 2489 // Show the task manager. This populates the model. Importantly, we're doing 2490 // this after the prerender has been swapped in. 2491 chrome::OpenTaskManager(current_browser()); 2492 2493 // We should not see a prerender resource in the task manager, just a normal 2494 // page. 2495 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final)); 2496 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); 2497 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); 2498} 2499 2500// Checks that audio loads are deferred on prerendering. 2501IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Audio) { 2502 PrerenderTestURL("files/prerender/prerender_html5_audio.html", 2503 FINAL_STATUS_USED, 2504 1); 2505 NavigateToDestURL(); 2506 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2507} 2508 2509// Checks that audio loads are deferred on prerendering and played back when 2510// the prerender is swapped in if autoplay is set. 2511IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioAutoplay) { 2512 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html", 2513 FINAL_STATUS_USED, 2514 1); 2515 NavigateToDestURL(); 2516 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2517} 2518 2519// Checks that audio loads are deferred on prerendering and played back when 2520// the prerender is swapped in if js starts playing. 2521IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioJsplay) { 2522 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html", 2523 FINAL_STATUS_USED, 2524 1); 2525 NavigateToDestURL(); 2526 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2527} 2528 2529// Checks that video loads are deferred on prerendering. 2530IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) { 2531 PrerenderTestURL("files/prerender/prerender_html5_video.html", 2532 FINAL_STATUS_USED, 2533 1); 2534 NavigateToDestURL(); 2535 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2536} 2537 2538// Checks that video tags inserted by javascript are deferred and played 2539// correctly on swap in. 2540IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) { 2541 PrerenderTestURL("files/prerender/prerender_html5_video_script.html", 2542 FINAL_STATUS_USED, 2543 1); 2544 NavigateToDestURL(); 2545 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2546} 2547 2548// Checks for correct network events by using a busy sleep the javascript. 2549IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoNetwork) { 2550 DisableJavascriptCalls(); 2551 scoped_ptr<TestPrerender> prerender = 2552 PrerenderTestURL("files/prerender/prerender_html5_video_network.html", 2553 FINAL_STATUS_USED, 2554 1); 2555 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle); 2556 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents())); 2557 NavigateToDestURL(); 2558 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 2559} 2560 2561// Checks that scripts can retrieve the correct window size while prerendering. 2562#if defined(TOOLKIT_VIEWS) 2563// TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363 2564IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) { 2565#else 2566IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) { 2567#endif 2568 PrerenderTestURL("files/prerender/prerender_size.html", 2569 FINAL_STATUS_USED, 2570 1); 2571 NavigateToDestURL(); 2572} 2573 2574// TODO(jam): http://crbug.com/350550 2575#if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER)) 2576 2577// Checks that prerenderers will terminate when the RenderView crashes. 2578IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRendererCrash) { 2579 scoped_ptr<TestPrerender> prerender = 2580 PrerenderTestURL("files/prerender/prerender_page.html", 2581 FINAL_STATUS_RENDERER_CRASHED, 2582 1); 2583 2584 // Navigate to about:crash and then wait for the renderer to crash. 2585 ASSERT_TRUE(prerender->contents()); 2586 ASSERT_TRUE(prerender->contents()->prerender_contents()); 2587 prerender->contents()->prerender_contents()->GetController(). 2588 LoadURL( 2589 GURL(content::kChromeUICrashURL), 2590 content::Referrer(), 2591 content::PAGE_TRANSITION_TYPED, 2592 std::string()); 2593 prerender->WaitForStop(); 2594} 2595#endif 2596 2597IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2598 PrerenderPageWithFragment) { 2599 PrerenderTestURL("files/prerender/prerender_page.html#fragment", 2600 FINAL_STATUS_USED, 2601 1); 2602 2603 ChannelDestructionWatcher channel_close_watcher; 2604 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2605 GetActiveWebContents()->GetRenderProcessHost()); 2606 NavigateToDestURL(); 2607 channel_close_watcher.WaitForChannelClose(); 2608 2609 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2610} 2611 2612IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2613 PrerenderPageWithRedirectedFragment) { 2614 PrerenderTestURL( 2615 CreateClientRedirect("files/prerender/prerender_page.html#fragment"), 2616 FINAL_STATUS_USED, 2617 2); 2618 2619 ChannelDestructionWatcher channel_close_watcher; 2620 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 2621 GetActiveWebContents()->GetRenderProcessHost()); 2622 NavigateToDestURL(); 2623 channel_close_watcher.WaitForChannelClose(); 2624 2625 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 2626} 2627 2628// Checks that we do not use a prerendered page when navigating from 2629// the main page to a fragment. 2630IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2631 PrerenderPageNavigateFragment) { 2632 PrerenderTestURL("files/prerender/no_prerender_page.html", 2633 FINAL_STATUS_APP_TERMINATING, 2634 1); 2635 NavigateToURLWithDisposition( 2636 "files/prerender/no_prerender_page.html#fragment", 2637 CURRENT_TAB, false); 2638} 2639 2640// Checks that we do not use a prerendered page when we prerender a fragment 2641// but navigate to the main page. 2642IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2643 PrerenderFragmentNavigatePage) { 2644 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment", 2645 FINAL_STATUS_APP_TERMINATING, 2646 1); 2647 NavigateToURLWithDisposition( 2648 "files/prerender/no_prerender_page.html", 2649 CURRENT_TAB, false); 2650} 2651 2652// Checks that we do not use a prerendered page when we prerender a fragment 2653// but navigate to a different fragment on the same page. 2654IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2655 PrerenderFragmentNavigateFragment) { 2656 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment", 2657 FINAL_STATUS_APP_TERMINATING, 2658 1); 2659 NavigateToURLWithDisposition( 2660 "files/prerender/no_prerender_page.html#fragment", 2661 CURRENT_TAB, false); 2662} 2663 2664// Checks that we do not use a prerendered page when the page uses a client 2665// redirect to refresh from a fragment on the same page. 2666IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2667 PrerenderClientRedirectFromFragment) { 2668 PrerenderTestURL( 2669 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"), 2670 FINAL_STATUS_APP_TERMINATING, 2671 2); 2672 NavigateToURLWithDisposition( 2673 "files/prerender/no_prerender_page.html", 2674 CURRENT_TAB, false); 2675} 2676 2677// Checks that we do not use a prerendered page when the page uses a client 2678// redirect to refresh to a fragment on the same page. 2679IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2680 PrerenderClientRedirectToFragment) { 2681 PrerenderTestURL( 2682 CreateClientRedirect("files/prerender/no_prerender_page.html"), 2683 FINAL_STATUS_APP_TERMINATING, 2684 2); 2685 NavigateToURLWithDisposition( 2686 "files/prerender/no_prerender_page.html#fragment", 2687 CURRENT_TAB, false); 2688} 2689 2690// Checks that we correctly use a prerendered page when the page uses JS to set 2691// the window.location.hash to a fragment on the same page. 2692IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2693 PrerenderPageChangeFragmentLocationHash) { 2694 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html", 2695 FINAL_STATUS_USED, 2696 1); 2697 NavigateToURL("files/prerender/prerender_fragment_location_hash.html"); 2698} 2699 2700// Checks that prerendering a PNG works correctly. 2701IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) { 2702 DisableJavascriptCalls(); 2703 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1); 2704 NavigateToDestURL(); 2705} 2706 2707// Checks that prerendering a JPG works correctly. 2708IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) { 2709 DisableJavascriptCalls(); 2710 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1); 2711 NavigateToDestURL(); 2712} 2713 2714// Checks that a prerender of a CRX will result in a cancellation due to 2715// download. 2716IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) { 2717 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 0); 2718} 2719 2720// Checks that xhr GET requests allow prerenders. 2721IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) { 2722 PrerenderTestURL("files/prerender/prerender_xhr_get.html", 2723 FINAL_STATUS_USED, 2724 1); 2725 NavigateToDestURL(); 2726} 2727 2728// Checks that xhr HEAD requests allow prerenders. 2729IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) { 2730 PrerenderTestURL("files/prerender/prerender_xhr_head.html", 2731 FINAL_STATUS_USED, 2732 1); 2733 NavigateToDestURL(); 2734} 2735 2736// Checks that xhr OPTIONS requests allow prerenders. 2737IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) { 2738 PrerenderTestURL("files/prerender/prerender_xhr_options.html", 2739 FINAL_STATUS_USED, 2740 1); 2741 NavigateToDestURL(); 2742} 2743 2744// Checks that xhr TRACE requests allow prerenders. 2745IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) { 2746 PrerenderTestURL("files/prerender/prerender_xhr_trace.html", 2747 FINAL_STATUS_USED, 2748 1); 2749 NavigateToDestURL(); 2750} 2751 2752// Checks that xhr POST requests allow prerenders. 2753IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) { 2754 PrerenderTestURL("files/prerender/prerender_xhr_post.html", 2755 FINAL_STATUS_USED, 2756 1); 2757 NavigateToDestURL(); 2758} 2759 2760// Checks that xhr PUT cancels prerenders. 2761IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) { 2762 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 2763 FINAL_STATUS_INVALID_HTTP_METHOD, 2764 1); 2765} 2766 2767// Checks that xhr DELETE cancels prerenders. 2768IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) { 2769 PrerenderTestURL("files/prerender/prerender_xhr_delete.html", 2770 FINAL_STATUS_INVALID_HTTP_METHOD, 2771 1); 2772} 2773 2774// Checks that a top-level page which would trigger an SSL error is canceled. 2775IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) { 2776 net::SpawnedTestServer::SSLOptions ssl_options; 2777 ssl_options.server_certificate = 2778 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2779 net::SpawnedTestServer https_server( 2780 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2781 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2782 ASSERT_TRUE(https_server.Start()); 2783 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2784 PrerenderTestURL(https_url, 2785 FINAL_STATUS_SSL_ERROR, 2786 0); 2787} 2788 2789// Checks that an SSL error that comes from a subresource does not cancel 2790// the page. Non-main-frame requests are simply cancelled if they run into 2791// an SSL problem. 2792IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) { 2793 net::SpawnedTestServer::SSLOptions ssl_options; 2794 ssl_options.server_certificate = 2795 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2796 net::SpawnedTestServer https_server( 2797 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2798 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2799 ASSERT_TRUE(https_server.Start()); 2800 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2801 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2802 replacement_text.push_back( 2803 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2804 std::string replacement_path; 2805 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2806 "files/prerender/prerender_with_image.html", 2807 replacement_text, 2808 &replacement_path)); 2809 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2810 NavigateToDestURL(); 2811} 2812 2813// Checks that an SSL error that comes from an iframe does not cancel 2814// the page. Non-main-frame requests are simply cancelled if they run into 2815// an SSL problem. 2816IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) { 2817 net::SpawnedTestServer::SSLOptions ssl_options; 2818 ssl_options.server_certificate = 2819 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 2820 net::SpawnedTestServer https_server( 2821 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2822 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2823 ASSERT_TRUE(https_server.Start()); 2824 GURL https_url = https_server.GetURL( 2825 "files/prerender/prerender_embedded_content.html"); 2826 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2827 replacement_text.push_back( 2828 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2829 std::string replacement_path; 2830 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2831 "files/prerender/prerender_with_iframe.html", 2832 replacement_text, 2833 &replacement_path)); 2834 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 2835 NavigateToDestURL(); 2836} 2837 2838// Checks that we cancel correctly when window.print() is called. 2839IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) { 2840 PrerenderTestURL("files/prerender/prerender_print.html", 2841 FINAL_STATUS_WINDOW_PRINT, 2842 0); 2843} 2844 2845// Checks that if a page is opened in a new window by javascript and both the 2846// pages are in the same domain, the prerendered page is not used, due to 2847// window.opener. 2848IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2849 PrerenderSameDomainWindowOpenerWindowOpen) { 2850 PrerenderTestURL("files/prerender/prerender_page.html", 2851 FINAL_STATUS_WINDOW_OPENER, 2852 1); 2853 OpenDestURLViaWindowOpen(); 2854} 2855 2856// Checks that if a page is opened due to click on a href with target="_blank" 2857// and both pages are in the same domain the prerendered page is not used, due 2858// to window.opener. 2859IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2860 PrerenderSameDomainWindowOpenerClickTarget) { 2861 PrerenderTestURL("files/prerender/prerender_page.html", 2862 FINAL_STATUS_WINDOW_OPENER, 2863 1); 2864 OpenDestURLViaClickTarget(); 2865} 2866 2867class TestClientCertStore : public net::ClientCertStore { 2868 public: 2869 TestClientCertStore() {} 2870 virtual ~TestClientCertStore() {} 2871 2872 // net::ClientCertStore: 2873 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, 2874 net::CertificateList* selected_certs, 2875 const base::Closure& callback) OVERRIDE { 2876 *selected_certs = net::CertificateList( 2877 1, scoped_refptr<net::X509Certificate>( 2878 new net::X509Certificate("test", "test", base::Time(), base::Time()))); 2879 callback.Run(); 2880 } 2881}; 2882 2883scoped_ptr<net::ClientCertStore> CreateCertStore() { 2884 return scoped_ptr<net::ClientCertStore>(new TestClientCertStore); 2885} 2886 2887// Checks that a top-level page which would normally request an SSL client 2888// certificate will never be seen since it's an https top-level resource. 2889IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2890 PrerenderSSLClientCertTopLevel) { 2891 ProfileIOData::FromResourceContext( 2892 current_browser()->profile()->GetResourceContext())-> 2893 set_client_cert_store_factory_for_testing( 2894 base::Bind(&CreateCertStore)); 2895 net::SpawnedTestServer::SSLOptions ssl_options; 2896 ssl_options.request_client_certificate = true; 2897 net::SpawnedTestServer https_server( 2898 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2899 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2900 ASSERT_TRUE(https_server.Start()); 2901 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); 2902 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0); 2903} 2904 2905// Checks that an SSL Client Certificate request that originates from a 2906// subresource will cancel the prerendered page. 2907IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2908 PrerenderSSLClientCertSubresource) { 2909 ProfileIOData::FromResourceContext( 2910 current_browser()->profile()->GetResourceContext())-> 2911 set_client_cert_store_factory_for_testing( 2912 base::Bind(&CreateCertStore)); 2913 net::SpawnedTestServer::SSLOptions ssl_options; 2914 ssl_options.request_client_certificate = true; 2915 net::SpawnedTestServer https_server( 2916 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2917 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2918 ASSERT_TRUE(https_server.Start()); 2919 GURL https_url = https_server.GetURL("files/prerender/image.jpeg"); 2920 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2921 replacement_text.push_back( 2922 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); 2923 std::string replacement_path; 2924 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2925 "files/prerender/prerender_with_image.html", 2926 replacement_text, 2927 &replacement_path)); 2928 PrerenderTestURL(replacement_path, 2929 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2930 0); 2931} 2932 2933// Checks that an SSL Client Certificate request that originates from an 2934// iframe will cancel the prerendered page. 2935IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) { 2936 ProfileIOData::FromResourceContext( 2937 current_browser()->profile()->GetResourceContext())-> 2938 set_client_cert_store_factory_for_testing( 2939 base::Bind(&CreateCertStore)); 2940 net::SpawnedTestServer::SSLOptions ssl_options; 2941 ssl_options.request_client_certificate = true; 2942 net::SpawnedTestServer https_server( 2943 net::SpawnedTestServer::TYPE_HTTPS, ssl_options, 2944 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 2945 ASSERT_TRUE(https_server.Start()); 2946 GURL https_url = https_server.GetURL( 2947 "files/prerender/prerender_embedded_content.html"); 2948 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 2949 replacement_text.push_back( 2950 std::make_pair("REPLACE_WITH_URL", https_url.spec())); 2951 std::string replacement_path; 2952 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 2953 "files/prerender/prerender_with_iframe.html", 2954 replacement_text, 2955 &replacement_path)); 2956 PrerenderTestURL(replacement_path, 2957 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 2958 0); 2959} 2960 2961#if defined(FULL_SAFE_BROWSING) 2962// Ensures that we do not prerender pages with a safe browsing 2963// interstitial. 2964IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) { 2965 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2966 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2967 url, SB_THREAT_TYPE_URL_MALWARE); 2968 PrerenderTestURL("files/prerender/prerender_page.html", 2969 FINAL_STATUS_SAFE_BROWSING, 0); 2970} 2971 2972// Ensures that server redirects to a malware page will cancel prerenders. 2973IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2974 PrerenderSafeBrowsingServerRedirect) { 2975 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2976 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2977 url, SB_THREAT_TYPE_URL_MALWARE); 2978 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"), 2979 FINAL_STATUS_SAFE_BROWSING, 2980 0); 2981} 2982 2983// Ensures that client redirects to a malware page will cancel prerenders. 2984IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 2985 PrerenderSafeBrowsingClientRedirect) { 2986 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 2987 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2988 url, SB_THREAT_TYPE_URL_MALWARE); 2989 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"), 2990 FINAL_STATUS_SAFE_BROWSING, 2991 1); 2992} 2993 2994// Ensures that we do not prerender pages which have a malware subresource. 2995IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) { 2996 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg"); 2997 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 2998 image_url, SB_THREAT_TYPE_URL_MALWARE); 2999 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3000 replacement_text.push_back( 3001 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3002 std::string replacement_path; 3003 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3004 "files/prerender/prerender_with_image.html", 3005 replacement_text, 3006 &replacement_path)); 3007 PrerenderTestURL(replacement_path, 3008 FINAL_STATUS_SAFE_BROWSING, 3009 0); 3010} 3011 3012// Ensures that we do not prerender pages which have a malware iframe. 3013IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) { 3014 GURL iframe_url = test_server()->GetURL( 3015 "files/prerender/prerender_embedded_content.html"); 3016 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( 3017 iframe_url, SB_THREAT_TYPE_URL_MALWARE); 3018 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3019 replacement_text.push_back( 3020 std::make_pair("REPLACE_WITH_URL", iframe_url.spec())); 3021 std::string replacement_path; 3022 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3023 "files/prerender/prerender_with_iframe.html", 3024 replacement_text, 3025 &replacement_path)); 3026 PrerenderTestURL(replacement_path, 3027 FINAL_STATUS_SAFE_BROWSING, 3028 0); 3029} 3030 3031#endif 3032 3033// Checks that a local storage read will not cause prerender to fail. 3034IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) { 3035 PrerenderTestURL("files/prerender/prerender_localstorage_read.html", 3036 FINAL_STATUS_USED, 3037 1); 3038 NavigateToDestURL(); 3039} 3040 3041// Checks that a local storage write will not cause prerender to fail. 3042IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) { 3043 PrerenderTestURL("files/prerender/prerender_localstorage_write.html", 3044 FINAL_STATUS_USED, 3045 1); 3046 NavigateToDestURL(); 3047} 3048 3049// Checks that the favicon is properly loaded on prerender. 3050IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) { 3051 scoped_ptr<TestPrerender> prerender = 3052 PrerenderTestURL("files/prerender/prerender_favicon.html", 3053 FINAL_STATUS_USED, 3054 1); 3055 NavigateToDestURL(); 3056 3057 if (!FaviconTabHelper::FromWebContents( 3058 GetActiveWebContents())->FaviconIsValid()) { 3059 // If the favicon has not been set yet, wait for it to be. 3060 content::WindowedNotificationObserver favicon_update_watcher( 3061 chrome::NOTIFICATION_FAVICON_UPDATED, 3062 content::Source<WebContents>(GetActiveWebContents())); 3063 favicon_update_watcher.Wait(); 3064 } 3065 EXPECT_TRUE(FaviconTabHelper::FromWebContents( 3066 GetActiveWebContents())->FaviconIsValid()); 3067} 3068 3069// Checks that when a prerendered page is swapped in to a referring page, the 3070// unload handlers on the referring page are executed. 3071IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderUnload) { 3072 // Matches URL in prerender_loader_with_unload.html. 3073 const GURL unload_url("http://unload-url.test"); 3074 base::FilePath empty_file = ui_test_utils::GetTestFilePath( 3075 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html"))); 3076 RequestCounter unload_counter; 3077 BrowserThread::PostTask( 3078 BrowserThread::IO, FROM_HERE, 3079 base::Bind(&CreateCountingProtocolHandlerOnIO, 3080 unload_url, empty_file, unload_counter.AsWeakPtr())); 3081 3082 set_loader_path("files/prerender/prerender_loader_with_unload.html"); 3083 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 3084 NavigateToDestURL(); 3085 unload_counter.WaitForCount(1); 3086} 3087 3088// Checks that a hanging unload on the referring page of a prerender swap does 3089// not crash the browser on exit. 3090IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHangingUnload) { 3091 // Matches URL in prerender_loader_with_unload.html. 3092 const GURL hang_url("http://unload-url.test"); 3093 base::FilePath empty_file = ui_test_utils::GetTestFilePath( 3094 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html"))); 3095 BrowserThread::PostTask( 3096 BrowserThread::IO, FROM_HERE, 3097 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, 3098 hang_url, empty_file, 3099 base::Closure())); 3100 3101 set_loader_path("files/prerender/prerender_loader_with_unload.html"); 3102 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 3103 NavigateToDestURL(); 3104} 3105 3106 3107// Checks that when the history is cleared, prerendering is cancelled and 3108// prerendering history is cleared. 3109IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) { 3110 scoped_ptr<TestPrerender> prerender = 3111 PrerenderTestURL("files/prerender/prerender_page.html", 3112 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 3113 1); 3114 3115 base::MessageLoop::current()->PostTask( 3116 FROM_HERE, 3117 base::Bind(&ClearBrowsingData, current_browser(), 3118 BrowsingDataRemover::REMOVE_HISTORY)); 3119 prerender->WaitForStop(); 3120 3121 // Make sure prerender history was cleared. 3122 EXPECT_EQ(0, GetHistoryLength()); 3123} 3124 3125// Disabled due to flakiness: crbug.com/316225 3126// Checks that when the cache is cleared, prerenders are cancelled but 3127// prerendering history is not cleared. 3128IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderClearCache) { 3129 scoped_ptr<TestPrerender> prerender = 3130 PrerenderTestURL("files/prerender/prerender_page.html", 3131 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED, 3132 1); 3133 3134 base::MessageLoop::current()->PostTask(FROM_HERE, 3135 base::Bind(&ClearBrowsingData, current_browser(), 3136 BrowsingDataRemover::REMOVE_CACHE)); 3137 prerender->WaitForStop(); 3138 3139 // Make sure prerender history was not cleared. Not a vital behavior, but 3140 // used to compare with PrerenderClearHistory test. 3141 EXPECT_EQ(1, GetHistoryLength()); 3142} 3143 3144IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) { 3145 scoped_ptr<TestPrerender> prerender = 3146 PrerenderTestURL("files/prerender/prerender_page.html", 3147 FINAL_STATUS_CANCELLED, 3148 1); 3149 3150 GetPrerenderManager()->CancelAllPrerenders(); 3151 prerender->WaitForStop(); 3152 3153 EXPECT_FALSE(prerender->contents()); 3154} 3155 3156IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) { 3157 scoped_ptr<TestPrerender> prerender = 3158 PrerenderTestURL("files/prerender/prerender_page.html", 3159 FINAL_STATUS_CANCELLED, 1); 3160 3161 GetPrerenderManager()->CancelAllPrerenders(); 3162 prerender->WaitForStop(); 3163 3164 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0)); 3165 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0)); 3166 EXPECT_FALSE(HadPrerenderEventErrors()); 3167} 3168 3169// Cancels the prerender of a page with its own prerender. The second prerender 3170// should never be started. 3171IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3172 PrerenderCancelPrerenderWithPrerender) { 3173 scoped_ptr<TestPrerender> prerender = 3174 PrerenderTestURL("files/prerender/prerender_infinite_a.html", 3175 FINAL_STATUS_CANCELLED, 3176 1); 3177 3178 GetPrerenderManager()->CancelAllPrerenders(); 3179 prerender->WaitForStop(); 3180 3181 EXPECT_FALSE(prerender->contents()); 3182} 3183 3184// Prerendering and history tests. 3185// The prerendered page is navigated to in several ways [navigate via 3186// omnibox, click on link, key-modified click to open in background tab, etc], 3187// followed by a navigation to another page from the prerendered page, followed 3188// by a back navigation. 3189 3190IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) { 3191 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3192 FINAL_STATUS_USED, 3193 1); 3194 NavigateToDestURL(); 3195 ClickToNextPageAfterPrerender(); 3196 GoBackToPrerender(); 3197} 3198 3199IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateNavigateGoBack) { 3200 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3201 FINAL_STATUS_USED, 3202 1); 3203 NavigateToDestURL(); 3204 NavigateToNextPageAfterPrerender(); 3205 GoBackToPrerender(); 3206} 3207 3208IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) { 3209 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3210 FINAL_STATUS_USED, 3211 1); 3212 OpenDestURLViaClick(); 3213 ClickToNextPageAfterPrerender(); 3214 GoBackToPrerender(); 3215} 3216 3217IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNavigateGoBack) { 3218 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3219 FINAL_STATUS_USED, 3220 1); 3221 OpenDestURLViaClick(); 3222 NavigateToNextPageAfterPrerender(); 3223 GoBackToPrerender(); 3224} 3225 3226// http://crbug.com/345474 3227IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3228 DISABLED_PrerenderClickNewWindow) { 3229 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3230 FINAL_STATUS_WINDOW_OPENER, 3231 1); 3232 OpenDestURLViaClickNewWindow(); 3233} 3234 3235// http://crbug.com/345474 3236IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3237 DISABLED_PrerenderClickNewForegroundTab) { 3238 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3239 FINAL_STATUS_WINDOW_OPENER, 3240 1); 3241 OpenDestURLViaClickNewForegroundTab(); 3242} 3243 3244// http://crbug.com/345474 3245IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3246 DISABLED_PrerenderClickNewBackgroundTab) { 3247 scoped_ptr<TestPrerender> prerender = 3248 PrerenderTestURL("files/prerender/prerender_page_with_link.html", 3249 FINAL_STATUS_WINDOW_OPENER, 3250 1); 3251 ASSERT_TRUE(prerender->contents()); 3252 prerender->contents()->set_should_be_shown(false); 3253 OpenDestURLViaClickNewBackgroundTab(); 3254} 3255 3256IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3257 NavigateToPrerenderedPageWhenDevToolsAttached) { 3258 DisableJavascriptCalls(); 3259 WebContents* web_contents = 3260 current_browser()->tab_strip_model()->GetActiveWebContents(); 3261 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( 3262 web_contents->GetRenderViewHost())); 3263 DevToolsManager* manager = DevToolsManager::GetInstance(); 3264 FakeDevToolsClientHost client_host; 3265 manager->RegisterDevToolsClientHostFor(agent.get(), &client_host); 3266 const char* url = "files/prerender/prerender_page.html"; 3267 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1); 3268 NavigateToURLWithDisposition(url, CURRENT_TAB, false); 3269 manager->ClientHostClosing(&client_host); 3270} 3271 3272// Validate that the sessionStorage namespace remains the same when swapping 3273// in a prerendered page. 3274IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) { 3275 set_loader_path("files/prerender/prerender_loader_with_session_storage.html"); 3276 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"), 3277 FINAL_STATUS_USED, 3278 1); 3279 NavigateToDestURL(); 3280 GoBackToPageBeforePrerender(); 3281} 3282 3283// Checks that the control group works. An XHR PUT cannot be detected in the 3284// control group. 3285IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroup) { 3286 RestorePrerenderMode restore_prerender_mode; 3287 PrerenderManager::SetMode( 3288 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP); 3289 DisableJavascriptCalls(); 3290 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 3291 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0); 3292 NavigateToDestURL(); 3293} 3294 3295// Checks that the control group correctly hits WOULD_HAVE_BEEN_USED 3296// renderer-initiated navigations. (This verifies that the ShouldFork logic 3297// behaves correctly.) 3298IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroupRendererInitiated) { 3299 RestorePrerenderMode restore_prerender_mode; 3300 PrerenderManager::SetMode( 3301 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP); 3302 DisableJavascriptCalls(); 3303 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 3304 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0); 3305 OpenDestURLViaClick(); 3306} 3307 3308// Make sure that the MatchComplete dummy works in the normal case. Once 3309// a prerender is cancelled because of a script, a dummy must be created to 3310// account for the MatchComplete case, and it must have a final status of 3311// FINAL_STATUS_WOULD_HAVE_BEEN_USED. 3312IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MatchCompleteDummy) { 3313 UMAHistogramHelper histograms; 3314 3315 std::vector<FinalStatus> expected_final_status_queue; 3316 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD); 3317 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 3318 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 3319 expected_final_status_queue, 1); 3320 histograms.Fetch(); 3321 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 3322 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 3323 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 3324 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1); 3325 3326 NavigateToDestURL(); 3327 histograms.Fetch(); 3328 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1); 3329 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0); 3330 histograms.ExpectTotalCount( 3331 "Prerender.websame_PerceivedPLTMatchedComplete", 1); 3332} 3333 3334// Verify that a navigation that hits a MatchComplete dummy while another is in 3335// progress does not also classify the previous navigation as a MatchComplete. 3336IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3337 MatchCompleteDummyCancelNavigation) { 3338 UMAHistogramHelper histograms; 3339 3340 // Arrange for a URL to hang. 3341 const GURL kNoCommitUrl("http://never-respond.example.com"); 3342 base::FilePath file(FILE_PATH_LITERAL( 3343 "chrome/test/data/prerender/prerender_page.html")); 3344 base::RunLoop hang_loop; 3345 BrowserThread::PostTask( 3346 BrowserThread::IO, FROM_HERE, 3347 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, 3348 kNoCommitUrl, file, hang_loop.QuitClosure())); 3349 3350 // First, fire a prerender that aborts after it completes its load. 3351 std::vector<FinalStatus> expected_final_status_queue; 3352 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD); 3353 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 3354 PrerenderTestURL("files/prerender/prerender_xhr_put.html", 3355 expected_final_status_queue, 1); 3356 histograms.Fetch(); 3357 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 3358 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 3359 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 3360 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1); 3361 3362 // Open the hanging URL in a new tab. Wait for both the new tab to open and 3363 // the hanging request to be scheduled. 3364 ui_test_utils::NavigateToURLWithDisposition( 3365 current_browser(), kNoCommitUrl, NEW_FOREGROUND_TAB, 3366 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 3367 hang_loop.Run(); 3368 3369 // Now interrupt that navigation and navigate to the destination URL. This 3370 // should forcibly complete the previous navigation and also complete a 3371 // WOULD_HAVE_BEEN_PRERENDERED navigation. 3372 NavigateToDestURL(); 3373 histograms.Fetch(); 3374 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 2); 3375 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 3376 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 3377 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1); 3378 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0); 3379 histograms.ExpectTotalCount( 3380 "Prerender.websame_PerceivedPLTMatchedComplete", 1); 3381} 3382 3383class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest { 3384 public: 3385 PrerenderBrowserTestWithNaCl() {} 3386 virtual ~PrerenderBrowserTestWithNaCl() {} 3387 3388 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 3389 PrerenderBrowserTest::SetUpCommandLine(command_line); 3390 command_line->AppendSwitch(switches::kEnableNaCl); 3391 } 3392}; 3393 3394// Check that NaCl plugins work when enabled, with prerendering. 3395IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl, 3396 PrerenderNaClPluginEnabled) { 3397#if defined(OS_WIN) && defined(USE_ASH) 3398 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 3399 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 3400 return; 3401#endif 3402 3403 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html", 3404 FINAL_STATUS_USED, 3405 1); 3406 NavigateToDestURL(); 3407 3408 // To avoid any chance of a race, we have to let the script send its response 3409 // asynchronously. 3410 WebContents* web_contents = 3411 browser()->tab_strip_model()->GetActiveWebContents(); 3412 bool display_test_result = false; 3413 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, 3414 "DidDisplayReallyPass()", 3415 &display_test_result)); 3416 ASSERT_TRUE(display_test_result); 3417} 3418 3419// Checks that the referrer policy is used when prerendering. 3420IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) { 3421 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 3422 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 3423 FINAL_STATUS_USED, 3424 1); 3425 NavigateToDestURL(); 3426} 3427 3428// Checks that the referrer policy is used when prerendering on HTTPS. 3429IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3430 PrerenderSSLReferrerPolicy) { 3431 UseHttpsSrcServer(); 3432 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 3433 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 3434 FINAL_STATUS_USED, 3435 1); 3436 NavigateToDestURL(); 3437} 3438 3439// Checks that the referrer policy is used when prerendering is cancelled. 3440IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrerPolicy) { 3441 scoped_ptr<TestContentBrowserClient> test_content_browser_client( 3442 new TestContentBrowserClient); 3443 content::ContentBrowserClient* original_browser_client = 3444 content::SetBrowserClientForTesting(test_content_browser_client.get()); 3445 3446 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html"); 3447 PrerenderTestURL("files/prerender/prerender_referrer_policy.html", 3448 FINAL_STATUS_CANCELLED, 3449 1); 3450 OpenDestURLViaClick(); 3451 3452 bool display_test_result = false; 3453 WebContents* web_contents = 3454 browser()->tab_strip_model()->GetActiveWebContents(); 3455 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 3456 web_contents, 3457 "window.domAutomationController.send(DidDisplayPass())", 3458 &display_test_result)); 3459 EXPECT_TRUE(display_test_result); 3460 3461 content::SetBrowserClientForTesting(original_browser_client); 3462} 3463 3464// Test interaction of the webNavigation and tabs API with prerender. 3465class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest, 3466 public ExtensionApiTest { 3467 public: 3468 PrerenderBrowserTestWithExtensions() { 3469 // The individual tests start the test server through ExtensionApiTest, so 3470 // the port number can be passed through to the extension. 3471 autostart_test_server_ = false; 3472 } 3473 3474 virtual void SetUp() OVERRIDE { 3475 PrerenderBrowserTest::SetUp(); 3476 } 3477 3478 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 3479 PrerenderBrowserTest::SetUpCommandLine(command_line); 3480 ExtensionApiTest::SetUpCommandLine(command_line); 3481 } 3482 3483 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 3484 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture(); 3485 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); 3486 } 3487 3488 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 3489 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture(); 3490 ExtensionApiTest::TearDownInProcessBrowserTestFixture(); 3491 } 3492 3493 virtual void SetUpOnMainThread() OVERRIDE { 3494 PrerenderBrowserTest::SetUpOnMainThread(); 3495 } 3496}; 3497 3498IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) { 3499 ASSERT_TRUE(StartSpawnedTestServer()); 3500 extensions::FrameNavigationState::set_allow_extension_scheme(true); 3501 3502 CommandLine::ForCurrentProcess()->AppendSwitch( 3503 extensions::switches::kAllowLegacyExtensionManifests); 3504 3505 // Wait for the extension to set itself up and return control to us. 3506 ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_; 3507 3508 ResultCatcher catcher; 3509 3510 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 3511 3512 ChannelDestructionWatcher channel_close_watcher; 3513 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 3514 GetActiveWebContents()->GetRenderProcessHost()); 3515 NavigateToDestURL(); 3516 channel_close_watcher.WaitForChannelClose(); 3517 3518 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 3519 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 3520} 3521 3522// Fails often on Windows dbg bots. http://crbug.com/177163 3523#if defined(OS_WIN) && !defined(NDEBUG) 3524#define MAYBE_TabsApi DISABLED_TabsApi 3525#else 3526#define MAYBE_TabsApi TabsApi 3527#endif // defined(OS_WIN) && !defined(NDEBUG) 3528IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, MAYBE_TabsApi) { 3529 ASSERT_TRUE(StartSpawnedTestServer()); 3530 extensions::FrameNavigationState::set_allow_extension_scheme(true); 3531 3532 // Wait for the extension to set itself up and return control to us. 3533 ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html")) 3534 << message_; 3535 3536 ResultCatcher catcher; 3537 3538 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 3539 3540 ChannelDestructionWatcher channel_close_watcher; 3541 channel_close_watcher.WatchChannel(browser()->tab_strip_model()-> 3542 GetActiveWebContents()->GetRenderProcessHost()); 3543 NavigateToDestURL(); 3544 channel_close_watcher.WaitForChannelClose(); 3545 3546 ASSERT_TRUE(IsEmptyPrerenderLinkManager()); 3547 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 3548} 3549 3550// Test that prerenders abort when navigating to a stream. 3551// See chrome/browser/extensions/api/streams_private/streams_private_apitest.cc 3552IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, StreamsTest) { 3553 ASSERT_TRUE(StartSpawnedTestServer()); 3554 3555 const extensions::Extension* extension = LoadExtension( 3556 test_data_dir_.AppendASCII("streams_private/handle_mime_type")); 3557 ASSERT_TRUE(extension); 3558 EXPECT_EQ(std::string(extension_misc::kStreamsPrivateTestExtensionId), 3559 extension->id()); 3560 MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension); 3561 ASSERT_TRUE(handler); 3562 EXPECT_TRUE(handler->CanHandleMIMEType("application/msword")); 3563 3564 PrerenderTestURL("files/prerender/document.doc", FINAL_STATUS_DOWNLOAD, 0); 3565 3566 // Sanity-check that the extension would have picked up the stream in a normal 3567 // navigation had prerender not intercepted it. 3568 // streams_private/handle_mime_type reports success if it has handled the 3569 // application/msword type. 3570 ResultCatcher catcher; 3571 NavigateToDestURL(); 3572 EXPECT_TRUE(catcher.GetNextResult()); 3573} 3574 3575// Checks that non-http/https/chrome-extension subresource cancels the 3576// prerender. 3577IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3578 PrerenderCancelSubresourceUnsupportedScheme) { 3579 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg"); 3580 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3581 replacement_text.push_back( 3582 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3583 std::string replacement_path; 3584 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3585 "files/prerender/prerender_with_image.html", 3586 replacement_text, 3587 &replacement_path)); 3588 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0); 3589} 3590 3591// Ensure that about:blank is permitted for any subresource. 3592IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3593 PrerenderAllowAboutBlankSubresource) { 3594 GURL image_url = GURL("about:blank"); 3595 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3596 replacement_text.push_back( 3597 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3598 std::string replacement_path; 3599 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3600 "files/prerender/prerender_with_image.html", 3601 replacement_text, 3602 &replacement_path)); 3603 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 3604 NavigateToDestURL(); 3605} 3606 3607// Checks that non-http/https/chrome-extension subresource cancels the prerender 3608// on redirect. 3609IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3610 PrerenderCancelSubresourceRedirectUnsupportedScheme) { 3611 GURL image_url = test_server()->GetURL( 3612 CreateServerRedirect("invalidscheme://www.google.com/test.jpg")); 3613 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3614 replacement_text.push_back( 3615 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3616 std::string replacement_path; 3617 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3618 "files/prerender/prerender_with_image.html", 3619 replacement_text, 3620 &replacement_path)); 3621 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0); 3622} 3623 3624// Checks that chrome-extension subresource does not cancel the prerender. 3625IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3626 PrerenderKeepSubresourceExtensionScheme) { 3627 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg"); 3628 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3629 replacement_text.push_back( 3630 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3631 std::string replacement_path; 3632 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3633 "files/prerender/prerender_with_image.html", 3634 replacement_text, 3635 &replacement_path)); 3636 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 3637 NavigateToDestURL(); 3638} 3639 3640// Checks that redirect to chrome-extension subresource does not cancel the 3641// prerender. 3642IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3643 PrerenderKeepSubresourceRedirectExtensionScheme) { 3644 GURL image_url = test_server()->GetURL( 3645 CreateServerRedirect("chrome-extension://abcdefg/test.jpg")); 3646 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 3647 replacement_text.push_back( 3648 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); 3649 std::string replacement_path; 3650 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements( 3651 "files/prerender/prerender_with_image.html", 3652 replacement_text, 3653 &replacement_path)); 3654 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1); 3655 NavigateToDestURL(); 3656} 3657 3658// Checks that non-http/https main page redirects cancel the prerender. 3659IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3660 PrerenderCancelMainFrameRedirectUnsupportedScheme) { 3661 GURL url = test_server()->GetURL( 3662 CreateServerRedirect("invalidscheme://www.google.com/test.html")); 3663 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 0); 3664} 3665 3666// Checks that media source video loads are deferred on prerendering. 3667IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) { 3668 PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html", 3669 FINAL_STATUS_USED, 3670 1); 3671 NavigateToDestURL(); 3672 WaitForASCIITitle(GetActiveWebContents(), kPassTitle); 3673} 3674 3675// Checks that a prerender that creates an audio stream (via a WebAudioDevice) 3676// is cancelled. 3677// http://crbug.com/261489 3678IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWebAudioDevice) { 3679 PrerenderTestURL("files/prerender/prerender_web_audio_device.html", 3680 FINAL_STATUS_CREATING_AUDIO_STREAM, 1); 3681} 3682 3683// Checks that prerenders do not swap in to WebContents being captured. 3684IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) { 3685 PrerenderTestURL("files/prerender/prerender_page.html", 3686 FINAL_STATUS_PAGE_BEING_CAPTURED, 1); 3687 WebContents* web_contents = GetActiveWebContents(); 3688 web_contents->IncrementCapturerCount(gfx::Size()); 3689 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 3690 web_contents->DecrementCapturerCount(); 3691} 3692 3693// Checks that prerenders are aborted on cross-process navigation from 3694// a server redirect. 3695IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3696 PrerenderCrossProcessServerRedirect) { 3697 // Force everything to be a process swap. 3698 SwapProcessesContentBrowserClient test_browser_client; 3699 content::ContentBrowserClient* original_browser_client = 3700 content::SetBrowserClientForTesting(&test_browser_client); 3701 3702 PrerenderTestURL( 3703 CreateServerRedirect("files/prerender/prerender_page.html"), 3704 FINAL_STATUS_OPEN_URL, 0); 3705 3706 content::SetBrowserClientForTesting(original_browser_client); 3707} 3708 3709// Checks that URLRequests for prerenders being aborted on cross-process 3710// navigation from a server redirect are cleaned up, so they don't keep cache 3711// entries locked. 3712// See http://crbug.com/341134 3713IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3714 PrerenderCrossProcessServerRedirectNoHang) { 3715 const char kDestPath[] = "files/prerender/prerender_page.html"; 3716 // Force everything to be a process swap. 3717 SwapProcessesContentBrowserClient test_browser_client; 3718 content::ContentBrowserClient* original_browser_client = 3719 content::SetBrowserClientForTesting(&test_browser_client); 3720 3721 PrerenderTestURL(CreateServerRedirect(kDestPath), FINAL_STATUS_OPEN_URL, 0); 3722 3723 ui_test_utils::NavigateToURL( 3724 browser(), 3725 test_server()->GetURL(kDestPath)); 3726 3727 content::SetBrowserClientForTesting(original_browser_client); 3728} 3729 3730// Checks that prerenders are aborted on cross-process navigation from 3731// a client redirect. 3732IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3733 PrerenderCrossProcessClientRedirect) { 3734 // Cross-process navigation logic for renderer-initiated navigations 3735 // is partially controlled by the renderer, namely 3736 // ChromeContentRendererClient. This test instead relies on the Web 3737 // Store triggering such navigations. 3738 std::string webstore_url = extension_urls::GetWebstoreLaunchURL(); 3739 3740 // Mock out requests to the Web Store. 3741 base::FilePath file(GetTestPath("prerender_page.html")); 3742 BrowserThread::PostTask( 3743 BrowserThread::IO, FROM_HERE, 3744 base::Bind(&CreateMockProtocolHandlerOnIO, 3745 GURL(webstore_url), file)); 3746 3747 PrerenderTestURL(CreateClientRedirect(webstore_url), 3748 FINAL_STATUS_OPEN_URL, 1); 3749} 3750 3751// Checks that canceling a MatchComplete dummy doesn't result in two 3752// stop events. 3753IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelMatchCompleteDummy) { 3754 std::vector<FinalStatus> expected_final_status_queue; 3755 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT); 3756 expected_final_status_queue.push_back(FINAL_STATUS_CANCELLED); 3757 ScopedVector<TestPrerender> prerenders = 3758 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", 3759 expected_final_status_queue, 0); 3760 3761 // Cancel the MatchComplete dummy. 3762 GetPrerenderManager()->CancelAllPrerenders(); 3763 prerenders[1]->WaitForStop(); 3764 3765 // Check the referring page only got one copy of the event. 3766 EXPECT_FALSE(HadPrerenderEventErrors()); 3767} 3768 3769// Checks that a deferred redirect to an image is not loaded until the page is 3770// visible. Also test the right histogram events are emitted in this case. 3771IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredImage) { 3772 DisableJavascriptCalls(); 3773 UMAHistogramHelper histograms; 3774 3775 // The prerender will not completely load until after the swap, so wait for a 3776 // title change before calling DidPrerenderPass. 3777 scoped_ptr<TestPrerender> prerender = 3778 PrerenderTestURL( 3779 "files/prerender/prerender_deferred_image.html", 3780 FINAL_STATUS_USED, 0); 3781 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle); 3782 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0)); 3783 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents())); 3784 EXPECT_EQ(0, prerender->number_of_loads()); 3785 histograms.Fetch(); 3786 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 3787 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 3788 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 3789 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0); 3790 3791 // Swap. 3792 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(), 3793 GetActiveWebContents()); 3794 ui_test_utils::NavigateToURLWithDisposition( 3795 current_browser(), dest_url(), CURRENT_TAB, 3796 ui_test_utils::BROWSER_TEST_NONE); 3797 swap_observer.Wait(); 3798 3799 // The prerender never observes the final load. 3800 EXPECT_EQ(0, prerender->number_of_loads()); 3801 3802 // Now check DidDisplayPass. 3803 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 3804 3805 histograms.Fetch(); 3806 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0); 3807 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1); 3808 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1); 3809 histograms.ExpectTotalCount( 3810 "Prerender.websame_PerceivedPLTMatchedComplete", 1); 3811} 3812 3813// Checks that a deferred redirect to an image is not loaded until the 3814// page is visible, even after another redirect. 3815IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3816 PrerenderDeferredImageAfterRedirect) { 3817 DisableJavascriptCalls(); 3818 3819 // The prerender will not completely load until after the swap, so wait for a 3820 // title change before calling DidPrerenderPass. 3821 scoped_ptr<TestPrerender> prerender = 3822 PrerenderTestURL( 3823 "files/prerender/prerender_deferred_image.html", 3824 FINAL_STATUS_USED, 0); 3825 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle); 3826 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents())); 3827 EXPECT_EQ(0, prerender->number_of_loads()); 3828 3829 // Swap. 3830 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(), 3831 GetActiveWebContents()); 3832 ui_test_utils::NavigateToURLWithDisposition( 3833 current_browser(), dest_url(), CURRENT_TAB, 3834 ui_test_utils::BROWSER_TEST_NONE); 3835 swap_observer.Wait(); 3836 3837 // The prerender never observes the final load. 3838 EXPECT_EQ(0, prerender->number_of_loads()); 3839 3840 // Now check DidDisplayPass. 3841 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 3842} 3843 3844// Checks that deferred redirects in the main frame are followed. 3845IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredMainFrame) { 3846 DisableJavascriptCalls(); 3847 PrerenderTestURL( 3848 "files/prerender/image-deferred.png", 3849 FINAL_STATUS_USED, 1); 3850 NavigateToDestURL(); 3851} 3852 3853// Checks that deferred redirects in the main frame are followed, even 3854// with a double-redirect. 3855IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3856 PrerenderDeferredMainFrameAfterRedirect) { 3857 DisableJavascriptCalls(); 3858 PrerenderTestURL( 3859 CreateServerRedirect("files/prerender/image-deferred.png"), 3860 FINAL_STATUS_USED, 1); 3861 NavigateToDestURL(); 3862} 3863 3864// Checks that deferred redirects in a synchronous XHR abort the 3865// prerender. 3866IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredSynchronousXHR) { 3867 PrerenderTestURL("files/prerender/prerender_deferred_sync_xhr.html", 3868 FINAL_STATUS_BAD_DEFERRED_REDIRECT, 0); 3869 NavigateToDestURL(); 3870} 3871 3872// Checks that prerenders are not swapped for navigations with extra headers. 3873IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExtraHeadersNoSwap) { 3874 PrerenderTestURL("files/prerender/prerender_page.html", 3875 FINAL_STATUS_APP_TERMINATING, 1); 3876 3877 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB, 3878 content::PAGE_TRANSITION_TYPED, false); 3879 params.extra_headers = "X-Custom-Header: 42\r\n"; 3880 NavigateToURLWithParams(params, false); 3881} 3882 3883// Checks that prerenders are not swapped for navigations with browser-initiated 3884// POST data. 3885IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 3886 PrerenderBrowserInitiatedPostNoSwap) { 3887 PrerenderTestURL("files/prerender/prerender_page.html", 3888 FINAL_STATUS_APP_TERMINATING, 1); 3889 3890 std::string post_data = "DATA"; 3891 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB, 3892 content::PAGE_TRANSITION_TYPED, false); 3893 params.uses_post = true; 3894 params.browser_initiated_post_data = 3895 base::RefCountedString::TakeString(&post_data); 3896 NavigateToURLWithParams(params, false); 3897} 3898 3899// Checks that the prerendering of a page is canceled correctly when the 3900// prerendered page tries to make a second navigation entry. 3901IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) { 3902 PrerenderTestURL("files/prerender/prerender_new_entry.html", 3903 FINAL_STATUS_NEW_NAVIGATION_ENTRY, 3904 1); 3905} 3906 3907// Attempt a swap-in in a new tab, verifying that session storage namespace 3908// merging works. 3909IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) { 3910 // Mock out some URLs and count the number of requests to one of them. Both 3911 // prerender_session_storage.html and init_session_storage.html need to be 3912 // mocked so they are same-origin. 3913 const GURL kInitURL("http://prerender.test/init_session_storage.html"); 3914 base::FilePath init_file = GetTestPath("init_session_storage.html"); 3915 BrowserThread::PostTask( 3916 BrowserThread::IO, FROM_HERE, 3917 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file)); 3918 3919 const GURL kTestURL("http://prerender.test/prerender_session_storage.html"); 3920 base::FilePath test_file = GetTestPath("prerender_session_storage.html"); 3921 RequestCounter counter; 3922 BrowserThread::PostTask( 3923 BrowserThread::IO, FROM_HERE, 3924 base::Bind(&CreateCountingProtocolHandlerOnIO, 3925 kTestURL, test_file, counter.AsWeakPtr())); 3926 3927 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1); 3928 3929 // Open a new tab to navigate in. 3930 ui_test_utils::NavigateToURLWithDisposition( 3931 current_browser(), kInitURL, NEW_FOREGROUND_TAB, 3932 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 3933 3934 // Now navigate in the new tab. Set expect_swap_to_succeed to false because 3935 // the swap does not occur synchronously. 3936 // 3937 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL 3938 // return value assertion and let this go through the usual successful-swap 3939 // codepath. 3940 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 3941 3942 // Verify DidDisplayPass manually since the previous call skipped it. 3943 EXPECT_TRUE(DidDisplayPass( 3944 current_browser()->tab_strip_model()->GetActiveWebContents())); 3945 3946 // Only one request to the test URL started. 3947 // 3948 // TODO(davidben): Re-enable this check when the races in attaching the 3949 // throttle are resolved. http://crbug.com/335835 3950 // EXPECT_EQ(1, counter.count()); 3951} 3952 3953// Attempt a swap-in in a new tab, verifying that session storage namespace 3954// merging works. Unlike the above test, the swap is for a navigation that would 3955// normally be cross-process. 3956IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) { 3957 base::FilePath test_data_dir; 3958 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); 3959 3960 // Mock out some URLs and count the number of requests to one of them. Both 3961 // prerender_session_storage.html and init_session_storage.html need to be 3962 // mocked so they are same-origin. 3963 const GURL kInitURL("http://prerender.test/init_session_storage.html"); 3964 base::FilePath init_file = GetTestPath("init_session_storage.html"); 3965 BrowserThread::PostTask( 3966 BrowserThread::IO, FROM_HERE, 3967 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file)); 3968 3969 const GURL kTestURL("http://prerender.test/prerender_session_storage.html"); 3970 base::FilePath test_file = GetTestPath("prerender_session_storage.html"); 3971 RequestCounter counter; 3972 BrowserThread::PostTask( 3973 BrowserThread::IO, FROM_HERE, 3974 base::Bind(&CreateCountingProtocolHandlerOnIO, 3975 kTestURL, test_file, counter.AsWeakPtr())); 3976 3977 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1); 3978 3979 // Open a new tab to navigate in. 3980 ui_test_utils::NavigateToURLWithDisposition( 3981 current_browser(), kInitURL, NEW_FOREGROUND_TAB, 3982 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 3983 3984 // Navigate to about:blank so the next navigation is cross-process. 3985 ui_test_utils::NavigateToURL(current_browser(), 3986 GURL(content::kAboutBlankURL)); 3987 3988 // Now navigate in the new tab. Set expect_swap_to_succeed to false because 3989 // the swap does not occur synchronously. 3990 // 3991 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL 3992 // return value assertion and let this go through the usual successful-swap 3993 // codepath. 3994 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 3995 3996 // Verify DidDisplayPass manually since the previous call skipped it. 3997 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 3998 3999 // Only one request to the test URL started. 4000 // 4001 // TODO(davidben): Re-enable this check when the races in attaching the 4002 // throttle are resolved. http://crbug.com/335835 4003 // EXPECT_EQ(1, counter.count()); 4004} 4005 4006// Verify that session storage conflicts don't merge. 4007IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) { 4008 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html", 4009 FINAL_STATUS_APP_TERMINATING, 1); 4010 4011 // Open a new tab to navigate in. 4012 ui_test_utils::NavigateToURLWithDisposition( 4013 current_browser(), 4014 test_server()->GetURL("files/prerender/init_session_storage.html"), 4015 NEW_FOREGROUND_TAB, 4016 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 4017 4018 // Now navigate in the new tab. 4019 NavigateToDestURLWithDisposition(CURRENT_TAB, false); 4020 4021 // Verify DidDisplayPass in the new tab. 4022 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents())); 4023} 4024 4025// Checks that prerenders honor |should_replace_current_entry|. 4026IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReplaceCurrentEntry) { 4027 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 4028 4029 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB, 4030 content::PAGE_TRANSITION_TYPED, false); 4031 params.should_replace_current_entry = true; 4032 NavigateToURLWithParams(params, false); 4033 4034 const NavigationController& controller = 4035 GetActiveWebContents()->GetController(); 4036 // First entry is about:blank, second is prerender_page.html. 4037 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 4038 EXPECT_EQ(2, controller.GetEntryCount()); 4039 EXPECT_EQ(GURL(content::kAboutBlankURL), 4040 controller.GetEntryAtIndex(0)->GetURL()); 4041 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL()); 4042} 4043 4044// Checks prerender does not hit DCHECKs and behaves properly if two pending 4045// swaps occur in a row. 4046IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDoublePendingSwap) { 4047 GetPrerenderManager()->mutable_config().max_link_concurrency = 2; 4048 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; 4049 4050 GURL url1 = test_server()->GetURL("files/prerender/prerender_page.html?1"); 4051 scoped_ptr<TestPrerender> prerender1 = 4052 PrerenderTestURL(url1, FINAL_STATUS_APP_TERMINATING, 1); 4053 4054 GURL url2 = test_server()->GetURL("files/prerender/prerender_page.html?2"); 4055 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED); 4056 AddPrerender(url2, 1); 4057 prerender2->WaitForStart(); 4058 prerender2->WaitForLoads(1); 4059 4060 // There's no reason the second prerender can't be used, but the swap races 4061 // with didStartProvisionalLoad and didFailProvisionalLoad from the previous 4062 // navigation. The current logic will conservatively fail to swap under such 4063 // races. However, if the renderer is slow enough, it's possible for the 4064 // prerender to still be used, so don't program in either expectation. 4065 ASSERT_TRUE(prerender2->contents()); 4066 prerender2->contents()->set_skip_final_checks(true); 4067 4068 // Open a new tab to navigate in. 4069 ui_test_utils::NavigateToURLWithDisposition( 4070 current_browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB, 4071 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 4072 4073 // Fire off two navigations, without running the event loop between them. 4074 NavigationOrSwapObserver swap_observer( 4075 current_browser()->tab_strip_model(), 4076 GetActiveWebContents(), 2); 4077 current_browser()->OpenURL(OpenURLParams( 4078 url1, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 4079 current_browser()->OpenURL(OpenURLParams( 4080 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 4081 swap_observer.Wait(); 4082 4083 // The WebContents should be on url2. There may be 2 or 3 entries, depending 4084 // on whether the first one managed to complete. 4085 // 4086 // TODO(davidben): When http://crbug.com/335835 is fixed, the 3 entry case 4087 // shouldn't be possible because it's throttled by the pending swap that 4088 // cannot complete. 4089 const NavigationController& controller = 4090 GetActiveWebContents()->GetController(); 4091 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 4092 EXPECT_LE(2, controller.GetEntryCount()); 4093 EXPECT_GE(3, controller.GetEntryCount()); 4094 EXPECT_EQ(GURL(content::kAboutBlankURL), 4095 controller.GetEntryAtIndex(0)->GetURL()); 4096 EXPECT_EQ(url2, controller.GetEntryAtIndex( 4097 controller.GetEntryCount() - 1)->GetURL()); 4098} 4099 4100// Verify that pending swaps get aborted on new navigations. 4101IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 4102 PrerenderPendingSwapNewNavigation) { 4103 PrerenderManager::HangSessionStorageMergesForTesting(); 4104 4105 PrerenderTestURL("files/prerender/prerender_page.html", 4106 FINAL_STATUS_APP_TERMINATING, 1); 4107 4108 // Open a new tab to navigate in. 4109 ui_test_utils::NavigateToURLWithDisposition( 4110 current_browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB, 4111 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 4112 4113 // Navigate to the URL. Wait for DidStartLoading, just so it's definitely 4114 // progressed somewhere. 4115 content::WindowedNotificationObserver page_load_observer( 4116 content::NOTIFICATION_LOAD_START, 4117 content::Source<NavigationController>( 4118 &GetActiveWebContents()->GetController())); 4119 current_browser()->OpenURL(OpenURLParams( 4120 dest_url(), Referrer(), CURRENT_TAB, 4121 content::PAGE_TRANSITION_TYPED, false)); 4122 page_load_observer.Wait(); 4123 4124 // Navigate somewhere else. This should succeed and abort the pending swap. 4125 TestNavigationObserver nav_observer(GetActiveWebContents()); 4126 current_browser()->OpenURL(OpenURLParams( 4127 GURL(content::kAboutBlankURL), Referrer(), CURRENT_TAB, 4128 content::PAGE_TRANSITION_TYPED, false)); 4129 nav_observer.Wait(); 4130} 4131 4132// Checks that <a ping> requests are not dropped in prerender. 4133IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPing) { 4134 // Count hits to a certain URL. 4135 const GURL kPingURL("http://prerender.test/ping"); 4136 base::FilePath empty_file = ui_test_utils::GetTestFilePath( 4137 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html"))); 4138 RequestCounter ping_counter; 4139 BrowserThread::PostTask( 4140 BrowserThread::IO, FROM_HERE, 4141 base::Bind(&CreateCountingProtocolHandlerOnIO, 4142 kPingURL, empty_file, ping_counter.AsWeakPtr())); 4143 4144 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 4145 OpenDestURLViaClickPing(kPingURL); 4146 4147 ping_counter.WaitForCount(1); 4148} 4149 4150IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPPLTNormalNavigation) { 4151 UMAHistogramHelper histograms; 4152 4153 GURL url = test_server()->GetURL("files/prerender/prerender_page.html"); 4154 ui_test_utils::NavigateToURL(current_browser(), url); 4155 histograms.Fetch(); 4156 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1); 4157 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0); 4158 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0); 4159} 4160 4161class PrerenderIncognitoBrowserTest : public PrerenderBrowserTest { 4162 public: 4163 virtual void SetUpOnMainThread() OVERRIDE { 4164 Profile* normal_profile = current_browser()->profile(); 4165 set_browser(ui_test_utils::OpenURLOffTheRecord( 4166 normal_profile, GURL("about:blank"))); 4167 PrerenderBrowserTest::SetUpOnMainThread(); 4168 } 4169}; 4170 4171// Checks that prerendering works in incognito mode. 4172IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) { 4173 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1); 4174 NavigateToDestURL(); 4175} 4176 4177} // namespace prerender 4178