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.
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/test/test_timeouts.h"
21 #include "base/values.h"
22 #include "chrome/browser/browsing_data/browsing_data_helper.h"
23 #include "chrome/browser/browsing_data/browsing_data_remover.h"
24 #include "chrome/browser/chrome_content_browser_client.h"
25 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/content_settings/host_content_settings_map.h"
27 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
28 #include "chrome/browser/extensions/extension_apitest.h"
29 #include "chrome/browser/external_protocol/external_protocol_handler.h"
30 #include "chrome/browser/favicon/favicon_tab_helper.h"
31 #include "chrome/browser/prerender/prerender_contents.h"
32 #include "chrome/browser/prerender/prerender_handle.h"
33 #include "chrome/browser/prerender/prerender_link_manager.h"
34 #include "chrome/browser/prerender/prerender_link_manager_factory.h"
35 #include "chrome/browser/prerender/prerender_manager.h"
36 #include "chrome/browser/prerender/prerender_manager_factory.h"
37 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/profiles/profile_io_data.h"
39 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
40 #include "chrome/browser/safe_browsing/database_manager.h"
41 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
42 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
43 #include "chrome/browser/task_manager/task_manager.h"
44 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
45 #include "chrome/browser/ui/browser.h"
46 #include "chrome/browser/ui/browser_commands.h"
47 #include "chrome/browser/ui/browser_finder.h"
48 #include "chrome/browser/ui/browser_navigator.h"
49 #include "chrome/browser/ui/browser_window.h"
50 #include "chrome/browser/ui/tabs/tab_strip_model.h"
51 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
52 #include "chrome/common/chrome_paths.h"
53 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/extensions/extension_constants.h"
55 #include "chrome/common/pref_names.h"
56 #include "chrome/test/base/in_process_browser_test.h"
57 #include "chrome/test/base/test_switches.h"
58 #include "chrome/test/base/ui_test_utils.h"
59 #include "chrome/test/base/uma_histogram_helper.h"
60 #include "content/public/browser/browser_message_filter.h"
61 #include "content/public/browser/devtools_agent_host.h"
62 #include "content/public/browser/devtools_client_host.h"
63 #include "content/public/browser/devtools_manager.h"
64 #include "content/public/browser/navigation_controller.h"
65 #include "content/public/browser/navigation_entry.h"
66 #include "content/public/browser/notification_service.h"
67 #include "content/public/browser/render_process_host.h"
68 #include "content/public/browser/render_view_host.h"
69 #include "content/public/browser/site_instance.h"
70 #include "content/public/browser/web_contents.h"
71 #include "content/public/browser/web_contents_observer.h"
72 #include "content/public/common/url_constants.h"
73 #include "content/public/test/browser_test_utils.h"
74 #include "content/public/test/test_navigation_observer.h"
75 #include "content/public/test/test_utils.h"
76 #include "content/test/net/url_request_mock_http_job.h"
77 #include "extensions/common/switches.h"
78 #include "grit/generated_resources.h"
79 #include "net/base/escape.h"
80 #include "net/cert/x509_certificate.h"
81 #include "net/dns/mock_host_resolver.h"
82 #include "net/ssl/client_cert_store.h"
83 #include "net/ssl/ssl_cert_request_info.h"
84 #include "net/url_request/url_request_context.h"
85 #include "net/url_request/url_request_context_getter.h"
86 #include "net/url_request/url_request_filter.h"
87 #include "net/url_request/url_request_job.h"
88 #include "ui/base/l10n/l10n_util.h"
91 using content::BrowserThread;
92 using content::DevToolsAgentHost;
93 using content::DevToolsClientHost;
94 using content::DevToolsManager;
95 using content::NavigationController;
96 using content::OpenURLParams;
97 using content::Referrer;
98 using content::RenderViewHost;
99 using content::RenderWidgetHost;
100 using content::TestNavigationObserver;
101 using content::WebContents;
102 using content::WebContentsObserver;
104 // Prerender tests work as follows:
106 // A page with a prefetch link to the test page is loaded. Once prerendered,
107 // its Javascript function DidPrerenderPass() is called, which returns true if
108 // the page behaves as expected when prerendered.
110 // The prerendered page is then displayed on a tab. The Javascript function
111 // DidDisplayPass() is called, and returns true if the page behaved as it
112 // should while being displayed.
114 namespace prerender {
118 // Constants used in the test HTML files.
119 const char* kReadyTitle = "READY";
120 const char* kPassTitle = "PASS";
122 std::string CreateClientRedirect(const std::string& dest_url) {
123 const char* const kClientRedirectBase = "client-redirect?";
124 return kClientRedirectBase + net::EscapeQueryParamValue(dest_url, false);
127 std::string CreateServerRedirect(const std::string& dest_url) {
128 const char* const kServerRedirectBase = "server-redirect?";
129 return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false);
132 // Clears the specified data using BrowsingDataRemover.
133 void ClearBrowsingData(Browser* browser, int remove_mask) {
134 BrowsingDataRemover* remover =
135 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
136 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
137 // BrowsingDataRemover deletes itself.
140 // Returns true if the prerender is expected to abort on its own, before
141 // attempting to swap it.
142 bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) {
144 case FINAL_STATUS_USED:
145 case FINAL_STATUS_WINDOW_OPENER:
146 case FINAL_STATUS_APP_TERMINATING:
147 case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
148 // We'll crash the renderer after it's loaded.
149 case FINAL_STATUS_RENDERER_CRASHED:
150 case FINAL_STATUS_CANCELLED:
151 case FINAL_STATUS_DEVTOOLS_ATTACHED:
152 case FINAL_STATUS_PAGE_BEING_CAPTURED:
153 case FINAL_STATUS_NAVIGATION_UNCOMMITTED:
154 case FINAL_STATUS_WOULD_HAVE_BEEN_USED:
161 // Convenience function to wait for a title. Handles the case when the
162 // WebContents already has the expected title.
163 void WaitForASCIITitle(WebContents* web_contents,
164 const char* expected_title_ascii) {
165 base::string16 expected_title = base::ASCIIToUTF16(expected_title_ascii);
166 if (web_contents->GetTitle() == expected_title)
168 content::TitleWatcher title_watcher(web_contents, expected_title);
169 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
172 // Waits for the destruction of a RenderProcessHost's IPC channel.
173 // Used to make sure the PrerenderLinkManager's OnChannelClosed function has
174 // been called, before checking its state.
175 class ChannelDestructionWatcher {
177 ChannelDestructionWatcher() : channel_destroyed_(false) {
180 ~ChannelDestructionWatcher() {
183 void WatchChannel(content::RenderProcessHost* host) {
184 host->AddFilter(new DestructionMessageFilter(this));
187 void WaitForChannelClose() {
189 EXPECT_TRUE(channel_destroyed_);
193 // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed.
194 // Ignores all messages.
195 class DestructionMessageFilter : public content::BrowserMessageFilter {
197 explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher)
198 : watcher_(watcher) {
202 virtual ~DestructionMessageFilter() {
203 content::BrowserThread::PostTask(
204 content::BrowserThread::UI, FROM_HERE,
205 base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
206 base::Unretained(watcher_)));
209 virtual bool OnMessageReceived(const IPC::Message& message,
210 bool* message_was_ok) OVERRIDE {
214 ChannelDestructionWatcher* watcher_;
216 DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter);
219 void OnChannelDestroyed() {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
222 EXPECT_FALSE(channel_destroyed_);
223 channel_destroyed_ = true;
227 bool channel_destroyed_;
228 base::RunLoop run_loop_;
230 DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher);
233 // A navigation observer to wait on either a new load or a swap of a
234 // WebContents. On swap, if the new WebContents is still loading, wait for that
235 // load to complete as well. Note that the load must begin after the observer is
237 class NavigationOrSwapObserver : public WebContentsObserver,
238 public TabStripModelObserver {
240 // Waits for either a new load or a swap of |tab_strip_model|'s active
242 NavigationOrSwapObserver(TabStripModel* tab_strip_model,
243 WebContents* web_contents)
244 : WebContentsObserver(web_contents),
245 tab_strip_model_(tab_strip_model),
246 did_start_loading_(false),
247 number_of_loads_(1) {
248 CHECK_NE(TabStripModel::kNoTab,
249 tab_strip_model->GetIndexOfWebContents(web_contents));
250 tab_strip_model_->AddObserver(this);
253 // Waits for either |number_of_loads| loads or a swap of |tab_strip_model|'s
254 // active WebContents.
255 NavigationOrSwapObserver(TabStripModel* tab_strip_model,
256 WebContents* web_contents,
258 : WebContentsObserver(web_contents),
259 tab_strip_model_(tab_strip_model),
260 did_start_loading_(false),
261 number_of_loads_(number_of_loads) {
262 CHECK_NE(TabStripModel::kNoTab,
263 tab_strip_model->GetIndexOfWebContents(web_contents));
264 tab_strip_model_->AddObserver(this);
267 virtual ~NavigationOrSwapObserver() {
268 tab_strip_model_->RemoveObserver(this);
275 // WebContentsObserver implementation:
276 virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE {
277 did_start_loading_ = true;
279 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
280 if (!did_start_loading_)
283 if (number_of_loads_ == 0)
287 // TabStripModelObserver implementation:
288 virtual void TabReplacedAt(TabStripModel* tab_strip_model,
289 WebContents* old_contents,
290 WebContents* new_contents,
291 int index) OVERRIDE {
292 if (old_contents != web_contents())
294 // Switch to observing the new WebContents.
295 Observe(new_contents);
296 if (new_contents->IsLoading()) {
297 // If the new WebContents is still loading, wait for it to complete. Only
298 // one load post-swap is supported.
299 did_start_loading_ = true;
300 number_of_loads_ = 1;
307 TabStripModel* tab_strip_model_;
308 bool did_start_loading_;
309 int number_of_loads_;
313 // Waits for a new tab to open and a navigation or swap in it.
314 class NewTabNavigationOrSwapObserver {
316 NewTabNavigationOrSwapObserver()
318 chrome::NOTIFICATION_TAB_ADDED,
319 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded,
320 base::Unretained(this))) {
321 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the
322 // NavigationOrSwapObserver can be attached synchronously and no events are
327 new_tab_observer_.Wait();
328 swap_observer_->Wait();
331 bool OnTabAdded(const content::NotificationSource& source,
332 const content::NotificationDetails& details) {
335 WebContents* new_tab = content::Details<WebContents>(details).ptr();
336 // Get the TabStripModel. Assume this is attached to a Browser.
337 TabStripModel* tab_strip_model =
338 static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model();
339 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model,
345 content::WindowedNotificationObserver new_tab_observer_;
346 scoped_ptr<NavigationOrSwapObserver> swap_observer_;
349 // PrerenderContents that stops the UI message loop on DidStopLoading().
350 class TestPrerenderContents : public PrerenderContents {
352 TestPrerenderContents(
353 PrerenderManager* prerender_manager,
356 const content::Referrer& referrer,
358 FinalStatus expected_final_status)
359 : PrerenderContents(prerender_manager, profile, url,
360 referrer, origin, PrerenderManager::kNoExperiment),
361 expected_final_status_(expected_final_status),
362 new_render_view_host_(NULL),
365 should_be_shown_(expected_final_status == FINAL_STATUS_USED),
366 skip_final_checks_(false) {
369 virtual ~TestPrerenderContents() {
370 if (skip_final_checks_)
373 if (expected_final_status_ == FINAL_STATUS_MAX) {
374 EXPECT_EQ(MATCH_COMPLETE_REPLACEMENT, match_complete_status());
376 EXPECT_EQ(expected_final_status_, final_status()) <<
377 " when testing URL " << prerender_url().path() <<
378 " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
379 ", Actual: " << NameFromFinalStatus(final_status()) << ")";
381 // Prerendering RenderViewHosts should be hidden before the first
382 // navigation, so this should be happen for every PrerenderContents for
383 // which a RenderViewHost is created, regardless of whether or not it's
385 if (new_render_view_host_)
386 EXPECT_TRUE(was_hidden_);
388 // A used PrerenderContents will only be destroyed when we swap out
389 // WebContents, at the end of a navigation caused by a call to
390 // NavigateToURLImpl().
391 if (final_status() == FINAL_STATUS_USED)
392 EXPECT_TRUE(new_render_view_host_);
394 EXPECT_EQ(should_be_shown_, was_shown_);
397 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
398 // On quit, it's possible to end up here when render processes are closed
399 // before the PrerenderManager is destroyed. As a result, it's possible to
400 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
403 // It's also possible for this to be called after we've been notified of
404 // app termination, but before we've been deleted, which is why the second
406 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
407 final_status() != expected_final_status_) {
408 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
411 PrerenderContents::RenderProcessGone(status);
414 virtual bool CheckURL(const GURL& url) OVERRIDE {
415 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
416 // the PrerenderRendererCrash test.
417 if (url.spec() != content::kChromeUICrashURL)
418 return PrerenderContents::CheckURL(url);
422 // For tests that open the prerender in a new background tab, the RenderView
423 // will not have been made visible when the PrerenderContents is destroyed
424 // even though it is used.
425 void set_should_be_shown(bool value) { should_be_shown_ = value; }
427 // For tests which do not know whether the prerender will be used.
428 void set_skip_final_checks(bool value) { skip_final_checks_ = value; }
430 FinalStatus expected_final_status() const { return expected_final_status_; }
433 virtual void OnRenderViewHostCreated(
434 RenderViewHost* new_render_view_host) OVERRIDE {
435 // Used to make sure the RenderViewHost is hidden and, if used,
436 // subsequently shown.
437 notification_registrar().Add(
439 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
440 content::Source<RenderWidgetHost>(new_render_view_host));
442 new_render_view_host_ = new_render_view_host;
444 PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
447 virtual void Observe(int type,
448 const content::NotificationSource& source,
449 const content::NotificationDetails& details) OVERRIDE {
451 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
452 EXPECT_EQ(new_render_view_host_,
453 content::Source<RenderWidgetHost>(source).ptr());
454 bool is_visible = *content::Details<bool>(details).ptr();
458 } else if (is_visible && was_hidden_) {
459 // Once hidden, a prerendered RenderViewHost should only be shown after
460 // being removed from the PrerenderContents for display.
461 EXPECT_FALSE(GetRenderViewHost());
466 PrerenderContents::Observe(type, source, details);
469 FinalStatus expected_final_status_;
471 // The RenderViewHost created for the prerender, if any.
472 RenderViewHost* new_render_view_host_;
473 // Set to true when the prerendering RenderWidget is hidden.
475 // Set to true when the prerendering RenderWidget is shown, after having been
478 // Expected final value of was_shown_. Defaults to true for
479 // FINAL_STATUS_USED, and false otherwise.
480 bool should_be_shown_;
481 // If true, |expected_final_status_| and other shutdown checks are skipped.
482 bool skip_final_checks_;
485 // A handle to a TestPrerenderContents whose lifetime is under the caller's
486 // control. A PrerenderContents may be destroyed at any point. This allows
487 // tracking the final status, etc.
488 class TestPrerender : public PrerenderContents::Observer,
489 public base::SupportsWeakPtr<TestPrerender> {
494 expected_number_of_loads_(0) {
496 virtual ~TestPrerender() {
498 contents_->RemoveObserver(this);
501 TestPrerenderContents* contents() const { return contents_; }
502 int number_of_loads() const { return number_of_loads_; }
504 void WaitForCreate() { create_loop_.Run(); }
505 void WaitForStart() { start_loop_.Run(); }
506 void WaitForStop() { stop_loop_.Run(); }
508 // Waits for |number_of_loads()| to be at least |expected_number_of_loads| OR
509 // for the prerender to stop running (just to avoid a timeout if the prerender
510 // dies). Note: this does not assert equality on the number of loads; the
511 // caller must do it instead.
512 void WaitForLoads(int expected_number_of_loads) {
513 DCHECK(!load_waiter_);
514 DCHECK(!expected_number_of_loads_);
515 if (number_of_loads_ < expected_number_of_loads) {
516 load_waiter_.reset(new base::RunLoop);
517 expected_number_of_loads_ = expected_number_of_loads;
519 load_waiter_.reset();
520 expected_number_of_loads_ = 0;
522 EXPECT_LE(expected_number_of_loads, number_of_loads_);
525 void OnPrerenderCreated(TestPrerenderContents* contents) {
527 contents_ = contents;
528 contents_->AddObserver(this);
532 // PrerenderContents::Observer implementation:
533 virtual void OnPrerenderStart(PrerenderContents* contents) OVERRIDE {
537 virtual void OnPrerenderStopLoading(PrerenderContents* contents) OVERRIDE {
539 if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
540 load_waiter_->Quit();
543 virtual void OnPrerenderStop(PrerenderContents* contents) OVERRIDE {
547 // If there is a WaitForLoads call and it has yet to see the expected number
548 // of loads, stop the loop so the test fails instead of timing out.
550 load_waiter_->Quit();
553 virtual void OnPrerenderCreatedMatchCompleteReplacement(
554 PrerenderContents* contents, PrerenderContents* replacement) OVERRIDE {
558 TestPrerenderContents* contents_;
559 int number_of_loads_;
561 int expected_number_of_loads_;
562 scoped_ptr<base::RunLoop> load_waiter_;
564 base::RunLoop create_loop_;
565 base::RunLoop start_loop_;
566 base::RunLoop stop_loop_;
568 DISALLOW_COPY_AND_ASSIGN(TestPrerender);
571 // PrerenderManager that uses TestPrerenderContents.
572 class TestPrerenderContentsFactory : public PrerenderContents::Factory {
574 TestPrerenderContentsFactory() {}
576 virtual ~TestPrerenderContentsFactory() {
577 EXPECT_TRUE(expected_contents_queue_.empty());
580 scoped_ptr<TestPrerender> ExpectPrerenderContents(FinalStatus final_status) {
581 scoped_ptr<TestPrerender> handle(new TestPrerender());
582 expected_contents_queue_.push_back(
583 ExpectedContents(final_status, handle->AsWeakPtr()));
584 return handle.Pass();
587 virtual PrerenderContents* CreatePrerenderContents(
588 PrerenderManager* prerender_manager,
591 const content::Referrer& referrer,
593 uint8 experiment_id) OVERRIDE {
594 ExpectedContents expected;
595 if (!expected_contents_queue_.empty()) {
596 expected = expected_contents_queue_.front();
597 expected_contents_queue_.pop_front();
599 VLOG(1) << "Creating prerender contents for " << url.path() <<
600 " with expected final status " << expected.final_status;
601 VLOG(1) << expected_contents_queue_.size() << " left in the queue.";
602 TestPrerenderContents* contents =
603 new TestPrerenderContents(prerender_manager,
604 profile, url, referrer, origin,
605 expected.final_status);
607 expected.handle->OnPrerenderCreated(contents);
612 struct ExpectedContents {
613 ExpectedContents() : final_status(FINAL_STATUS_MAX) { }
614 ExpectedContents(FinalStatus final_status,
615 const base::WeakPtr<TestPrerender>& handle)
616 : final_status(final_status),
620 FinalStatus final_status;
621 base::WeakPtr<TestPrerender> handle;
624 std::deque<ExpectedContents> expected_contents_queue_;
627 #if defined(FULL_SAFE_BROWSING)
628 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
630 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
632 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
633 : SafeBrowsingDatabaseManager(service),
634 threat_type_(SB_THREAT_TYPE_SAFE) { }
636 // Called on the IO thread to check if the given url is safe or not. If we
637 // can synchronously determine that the url is safe, CheckUrl returns true.
638 // Otherwise it returns false, and "client" is called asynchronously with the
639 // result when it is ready.
640 // Returns true, indicating a SAFE result, unless the URL is the fixed URL
641 // specified by the user, and the user-specified result is not SAFE
642 // (in which that result will be communicated back via a call into the
643 // client, and false will be returned).
644 // Overrides SafeBrowsingService::CheckBrowseUrl.
645 virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE {
646 if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
649 BrowserThread::PostTask(
650 BrowserThread::IO, FROM_HERE,
651 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
652 this, gurl, client));
656 void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) {
658 threat_type_ = threat_type;
662 virtual ~FakeSafeBrowsingDatabaseManager() {}
664 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
665 std::vector<SBThreatType> expected_threats;
666 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
667 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
668 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
669 std::vector<GURL>(1, gurl),
670 std::vector<SBFullHash>(),
672 safe_browsing_util::MALWARE,
674 sb_check.url_results[0] = threat_type_;
675 client->OnSafeBrowsingResult(sb_check);
679 SBThreatType threat_type_;
680 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
683 class FakeSafeBrowsingService : public SafeBrowsingService {
685 FakeSafeBrowsingService() { }
687 // Returned pointer has the same lifespan as the database_manager_ refcounted
689 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
690 return fake_database_manager_;
694 virtual ~FakeSafeBrowsingService() { }
696 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
697 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
698 return fake_database_manager_;
702 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
704 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
707 // Factory that creates FakeSafeBrowsingService instances.
708 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
710 TestSafeBrowsingServiceFactory() :
711 most_recent_service_(NULL) { }
712 virtual ~TestSafeBrowsingServiceFactory() { }
714 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
715 most_recent_service_ = new FakeSafeBrowsingService();
716 return most_recent_service_;
719 FakeSafeBrowsingService* most_recent_service() const {
720 return most_recent_service_;
724 FakeSafeBrowsingService* most_recent_service_;
728 class FakeDevToolsClientHost : public DevToolsClientHost {
730 FakeDevToolsClientHost() {}
731 virtual ~FakeDevToolsClientHost() {}
732 virtual void InspectedContentsClosing() OVERRIDE {}
733 virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {}
734 virtual void ReplacedWithAnotherClient() OVERRIDE {}
737 class RestorePrerenderMode {
739 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
742 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
744 PrerenderManager::PrerenderManagerMode prev_mode_;
747 // URLRequestJob (and associated handler) which hangs.
748 class HangingURLRequestJob : public net::URLRequestJob {
750 HangingURLRequestJob(net::URLRequest* request,
751 net::NetworkDelegate* network_delegate)
752 : net::URLRequestJob(request, network_delegate) {
755 virtual void Start() OVERRIDE {}
758 virtual ~HangingURLRequestJob() {}
761 class HangingFirstRequestProtocolHandler
762 : public net::URLRequestJobFactory::ProtocolHandler {
764 HangingFirstRequestProtocolHandler(const base::FilePath& file,
765 base::Closure callback)
770 virtual ~HangingFirstRequestProtocolHandler() {}
772 virtual net::URLRequestJob* MaybeCreateJob(
773 net::URLRequest* request,
774 net::NetworkDelegate* network_delegate) const OVERRIDE {
777 BrowserThread::PostTask(
778 BrowserThread::UI, FROM_HERE, callback_);
779 return new HangingURLRequestJob(request, network_delegate);
781 return new content::URLRequestMockHTTPJob(request, network_delegate, file_);
785 base::FilePath file_;
786 base::Closure callback_;
787 mutable bool first_run_;
790 // Makes |url| never respond on the first load, and then with the contents of
791 // |file| afterwards. When the first load has been scheduled, runs |callback| on
793 void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url,
794 const base::FilePath& file,
795 base::Closure callback) {
796 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
797 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler(
798 new HangingFirstRequestProtocolHandler(file, callback));
799 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
800 url, never_respond_handler.Pass());
803 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks.
804 class MockHTTPJob : public content::URLRequestMockHTTPJob {
806 MockHTTPJob(net::URLRequest* request,
807 net::NetworkDelegate* delegate,
808 const base::FilePath& file)
809 : content::URLRequestMockHTTPJob(request, delegate, file) {
812 void set_start_callback(const base::Closure& start_callback) {
813 start_callback_ = start_callback;
816 virtual void Start() OVERRIDE {
817 if (!start_callback_.is_null())
818 start_callback_.Run();
819 content::URLRequestMockHTTPJob::Start();
823 virtual ~MockHTTPJob() {}
825 base::Closure start_callback_;
828 // Dummy counter class to live on the UI thread for counting requests.
829 class RequestCounter : public base::SupportsWeakPtr<RequestCounter> {
831 RequestCounter() : count_(0), expected_count_(-1) {}
832 int count() const { return count_; }
834 void RequestStarted() {
836 if (loop_ && count_ == expected_count_)
840 void WaitForCount(int expected_count) {
842 ASSERT_EQ(-1, expected_count_);
843 if (count_ < expected_count) {
844 expected_count_ = expected_count;
845 loop_.reset(new base::RunLoop);
847 expected_count_ = -1;
851 EXPECT_EQ(expected_count, count_);
856 scoped_ptr<base::RunLoop> loop_;
859 // Protocol handler which counts the number of requests that start.
860 class CountingProtocolHandler
861 : public net::URLRequestJobFactory::ProtocolHandler {
863 CountingProtocolHandler(const base::FilePath& file,
864 const base::WeakPtr<RequestCounter>& counter)
867 weak_factory_(this) {
869 virtual ~CountingProtocolHandler() {}
871 virtual net::URLRequestJob* MaybeCreateJob(
872 net::URLRequest* request,
873 net::NetworkDelegate* network_delegate) const OVERRIDE {
874 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
875 job->set_start_callback(base::Bind(&CountingProtocolHandler::RequestStarted,
876 weak_factory_.GetWeakPtr()));
880 void RequestStarted() {
881 BrowserThread::PostTask(
882 BrowserThread::UI, FROM_HERE,
883 base::Bind(&RequestCounter::RequestStarted, counter_));
887 base::FilePath file_;
888 base::WeakPtr<RequestCounter> counter_;
889 mutable base::WeakPtrFactory<CountingProtocolHandler> weak_factory_;
892 // Makes |url| respond to requests with the contents of |file|, counting the
893 // number that start in |counter|.
894 void CreateCountingProtocolHandlerOnIO(
896 const base::FilePath& file,
897 const base::WeakPtr<RequestCounter>& counter) {
898 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
899 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> protocol_handler(
900 new CountingProtocolHandler(file, counter));
901 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
902 url, protocol_handler.Pass());
905 // Makes |url| respond to requests with the contents of |file|.
906 void CreateMockProtocolHandlerOnIO(const GURL& url,
907 const base::FilePath& file) {
908 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
909 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
910 url, content::URLRequestMockHTTPJob::CreateProtocolHandlerForSingleFile(
914 // A ContentBrowserClient that cancels all prerenderers on OpenURL.
915 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
917 TestContentBrowserClient() {}
918 virtual ~TestContentBrowserClient() {}
920 // chrome::ChromeContentBrowserClient implementation.
921 virtual bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
922 const GURL& url) OVERRIDE {
923 PrerenderManagerFactory::GetForProfile(
924 Profile::FromBrowserContext(site_instance->GetBrowserContext()))
925 ->CancelAllPrerenders();
926 return chrome::ChromeContentBrowserClient::ShouldAllowOpenURL(site_instance,
931 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
934 // A ContentBrowserClient that forces cross-process navigations.
935 class SwapProcessesContentBrowserClient
936 : public chrome::ChromeContentBrowserClient {
938 SwapProcessesContentBrowserClient() {}
939 virtual ~SwapProcessesContentBrowserClient() {}
941 // chrome::ChromeContentBrowserClient implementation.
942 virtual bool ShouldSwapProcessesForRedirect(
943 content::ResourceContext* resource_context,
944 const GURL& current_url,
945 const GURL& new_url) OVERRIDE {
950 DISALLOW_COPY_AND_ASSIGN(SwapProcessesContentBrowserClient);
953 // An ExternalProtocolHandler that blocks everything and asserts it never is
955 class NeverRunsExternalProtocolHandlerDelegate
956 : public ExternalProtocolHandler::Delegate {
958 // ExternalProtocolHandler::Delegate implementation.
959 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
960 ShellIntegration::DefaultWebClientObserver* observer,
961 const std::string& protocol) OVERRIDE {
963 // This will crash, but it shouldn't get this far with BlockState::BLOCK
967 virtual ExternalProtocolHandler::BlockState GetBlockState(
968 const std::string& scheme) OVERRIDE {
969 // Block everything and fail the test.
971 return ExternalProtocolHandler::BLOCK;
973 virtual void BlockRequest() OVERRIDE { }
974 virtual void RunExternalProtocolDialog(const GURL& url,
975 int render_process_host_id,
976 int routing_id) OVERRIDE {
979 virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE {
982 virtual void FinishedProcessingCheck() OVERRIDE {
987 base::FilePath GetTestPath(const std::string& file_name) {
988 return ui_test_utils::GetTestFilePath(
989 base::FilePath(FILE_PATH_LITERAL("prerender")),
990 base::FilePath().AppendASCII(file_name));
995 // Many of these tests are flaky. See http://crbug.com/249179
996 class PrerenderBrowserTest : virtual public InProcessBrowserTest {
998 PrerenderBrowserTest()
999 : autostart_test_server_(true),
1000 prerender_contents_factory_(NULL),
1001 #if defined(FULL_SAFE_BROWSING)
1002 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
1004 call_javascript_(true),
1005 check_load_events_(true),
1006 loader_path_("files/prerender/prerender_loader.html"),
1007 explicitly_set_browser_(NULL) {}
1009 virtual ~PrerenderBrowserTest() {}
1011 content::SessionStorageNamespace* GetSessionStorageNamespace() const {
1012 WebContents* web_contents = GetActiveWebContents();
1015 return web_contents->GetController().GetDefaultSessionStorageNamespace();
1018 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
1019 #if defined(FULL_SAFE_BROWSING)
1020 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
1024 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
1025 #if defined(FULL_SAFE_BROWSING)
1026 SafeBrowsingService::RegisterFactory(NULL);
1030 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1031 command_line->AppendSwitchASCII(switches::kPrerenderMode,
1032 switches::kPrerenderModeSwitchValueEnabled);
1033 #if defined(OS_MACOSX)
1034 // The plugins directory isn't read by default on the Mac, so it needs to be
1035 // explicitly registered.
1036 base::FilePath app_dir;
1037 PathService::Get(chrome::DIR_APP, &app_dir);
1038 command_line->AppendSwitchPath(
1039 switches::kExtraPluginDir,
1040 app_dir.Append(FILE_PATH_LITERAL("plugins")));
1042 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
1045 virtual void SetUpOnMainThread() OVERRIDE {
1046 current_browser()->profile()->GetPrefs()->SetBoolean(
1047 prefs::kPromptForDownload, false);
1048 IncreasePrerenderMemory();
1049 if (autostart_test_server_)
1050 ASSERT_TRUE(test_server()->Start());
1051 ChromeResourceDispatcherHostDelegate::
1052 SetExternalProtocolHandlerDelegateForTesting(
1053 &external_protocol_handler_delegate_);
1055 PrerenderManager* prerender_manager = GetPrerenderManager();
1056 ASSERT_TRUE(prerender_manager);
1057 prerender_manager->mutable_config().rate_limit_enabled = false;
1058 ASSERT_TRUE(prerender_contents_factory_ == NULL);
1059 prerender_contents_factory_ = new TestPrerenderContentsFactory;
1060 prerender_manager->SetPrerenderContentsFactory(prerender_contents_factory_);
1063 // Convenience function to get the currently active WebContents in
1064 // current_browser().
1065 WebContents* GetActiveWebContents() const {
1066 return current_browser()->tab_strip_model()->GetActiveWebContents();
1069 // Overload for a single expected final status
1070 scoped_ptr<TestPrerender> PrerenderTestURL(
1071 const std::string& html_file,
1072 FinalStatus expected_final_status,
1073 int expected_number_of_loads) {
1074 GURL url = test_server()->GetURL(html_file);
1075 return PrerenderTestURL(url,
1076 expected_final_status,
1077 expected_number_of_loads);
1080 ScopedVector<TestPrerender> PrerenderTestURL(
1081 const std::string& html_file,
1082 const std::vector<FinalStatus>& expected_final_status_queue,
1083 int expected_number_of_loads) {
1084 GURL url = test_server()->GetURL(html_file);
1085 return PrerenderTestURLImpl(url,
1086 expected_final_status_queue,
1087 expected_number_of_loads);
1090 scoped_ptr<TestPrerender> PrerenderTestURL(
1092 FinalStatus expected_final_status,
1093 int expected_number_of_loads) {
1094 std::vector<FinalStatus> expected_final_status_queue(
1095 1, expected_final_status);
1096 std::vector<TestPrerender*> prerenders;
1097 PrerenderTestURLImpl(url,
1098 expected_final_status_queue,
1099 expected_number_of_loads).release(&prerenders);
1100 CHECK_EQ(1u, prerenders.size());
1101 return scoped_ptr<TestPrerender>(prerenders[0]);
1104 void NavigateToDestURL() const {
1105 NavigateToDestURLWithDisposition(CURRENT_TAB, true);
1108 // Opens the url in a new tab, with no opener.
1109 void NavigateToDestURLWithDisposition(
1110 WindowOpenDisposition disposition,
1111 bool expect_swap_to_succeed) const {
1112 NavigateToURLWithParams(
1113 content::OpenURLParams(dest_url_, Referrer(), disposition,
1114 content::PAGE_TRANSITION_TYPED, false),
1115 expect_swap_to_succeed);
1118 void NavigateToURL(const std::string& dest_html_file) const {
1119 NavigateToURLWithDisposition(dest_html_file, CURRENT_TAB, true);
1122 void NavigateToURLWithDisposition(const std::string& dest_html_file,
1123 WindowOpenDisposition disposition,
1124 bool expect_swap_to_succeed) const {
1125 GURL dest_url = test_server()->GetURL(dest_html_file);
1126 NavigateToURLWithDisposition(dest_url, disposition, expect_swap_to_succeed);
1129 void NavigateToURLWithDisposition(const GURL& dest_url,
1130 WindowOpenDisposition disposition,
1131 bool expect_swap_to_succeed) const {
1132 NavigateToURLWithParams(
1133 content::OpenURLParams(dest_url, Referrer(), disposition,
1134 content::PAGE_TRANSITION_TYPED, false),
1135 expect_swap_to_succeed);
1138 void NavigateToURLWithParams(const content::OpenURLParams& params,
1139 bool expect_swap_to_succeed) const {
1140 NavigateToURLImpl(params, expect_swap_to_succeed);
1143 void OpenDestURLViaClick() const {
1144 OpenURLViaClick(dest_url_);
1147 void OpenURLViaClick(const GURL& url) const {
1148 OpenURLWithJSImpl("Click", url, GURL(), false);
1151 void OpenDestURLViaClickTarget() const {
1152 OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true);
1155 void OpenDestURLViaClickPing(const GURL& ping_url) const {
1156 OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false);
1159 void OpenDestURLViaClickNewWindow() const {
1160 OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true);
1163 void OpenDestURLViaClickNewForegroundTab() const {
1164 #if defined(OS_MACOSX)
1165 OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true);
1167 OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true);
1171 void OpenDestURLViaClickNewBackgroundTab() const {
1172 #if defined(OS_MACOSX)
1173 OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true);
1175 OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true);
1179 void OpenDestURLViaWindowOpen() const {
1180 OpenURLWithJSImpl("WindowOpen", dest_url_, GURL(), true);
1183 void RemoveLinkElement(int i) const {
1184 GetActiveWebContents()->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
1186 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i)));
1189 void ClickToNextPageAfterPrerender() {
1190 TestNavigationObserver nav_observer(GetActiveWebContents());
1191 RenderViewHost* render_view_host =
1192 GetActiveWebContents()->GetRenderViewHost();
1193 render_view_host->ExecuteJavascriptInWebFrame(
1195 base::ASCIIToUTF16("ClickOpenLink()"));
1196 nav_observer.Wait();
1199 void NavigateToNextPageAfterPrerender() const {
1200 ui_test_utils::NavigateToURL(
1202 test_server()->GetURL("files/prerender/prerender_page.html"));
1205 // Called after the prerendered page has been navigated to and then away from.
1206 // Navigates back through the history to the prerendered page.
1207 void GoBackToPrerender() {
1208 TestNavigationObserver back_nav_observer(GetActiveWebContents());
1209 chrome::GoBack(current_browser(), CURRENT_TAB);
1210 back_nav_observer.Wait();
1211 bool original_prerender_page = false;
1212 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1213 GetActiveWebContents(),
1214 "window.domAutomationController.send(IsOriginalPrerenderPage())",
1215 &original_prerender_page));
1216 EXPECT_TRUE(original_prerender_page);
1219 // Goes back to the page that was active before the prerender was swapped
1220 // in. This must be called when the prerendered page is the current page
1221 // in the active tab.
1222 void GoBackToPageBeforePrerender() {
1223 WebContents* tab = GetActiveWebContents();
1225 EXPECT_FALSE(tab->IsLoading());
1226 TestNavigationObserver back_nav_observer(tab);
1227 chrome::GoBack(current_browser(), CURRENT_TAB);
1228 back_nav_observer.Wait();
1230 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1232 "window.domAutomationController.send(DidBackToOriginalPagePass())",
1234 EXPECT_TRUE(js_result);
1237 bool UrlIsInPrerenderManager(const std::string& html_file) const {
1238 return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
1241 bool UrlIsInPrerenderManager(const GURL& url) const {
1242 return GetPrerenderManager()->FindPrerenderData(
1243 url, GetSessionStorageNamespace()) != NULL;
1246 void UseHttpsSrcServer() {
1247 if (https_src_server_)
1249 https_src_server_.reset(
1250 new net::SpawnedTestServer(
1251 net::SpawnedTestServer::TYPE_HTTPS,
1252 net::SpawnedTestServer::kLocalhost,
1253 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
1254 CHECK(https_src_server_->Start());
1257 void DisableJavascriptCalls() {
1258 call_javascript_ = false;
1261 void DisableLoadEventCheck() {
1262 check_load_events_ = false;
1265 TaskManagerModel* GetModel() const {
1266 return TaskManager::GetInstance()->model();
1269 PrerenderManager* GetPrerenderManager() const {
1270 PrerenderManager* prerender_manager =
1271 PrerenderManagerFactory::GetForProfile(current_browser()->profile());
1272 return prerender_manager;
1275 const PrerenderLinkManager* GetPrerenderLinkManager() const {
1276 PrerenderLinkManager* prerender_link_manager =
1277 PrerenderLinkManagerFactory::GetForProfile(
1278 current_browser()->profile());
1279 return prerender_link_manager;
1282 bool DidReceivePrerenderStartEventForLinkNumber(int index) const {
1283 bool received_prerender_started;
1284 std::string expression = base::StringPrintf(
1285 "window.domAutomationController.send(Boolean("
1286 "receivedPrerenderStartEvents[%d]))", index);
1288 CHECK(content::ExecuteScriptAndExtractBool(
1289 GetActiveWebContents(),
1291 &received_prerender_started));
1292 return received_prerender_started;
1295 int GetPrerenderLoadEventCountForLinkNumber(int index) const {
1296 int load_event_count;
1297 std::string expression = base::StringPrintf(
1298 "window.domAutomationController.send("
1299 "receivedPrerenderLoadEvents[%d] || 0)", index);
1301 CHECK(content::ExecuteScriptAndExtractInt(
1302 GetActiveWebContents(),
1304 &load_event_count));
1305 return load_event_count;
1308 int GetPrerenderDomContentLoadedEventCountForLinkNumber(int index) const {
1309 int dom_content_loaded_event_count;
1310 std::string expression = base::StringPrintf(
1311 "window.domAutomationController.send("
1312 "receivedPrerenderDomContentLoadedEvents[%d] || 0)", index);
1314 CHECK(content::ExecuteScriptAndExtractInt(
1315 GetActiveWebContents(),
1317 &dom_content_loaded_event_count));
1318 return dom_content_loaded_event_count;
1321 bool DidReceivePrerenderStopEventForLinkNumber(int index) const {
1322 bool received_prerender_stopped;
1323 std::string expression = base::StringPrintf(
1324 "window.domAutomationController.send(Boolean("
1325 "receivedPrerenderStopEvents[%d]))", index);
1327 CHECK(content::ExecuteScriptAndExtractBool(
1328 GetActiveWebContents(),
1330 &received_prerender_stopped));
1331 return received_prerender_stopped;
1334 bool HadPrerenderEventErrors() const {
1335 bool had_prerender_event_errors;
1336 CHECK(content::ExecuteScriptAndExtractBool(
1337 GetActiveWebContents(),
1338 "window.domAutomationController.send(Boolean("
1339 " hadPrerenderEventErrors))",
1340 &had_prerender_event_errors));
1341 return had_prerender_event_errors;
1344 // Asserting on this can result in flaky tests. PrerenderHandles are
1345 // removed from the PrerenderLinkManager when the prerender is canceled from
1346 // the browser, when the prerenders are cancelled from the renderer process,
1347 // or the channel for the renderer process is closed on the IO thread. In the
1348 // last case, the code must be careful to wait for the channel to close, as it
1349 // is done asynchronously after swapping out the old process. See
1350 // ChannelDestructionWatcher.
1351 bool IsEmptyPrerenderLinkManager() const {
1352 return GetPrerenderLinkManager()->IsEmpty();
1355 size_t GetLinkPrerenderCount() const {
1356 return GetPrerenderLinkManager()->prerenders_.size();
1359 size_t GetRunningLinkPrerenderCount() const {
1360 return GetPrerenderLinkManager()->CountRunningPrerenders();
1363 // Returns length of |prerender_manager_|'s history, or -1 on failure.
1364 int GetHistoryLength() const {
1365 scoped_ptr<base::DictionaryValue> prerender_dict(
1366 static_cast<base::DictionaryValue*>(
1367 GetPrerenderManager()->GetAsValue()));
1368 if (!prerender_dict.get())
1370 base::ListValue* history_list;
1371 if (!prerender_dict->GetList("history", &history_list))
1373 return static_cast<int>(history_list->GetSize());
1376 #if defined(FULL_SAFE_BROWSING)
1377 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() {
1378 return safe_browsing_factory_->most_recent_service()->
1379 fake_database_manager();
1383 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const {
1384 PrerenderManager::PrerenderData* prerender_data =
1385 GetPrerenderManager()->FindPrerenderData(url, NULL);
1386 return static_cast<TestPrerenderContents*>(
1387 prerender_data ? prerender_data->contents() : NULL);
1390 void SetLoaderHostOverride(const std::string& host) {
1391 loader_host_override_ = host;
1392 host_resolver()->AddRule(host, "127.0.0.1");
1395 void set_loader_path(const std::string& path) {
1396 loader_path_ = path;
1399 void set_loader_query_and_fragment(const std::string& query_and_fragment) {
1400 loader_query_and_fragment_ = query_and_fragment;
1403 GURL GetCrossDomainTestUrl(const std::string& path) {
1404 static const std::string secondary_domain = "www.foo.com";
1405 host_resolver()->AddRule(secondary_domain, "127.0.0.1");
1406 std::string url_str(base::StringPrintf(
1408 secondary_domain.c_str(),
1409 test_server()->host_port_pair().port(),
1411 return GURL(url_str);
1414 void set_browser(Browser* browser) {
1415 explicitly_set_browser_ = browser;
1418 Browser* current_browser() const {
1419 return explicitly_set_browser_ ? explicitly_set_browser_ : browser();
1422 const GURL& dest_url() const {
1426 void IncreasePrerenderMemory() {
1427 // Increase the memory allowed in a prerendered page above normal settings.
1428 // Debug build bots occasionally run against the default limit, and tests
1429 // were failing because the prerender was canceled due to memory exhaustion.
1430 // http://crbug.com/93076
1431 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024;
1434 bool DidPrerenderPass(WebContents* web_contents) const {
1435 bool prerender_test_result = false;
1436 if (!content::ExecuteScriptAndExtractBool(
1438 "window.domAutomationController.send(DidPrerenderPass())",
1439 &prerender_test_result))
1441 return prerender_test_result;
1444 bool DidDisplayPass(WebContents* web_contents) const {
1445 bool display_test_result = false;
1446 if (!content::ExecuteScriptAndExtractBool(
1448 "window.domAutomationController.send(DidDisplayPass())",
1449 &display_test_result))
1451 return display_test_result;
1454 scoped_ptr<TestPrerender> ExpectPrerender(FinalStatus expected_final_status) {
1455 return prerender_contents_factory_->ExpectPrerenderContents(
1456 expected_final_status);
1459 void AddPrerender(const GURL& url, int index) {
1460 std::string javascript = base::StringPrintf(
1461 "AddPrerender('%s', %d)", url.spec().c_str(), index);
1462 RenderViewHost* render_view_host =
1463 GetActiveWebContents()->GetRenderViewHost();
1464 render_view_host->ExecuteJavascriptInWebFrame(
1465 base::string16(), base::ASCIIToUTF16(javascript));
1469 bool autostart_test_server_;
1472 // TODO(davidben): Remove this altogether so the tests don't globally assume
1473 // only one prerender.
1474 TestPrerenderContents* GetPrerenderContents() const {
1475 return GetPrerenderContentsFor(dest_url_);
1478 ScopedVector<TestPrerender> PrerenderTestURLImpl(
1479 const GURL& prerender_url,
1480 const std::vector<FinalStatus>& expected_final_status_queue,
1481 int expected_number_of_loads) {
1482 dest_url_ = prerender_url;
1484 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
1485 replacement_text.push_back(
1486 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
1487 std::string replacement_path;
1488 CHECK(net::SpawnedTestServer::GetFilePathWithReplacements(
1491 &replacement_path));
1493 const net::SpawnedTestServer* src_server = test_server();
1494 if (https_src_server_)
1495 src_server = https_src_server_.get();
1496 GURL loader_url = src_server->GetURL(replacement_path +
1497 loader_query_and_fragment_);
1499 GURL::Replacements loader_replacements;
1500 if (!loader_host_override_.empty())
1501 loader_replacements.SetHostStr(loader_host_override_);
1502 loader_url = loader_url.ReplaceComponents(loader_replacements);
1504 VLOG(1) << "Running test with queue length " <<
1505 expected_final_status_queue.size();
1506 CHECK(!expected_final_status_queue.empty());
1507 ScopedVector<TestPrerender> prerenders;
1508 for (size_t i = 0; i < expected_final_status_queue.size(); i++) {
1509 prerenders.push_back(
1510 prerender_contents_factory_->ExpectPrerenderContents(
1511 expected_final_status_queue[i]).release());
1514 FinalStatus expected_final_status = expected_final_status_queue.front();
1516 // Navigate to the loader URL and then wait for the first prerender to be
1518 ui_test_utils::NavigateToURL(current_browser(), loader_url);
1519 prerenders[0]->WaitForCreate();
1520 prerenders[0]->WaitForLoads(expected_number_of_loads);
1522 if (ShouldAbortPrerenderBeforeSwap(expected_final_status)) {
1523 // The prerender will abort on its own. Assert it does so correctly.
1524 prerenders[0]->WaitForStop();
1525 EXPECT_FALSE(prerenders[0]->contents());
1526 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
1528 // Otherwise, check that it prerendered correctly.
1529 TestPrerenderContents* prerender_contents = prerenders[0]->contents();
1531 CHECK_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1532 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
1533 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1535 if (call_javascript_) {
1536 // Check if page behaves as expected while in prerendered state.
1537 EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents()));
1541 // Test that the referring page received the right start and load events.
1542 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1543 if (check_load_events_) {
1544 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads());
1545 EXPECT_EQ(expected_number_of_loads,
1546 GetPrerenderLoadEventCountForLinkNumber(0));
1548 EXPECT_FALSE(HadPrerenderEventErrors());
1550 return prerenders.Pass();
1553 void NavigateToURLImpl(const content::OpenURLParams& params,
1554 bool expect_swap_to_succeed) const {
1555 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager());
1556 // Make sure in navigating we have a URL to use in the PrerenderManager.
1557 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
1559 WebContents* web_contents = GetPrerenderContents()->prerender_contents();
1561 // Navigate and wait for either the load to finish normally or for a swap to
1563 // TODO(davidben): The only handles CURRENT_TAB navigations, which is the
1564 // only case tested or prerendered right now.
1565 CHECK_EQ(CURRENT_TAB, params.disposition);
1566 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
1567 GetActiveWebContents());
1568 WebContents* target_web_contents = current_browser()->OpenURL(params);
1569 swap_observer.Wait();
1571 if (web_contents && expect_swap_to_succeed) {
1572 EXPECT_EQ(web_contents, target_web_contents);
1573 if (call_javascript_)
1574 EXPECT_TRUE(DidDisplayPass(web_contents));
1578 // Opens the prerendered page using javascript functions in the loader
1579 // page. |javascript_function_name| should be a 0 argument function which is
1580 // invoked. |new_web_contents| is true if the navigation is expected to
1581 // happen in a new WebContents via OpenURL.
1582 void OpenURLWithJSImpl(const std::string& javascript_function_name,
1584 const GURL& ping_url,
1585 bool new_web_contents) const {
1586 WebContents* web_contents = GetActiveWebContents();
1587 RenderViewHost* render_view_host =
1588 GetActiveWebContents()->GetRenderViewHost();
1589 // Extra arguments in JS are ignored.
1590 std::string javascript = base::StringPrintf(
1591 "%s('%s', '%s')", javascript_function_name.c_str(),
1592 url.spec().c_str(), ping_url.spec().c_str());
1594 if (new_web_contents) {
1595 NewTabNavigationOrSwapObserver observer;
1596 render_view_host->ExecuteJavascriptInWebFrame(
1597 base::string16(), base::ASCIIToUTF16(javascript));
1600 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
1602 render_view_host->ExecuteJavascriptInWebFrame(
1603 base::string16(), base::ASCIIToUTF16(javascript));
1608 TestPrerenderContentsFactory* prerender_contents_factory_;
1609 #if defined(FULL_SAFE_BROWSING)
1610 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_;
1612 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_;
1614 scoped_ptr<net::SpawnedTestServer> https_src_server_;
1615 bool call_javascript_;
1616 bool check_load_events_;
1617 std::string loader_host_override_;
1618 std::string loader_path_;
1619 std::string loader_query_and_fragment_;
1620 Browser* explicitly_set_browser_;
1623 // Checks that a page is correctly prerendered in the case of a
1624 // <link rel=prerender> tag and then loaded into a tab in response to a
1626 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
1627 UMAHistogramHelper histograms;
1629 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1630 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
1632 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
1633 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
1634 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
1635 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
1637 ChannelDestructionWatcher channel_close_watcher;
1638 channel_close_watcher.WatchChannel(
1639 GetActiveWebContents()->GetRenderProcessHost());
1640 NavigateToDestURL();
1641 channel_close_watcher.WaitForChannelClose();
1644 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
1645 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1);
1646 histograms.ExpectTotalCount(
1647 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
1649 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1652 // Checks that cross-domain prerenders emit the correct histograms.
1653 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageCrossDomain) {
1654 UMAHistogramHelper histograms;
1656 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
1657 FINAL_STATUS_USED, 1);
1659 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
1660 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
1661 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
1662 histograms.ExpectTotalCount("Prerender.webcross_PrerenderNotSwappedInPLT", 1);
1664 NavigateToDestURL();
1666 histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLT", 1);
1667 histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLTMatched", 1);
1668 histograms.ExpectTotalCount(
1669 "Prerender.webcross_PerceivedPLTMatchedComplete", 1);
1672 // Checks that pending prerenders launch and receive proper event treatment.
1673 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPagePending) {
1674 scoped_ptr<TestPrerender> prerender =
1675 PrerenderTestURL("files/prerender/prerender_page_pending.html",
1676 FINAL_STATUS_USED, 1);
1678 // Navigate to the prerender.
1679 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
1680 NavigateToDestURL();
1681 // Abort early if the original prerender didn't swap, so as not to hang.
1682 ASSERT_FALSE(prerender->contents());
1684 // Wait for the new prerender to be ready.
1685 prerender2->WaitForStart();
1686 prerender2->WaitForLoads(1);
1688 const GURL prerender_page_url =
1689 test_server()->GetURL("files/prerender/prerender_page.html");
1690 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1691 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL),
1692 GetPrerenderContentsFor(prerender_page_url));
1694 // Now navigate to our target page.
1695 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
1696 GetActiveWebContents());
1697 ui_test_utils::NavigateToURLWithDisposition(
1698 current_browser(), prerender_page_url, CURRENT_TAB,
1699 ui_test_utils::BROWSER_TEST_NONE);
1700 swap_observer.Wait();
1702 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1705 // Checks that pending prerenders which are canceled before they are launched
1706 // never get started.
1707 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) {
1708 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html",
1709 FINAL_STATUS_USED, 1);
1711 ChannelDestructionWatcher channel_close_watcher;
1712 channel_close_watcher.WatchChannel(
1713 GetActiveWebContents()->GetRenderProcessHost());
1714 NavigateToDestURL();
1715 channel_close_watcher.WaitForChannelClose();
1717 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1));
1718 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1719 EXPECT_FALSE(HadPrerenderEventErrors());
1720 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1721 // calls did a thread/process hop to the renderer which insured pending
1722 // renderer events have arrived.
1723 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1726 // Flaky, http://crbug.com/167340.
1727 IN_PROC_BROWSER_TEST_F(
1728 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLink) {
1729 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1730 set_loader_query_and_fragment("?links_to_insert=1");
1731 PrerenderTestURL("files/prerender/prerender_page.html",
1732 FINAL_STATUS_CANCELLED, 1);
1734 // No ChannelDestructionWatcher is needed here, since prerenders in the
1735 // PrerenderLinkManager should be deleted by removing the links, rather than
1736 // shutting down the renderer process.
1737 RemoveLinkElement(0);
1738 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1739 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1740 EXPECT_FALSE(HadPrerenderEventErrors());
1741 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1742 // calls did a thread/process hop to the renderer which insured pending
1743 // renderer events have arrived.
1744 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1747 // Flaky, http://crbug.com/167340.
1748 IN_PROC_BROWSER_TEST_F(
1749 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLinkWithTwoLinks) {
1750 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1751 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1753 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1754 set_loader_query_and_fragment("?links_to_insert=2");
1755 PrerenderTestURL("files/prerender/prerender_page.html",
1756 FINAL_STATUS_CANCELLED, 1);
1757 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1758 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1759 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1760 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1762 RemoveLinkElement(0);
1763 RemoveLinkElement(1);
1764 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1765 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1766 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1767 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1768 EXPECT_FALSE(HadPrerenderEventErrors());
1769 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1770 // calls did a thread/process hop to the renderer which insured pending
1771 // renderer events have arrived.
1772 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1776 // TODO(gavinp): Fails on XP Rel - http://crbug.com/128841
1777 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1778 DISABLED_PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1780 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1781 PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1782 #endif // defined(OS_WIN)
1783 IN_PROC_BROWSER_TEST_F(
1784 PrerenderBrowserTest,
1785 MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne) {
1786 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1787 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1788 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1789 set_loader_query_and_fragment("?links_to_insert=2");
1790 PrerenderTestURL("files/prerender/prerender_page.html",
1791 FINAL_STATUS_USED, 1);
1792 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1793 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1794 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1795 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1797 RemoveLinkElement(0);
1798 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1799 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1800 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1801 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1802 EXPECT_FALSE(HadPrerenderEventErrors());
1803 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1804 // calls did a thread/process hop to the renderer which insured pending
1805 // renderer events have arrived.
1806 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1808 ChannelDestructionWatcher channel_close_watcher;
1809 channel_close_watcher.WatchChannel(
1810 GetActiveWebContents()->GetRenderProcessHost());
1811 NavigateToDestURL();
1812 channel_close_watcher.WaitForChannelClose();
1814 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1817 // Checks that the visibility API works.
1818 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) {
1819 PrerenderTestURL("files/prerender/prerender_visibility.html",
1822 NavigateToDestURL();
1825 // Checks that the prerendering of a page is canceled correctly if we try to
1826 // swap it in before it commits.
1827 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) {
1828 // Navigate to a page that triggers a prerender for a URL that never commits.
1829 const GURL kNoCommitUrl("http://never-respond.example.com");
1830 base::FilePath file(GetTestPath("prerender_page.html"));
1832 base::RunLoop prerender_start_loop;
1833 BrowserThread::PostTask(
1834 BrowserThread::IO, FROM_HERE,
1835 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO,
1836 kNoCommitUrl, file, prerender_start_loop.QuitClosure()));
1837 DisableJavascriptCalls();
1838 PrerenderTestURL(kNoCommitUrl,
1839 FINAL_STATUS_NAVIGATION_UNCOMMITTED,
1841 // Wait for the hanging request to be scheduled.
1842 prerender_start_loop.Run();
1844 // Navigate to the URL, but assume the contents won't be swapped in.
1845 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
1848 // Checks that client redirects don't add alias URLs until after they commit.
1849 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) {
1850 // Navigate to a page that then navigates to a URL that never commits.
1851 const GURL kNoCommitUrl("http://never-respond.example.com");
1852 base::FilePath file(GetTestPath("prerender_page.html"));
1854 base::RunLoop prerender_start_loop;
1855 BrowserThread::PostTask(
1856 BrowserThread::IO, FROM_HERE,
1857 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO,
1858 kNoCommitUrl, file, prerender_start_loop.QuitClosure()));
1859 DisableJavascriptCalls();
1860 PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()),
1861 FINAL_STATUS_APP_TERMINATING, 1);
1862 // Wait for the hanging request to be scheduled.
1863 prerender_start_loop.Run();
1865 // Navigating to the second URL should not swap.
1866 NavigateToURLWithDisposition(kNoCommitUrl, CURRENT_TAB, false);
1869 // Checks that the prerendering of a page is canceled correctly when a
1870 // Javascript alert is called.
1871 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
1872 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
1873 FINAL_STATUS_JAVASCRIPT_ALERT,
1877 // Checks that the prerendering of a page is canceled correctly when a
1878 // Javascript alert is called.
1879 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
1880 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
1881 FINAL_STATUS_JAVASCRIPT_ALERT,
1885 // Checks that plugins are not loaded while a page is being preloaded, but
1886 // are loaded when the page is displayed.
1887 #if defined(USE_AURA) && !defined(OS_WIN)
1888 // http://crbug.com/103496
1889 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1890 #elif defined(OS_MACOSX)
1891 // http://crbug.com/100514
1892 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1893 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
1894 // TODO(jschuh): Failing plugin tests. crbug.com/244653
1895 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1896 #elif defined(OS_LINUX)
1897 // http://crbug.com/306715
1898 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1900 #define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin
1902 // http://crbug.com/306715
1903 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) {
1904 PrerenderTestURL("files/prerender/plugin_delay_load.html",
1907 NavigateToDestURL();
1910 // Checks that plugins are not loaded on prerendering pages when click-to-play
1912 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) {
1913 // Enable click-to-play.
1914 HostContentSettingsMap* content_settings_map =
1915 current_browser()->profile()->GetHostContentSettingsMap();
1916 content_settings_map->SetDefaultContentSetting(
1917 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK);
1919 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html",
1922 NavigateToDestURL();
1925 // Checks that we don't load a NaCl plugin when NaCl is disabled.
1926 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) {
1927 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html",
1930 NavigateToDestURL();
1933 // Run this check again. When we try to load aa ppapi plugin, the
1934 // "loadstart" event is asynchronously posted to a message loop.
1935 // It's possible that earlier call could have been run before the
1936 // the "loadstart" event was posted.
1937 // TODO(mmenke): While this should reliably fail on regressions, the
1938 // reliability depends on the specifics of ppapi plugin
1939 // loading. It would be great if we could avoid that.
1940 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
1943 // Checks that plugins in an iframe are not loaded while a page is
1944 // being preloaded, but are loaded when the page is displayed.
1945 #if defined(USE_AURA) && !defined(OS_WIN)
1946 // http://crbug.com/103496
1947 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1948 DISABLED_PrerenderIframeDelayLoadPlugin
1949 #elif defined(OS_MACOSX)
1950 // http://crbug.com/100514
1951 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1952 DISABLED_PrerenderIframeDelayLoadPlugin
1953 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
1954 // TODO(jschuh): Failing plugin tests. crbug.com/244653
1955 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1956 DISABLED_PrerenderIframeDelayLoadPlugin
1958 #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin
1960 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1961 MAYBE_PrerenderIframeDelayLoadPlugin) {
1962 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
1965 NavigateToDestURL();
1968 // Renders a page that contains a prerender link to a page that contains an
1969 // iframe with a source that requires http authentication. This should not
1970 // prerender successfully.
1971 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
1972 PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
1973 FINAL_STATUS_AUTH_NEEDED,
1977 // Checks that client-issued redirects work with prerendering.
1978 // This version navigates to the page which issues the redirection, rather
1979 // than the final destination page.
1980 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1981 PrerenderClientRedirectNavigateToFirst) {
1982 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1985 NavigateToDestURL();
1988 // Checks that client-issued redirects work with prerendering.
1989 // This version navigates to the final destination page, rather than the
1990 // page which does the redirection.
1991 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1992 PrerenderClientRedirectNavigateToSecond) {
1993 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1996 NavigateToURL("files/prerender/prerender_page.html");
1999 // Checks that redirects with location.replace do not cancel a prerender and
2000 // and swap when navigating to the first page.
2001 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2002 PrerenderLocationReplaceNavigateToFirst) {
2003 PrerenderTestURL("files/prerender/prerender_location_replace.html",
2006 NavigateToDestURL();
2009 // Checks that redirects with location.replace do not cancel a prerender and
2010 // and swap when navigating to the second.
2011 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2012 PrerenderLocationReplaceNavigateToSecond) {
2013 PrerenderTestURL("files/prerender/prerender_location_replace.html",
2016 NavigateToURL("files/prerender/prerender_page.html");
2019 // Checks that we get the right PPLT histograms for client redirect prerenders
2020 // and navigations when the referring page is Google.
2021 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2022 PrerenderLocationReplaceGWSHistograms) {
2023 DisableJavascriptCalls();
2024 UMAHistogramHelper histograms;
2026 // The loader page should look like Google.
2027 const std::string kGoogleDotCom("www.google.com");
2028 SetLoaderHostOverride(kGoogleDotCom);
2029 set_loader_path("files/prerender/prerender_loader_with_replace_state.html");
2031 GURL dest_url = GetCrossDomainTestUrl(
2032 "files/prerender/prerender_deferred_image.html");
2034 GURL prerender_url = test_server()->GetURL(
2035 "files/prerender/prerender_location_replace.html?" +
2036 net::EscapeQueryParamValue(dest_url.spec(), false) +
2038 GURL::Replacements replacements;
2039 replacements.SetHostStr(kGoogleDotCom);
2040 prerender_url = prerender_url.ReplaceComponents(replacements);
2042 // The prerender will not completely load until after the swap, so wait for a
2043 // title change before calling DidPrerenderPass.
2044 scoped_ptr<TestPrerender> prerender =
2045 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
2046 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
2047 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
2048 EXPECT_EQ(1, prerender->number_of_loads());
2051 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
2052 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
2053 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
2054 // Although there is a client redirect, it is dropped from histograms because
2055 // it is a Google URL. The target page itself does not load until after the
2057 histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0);
2059 GURL navigate_url = test_server()->GetURL(
2060 "files/prerender/prerender_location_replace.html?" +
2061 net::EscapeQueryParamValue(dest_url.spec(), false) +
2063 navigate_url = navigate_url.ReplaceComponents(replacements);
2065 NavigationOrSwapObserver swap_observer(
2066 current_browser()->tab_strip_model(),
2067 GetActiveWebContents(), 2);
2068 current_browser()->OpenURL(OpenURLParams(
2069 navigate_url, Referrer(), CURRENT_TAB,
2070 content::PAGE_TRANSITION_TYPED, false));
2071 swap_observer.Wait();
2073 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
2076 histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0);
2077 histograms.ExpectTotalCount("Prerender.gws_PerceivedPLT", 1);
2078 histograms.ExpectTotalCount("Prerender.gws_PerceivedPLTMatched", 1);
2079 histograms.ExpectTotalCount(
2080 "Prerender.gws_PerceivedPLTMatchedComplete", 1);
2082 // The client redirect does /not/ count as a miss because it's a Google URL.
2083 histograms.ExpectTotalCount("Prerender.PerceivedPLTFirstAfterMiss", 0);
2086 // Checks that client-issued redirects work with prerendering.
2087 // This version navigates to the final destination page, rather than the
2088 // page which does the redirection via a mouse click.
2089 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2090 PrerenderClientRedirectNavigateToSecondViaClick) {
2091 GURL prerender_url = test_server()->GetURL(
2092 CreateClientRedirect("files/prerender/prerender_page.html"));
2093 GURL destination_url = test_server()->GetURL(
2094 "files/prerender/prerender_page.html");
2095 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 2);
2096 OpenURLViaClick(destination_url);
2099 // Checks that a page served over HTTPS is correctly prerendered.
2100 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) {
2101 net::SpawnedTestServer https_server(
2102 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2103 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2104 ASSERT_TRUE(https_server.Start());
2105 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2106 PrerenderTestURL(https_url,
2109 NavigateToDestURL();
2112 // Checks that client-issued redirects within an iframe in a prerendered
2113 // page will not count as an "alias" for the prerendered page.
2114 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2115 PrerenderClientRedirectInIframe) {
2116 std::string redirect_path = CreateClientRedirect(
2117 "/files/prerender/prerender_embedded_content.html");
2118 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2119 replacement_text.push_back(
2120 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2121 std::string replacement_path;
2122 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2123 "files/prerender/prerender_with_iframe.html",
2125 &replacement_path));
2126 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
2127 EXPECT_FALSE(UrlIsInPrerenderManager(
2128 "files/prerender/prerender_embedded_content.html"));
2129 NavigateToDestURL();
2132 // Checks that server-issued redirects work with prerendering.
2133 // This version navigates to the page which issues the redirection, rather
2134 // than the final destination page.
2135 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2136 PrerenderServerRedirectNavigateToFirst) {
2137 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2140 NavigateToDestURL();
2143 // Checks that server-issued redirects work with prerendering.
2144 // This version navigates to the final destination page, rather than the
2145 // page which does the redirection.
2146 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2147 PrerenderServerRedirectNavigateToSecond) {
2148 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2151 NavigateToURL("files/prerender/prerender_page.html");
2154 // Checks that server-issued redirects work with prerendering.
2155 // This version navigates to the final destination page, rather than the
2156 // page which does the redirection via a mouse click.
2157 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2158 PrerenderServerRedirectNavigateToSecondViaClick) {
2159 GURL prerender_url = test_server()->GetURL(
2160 CreateServerRedirect("files/prerender/prerender_page.html"));
2161 GURL destination_url = test_server()->GetURL(
2162 "files/prerender/prerender_page.html");
2163 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
2164 OpenURLViaClick(destination_url);
2167 // Checks that server-issued redirects within an iframe in a prerendered
2168 // page will not count as an "alias" for the prerendered page.
2169 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
2170 std::string redirect_path = CreateServerRedirect(
2171 "/files/prerender/prerender_embedded_content.html");
2172 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2173 replacement_text.push_back(
2174 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2175 std::string replacement_path;
2176 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2177 "files/prerender/prerender_with_iframe.html",
2179 &replacement_path));
2180 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2181 EXPECT_FALSE(UrlIsInPrerenderManager(
2182 "files/prerender/prerender_embedded_content.html"));
2183 NavigateToDestURL();
2186 // Prerenders a page that contains an automatic download triggered through an
2187 // iframe. This should not prerender successfully.
2188 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) {
2189 PrerenderTestURL("files/prerender/prerender_download_iframe.html",
2190 FINAL_STATUS_DOWNLOAD,
2194 // Prerenders a page that contains an automatic download triggered through
2195 // Javascript changing the window.location. This should not prerender
2197 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
2198 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
2199 FINAL_STATUS_DOWNLOAD,
2203 // Prerenders a page that contains an automatic download triggered through a
2204 // client-issued redirect. This should not prerender successfully.
2205 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
2206 PrerenderTestURL("files/prerender/prerender_download_refresh.html",
2207 FINAL_STATUS_DOWNLOAD,
2211 // Checks that the referrer is set when prerendering.
2212 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
2213 PrerenderTestURL("files/prerender/prerender_referrer.html",
2216 NavigateToDestURL();
2219 // Checks that the referrer is not set when prerendering and the source page is
2221 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2222 PrerenderNoSSLReferrer) {
2223 UseHttpsSrcServer();
2224 PrerenderTestURL("files/prerender/prerender_no_referrer.html",
2227 NavigateToDestURL();
2230 // Checks that the referrer is set when prerendering is cancelled.
2231 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrer) {
2232 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
2233 new TestContentBrowserClient);
2234 content::ContentBrowserClient* original_browser_client =
2235 content::SetBrowserClientForTesting(test_content_browser_client.get());
2237 PrerenderTestURL("files/prerender/prerender_referrer.html",
2238 FINAL_STATUS_CANCELLED,
2240 OpenDestURLViaClick();
2242 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
2244 content::SetBrowserClientForTesting(original_browser_client);
2247 // Checks that popups on a prerendered page cause cancellation.
2248 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
2249 PrerenderTestURL("files/prerender/prerender_popup.html",
2250 FINAL_STATUS_CREATE_NEW_WINDOW,
2254 // Checks that registering a protocol handler causes cancellation.
2255 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) {
2256 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html",
2257 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER,
2261 // Checks that renderers using excessive memory will be terminated.
2262 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
2263 ASSERT_TRUE(GetPrerenderManager());
2264 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024;
2265 // The excessive memory kill may happen before or after the load event as it
2266 // happens asynchronously with IPC calls. Even if the test does not start
2267 // allocating until after load, the browser process might notice before the
2268 // message gets through. This happens on XP debug bots because they're so
2269 // slow. Instead, don't bother checking the load event count.
2270 DisableLoadEventCheck();
2271 PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
2272 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 0);
2275 // Checks shutdown code while a prerender is active.
2276 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
2277 DisableJavascriptCalls();
2278 DisableLoadEventCheck();
2279 PrerenderTestURL("files/prerender/prerender_page.html",
2280 FINAL_STATUS_APP_TERMINATING,
2284 // Checks that we don't prerender in an infinite loop.
2285 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
2286 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
2287 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
2289 std::vector<FinalStatus> expected_final_status_queue;
2290 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2291 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2293 ScopedVector<TestPrerender> prerenders =
2294 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2295 ASSERT_TRUE(prerenders[0]->contents());
2296 // Assert that the pending prerender is in there already. This relies on the
2297 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
2298 // the page load one.
2299 EXPECT_EQ(2U, GetLinkPrerenderCount());
2300 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2302 // Next url should be in pending list but not an active entry.
2303 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2305 NavigateToDestURL();
2307 // Make sure the PrerenderContents for the next url is now in the manager and
2308 // not pending. This relies on pending prerenders being resolved in the same
2309 // event loop iteration as OnPrerenderStop.
2310 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
2311 EXPECT_EQ(1U, GetLinkPrerenderCount());
2312 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2315 // Checks that we don't prerender in an infinite loop and multiple links are
2316 // handled correctly.
2317 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2318 PrerenderInfiniteLoopMultiple) {
2319 const char* const kHtmlFileA =
2320 "files/prerender/prerender_infinite_a_multiple.html";
2321 const char* const kHtmlFileB =
2322 "files/prerender/prerender_infinite_b_multiple.html";
2323 const char* const kHtmlFileC =
2324 "files/prerender/prerender_infinite_c_multiple.html";
2326 // This test is conceptually simplest if concurrency is at two, since we
2327 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
2328 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
2329 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
2331 std::vector<FinalStatus> expected_final_status_queue;
2332 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2333 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2334 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2336 ScopedVector<TestPrerender> prerenders =
2337 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2338 ASSERT_TRUE(prerenders[0]->contents());
2340 // Next url should be in pending list but not an active entry. This relies on
2341 // the fact that the renderer sends out the AddLinkRelPrerender IPC before
2342 // sending the page load one.
2343 EXPECT_EQ(3U, GetLinkPrerenderCount());
2344 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2345 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2346 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
2348 NavigateToDestURL();
2350 // Make sure the PrerenderContents for the next urls are now in the manager
2351 // and not pending. One and only one of the URLs (the last seen) should be the
2352 // active entry. This relies on pending prerenders being resolved in the same
2353 // event loop iteration as OnPrerenderStop.
2354 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
2355 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
2356 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
2357 EXPECT_EQ(2U, GetLinkPrerenderCount());
2358 EXPECT_EQ(2U, GetRunningLinkPrerenderCount());
2361 // Checks that pending prerenders are aborted (and never launched) when launched
2362 // by a prerender that itself gets aborted.
2363 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) {
2364 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
2365 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
2367 scoped_ptr<TestPrerender> prerender =
2368 PrerenderTestURL(kHtmlFileA, FINAL_STATUS_CANCELLED, 1);
2369 ASSERT_TRUE(prerender->contents());
2370 // Assert that the pending prerender is in there already. This relies on the
2371 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
2372 // the page load one.
2373 EXPECT_EQ(2U, GetLinkPrerenderCount());
2374 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2376 // Next url should be in pending list but not an active entry.
2377 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2379 // Cancel the prerender.
2380 GetPrerenderManager()->CancelAllPrerenders();
2381 prerender->WaitForStop();
2383 // All prerenders are now gone.
2384 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
2387 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderTaskManager) {
2388 // Show the task manager. This populates the model.
2389 chrome::OpenTaskManager(current_browser());
2390 // Wait for the model of task manager to start.
2391 TaskManagerBrowserTestUtil::WaitForWebResourceChange(1);
2393 // Start with two resources.
2394 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2396 // One of the resources that has a WebContents associated with it should have
2397 // the Prerender prefix.
2398 const base::string16 prefix =
2399 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX,
2401 base::string16 prerender_title;
2402 int num_prerender_tabs = 0;
2404 TaskManagerModel* model = GetModel();
2405 // The task manager caches values. Force the titles to be fresh.
2407 for (int i = 0; i < model->ResourceCount(); ++i) {
2408 if (model->GetResourceWebContents(i)) {
2409 prerender_title = model->GetResourceTitle(i);
2410 if (StartsWith(prerender_title, prefix, true))
2411 ++num_prerender_tabs;
2414 EXPECT_EQ(1, num_prerender_tabs);
2415 const base::string16 prerender_page_title =
2416 prerender_title.substr(prefix.length());
2418 NavigateToDestURL();
2420 // There should be no tabs with the Prerender prefix.
2421 const base::string16 tab_prefix =
2422 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, base::string16());
2423 num_prerender_tabs = 0;
2424 int num_tabs_with_prerender_page_title = 0;
2426 for (int i = 0; i < model->ResourceCount(); ++i) {
2427 if (model->GetResourceWebContents(i)) {
2428 base::string16 tab_title = model->GetResourceTitle(i);
2429 if (StartsWith(tab_title, prefix, true)) {
2430 ++num_prerender_tabs;
2432 EXPECT_TRUE(StartsWith(tab_title, tab_prefix, true));
2434 // The prerender tab should now be a normal tab but the title should be
2435 // the same. Depending on timing, there may be more than one of these.
2436 const base::string16 tab_page_title =
2437 tab_title.substr(tab_prefix.length());
2438 if (prerender_page_title.compare(tab_page_title) == 0)
2439 ++num_tabs_with_prerender_page_title;
2443 EXPECT_EQ(0, num_prerender_tabs);
2445 // We may have deleted the prerender tab, but the swapped in tab should be
2447 EXPECT_GE(num_tabs_with_prerender_page_title, 1);
2448 EXPECT_LE(num_tabs_with_prerender_page_title, 2);
2451 // Checks that audio loads are deferred on prerendering.
2452 // Times out under AddressSanitizer, see http://crbug.com/108402
2453 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Audio) {
2454 PrerenderTestURL("files/prerender/prerender_html5_audio.html",
2457 NavigateToDestURL();
2458 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2461 // Checks that audio loads are deferred on prerendering and played back when
2462 // the prerender is swapped in if autoplay is set.
2463 // Periodically fails on chrome-os. See http://crbug.com/145263
2464 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2465 DISABLED_PrerenderHTML5AudioAutoplay) {
2466 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html",
2469 NavigateToDestURL();
2470 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2473 // Checks that audio loads are deferred on prerendering and played back when
2474 // the prerender is swapped in if js starts playing.
2475 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2476 DISABLED_PrerenderHTML5AudioJsplay) {
2477 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html",
2480 NavigateToDestURL();
2481 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2484 // Checks that video loads are deferred on prerendering.
2485 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Video) {
2486 PrerenderTestURL("files/prerender/prerender_html5_video.html",
2489 NavigateToDestURL();
2490 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2493 // Checks that video tags inserted by javascript are deferred and played
2494 // correctly on swap in.
2495 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2496 DISABLED_PrerenderHTML5VideoJs) {
2497 PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
2500 NavigateToDestURL();
2501 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2504 // Checks for correct network events by using a busy sleep the javascript.
2505 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2506 DISABLED_PrerenderHTML5VideoNetwork) {
2507 DisableJavascriptCalls();
2508 scoped_ptr<TestPrerender> prerender =
2509 PrerenderTestURL("files/prerender/prerender_html5_video_network.html",
2512 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
2513 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
2514 NavigateToDestURL();
2515 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2518 // Checks that scripts can retrieve the correct window size while prerendering.
2519 #if defined(TOOLKIT_VIEWS)
2520 // TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363
2521 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) {
2523 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
2525 PrerenderTestURL("files/prerender/prerender_size.html",
2528 NavigateToDestURL();
2531 // Checks that prerenderers will terminate when the RenderView crashes.
2532 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRendererCrash) {
2533 scoped_ptr<TestPrerender> prerender =
2534 PrerenderTestURL("files/prerender/prerender_page.html",
2535 FINAL_STATUS_RENDERER_CRASHED,
2538 // Navigate to about:crash and then wait for the renderer to crash.
2539 ASSERT_TRUE(prerender->contents());
2540 ASSERT_TRUE(prerender->contents()->prerender_contents());
2541 prerender->contents()->prerender_contents()->GetController().
2543 GURL(content::kChromeUICrashURL),
2544 content::Referrer(),
2545 content::PAGE_TRANSITION_TYPED,
2547 prerender->WaitForStop();
2550 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2551 PrerenderPageWithFragment) {
2552 PrerenderTestURL("files/prerender/prerender_page.html#fragment",
2556 ChannelDestructionWatcher channel_close_watcher;
2557 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2558 GetActiveWebContents()->GetRenderProcessHost());
2559 NavigateToDestURL();
2560 channel_close_watcher.WaitForChannelClose();
2562 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2565 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2566 PrerenderPageWithRedirectedFragment) {
2568 CreateClientRedirect("files/prerender/prerender_page.html#fragment"),
2572 ChannelDestructionWatcher channel_close_watcher;
2573 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2574 GetActiveWebContents()->GetRenderProcessHost());
2575 NavigateToDestURL();
2576 channel_close_watcher.WaitForChannelClose();
2578 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2581 // Checks that we do not use a prerendered page when navigating from
2582 // the main page to a fragment.
2583 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2584 PrerenderPageNavigateFragment) {
2585 PrerenderTestURL("files/prerender/no_prerender_page.html",
2586 FINAL_STATUS_APP_TERMINATING,
2588 NavigateToURLWithDisposition(
2589 "files/prerender/no_prerender_page.html#fragment",
2590 CURRENT_TAB, false);
2593 // Checks that we do not use a prerendered page when we prerender a fragment
2594 // but navigate to the main page.
2595 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2596 PrerenderFragmentNavigatePage) {
2597 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment",
2598 FINAL_STATUS_APP_TERMINATING,
2600 NavigateToURLWithDisposition(
2601 "files/prerender/no_prerender_page.html",
2602 CURRENT_TAB, false);
2605 // Checks that we do not use a prerendered page when we prerender a fragment
2606 // but navigate to a different fragment on the same page.
2607 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2608 PrerenderFragmentNavigateFragment) {
2609 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment",
2610 FINAL_STATUS_APP_TERMINATING,
2612 NavigateToURLWithDisposition(
2613 "files/prerender/no_prerender_page.html#fragment",
2614 CURRENT_TAB, false);
2617 // Checks that we do not use a prerendered page when the page uses a client
2618 // redirect to refresh from a fragment on the same page.
2619 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2620 PrerenderClientRedirectFromFragment) {
2622 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"),
2623 FINAL_STATUS_APP_TERMINATING,
2625 NavigateToURLWithDisposition(
2626 "files/prerender/no_prerender_page.html",
2627 CURRENT_TAB, false);
2630 // Checks that we do not use a prerendered page when the page uses a client
2631 // redirect to refresh to a fragment on the same page.
2632 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2633 PrerenderClientRedirectToFragment) {
2635 CreateClientRedirect("files/prerender/no_prerender_page.html"),
2636 FINAL_STATUS_APP_TERMINATING,
2638 NavigateToURLWithDisposition(
2639 "files/prerender/no_prerender_page.html#fragment",
2640 CURRENT_TAB, false);
2643 // Checks that we correctly use a prerendered page when the page uses JS to set
2644 // the window.location.hash to a fragment on the same page.
2645 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2646 PrerenderPageChangeFragmentLocationHash) {
2647 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html",
2650 NavigateToURL("files/prerender/prerender_fragment_location_hash.html");
2653 // Checks that prerendering a PNG works correctly.
2654 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) {
2655 DisableJavascriptCalls();
2656 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1);
2657 NavigateToDestURL();
2660 // Checks that prerendering a JPG works correctly.
2661 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) {
2662 DisableJavascriptCalls();
2663 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1);
2664 NavigateToDestURL();
2667 // Checks that a prerender of a CRX will result in a cancellation due to
2669 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) {
2670 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 0);
2673 // Checks that xhr GET requests allow prerenders.
2674 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) {
2675 PrerenderTestURL("files/prerender/prerender_xhr_get.html",
2678 NavigateToDestURL();
2681 // Checks that xhr HEAD requests allow prerenders.
2682 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) {
2683 PrerenderTestURL("files/prerender/prerender_xhr_head.html",
2686 NavigateToDestURL();
2689 // Checks that xhr OPTIONS requests allow prerenders.
2690 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) {
2691 PrerenderTestURL("files/prerender/prerender_xhr_options.html",
2694 NavigateToDestURL();
2697 // Checks that xhr TRACE requests allow prerenders.
2698 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) {
2699 PrerenderTestURL("files/prerender/prerender_xhr_trace.html",
2702 NavigateToDestURL();
2705 // Checks that xhr POST requests allow prerenders.
2706 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) {
2707 PrerenderTestURL("files/prerender/prerender_xhr_post.html",
2710 NavigateToDestURL();
2713 // Checks that xhr PUT cancels prerenders.
2714 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) {
2715 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
2716 FINAL_STATUS_INVALID_HTTP_METHOD,
2720 // Checks that xhr DELETE cancels prerenders.
2721 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) {
2722 PrerenderTestURL("files/prerender/prerender_xhr_delete.html",
2723 FINAL_STATUS_INVALID_HTTP_METHOD,
2727 // Checks that a top-level page which would trigger an SSL error is canceled.
2728 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) {
2729 net::SpawnedTestServer::SSLOptions ssl_options;
2730 ssl_options.server_certificate =
2731 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2732 net::SpawnedTestServer https_server(
2733 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2734 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2735 ASSERT_TRUE(https_server.Start());
2736 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2737 PrerenderTestURL(https_url,
2738 FINAL_STATUS_SSL_ERROR,
2742 // Checks that an SSL error that comes from a subresource does not cancel
2743 // the page. Non-main-frame requests are simply cancelled if they run into
2745 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) {
2746 net::SpawnedTestServer::SSLOptions ssl_options;
2747 ssl_options.server_certificate =
2748 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2749 net::SpawnedTestServer https_server(
2750 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2751 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2752 ASSERT_TRUE(https_server.Start());
2753 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2754 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2755 replacement_text.push_back(
2756 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2757 std::string replacement_path;
2758 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2759 "files/prerender/prerender_with_image.html",
2761 &replacement_path));
2762 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2763 NavigateToDestURL();
2766 // Checks that an SSL error that comes from an iframe does not cancel
2767 // the page. Non-main-frame requests are simply cancelled if they run into
2769 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) {
2770 net::SpawnedTestServer::SSLOptions ssl_options;
2771 ssl_options.server_certificate =
2772 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2773 net::SpawnedTestServer https_server(
2774 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2775 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2776 ASSERT_TRUE(https_server.Start());
2777 GURL https_url = https_server.GetURL(
2778 "files/prerender/prerender_embedded_content.html");
2779 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2780 replacement_text.push_back(
2781 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2782 std::string replacement_path;
2783 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2784 "files/prerender/prerender_with_iframe.html",
2786 &replacement_path));
2787 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2788 NavigateToDestURL();
2791 // Checks that we cancel correctly when window.print() is called.
2792 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
2793 PrerenderTestURL("files/prerender/prerender_print.html",
2794 FINAL_STATUS_WINDOW_PRINT,
2798 // Checks that if a page is opened in a new window by javascript and both the
2799 // pages are in the same domain, the prerendered page is not used, due to
2801 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2802 PrerenderSameDomainWindowOpenerWindowOpen) {
2803 PrerenderTestURL("files/prerender/prerender_page.html",
2804 FINAL_STATUS_WINDOW_OPENER,
2806 OpenDestURLViaWindowOpen();
2809 // Checks that if a page is opened due to click on a href with target="_blank"
2810 // and both pages are in the same domain the prerendered page is not used, due
2811 // to window.opener.
2812 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2813 PrerenderSameDomainWindowOpenerClickTarget) {
2814 PrerenderTestURL("files/prerender/prerender_page.html",
2815 FINAL_STATUS_WINDOW_OPENER,
2817 OpenDestURLViaClickTarget();
2820 class TestClientCertStore : public net::ClientCertStore {
2822 TestClientCertStore() {}
2823 virtual ~TestClientCertStore() {}
2825 // net::ClientCertStore:
2826 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
2827 net::CertificateList* selected_certs,
2828 const base::Closure& callback) OVERRIDE {
2829 *selected_certs = net::CertificateList(
2830 1, scoped_refptr<net::X509Certificate>(
2831 new net::X509Certificate("test", "test", base::Time(), base::Time())));
2836 scoped_ptr<net::ClientCertStore> CreateCertStore() {
2837 return scoped_ptr<net::ClientCertStore>(new TestClientCertStore);
2840 // Checks that a top-level page which would normally request an SSL client
2841 // certificate will never be seen since it's an https top-level resource.
2842 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2843 PrerenderSSLClientCertTopLevel) {
2844 ProfileIOData::FromResourceContext(
2845 current_browser()->profile()->GetResourceContext())->
2846 set_client_cert_store_factory_for_testing(
2847 base::Bind(&CreateCertStore));
2848 net::SpawnedTestServer::SSLOptions ssl_options;
2849 ssl_options.request_client_certificate = true;
2850 net::SpawnedTestServer https_server(
2851 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2852 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2853 ASSERT_TRUE(https_server.Start());
2854 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2855 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0);
2858 // Checks that an SSL Client Certificate request that originates from a
2859 // subresource will cancel the prerendered page.
2860 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2861 PrerenderSSLClientCertSubresource) {
2862 ProfileIOData::FromResourceContext(
2863 current_browser()->profile()->GetResourceContext())->
2864 set_client_cert_store_factory_for_testing(
2865 base::Bind(&CreateCertStore));
2866 net::SpawnedTestServer::SSLOptions ssl_options;
2867 ssl_options.request_client_certificate = true;
2868 net::SpawnedTestServer https_server(
2869 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2870 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2871 ASSERT_TRUE(https_server.Start());
2872 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2873 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2874 replacement_text.push_back(
2875 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2876 std::string replacement_path;
2877 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2878 "files/prerender/prerender_with_image.html",
2880 &replacement_path));
2881 PrerenderTestURL(replacement_path,
2882 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2886 // Checks that an SSL Client Certificate request that originates from an
2887 // iframe will cancel the prerendered page.
2888 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) {
2889 ProfileIOData::FromResourceContext(
2890 current_browser()->profile()->GetResourceContext())->
2891 set_client_cert_store_factory_for_testing(
2892 base::Bind(&CreateCertStore));
2893 net::SpawnedTestServer::SSLOptions ssl_options;
2894 ssl_options.request_client_certificate = true;
2895 net::SpawnedTestServer https_server(
2896 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2897 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2898 ASSERT_TRUE(https_server.Start());
2899 GURL https_url = https_server.GetURL(
2900 "files/prerender/prerender_embedded_content.html");
2901 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2902 replacement_text.push_back(
2903 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2904 std::string replacement_path;
2905 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2906 "files/prerender/prerender_with_iframe.html",
2908 &replacement_path));
2909 PrerenderTestURL(replacement_path,
2910 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2914 #if defined(FULL_SAFE_BROWSING)
2915 // Ensures that we do not prerender pages with a safe browsing
2917 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) {
2918 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2919 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2920 url, SB_THREAT_TYPE_URL_MALWARE);
2921 PrerenderTestURL("files/prerender/prerender_page.html",
2922 FINAL_STATUS_SAFE_BROWSING, 0);
2925 // Ensures that server redirects to a malware page will cancel prerenders.
2926 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2927 PrerenderSafeBrowsingServerRedirect) {
2928 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2929 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2930 url, SB_THREAT_TYPE_URL_MALWARE);
2931 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2932 FINAL_STATUS_SAFE_BROWSING,
2936 // Ensures that client redirects to a malware page will cancel prerenders.
2937 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2938 PrerenderSafeBrowsingClientRedirect) {
2939 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2940 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2941 url, SB_THREAT_TYPE_URL_MALWARE);
2942 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
2943 FINAL_STATUS_SAFE_BROWSING,
2947 // Ensures that we do not prerender pages which have a malware subresource.
2948 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) {
2949 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg");
2950 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2951 image_url, SB_THREAT_TYPE_URL_MALWARE);
2952 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2953 replacement_text.push_back(
2954 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
2955 std::string replacement_path;
2956 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2957 "files/prerender/prerender_with_image.html",
2959 &replacement_path));
2960 PrerenderTestURL(replacement_path,
2961 FINAL_STATUS_SAFE_BROWSING,
2965 // Ensures that we do not prerender pages which have a malware iframe.
2966 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) {
2967 GURL iframe_url = test_server()->GetURL(
2968 "files/prerender/prerender_embedded_content.html");
2969 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2970 iframe_url, SB_THREAT_TYPE_URL_MALWARE);
2971 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2972 replacement_text.push_back(
2973 std::make_pair("REPLACE_WITH_URL", iframe_url.spec()));
2974 std::string replacement_path;
2975 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2976 "files/prerender/prerender_with_iframe.html",
2978 &replacement_path));
2979 PrerenderTestURL(replacement_path,
2980 FINAL_STATUS_SAFE_BROWSING,
2986 // Checks that a local storage read will not cause prerender to fail.
2987 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) {
2988 PrerenderTestURL("files/prerender/prerender_localstorage_read.html",
2991 NavigateToDestURL();
2994 // Checks that a local storage write will not cause prerender to fail.
2995 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) {
2996 PrerenderTestURL("files/prerender/prerender_localstorage_write.html",
2999 NavigateToDestURL();
3002 // Checks that the favicon is properly loaded on prerender.
3003 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) {
3004 scoped_ptr<TestPrerender> prerender =
3005 PrerenderTestURL("files/prerender/prerender_favicon.html",
3008 NavigateToDestURL();
3010 if (!FaviconTabHelper::FromWebContents(
3011 GetActiveWebContents())->FaviconIsValid()) {
3012 // If the favicon has not been set yet, wait for it to be.
3013 content::WindowedNotificationObserver favicon_update_watcher(
3014 chrome::NOTIFICATION_FAVICON_UPDATED,
3015 content::Source<WebContents>(GetActiveWebContents()));
3016 favicon_update_watcher.Wait();
3018 EXPECT_TRUE(FaviconTabHelper::FromWebContents(
3019 GetActiveWebContents())->FaviconIsValid());
3022 // Checks that when a prerendered page is swapped in to a referring page, the
3023 // unload handlers on the referring page are executed.
3024 // Fails about 50% on CrOS, 5-10% on linux, win, mac. http://crbug.com/128986
3025 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderUnload) {
3026 set_loader_path("files/prerender/prerender_loader_with_unload.html");
3027 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3028 base::string16 expected_title = base::ASCIIToUTF16("Unloaded");
3029 content::TitleWatcher title_watcher(
3030 current_browser()->tab_strip_model()->GetActiveWebContents(),
3032 NavigateToDestURL();
3033 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
3036 // Checks that when the history is cleared, prerendering is cancelled and
3037 // prerendering history is cleared.
3038 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) {
3039 scoped_ptr<TestPrerender> prerender =
3040 PrerenderTestURL("files/prerender/prerender_page.html",
3041 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
3044 base::MessageLoop::current()->PostTask(
3046 base::Bind(&ClearBrowsingData, current_browser(),
3047 BrowsingDataRemover::REMOVE_HISTORY));
3048 prerender->WaitForStop();
3050 // Make sure prerender history was cleared.
3051 EXPECT_EQ(0, GetHistoryLength());
3054 // Disabled due to flakiness: crbug.com/316225
3055 // Checks that when the cache is cleared, prerenders are cancelled but
3056 // prerendering history is not cleared.
3057 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderClearCache) {
3058 scoped_ptr<TestPrerender> prerender =
3059 PrerenderTestURL("files/prerender/prerender_page.html",
3060 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
3063 base::MessageLoop::current()->PostTask(FROM_HERE,
3064 base::Bind(&ClearBrowsingData, current_browser(),
3065 BrowsingDataRemover::REMOVE_CACHE));
3066 prerender->WaitForStop();
3068 // Make sure prerender history was not cleared. Not a vital behavior, but
3069 // used to compare with PrerenderClearHistory test.
3070 EXPECT_EQ(1, GetHistoryLength());
3073 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) {
3074 scoped_ptr<TestPrerender> prerender =
3075 PrerenderTestURL("files/prerender/prerender_page.html",
3076 FINAL_STATUS_CANCELLED,
3079 GetPrerenderManager()->CancelAllPrerenders();
3080 prerender->WaitForStop();
3082 EXPECT_FALSE(prerender->contents());
3085 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) {
3086 scoped_ptr<TestPrerender> prerender =
3087 PrerenderTestURL("files/prerender/prerender_page.html",
3088 FINAL_STATUS_CANCELLED, 1);
3090 GetPrerenderManager()->CancelAllPrerenders();
3091 prerender->WaitForStop();
3093 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
3094 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
3095 EXPECT_FALSE(HadPrerenderEventErrors());
3098 // Cancels the prerender of a page with its own prerender. The second prerender
3099 // should never be started.
3100 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3101 PrerenderCancelPrerenderWithPrerender) {
3102 scoped_ptr<TestPrerender> prerender =
3103 PrerenderTestURL("files/prerender/prerender_infinite_a.html",
3104 FINAL_STATUS_CANCELLED,
3107 GetPrerenderManager()->CancelAllPrerenders();
3108 prerender->WaitForStop();
3110 EXPECT_FALSE(prerender->contents());
3113 // Prerendering and history tests.
3114 // The prerendered page is navigated to in several ways [navigate via
3115 // omnibox, click on link, key-modified click to open in background tab, etc],
3116 // followed by a navigation to another page from the prerendered page, followed
3117 // by a back navigation.
3119 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) {
3120 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3123 NavigateToDestURL();
3124 ClickToNextPageAfterPrerender();
3125 GoBackToPrerender();
3128 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateNavigateGoBack) {
3129 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3132 NavigateToDestURL();
3133 NavigateToNextPageAfterPrerender();
3134 GoBackToPrerender();
3137 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) {
3138 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3141 OpenDestURLViaClick();
3142 ClickToNextPageAfterPrerender();
3143 GoBackToPrerender();
3146 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNavigateGoBack) {
3147 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3150 OpenDestURLViaClick();
3151 NavigateToNextPageAfterPrerender();
3152 GoBackToPrerender();
3155 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
3156 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3157 FINAL_STATUS_WINDOW_OPENER,
3159 OpenDestURLViaClickNewWindow();
3162 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
3163 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3164 FINAL_STATUS_WINDOW_OPENER,
3166 OpenDestURLViaClickNewForegroundTab();
3169 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) {
3170 scoped_ptr<TestPrerender> prerender =
3171 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3172 FINAL_STATUS_WINDOW_OPENER,
3174 ASSERT_TRUE(prerender->contents());
3175 prerender->contents()->set_should_be_shown(false);
3176 OpenDestURLViaClickNewBackgroundTab();
3179 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3180 NavigateToPrerenderedPageWhenDevToolsAttached) {
3181 DisableJavascriptCalls();
3182 WebContents* web_contents =
3183 current_browser()->tab_strip_model()->GetActiveWebContents();
3184 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
3185 web_contents->GetRenderViewHost()));
3186 DevToolsManager* manager = DevToolsManager::GetInstance();
3187 FakeDevToolsClientHost client_host;
3188 manager->RegisterDevToolsClientHostFor(agent.get(), &client_host);
3189 const char* url = "files/prerender/prerender_page.html";
3190 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1);
3191 NavigateToURLWithDisposition(url, CURRENT_TAB, false);
3192 manager->ClientHostClosing(&client_host);
3195 // Validate that the sessionStorage namespace remains the same when swapping
3196 // in a prerendered page.
3197 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) {
3198 set_loader_path("files/prerender/prerender_loader_with_session_storage.html");
3199 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
3202 NavigateToDestURL();
3203 GoBackToPageBeforePrerender();
3206 // Checks that the control group works. An XHR PUT cannot be detected in the
3208 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroup) {
3209 RestorePrerenderMode restore_prerender_mode;
3210 PrerenderManager::SetMode(
3211 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
3212 DisableJavascriptCalls();
3213 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3214 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
3215 NavigateToDestURL();
3218 // Checks that the control group correctly hits WOULD_HAVE_BEEN_USED
3219 // renderer-initiated navigations. (This verifies that the ShouldFork logic
3220 // behaves correctly.)
3221 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroupRendererInitiated) {
3222 RestorePrerenderMode restore_prerender_mode;
3223 PrerenderManager::SetMode(
3224 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
3225 DisableJavascriptCalls();
3226 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3227 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
3228 OpenDestURLViaClick();
3231 // Make sure that the MatchComplete dummy works in the normal case. Once
3232 // a prerender is cancelled because of a script, a dummy must be created to
3233 // account for the MatchComplete case, and it must have a final status of
3234 // FINAL_STATUS_WOULD_HAVE_BEEN_USED.
3235 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MatchCompleteDummy) {
3236 UMAHistogramHelper histograms;
3238 std::vector<FinalStatus> expected_final_status_queue;
3239 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
3240 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
3241 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3242 expected_final_status_queue, 1);
3244 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3245 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3246 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
3247 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
3249 NavigateToDestURL();
3251 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3252 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0);
3253 histograms.ExpectTotalCount(
3254 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3257 // Verify that a navigation that hits a MatchComplete dummy while another is in
3258 // progress does not also classify the previous navigation as a MatchComplete.
3259 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3260 MatchCompleteDummyCancelNavigation) {
3261 UMAHistogramHelper histograms;
3263 // Arrange for a URL to hang.
3264 const GURL kNoCommitUrl("http://never-respond.example.com");
3265 base::FilePath file(FILE_PATH_LITERAL(
3266 "chrome/test/data/prerender/prerender_page.html"));
3267 base::RunLoop hang_loop;
3268 BrowserThread::PostTask(
3269 BrowserThread::IO, FROM_HERE,
3270 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO,
3271 kNoCommitUrl, file, hang_loop.QuitClosure()));
3273 // First, fire a prerender that aborts after it completes its load.
3274 std::vector<FinalStatus> expected_final_status_queue;
3275 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
3276 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
3277 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3278 expected_final_status_queue, 1);
3280 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3281 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3282 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
3283 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
3285 // Open the hanging URL in a new tab. Wait for both the new tab to open and
3286 // the hanging request to be scheduled.
3287 ui_test_utils::NavigateToURLWithDisposition(
3288 current_browser(), kNoCommitUrl, NEW_FOREGROUND_TAB,
3289 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
3292 // Now interrupt that navigation and navigate to the destination URL. This
3293 // should forcibly complete the previous navigation and also complete a
3294 // WOULD_HAVE_BEEN_PRERENDERED navigation.
3295 NavigateToDestURL();
3297 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 2);
3298 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3299 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
3300 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3301 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0);
3302 histograms.ExpectTotalCount(
3303 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3306 class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest {
3308 PrerenderBrowserTestWithNaCl() {}
3309 virtual ~PrerenderBrowserTestWithNaCl() {}
3311 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
3312 PrerenderBrowserTest::SetUpCommandLine(command_line);
3313 command_line->AppendSwitch(switches::kEnableNaCl);
3317 // Check that NaCl plugins work when enabled, with prerendering.
3318 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
3319 PrerenderNaClPluginEnabled) {
3320 #if defined(OS_WIN) && defined(USE_ASH)
3321 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
3322 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
3326 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
3329 NavigateToDestURL();
3331 // To avoid any chance of a race, we have to let the script send its response
3333 WebContents* web_contents =
3334 browser()->tab_strip_model()->GetActiveWebContents();
3335 bool display_test_result = false;
3336 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents,
3337 "DidDisplayReallyPass()",
3338 &display_test_result));
3339 ASSERT_TRUE(display_test_result);
3342 // Checks that the referrer policy is used when prerendering.
3343 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) {
3344 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3345 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3348 NavigateToDestURL();
3351 // Checks that the referrer policy is used when prerendering on HTTPS.
3352 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3353 PrerenderSSLReferrerPolicy) {
3354 UseHttpsSrcServer();
3355 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3356 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3359 NavigateToDestURL();
3362 // Checks that the referrer policy is used when prerendering is cancelled.
3363 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrerPolicy) {
3364 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
3365 new TestContentBrowserClient);
3366 content::ContentBrowserClient* original_browser_client =
3367 content::SetBrowserClientForTesting(test_content_browser_client.get());
3369 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3370 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3371 FINAL_STATUS_CANCELLED,
3373 OpenDestURLViaClick();
3375 bool display_test_result = false;
3376 WebContents* web_contents =
3377 browser()->tab_strip_model()->GetActiveWebContents();
3378 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
3380 "window.domAutomationController.send(DidDisplayPass())",
3381 &display_test_result));
3382 EXPECT_TRUE(display_test_result);
3384 content::SetBrowserClientForTesting(original_browser_client);
3387 // Test interaction of the webNavigation and tabs API with prerender.
3388 class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest,
3389 public ExtensionApiTest {
3391 PrerenderBrowserTestWithExtensions() {
3392 // The individual tests start the test server through ExtensionApiTest, so
3393 // the port number can be passed through to the extension.
3394 autostart_test_server_ = false;
3397 virtual void SetUp() OVERRIDE {
3398 PrerenderBrowserTest::SetUp();
3401 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
3402 PrerenderBrowserTest::SetUpCommandLine(command_line);
3403 ExtensionApiTest::SetUpCommandLine(command_line);
3406 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
3407 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
3408 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
3411 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
3412 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
3413 ExtensionApiTest::TearDownInProcessBrowserTestFixture();
3416 virtual void SetUpOnMainThread() OVERRIDE {
3417 PrerenderBrowserTest::SetUpOnMainThread();
3421 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) {
3422 ASSERT_TRUE(StartSpawnedTestServer());
3423 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3425 CommandLine::ForCurrentProcess()->AppendSwitch(
3426 extensions::switches::kAllowLegacyExtensionManifests);
3428 // Wait for the extension to set itself up and return control to us.
3429 ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_;
3431 ResultCatcher catcher;
3433 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3435 ChannelDestructionWatcher channel_close_watcher;
3436 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3437 GetActiveWebContents()->GetRenderProcessHost());
3438 NavigateToDestURL();
3439 channel_close_watcher.WaitForChannelClose();
3441 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3442 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3445 // Fails often on Windows dbg bots. http://crbug.com/177163
3446 #if defined(OS_WIN) && !defined(NDEBUG)
3447 #define MAYBE_TabsApi DISABLED_TabsApi
3449 #define MAYBE_TabsApi TabsApi
3450 #endif // defined(OS_WIN) && !defined(NDEBUG)
3451 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, MAYBE_TabsApi) {
3452 ASSERT_TRUE(StartSpawnedTestServer());
3453 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3455 // Wait for the extension to set itself up and return control to us.
3456 ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html"))
3459 ResultCatcher catcher;
3461 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3463 ChannelDestructionWatcher channel_close_watcher;
3464 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3465 GetActiveWebContents()->GetRenderProcessHost());
3466 NavigateToDestURL();
3467 channel_close_watcher.WaitForChannelClose();
3469 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3470 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3473 // Checks that non-http/https/chrome-extension subresource cancels the
3475 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3476 PrerenderCancelSubresourceUnsupportedScheme) {
3477 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg");
3478 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3479 replacement_text.push_back(
3480 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3481 std::string replacement_path;
3482 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3483 "files/prerender/prerender_with_image.html",
3485 &replacement_path));
3486 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3489 // Ensure that about:blank is permitted for any subresource.
3490 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3491 PrerenderAllowAboutBlankSubresource) {
3492 GURL image_url = GURL("about:blank");
3493 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3494 replacement_text.push_back(
3495 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3496 std::string replacement_path;
3497 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3498 "files/prerender/prerender_with_image.html",
3500 &replacement_path));
3501 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3502 NavigateToDestURL();
3505 // Checks that non-http/https/chrome-extension subresource cancels the prerender
3507 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3508 PrerenderCancelSubresourceRedirectUnsupportedScheme) {
3509 GURL image_url = test_server()->GetURL(
3510 CreateServerRedirect("invalidscheme://www.google.com/test.jpg"));
3511 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3512 replacement_text.push_back(
3513 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3514 std::string replacement_path;
3515 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3516 "files/prerender/prerender_with_image.html",
3518 &replacement_path));
3519 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3522 // Checks that chrome-extension subresource does not cancel the prerender.
3523 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3524 PrerenderKeepSubresourceExtensionScheme) {
3525 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg");
3526 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3527 replacement_text.push_back(
3528 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3529 std::string replacement_path;
3530 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3531 "files/prerender/prerender_with_image.html",
3533 &replacement_path));
3534 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3535 NavigateToDestURL();
3538 // Checks that redirect to chrome-extension subresource does not cancel the
3540 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3541 PrerenderKeepSubresourceRedirectExtensionScheme) {
3542 GURL image_url = test_server()->GetURL(
3543 CreateServerRedirect("chrome-extension://abcdefg/test.jpg"));
3544 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3545 replacement_text.push_back(
3546 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3547 std::string replacement_path;
3548 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3549 "files/prerender/prerender_with_image.html",
3551 &replacement_path));
3552 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3553 NavigateToDestURL();
3557 // Checks that non-http/https main page redirects cancel the prerender.
3558 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3559 PrerenderCancelMainFrameRedirectUnsupportedScheme) {
3560 GURL url = test_server()->GetURL(
3561 CreateServerRedirect("invalidscheme://www.google.com/test.html"));
3562 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3565 // Checks that media source video loads are deferred on prerendering.
3566 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) {
3567 PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html",
3570 NavigateToDestURL();
3571 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
3574 // Checks that a prerender that creates an audio stream (via a WebAudioDevice)
3576 // http://crbug.com/261489
3577 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWebAudioDevice) {
3578 PrerenderTestURL("files/prerender/prerender_web_audio_device.html",
3579 FINAL_STATUS_CREATING_AUDIO_STREAM, 1);
3582 // Checks that prerenders do not swap in to WebContents being captured.
3583 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) {
3584 PrerenderTestURL("files/prerender/prerender_page.html",
3585 FINAL_STATUS_PAGE_BEING_CAPTURED, 1);
3586 WebContents* web_contents = GetActiveWebContents();
3587 web_contents->IncrementCapturerCount(gfx::Size());
3588 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3589 web_contents->DecrementCapturerCount();
3592 // Checks that prerenders are aborted on cross-process navigation from
3593 // a server redirect.
3594 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3595 PrerenderCrossProcessServerRedirect) {
3596 // Force everything to be a process swap.
3597 SwapProcessesContentBrowserClient test_browser_client;
3598 content::ContentBrowserClient* original_browser_client =
3599 content::SetBrowserClientForTesting(&test_browser_client);
3602 CreateServerRedirect("files/prerender/prerender_page.html"),
3603 FINAL_STATUS_OPEN_URL, 0);
3605 content::SetBrowserClientForTesting(original_browser_client);
3608 // Checks that URLRequests for prerenders being aborted on cross-process
3609 // navigation from a server redirect are cleaned up, so they don't keep cache
3611 // See http://crbug.com/341134
3612 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3613 PrerenderCrossProcessServerRedirectNoHang) {
3614 const char kDestPath[] = "files/prerender/prerender_page.html";
3615 // Force everything to be a process swap.
3616 SwapProcessesContentBrowserClient test_browser_client;
3617 content::ContentBrowserClient* original_browser_client =
3618 content::SetBrowserClientForTesting(&test_browser_client);
3620 PrerenderTestURL(CreateServerRedirect(kDestPath), FINAL_STATUS_OPEN_URL, 0);
3622 ui_test_utils::NavigateToURL(
3624 test_server()->GetURL(kDestPath));
3626 content::SetBrowserClientForTesting(original_browser_client);
3629 // Checks that prerenders are aborted on cross-process navigation from
3630 // a client redirect.
3631 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3632 PrerenderCrossProcessClientRedirect) {
3633 // Cross-process navigation logic for renderer-initiated navigations
3634 // is partially controlled by the renderer, namely
3635 // ChromeContentRendererClient. This test instead relies on the Web
3636 // Store triggering such navigations.
3637 std::string webstore_url = extension_urls::GetWebstoreLaunchURL();
3639 // Mock out requests to the Web Store.
3640 base::FilePath file(GetTestPath("prerender_page.html"));
3641 BrowserThread::PostTask(
3642 BrowserThread::IO, FROM_HERE,
3643 base::Bind(&CreateMockProtocolHandlerOnIO,
3644 GURL(webstore_url), file));
3646 PrerenderTestURL(CreateClientRedirect(webstore_url),
3647 FINAL_STATUS_OPEN_URL, 1);
3650 // Checks that canceling a MatchComplete dummy doesn't result in two
3652 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelMatchCompleteDummy) {
3653 std::vector<FinalStatus> expected_final_status_queue;
3654 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT);
3655 expected_final_status_queue.push_back(FINAL_STATUS_CANCELLED);
3656 ScopedVector<TestPrerender> prerenders =
3657 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
3658 expected_final_status_queue, 0);
3660 // Cancel the MatchComplete dummy.
3661 GetPrerenderManager()->CancelAllPrerenders();
3662 prerenders[1]->WaitForStop();
3664 // Check the referring page only got one copy of the event.
3665 EXPECT_FALSE(HadPrerenderEventErrors());
3668 // Checks that a deferred redirect to an image is not loaded until the page is
3669 // visible. Also test the right histogram events are emitted in this case.
3670 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredImage) {
3671 DisableJavascriptCalls();
3672 UMAHistogramHelper histograms;
3674 // The prerender will not completely load until after the swap, so wait for a
3675 // title change before calling DidPrerenderPass.
3676 scoped_ptr<TestPrerender> prerender =
3678 "files/prerender/prerender_deferred_image.html",
3679 FINAL_STATUS_USED, 0);
3680 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
3681 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
3682 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
3683 EXPECT_EQ(0, prerender->number_of_loads());
3685 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3686 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3687 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
3688 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0);
3691 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
3692 GetActiveWebContents());
3693 ui_test_utils::NavigateToURLWithDisposition(
3694 current_browser(), dest_url(), CURRENT_TAB,
3695 ui_test_utils::BROWSER_TEST_NONE);
3696 swap_observer.Wait();
3698 // The prerender never observes the final load.
3699 EXPECT_EQ(0, prerender->number_of_loads());
3701 // Now check DidDisplayPass.
3702 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3705 histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0);
3706 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3707 histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1);
3708 histograms.ExpectTotalCount(
3709 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3712 // Checks that a deferred redirect to an image is not loaded until the
3713 // page is visible, even after another redirect.
3714 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3715 PrerenderDeferredImageAfterRedirect) {
3716 DisableJavascriptCalls();
3718 // The prerender will not completely load until after the swap, so wait for a
3719 // title change before calling DidPrerenderPass.
3720 scoped_ptr<TestPrerender> prerender =
3722 "files/prerender/prerender_deferred_image.html",
3723 FINAL_STATUS_USED, 0);
3724 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
3725 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
3726 EXPECT_EQ(0, prerender->number_of_loads());
3729 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
3730 GetActiveWebContents());
3731 ui_test_utils::NavigateToURLWithDisposition(
3732 current_browser(), dest_url(), CURRENT_TAB,
3733 ui_test_utils::BROWSER_TEST_NONE);
3734 swap_observer.Wait();
3736 // The prerender never observes the final load.
3737 EXPECT_EQ(0, prerender->number_of_loads());
3739 // Now check DidDisplayPass.
3740 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3743 // Checks that deferred redirects in the main frame are followed.
3744 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredMainFrame) {
3745 DisableJavascriptCalls();
3747 "files/prerender/image-deferred.png",
3748 FINAL_STATUS_USED, 1);
3749 NavigateToDestURL();
3752 // Checks that deferred redirects in the main frame are followed, even
3753 // with a double-redirect.
3754 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3755 PrerenderDeferredMainFrameAfterRedirect) {
3756 DisableJavascriptCalls();
3758 CreateServerRedirect("files/prerender/image-deferred.png"),
3759 FINAL_STATUS_USED, 1);
3760 NavigateToDestURL();
3763 // Checks that deferred redirects in a synchronous XHR abort the
3765 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredSynchronousXHR) {
3766 PrerenderTestURL("files/prerender/prerender_deferred_sync_xhr.html",
3767 FINAL_STATUS_BAD_DEFERRED_REDIRECT, 0);
3768 NavigateToDestURL();
3771 // Checks that prerenders are not swapped for navigations with extra headers.
3772 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExtraHeadersNoSwap) {
3773 PrerenderTestURL("files/prerender/prerender_page.html",
3774 FINAL_STATUS_APP_TERMINATING, 1);
3776 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3777 content::PAGE_TRANSITION_TYPED, false);
3778 params.extra_headers = "X-Custom-Header: 42\r\n";
3779 NavigateToURLWithParams(params, false);
3782 // Checks that prerenders are not swapped for navigations with browser-initiated
3784 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3785 PrerenderBrowserInitiatedPostNoSwap) {
3786 PrerenderTestURL("files/prerender/prerender_page.html",
3787 FINAL_STATUS_APP_TERMINATING, 1);
3789 std::string post_data = "DATA";
3790 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3791 content::PAGE_TRANSITION_TYPED, false);
3792 params.uses_post = true;
3793 params.browser_initiated_post_data =
3794 base::RefCountedString::TakeString(&post_data);
3795 NavigateToURLWithParams(params, false);
3798 // Checks that the prerendering of a page is canceled correctly when the
3799 // prerendered page tries to make a second navigation entry.
3800 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) {
3801 PrerenderTestURL("files/prerender/prerender_new_entry.html",
3802 FINAL_STATUS_NEW_NAVIGATION_ENTRY,
3806 // Attempt a swap-in in a new tab, verifying that session storage namespace
3808 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) {
3809 // Mock out some URLs and count the number of requests to one of them. Both
3810 // prerender_session_storage.html and init_session_storage.html need to be
3811 // mocked so they are same-origin.
3812 const GURL kInitURL("http://prerender.test/init_session_storage.html");
3813 base::FilePath init_file = GetTestPath("init_session_storage.html");
3814 BrowserThread::PostTask(
3815 BrowserThread::IO, FROM_HERE,
3816 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file));
3818 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
3819 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
3820 RequestCounter counter;
3821 BrowserThread::PostTask(
3822 BrowserThread::IO, FROM_HERE,
3823 base::Bind(&CreateCountingProtocolHandlerOnIO,
3824 kTestURL, test_file, counter.AsWeakPtr()));
3826 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
3828 // Open a new tab to navigate in.
3829 ui_test_utils::NavigateToURLWithDisposition(
3830 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
3831 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3833 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
3834 // the swap does not occur synchronously.
3836 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
3837 // return value assertion and let this go through the usual successful-swap
3839 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3841 // Verify DidDisplayPass manually since the previous call skipped it.
3842 EXPECT_TRUE(DidDisplayPass(
3843 current_browser()->tab_strip_model()->GetActiveWebContents()));
3845 // Only one request to the test URL started.
3847 // TODO(davidben): Re-enable this check when the races in attaching the
3848 // throttle are resolved. http://crbug.com/335835
3849 // EXPECT_EQ(1, counter.count());
3852 // Attempt a swap-in in a new tab, verifying that session storage namespace
3853 // merging works. Unlike the above test, the swap is for a navigation that would
3854 // normally be cross-process.
3855 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) {
3856 base::FilePath test_data_dir;
3857 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
3859 // Mock out some URLs and count the number of requests to one of them. Both
3860 // prerender_session_storage.html and init_session_storage.html need to be
3861 // mocked so they are same-origin.
3862 const GURL kInitURL("http://prerender.test/init_session_storage.html");
3863 base::FilePath init_file = GetTestPath("init_session_storage.html");
3864 BrowserThread::PostTask(
3865 BrowserThread::IO, FROM_HERE,
3866 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file));
3868 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
3869 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
3870 RequestCounter counter;
3871 BrowserThread::PostTask(
3872 BrowserThread::IO, FROM_HERE,
3873 base::Bind(&CreateCountingProtocolHandlerOnIO,
3874 kTestURL, test_file, counter.AsWeakPtr()));
3876 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
3878 // Open a new tab to navigate in.
3879 ui_test_utils::NavigateToURLWithDisposition(
3880 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
3881 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3883 // Navigate to about:blank so the next navigation is cross-process.
3884 ui_test_utils::NavigateToURL(current_browser(),
3885 GURL(content::kAboutBlankURL));
3887 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
3888 // the swap does not occur synchronously.
3890 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
3891 // return value assertion and let this go through the usual successful-swap
3893 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3895 // Verify DidDisplayPass manually since the previous call skipped it.
3896 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3898 // Only one request to the test URL started.
3900 // TODO(davidben): Re-enable this check when the races in attaching the
3901 // throttle are resolved. http://crbug.com/335835
3902 // EXPECT_EQ(1, counter.count());
3905 // Verify that session storage conflicts don't merge.
3906 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) {
3907 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html",
3908 FINAL_STATUS_APP_TERMINATING, 1);
3910 // Open a new tab to navigate in.
3911 ui_test_utils::NavigateToURLWithDisposition(
3913 test_server()->GetURL("files/prerender/init_session_storage.html"),
3915 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3917 // Now navigate in the new tab.
3918 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3920 // Verify DidDisplayPass in the new tab.
3921 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3924 // Checks that prerenders honor |should_replace_current_entry|.
3925 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReplaceCurrentEntry) {
3926 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3928 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3929 content::PAGE_TRANSITION_TYPED, false);
3930 params.should_replace_current_entry = true;
3931 NavigateToURLWithParams(params, false);
3933 const NavigationController& controller =
3934 GetActiveWebContents()->GetController();
3935 // First entry is about:blank, second is prerender_page.html.
3936 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
3937 EXPECT_EQ(2, controller.GetEntryCount());
3938 EXPECT_EQ(GURL(content::kAboutBlankURL),
3939 controller.GetEntryAtIndex(0)->GetURL());
3940 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL());
3943 // Checks prerender does not hit DCHECKs and behaves properly if two pending
3944 // swaps occur in a row.
3945 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDoublePendingSwap) {
3946 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
3947 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
3949 GURL url1 = test_server()->GetURL("files/prerender/prerender_page.html?1");
3950 scoped_ptr<TestPrerender> prerender1 =
3951 PrerenderTestURL(url1, FINAL_STATUS_APP_TERMINATING, 1);
3953 GURL url2 = test_server()->GetURL("files/prerender/prerender_page.html?2");
3954 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
3955 AddPrerender(url2, 1);
3956 prerender2->WaitForStart();
3957 prerender2->WaitForLoads(1);
3959 // There's no reason the second prerender can't be used, but the swap races
3960 // with didStartProvisionalLoad and didFailProvisionalLoad from the previous
3961 // navigation. The current logic will conservatively fail to swap under such
3962 // races. However, if the renderer is slow enough, it's possible for the
3963 // prerender to still be used, so don't program in either expectation.
3964 ASSERT_TRUE(prerender2->contents());
3965 prerender2->contents()->set_skip_final_checks(true);
3967 // Open a new tab to navigate in.
3968 ui_test_utils::NavigateToURLWithDisposition(
3969 current_browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB,
3970 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3972 // Fire off two navigations, without running the event loop between them.
3973 NavigationOrSwapObserver swap_observer(
3974 current_browser()->tab_strip_model(),
3975 GetActiveWebContents(), 2);
3976 current_browser()->OpenURL(OpenURLParams(
3977 url1, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false));
3978 current_browser()->OpenURL(OpenURLParams(
3979 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false));
3980 swap_observer.Wait();
3982 // The WebContents should be on url2. There may be 2 or 3 entries, depending
3983 // on whether the first one managed to complete.
3985 // TODO(davidben): When http://crbug.com/335835 is fixed, the 3 entry case
3986 // shouldn't be possible because it's throttled by the pending swap that
3988 const NavigationController& controller =
3989 GetActiveWebContents()->GetController();
3990 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
3991 EXPECT_LE(2, controller.GetEntryCount());
3992 EXPECT_GE(3, controller.GetEntryCount());
3993 EXPECT_EQ(GURL(content::kAboutBlankURL),
3994 controller.GetEntryAtIndex(0)->GetURL());
3995 EXPECT_EQ(url2, controller.GetEntryAtIndex(
3996 controller.GetEntryCount() - 1)->GetURL());
3999 // Verify that pending swaps get aborted on new navigations.
4000 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4001 PrerenderPendingSwapNewNavigation) {
4002 PrerenderManager::HangSessionStorageMergesForTesting();
4004 PrerenderTestURL("files/prerender/prerender_page.html",
4005 FINAL_STATUS_APP_TERMINATING, 1);
4007 // Open a new tab to navigate in.
4008 ui_test_utils::NavigateToURLWithDisposition(
4009 current_browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB,
4010 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4012 // Navigate to the URL. Wait for DidStartLoading, just so it's definitely
4013 // progressed somewhere.
4014 content::WindowedNotificationObserver page_load_observer(
4015 content::NOTIFICATION_LOAD_START,
4016 content::Source<NavigationController>(
4017 &GetActiveWebContents()->GetController()));
4018 current_browser()->OpenURL(OpenURLParams(
4019 dest_url(), Referrer(), CURRENT_TAB,
4020 content::PAGE_TRANSITION_TYPED, false));
4021 page_load_observer.Wait();
4023 // Navigate somewhere else. This should succeed and abort the pending swap.
4024 TestNavigationObserver nav_observer(GetActiveWebContents());
4025 current_browser()->OpenURL(OpenURLParams(
4026 GURL(content::kAboutBlankURL), Referrer(), CURRENT_TAB,
4027 content::PAGE_TRANSITION_TYPED, false));
4028 nav_observer.Wait();
4031 // Checks that <a ping> requests are not dropped in prerender.
4032 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPing) {
4033 // Count hits to a certain URL.
4034 const GURL kPingURL("http://prerender.test/ping");
4035 base::FilePath empty_file = ui_test_utils::GetTestFilePath(
4036 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
4037 RequestCounter ping_counter;
4038 BrowserThread::PostTask(
4039 BrowserThread::IO, FROM_HERE,
4040 base::Bind(&CreateCountingProtocolHandlerOnIO,
4041 kPingURL, empty_file, ping_counter.AsWeakPtr()));
4043 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
4044 OpenDestURLViaClickPing(kPingURL);
4046 ping_counter.WaitForCount(1);
4049 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPPLTNormalNavigation) {
4050 UMAHistogramHelper histograms;
4052 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
4053 ui_test_utils::NavigateToURL(current_browser(), url);
4055 histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
4056 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
4057 histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
4060 class PrerenderIncognitoBrowserTest : public PrerenderBrowserTest {
4062 virtual void SetUpOnMainThread() OVERRIDE {
4063 Profile* normal_profile = current_browser()->profile();
4064 set_browser(ui_test_utils::OpenURLOffTheRecord(
4065 normal_profile, GURL("about:blank")));
4066 PrerenderBrowserTest::SetUpOnMainThread();
4070 // Checks that prerendering works in incognito mode.
4071 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) {
4072 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
4073 NavigateToDestURL();
4076 } // namespace prerender