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