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/histogram_tester.h"
21 #include "base/test/test_timeouts.h"
22 #include "base/values.h"
23 #include "chrome/browser/browsing_data/browsing_data_helper.h"
24 #include "chrome/browser/browsing_data/browsing_data_remover.h"
25 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
26 #include "chrome/browser/chrome_content_browser_client.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
29 #include "chrome/browser/extensions/extension_apitest.h"
30 #include "chrome/browser/external_protocol/external_protocol_handler.h"
31 #include "chrome/browser/favicon/favicon_tab_helper.h"
32 #include "chrome/browser/net/prediction_options.h"
33 #include "chrome/browser/predictors/autocomplete_action_predictor.h"
34 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
35 #include "chrome/browser/prerender/prerender_contents.h"
36 #include "chrome/browser/prerender/prerender_field_trial.h"
37 #include "chrome/browser/prerender/prerender_handle.h"
38 #include "chrome/browser/prerender/prerender_link_manager.h"
39 #include "chrome/browser/prerender/prerender_link_manager_factory.h"
40 #include "chrome/browser/prerender/prerender_manager.h"
41 #include "chrome/browser/prerender/prerender_manager_factory.h"
42 #include "chrome/browser/profiles/profile.h"
43 #include "chrome/browser/profiles/profile_io_data.h"
44 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
45 #include "chrome/browser/safe_browsing/database_manager.h"
46 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
47 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
48 #include "chrome/browser/task_manager/task_manager.h"
49 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
50 #include "chrome/browser/ui/browser.h"
51 #include "chrome/browser/ui/browser_commands.h"
52 #include "chrome/browser/ui/browser_finder.h"
53 #include "chrome/browser/ui/browser_navigator.h"
54 #include "chrome/browser/ui/browser_window.h"
55 #include "chrome/browser/ui/location_bar/location_bar.h"
56 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
57 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
58 #include "chrome/browser/ui/omnibox/omnibox_view.h"
59 #include "chrome/browser/ui/tabs/tab_strip_model.h"
60 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
61 #include "chrome/common/chrome_paths.h"
62 #include "chrome/common/chrome_switches.h"
63 #include "chrome/common/extensions/extension_constants.h"
64 #include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
65 #include "chrome/common/pref_names.h"
66 #include "chrome/grit/generated_resources.h"
67 #include "chrome/test/base/in_process_browser_test.h"
68 #include "chrome/test/base/test_switches.h"
69 #include "chrome/test/base/ui_test_utils.h"
70 #include "components/content_settings/core/browser/host_content_settings_map.h"
71 #include "components/variations/entropy_provider.h"
72 #include "components/variations/variations_associated_data.h"
73 #include "content/public/browser/browser_message_filter.h"
74 #include "content/public/browser/devtools_agent_host.h"
75 #include "content/public/browser/navigation_controller.h"
76 #include "content/public/browser/navigation_entry.h"
77 #include "content/public/browser/notification_service.h"
78 #include "content/public/browser/render_frame_host.h"
79 #include "content/public/browser/render_process_host.h"
80 #include "content/public/browser/render_view_host.h"
81 #include "content/public/browser/site_instance.h"
82 #include "content/public/browser/web_contents.h"
83 #include "content/public/browser/web_contents_observer.h"
84 #include "content/public/common/url_constants.h"
85 #include "content/public/test/browser_test_utils.h"
86 #include "content/public/test/test_navigation_observer.h"
87 #include "content/public/test/test_utils.h"
88 #include "extensions/common/extension_urls.h"
89 #include "extensions/common/switches.h"
90 #include "extensions/test/result_catcher.h"
91 #include "net/base/escape.h"
92 #include "net/cert/x509_certificate.h"
93 #include "net/dns/mock_host_resolver.h"
94 #include "net/ssl/client_cert_store.h"
95 #include "net/ssl/ssl_cert_request_info.h"
96 #include "net/test/url_request/url_request_mock_http_job.h"
97 #include "net/url_request/url_request_context.h"
98 #include "net/url_request/url_request_context_getter.h"
99 #include "net/url_request/url_request_filter.h"
100 #include "net/url_request/url_request_interceptor.h"
101 #include "net/url_request/url_request_job.h"
102 #include "ui/base/l10n/l10n_util.h"
103 #include "url/gurl.h"
105 using chrome_browser_net::NetworkPredictionOptions;
106 using content::BrowserThread;
107 using content::DevToolsAgentHost;
108 using content::NavigationController;
109 using content::OpenURLParams;
110 using content::Referrer;
111 using content::RenderFrameHost;
112 using content::RenderViewHost;
113 using content::RenderWidgetHost;
114 using content::TestNavigationObserver;
115 using content::WebContents;
116 using content::WebContentsObserver;
117 using net::NetworkChangeNotifier;
118 using task_manager::browsertest_util::WaitForTaskManagerRows;
120 // Prerender tests work as follows:
122 // A page with a prefetch link to the test page is loaded. Once prerendered,
123 // its Javascript function DidPrerenderPass() is called, which returns true if
124 // the page behaves as expected when prerendered.
126 // The prerendered page is then displayed on a tab. The Javascript function
127 // DidDisplayPass() is called, and returns true if the page behaved as it
128 // should while being displayed.
130 namespace prerender {
134 class MockNetworkChangeNotifierWIFI : public NetworkChangeNotifier {
136 ConnectionType GetCurrentConnectionType() const override {
137 return NetworkChangeNotifier::CONNECTION_WIFI;
141 class MockNetworkChangeNotifier4G : public NetworkChangeNotifier {
143 ConnectionType GetCurrentConnectionType() const override {
144 return NetworkChangeNotifier::CONNECTION_4G;
148 // Constants used in the test HTML files.
149 const char* kReadyTitle = "READY";
150 const char* kPassTitle = "PASS";
152 std::string CreateClientRedirect(const std::string& dest_url) {
153 const char* const kClientRedirectBase = "client-redirect?";
154 return kClientRedirectBase + net::EscapeQueryParamValue(dest_url, false);
157 std::string CreateServerRedirect(const std::string& dest_url) {
158 const char* const kServerRedirectBase = "server-redirect?";
159 return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false);
162 // Clears the specified data using BrowsingDataRemover.
163 void ClearBrowsingData(Browser* browser, int remove_mask) {
164 BrowsingDataRemover* remover =
165 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
166 BrowsingDataRemoverCompletionObserver observer(remover);
167 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
168 observer.BlockUntilCompletion();
169 // BrowsingDataRemover deletes itself.
172 // Returns true if the prerender is expected to abort on its own, before
173 // attempting to swap it.
174 bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) {
176 case FINAL_STATUS_USED:
177 case FINAL_STATUS_WINDOW_OPENER:
178 case FINAL_STATUS_APP_TERMINATING:
179 case FINAL_STATUS_PROFILE_DESTROYED:
180 case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
181 // We'll crash the renderer after it's loaded.
182 case FINAL_STATUS_RENDERER_CRASHED:
183 case FINAL_STATUS_CANCELLED:
184 case FINAL_STATUS_DEVTOOLS_ATTACHED:
185 case FINAL_STATUS_PAGE_BEING_CAPTURED:
186 case FINAL_STATUS_NAVIGATION_UNCOMMITTED:
187 case FINAL_STATUS_WOULD_HAVE_BEEN_USED:
188 case FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE:
195 // Convenience function to wait for a title. Handles the case when the
196 // WebContents already has the expected title.
197 void WaitForASCIITitle(WebContents* web_contents,
198 const char* expected_title_ascii) {
199 base::string16 expected_title = base::ASCIIToUTF16(expected_title_ascii);
200 if (web_contents->GetTitle() == expected_title)
202 content::TitleWatcher title_watcher(web_contents, expected_title);
203 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
206 // Waits for the destruction of a RenderProcessHost's IPC channel.
207 // Used to make sure the PrerenderLinkManager's OnChannelClosed function has
208 // been called, before checking its state.
209 class ChannelDestructionWatcher {
211 ChannelDestructionWatcher() : channel_destroyed_(false) {
214 ~ChannelDestructionWatcher() {
217 void WatchChannel(content::RenderProcessHost* host) {
218 host->AddFilter(new DestructionMessageFilter(this));
221 void WaitForChannelClose() {
223 EXPECT_TRUE(channel_destroyed_);
227 // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed.
228 // Ignores all messages.
229 class DestructionMessageFilter : public content::BrowserMessageFilter {
231 explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher)
232 : BrowserMessageFilter(0),
237 ~DestructionMessageFilter() override {
238 content::BrowserThread::PostTask(
239 content::BrowserThread::UI, FROM_HERE,
240 base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
241 base::Unretained(watcher_)));
244 bool OnMessageReceived(const IPC::Message& message) override {
248 ChannelDestructionWatcher* watcher_;
250 DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter);
253 void OnChannelDestroyed() {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
256 EXPECT_FALSE(channel_destroyed_);
257 channel_destroyed_ = true;
261 bool channel_destroyed_;
262 base::RunLoop run_loop_;
264 DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher);
267 // A navigation observer to wait on either a new load or a swap of a
268 // WebContents. On swap, if the new WebContents is still loading, wait for that
269 // load to complete as well. Note that the load must begin after the observer is
271 class NavigationOrSwapObserver : public WebContentsObserver,
272 public TabStripModelObserver {
274 // Waits for either a new load or a swap of |tab_strip_model|'s active
276 NavigationOrSwapObserver(TabStripModel* tab_strip_model,
277 WebContents* web_contents)
278 : WebContentsObserver(web_contents),
279 tab_strip_model_(tab_strip_model),
280 did_start_loading_(false),
281 number_of_loads_(1) {
282 CHECK_NE(TabStripModel::kNoTab,
283 tab_strip_model->GetIndexOfWebContents(web_contents));
284 tab_strip_model_->AddObserver(this);
287 // Waits for either |number_of_loads| loads or a swap of |tab_strip_model|'s
288 // active WebContents.
289 NavigationOrSwapObserver(TabStripModel* tab_strip_model,
290 WebContents* web_contents,
292 : WebContentsObserver(web_contents),
293 tab_strip_model_(tab_strip_model),
294 did_start_loading_(false),
295 number_of_loads_(number_of_loads) {
296 CHECK_NE(TabStripModel::kNoTab,
297 tab_strip_model->GetIndexOfWebContents(web_contents));
298 tab_strip_model_->AddObserver(this);
301 ~NavigationOrSwapObserver() override {
302 tab_strip_model_->RemoveObserver(this);
305 void set_did_start_loading() {
306 did_start_loading_ = true;
313 // WebContentsObserver implementation:
314 void DidStartLoading(RenderViewHost* render_view_host) override {
315 did_start_loading_ = true;
317 void DidStopLoading(RenderViewHost* render_view_host) override {
318 if (!did_start_loading_)
321 if (number_of_loads_ == 0)
325 // TabStripModelObserver implementation:
326 void TabReplacedAt(TabStripModel* tab_strip_model,
327 WebContents* old_contents,
328 WebContents* new_contents,
329 int index) override {
330 if (old_contents != web_contents())
332 // Switch to observing the new WebContents.
333 Observe(new_contents);
334 if (new_contents->IsLoading()) {
335 // If the new WebContents is still loading, wait for it to complete. Only
336 // one load post-swap is supported.
337 did_start_loading_ = true;
338 number_of_loads_ = 1;
345 TabStripModel* tab_strip_model_;
346 bool did_start_loading_;
347 int number_of_loads_;
351 // Waits for a new tab to open and a navigation or swap in it.
352 class NewTabNavigationOrSwapObserver {
354 NewTabNavigationOrSwapObserver()
356 chrome::NOTIFICATION_TAB_ADDED,
357 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded,
358 base::Unretained(this))) {
359 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the
360 // NavigationOrSwapObserver can be attached synchronously and no events are
365 new_tab_observer_.Wait();
366 swap_observer_->Wait();
369 bool OnTabAdded(const content::NotificationSource& source,
370 const content::NotificationDetails& details) {
373 WebContents* new_tab = content::Details<WebContents>(details).ptr();
374 // Get the TabStripModel. Assume this is attached to a Browser.
375 TabStripModel* tab_strip_model =
376 static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model();
377 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model,
379 swap_observer_->set_did_start_loading();
384 content::WindowedNotificationObserver new_tab_observer_;
385 scoped_ptr<NavigationOrSwapObserver> swap_observer_;
388 // PrerenderContents that stops the UI message loop on DidStopLoading().
389 class TestPrerenderContents : public PrerenderContents {
391 TestPrerenderContents(
392 PrerenderManager* prerender_manager,
395 const content::Referrer& referrer,
397 FinalStatus expected_final_status)
398 : PrerenderContents(prerender_manager, profile, url,
399 referrer, origin, PrerenderManager::kNoExperiment),
400 expected_final_status_(expected_final_status),
401 new_render_view_host_(NULL),
404 should_be_shown_(expected_final_status == FINAL_STATUS_USED),
405 skip_final_checks_(false) {
408 ~TestPrerenderContents() override {
409 if (skip_final_checks_)
412 if (expected_final_status_ == FINAL_STATUS_MAX) {
413 EXPECT_EQ(MATCH_COMPLETE_REPLACEMENT, match_complete_status());
415 EXPECT_EQ(expected_final_status_, final_status()) <<
416 " when testing URL " << prerender_url().path() <<
417 " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
418 ", Actual: " << NameFromFinalStatus(final_status()) << ")";
420 // Prerendering RenderViewHosts should be hidden before the first
421 // navigation, so this should be happen for every PrerenderContents for
422 // which a RenderViewHost is created, regardless of whether or not it's
424 if (new_render_view_host_)
425 EXPECT_TRUE(was_hidden_);
427 // A used PrerenderContents will only be destroyed when we swap out
428 // WebContents, at the end of a navigation caused by a call to
429 // NavigateToURLImpl().
430 if (final_status() == FINAL_STATUS_USED)
431 EXPECT_TRUE(new_render_view_host_);
433 EXPECT_EQ(should_be_shown_, was_shown_);
436 void RenderProcessGone(base::TerminationStatus status) override {
437 // On quit, it's possible to end up here when render processes are closed
438 // before the PrerenderManager is destroyed. As a result, it's possible to
439 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
442 // It's also possible for this to be called after we've been notified of
443 // app termination, but before we've been deleted, which is why the second
445 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
446 final_status() != expected_final_status_) {
447 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
450 PrerenderContents::RenderProcessGone(status);
453 bool CheckURL(const GURL& url) override {
454 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
455 // the PrerenderRendererCrash test.
456 if (url.spec() != content::kChromeUICrashURL)
457 return PrerenderContents::CheckURL(url);
461 // For tests that open the prerender in a new background tab, the RenderView
462 // will not have been made visible when the PrerenderContents is destroyed
463 // even though it is used.
464 void set_should_be_shown(bool value) { should_be_shown_ = value; }
466 // For tests which do not know whether the prerender will be used.
467 void set_skip_final_checks(bool value) { skip_final_checks_ = value; }
469 FinalStatus expected_final_status() const { return expected_final_status_; }
472 void OnRenderViewHostCreated(RenderViewHost* new_render_view_host) override {
473 // Used to make sure the RenderViewHost is hidden and, if used,
474 // subsequently shown.
475 notification_registrar().Add(
477 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
478 content::Source<RenderWidgetHost>(new_render_view_host));
480 new_render_view_host_ = new_render_view_host;
482 PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
485 void Observe(int type,
486 const content::NotificationSource& source,
487 const content::NotificationDetails& details) override {
489 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
490 EXPECT_EQ(new_render_view_host_,
491 content::Source<RenderWidgetHost>(source).ptr());
492 bool is_visible = *content::Details<bool>(details).ptr();
496 } else if (is_visible && was_hidden_) {
497 // Once hidden, a prerendered RenderViewHost should only be shown after
498 // being removed from the PrerenderContents for display.
499 EXPECT_FALSE(GetRenderViewHost());
504 PrerenderContents::Observe(type, source, details);
507 FinalStatus expected_final_status_;
509 // The RenderViewHost created for the prerender, if any.
510 RenderViewHost* new_render_view_host_;
511 // Set to true when the prerendering RenderWidget is hidden.
513 // Set to true when the prerendering RenderWidget is shown, after having been
516 // Expected final value of was_shown_. Defaults to true for
517 // FINAL_STATUS_USED, and false otherwise.
518 bool should_be_shown_;
519 // If true, |expected_final_status_| and other shutdown checks are skipped.
520 bool skip_final_checks_;
523 // A handle to a TestPrerenderContents whose lifetime is under the caller's
524 // control. A PrerenderContents may be destroyed at any point. This allows
525 // tracking the final status, etc.
526 class TestPrerender : public PrerenderContents::Observer,
527 public base::SupportsWeakPtr<TestPrerender> {
532 expected_number_of_loads_(0) {
534 ~TestPrerender() override {
536 contents_->RemoveObserver(this);
539 TestPrerenderContents* contents() const { return contents_; }
540 int number_of_loads() const { return number_of_loads_; }
542 void WaitForCreate() { create_loop_.Run(); }
543 void WaitForStart() { start_loop_.Run(); }
544 void WaitForStop() { stop_loop_.Run(); }
546 // Waits for |number_of_loads()| to be at least |expected_number_of_loads| OR
547 // for the prerender to stop running (just to avoid a timeout if the prerender
548 // dies). Note: this does not assert equality on the number of loads; the
549 // caller must do it instead.
550 void WaitForLoads(int expected_number_of_loads) {
551 DCHECK(!load_waiter_);
552 DCHECK(!expected_number_of_loads_);
553 if (number_of_loads_ < expected_number_of_loads) {
554 load_waiter_.reset(new base::RunLoop);
555 expected_number_of_loads_ = expected_number_of_loads;
557 load_waiter_.reset();
558 expected_number_of_loads_ = 0;
560 EXPECT_LE(expected_number_of_loads, number_of_loads_);
563 void OnPrerenderCreated(TestPrerenderContents* contents) {
565 contents_ = contents;
566 contents_->AddObserver(this);
570 // PrerenderContents::Observer implementation:
571 void OnPrerenderStart(PrerenderContents* contents) override {
575 void OnPrerenderStopLoading(PrerenderContents* contents) override {
577 if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
578 load_waiter_->Quit();
581 void OnPrerenderStop(PrerenderContents* contents) override {
585 // If there is a WaitForLoads call and it has yet to see the expected number
586 // of loads, stop the loop so the test fails instead of timing out.
588 load_waiter_->Quit();
591 void OnPrerenderCreatedMatchCompleteReplacement(
592 PrerenderContents* contents,
593 PrerenderContents* replacement) override {}
596 TestPrerenderContents* contents_;
597 int number_of_loads_;
599 int expected_number_of_loads_;
600 scoped_ptr<base::RunLoop> load_waiter_;
602 base::RunLoop create_loop_;
603 base::RunLoop start_loop_;
604 base::RunLoop stop_loop_;
606 DISALLOW_COPY_AND_ASSIGN(TestPrerender);
609 // PrerenderManager that uses TestPrerenderContents.
610 class TestPrerenderContentsFactory : public PrerenderContents::Factory {
612 TestPrerenderContentsFactory() {}
614 ~TestPrerenderContentsFactory() override {
615 EXPECT_TRUE(expected_contents_queue_.empty());
618 scoped_ptr<TestPrerender> ExpectPrerenderContents(FinalStatus final_status) {
619 scoped_ptr<TestPrerender> handle(new TestPrerender());
620 expected_contents_queue_.push_back(
621 ExpectedContents(final_status, handle->AsWeakPtr()));
622 return handle.Pass();
625 PrerenderContents* CreatePrerenderContents(
626 PrerenderManager* prerender_manager,
629 const content::Referrer& referrer,
631 uint8 experiment_id) override {
632 ExpectedContents expected;
633 if (!expected_contents_queue_.empty()) {
634 expected = expected_contents_queue_.front();
635 expected_contents_queue_.pop_front();
637 VLOG(1) << "Creating prerender contents for " << url.path() <<
638 " with expected final status " << expected.final_status;
639 VLOG(1) << expected_contents_queue_.size() << " left in the queue.";
640 TestPrerenderContents* contents =
641 new TestPrerenderContents(prerender_manager,
642 profile, url, referrer, origin,
643 expected.final_status);
645 expected.handle->OnPrerenderCreated(contents);
650 struct ExpectedContents {
651 ExpectedContents() : final_status(FINAL_STATUS_MAX) { }
652 ExpectedContents(FinalStatus final_status,
653 const base::WeakPtr<TestPrerender>& handle)
654 : final_status(final_status),
658 FinalStatus final_status;
659 base::WeakPtr<TestPrerender> handle;
662 std::deque<ExpectedContents> expected_contents_queue_;
665 #if defined(FULL_SAFE_BROWSING)
666 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
668 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
670 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
671 : SafeBrowsingDatabaseManager(service),
672 threat_type_(SB_THREAT_TYPE_SAFE) { }
674 // Called on the IO thread to check if the given url is safe or not. If we
675 // can synchronously determine that the url is safe, CheckUrl returns true.
676 // Otherwise it returns false, and "client" is called asynchronously with the
677 // result when it is ready.
678 // Returns true, indicating a SAFE result, unless the URL is the fixed URL
679 // specified by the user, and the user-specified result is not SAFE
680 // (in which that result will be communicated back via a call into the
681 // client, and false will be returned).
682 // Overrides SafeBrowsingService::CheckBrowseUrl.
683 bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
684 if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
687 BrowserThread::PostTask(
688 BrowserThread::IO, FROM_HERE,
689 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
690 this, gurl, client));
694 void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) {
696 threat_type_ = threat_type;
700 ~FakeSafeBrowsingDatabaseManager() override {}
702 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
703 std::vector<SBThreatType> expected_threats;
704 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
705 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
706 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
707 std::vector<GURL>(1, gurl),
708 std::vector<SBFullHash>(),
710 safe_browsing_util::MALWARE,
712 sb_check.url_results[0] = threat_type_;
713 client->OnSafeBrowsingResult(sb_check);
717 SBThreatType threat_type_;
718 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
721 class FakeSafeBrowsingService : public SafeBrowsingService {
723 FakeSafeBrowsingService() { }
725 // Returned pointer has the same lifespan as the database_manager_ refcounted
727 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
728 return fake_database_manager_;
732 ~FakeSafeBrowsingService() override {}
734 SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
735 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
736 return fake_database_manager_;
740 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
742 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
745 // Factory that creates FakeSafeBrowsingService instances.
746 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
748 TestSafeBrowsingServiceFactory() :
749 most_recent_service_(NULL) { }
750 ~TestSafeBrowsingServiceFactory() override {}
752 SafeBrowsingService* CreateSafeBrowsingService() override {
753 most_recent_service_ = new FakeSafeBrowsingService();
754 return most_recent_service_;
757 FakeSafeBrowsingService* most_recent_service() const {
758 return most_recent_service_;
762 FakeSafeBrowsingService* most_recent_service_;
766 class FakeDevToolsClient : public content::DevToolsAgentHostClient {
768 FakeDevToolsClient() {}
769 ~FakeDevToolsClient() override {}
770 void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
771 const std::string& message) override {}
772 void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {}
775 class RestorePrerenderMode {
777 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
780 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
782 PrerenderManager::PrerenderManagerMode prev_mode_;
785 // URLRequestJob (and associated handler) which hangs.
786 class HangingURLRequestJob : public net::URLRequestJob {
788 HangingURLRequestJob(net::URLRequest* request,
789 net::NetworkDelegate* network_delegate)
790 : net::URLRequestJob(request, network_delegate) {
793 void Start() override {}
796 ~HangingURLRequestJob() override {}
799 class HangingFirstRequestInterceptor : public net::URLRequestInterceptor {
801 HangingFirstRequestInterceptor(const base::FilePath& file,
802 base::Closure callback)
807 ~HangingFirstRequestInterceptor() override {}
809 net::URLRequestJob* MaybeInterceptRequest(
810 net::URLRequest* request,
811 net::NetworkDelegate* network_delegate) const override {
814 if (!callback_.is_null()) {
815 BrowserThread::PostTask(
816 BrowserThread::UI, FROM_HERE, callback_);
818 return new HangingURLRequestJob(request, network_delegate);
820 return new net::URLRequestMockHTTPJob(
824 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
825 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
829 base::FilePath file_;
830 base::Closure callback_;
831 mutable bool first_run_;
834 // Makes |url| never respond on the first load, and then with the contents of
835 // |file| afterwards. When the first load has been scheduled, runs |callback| on
837 void CreateHangingFirstRequestInterceptorOnIO(
838 const GURL& url, const base::FilePath& file, base::Closure callback) {
839 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
840 scoped_ptr<net::URLRequestInterceptor> never_respond_handler(
841 new HangingFirstRequestInterceptor(file, callback));
842 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
843 url, never_respond_handler.Pass());
846 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks.
847 class MockHTTPJob : public net::URLRequestMockHTTPJob {
849 MockHTTPJob(net::URLRequest* request,
850 net::NetworkDelegate* delegate,
851 const base::FilePath& file)
852 : net::URLRequestMockHTTPJob(
856 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
857 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)) {}
859 void set_start_callback(const base::Closure& start_callback) {
860 start_callback_ = start_callback;
863 void Start() override {
864 if (!start_callback_.is_null())
865 start_callback_.Run();
866 net::URLRequestMockHTTPJob::Start();
870 ~MockHTTPJob() override {}
872 base::Closure start_callback_;
875 // Dummy counter class to live on the UI thread for counting requests.
876 class RequestCounter : public base::SupportsWeakPtr<RequestCounter> {
878 RequestCounter() : count_(0), expected_count_(-1) {}
879 int count() const { return count_; }
881 void RequestStarted() {
883 if (loop_ && count_ == expected_count_)
887 void WaitForCount(int expected_count) {
889 ASSERT_EQ(-1, expected_count_);
890 if (count_ < expected_count) {
891 expected_count_ = expected_count;
892 loop_.reset(new base::RunLoop);
894 expected_count_ = -1;
898 EXPECT_EQ(expected_count, count_);
903 scoped_ptr<base::RunLoop> loop_;
906 // Protocol handler which counts the number of requests that start.
907 class CountingInterceptor : public net::URLRequestInterceptor {
909 CountingInterceptor(const base::FilePath& file,
910 const base::WeakPtr<RequestCounter>& counter)
913 weak_factory_(this) {
915 ~CountingInterceptor() override {}
917 net::URLRequestJob* MaybeInterceptRequest(
918 net::URLRequest* request,
919 net::NetworkDelegate* network_delegate) const override {
920 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
921 job->set_start_callback(base::Bind(&CountingInterceptor::RequestStarted,
922 weak_factory_.GetWeakPtr()));
926 void RequestStarted() {
927 BrowserThread::PostTask(
928 BrowserThread::UI, FROM_HERE,
929 base::Bind(&RequestCounter::RequestStarted, counter_));
933 base::FilePath file_;
934 base::WeakPtr<RequestCounter> counter_;
935 mutable base::WeakPtrFactory<CountingInterceptor> weak_factory_;
938 // Makes |url| respond to requests with the contents of |file|, counting the
939 // number that start in |counter|.
940 void CreateCountingInterceptorOnIO(
942 const base::FilePath& file,
943 const base::WeakPtr<RequestCounter>& counter) {
944 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
945 scoped_ptr<net::URLRequestInterceptor> request_interceptor(
946 new CountingInterceptor(file, counter));
947 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
948 url, request_interceptor.Pass());
951 // Makes |url| respond to requests with the contents of |file|.
952 void CreateMockInterceptorOnIO(const GURL& url, const base::FilePath& file) {
953 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
954 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
956 net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
957 file, BrowserThread::GetBlockingPool()));
960 // A ContentBrowserClient that cancels all prerenderers on OpenURL.
961 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
963 TestContentBrowserClient() {}
964 ~TestContentBrowserClient() override {}
966 // chrome::ChromeContentBrowserClient implementation.
967 bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
968 const GURL& url) override {
969 PrerenderManagerFactory::GetForProfile(
970 Profile::FromBrowserContext(site_instance->GetBrowserContext()))
971 ->CancelAllPrerenders();
972 return chrome::ChromeContentBrowserClient::ShouldAllowOpenURL(site_instance,
977 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
980 // A ContentBrowserClient that forces cross-process navigations.
981 class SwapProcessesContentBrowserClient
982 : public chrome::ChromeContentBrowserClient {
984 SwapProcessesContentBrowserClient() {}
985 ~SwapProcessesContentBrowserClient() override {}
987 // chrome::ChromeContentBrowserClient implementation.
988 bool ShouldSwapProcessesForRedirect(
989 content::ResourceContext* resource_context,
990 const GURL& current_url,
991 const GURL& new_url) override {
996 DISALLOW_COPY_AND_ASSIGN(SwapProcessesContentBrowserClient);
999 // An ExternalProtocolHandler that blocks everything and asserts it never is
1001 class NeverRunsExternalProtocolHandlerDelegate
1002 : public ExternalProtocolHandler::Delegate {
1004 // ExternalProtocolHandler::Delegate implementation.
1005 ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
1006 ShellIntegration::DefaultWebClientObserver* observer,
1007 const std::string& protocol) override {
1009 // This will crash, but it shouldn't get this far with BlockState::BLOCK
1013 ExternalProtocolHandler::BlockState GetBlockState(
1014 const std::string& scheme) override {
1015 // Block everything and fail the test.
1017 return ExternalProtocolHandler::BLOCK;
1019 void BlockRequest() override {}
1020 void RunExternalProtocolDialog(const GURL& url,
1021 int render_process_host_id,
1022 int routing_id) override {
1025 void LaunchUrlWithoutSecurityCheck(const GURL& url) override { NOTREACHED(); }
1026 void FinishedProcessingCheck() override { NOTREACHED(); }
1029 base::FilePath GetTestPath(const std::string& file_name) {
1030 return ui_test_utils::GetTestFilePath(
1031 base::FilePath(FILE_PATH_LITERAL("prerender")),
1032 base::FilePath().AppendASCII(file_name));
1037 // Many of these tests are flaky. See http://crbug.com/249179
1038 class PrerenderBrowserTest : virtual public InProcessBrowserTest {
1040 PrerenderBrowserTest()
1041 : autostart_test_server_(true),
1042 prerender_contents_factory_(NULL),
1043 #if defined(FULL_SAFE_BROWSING)
1044 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
1046 call_javascript_(true),
1047 check_load_events_(true),
1048 loader_path_("files/prerender/prerender_loader.html"),
1049 explicitly_set_browser_(NULL) {}
1051 ~PrerenderBrowserTest() override {}
1053 content::SessionStorageNamespace* GetSessionStorageNamespace() const {
1054 WebContents* web_contents = GetActiveWebContents();
1057 return web_contents->GetController().GetDefaultSessionStorageNamespace();
1060 void SetUpInProcessBrowserTestFixture() override {
1061 #if defined(FULL_SAFE_BROWSING)
1062 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
1066 void TearDownInProcessBrowserTestFixture() override {
1067 #if defined(FULL_SAFE_BROWSING)
1068 SafeBrowsingService::RegisterFactory(NULL);
1072 void SetUpCommandLine(CommandLine* command_line) override {
1073 command_line->AppendSwitchASCII(switches::kPrerenderMode,
1074 switches::kPrerenderModeSwitchValueEnabled);
1075 #if defined(OS_MACOSX)
1076 // The plugins directory isn't read by default on the Mac, so it needs to be
1077 // explicitly registered.
1078 base::FilePath app_dir;
1079 PathService::Get(chrome::DIR_APP, &app_dir);
1080 command_line->AppendSwitchPath(
1081 switches::kExtraPluginDir,
1082 app_dir.Append(FILE_PATH_LITERAL("plugins")));
1084 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
1087 void SetPreference(NetworkPredictionOptions value) {
1088 browser()->profile()->GetPrefs()->SetInteger(
1089 prefs::kNetworkPredictionOptions, value);
1092 void CreateTestFieldTrial(const std::string& name,
1093 const std::string& group_name) {
1094 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
1099 // Verifies, for the current field trial, whether
1100 // ShouldDisableLocalPredictorDueToPreferencesAndNetwork produces the desired
1102 void TestShouldDisableLocalPredictorPreferenceNetworkMatrix(
1103 bool preference_wifi_network_wifi,
1104 bool preference_wifi_network_4g,
1105 bool preference_always_network_wifi,
1106 bool preference_always_network_4g,
1107 bool preference_never_network_wifi,
1108 bool preference_never_network_4g) {
1109 Profile* profile = browser()->profile();
1111 // Set real NetworkChangeNotifier singleton aside.
1112 scoped_ptr<NetworkChangeNotifier::DisableForTest> disable_for_test(
1113 new NetworkChangeNotifier::DisableForTest);
1115 // Set preference to WIFI_ONLY: prefetch when not on cellular.
1116 SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_WIFI_ONLY);
1118 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
1120 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1121 preference_wifi_network_wifi);
1124 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
1126 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1127 preference_wifi_network_4g);
1130 // Set preference to ALWAYS: always prefetch.
1131 SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_ALWAYS);
1133 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
1135 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1136 preference_always_network_wifi);
1139 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
1141 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1142 preference_always_network_4g);
1145 // Set preference to NEVER: never prefetch.
1146 SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_NEVER);
1148 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
1150 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1151 preference_never_network_wifi);
1154 scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
1156 ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile),
1157 preference_never_network_4g);
1161 void SetUpOnMainThread() override {
1162 current_browser()->profile()->GetPrefs()->SetBoolean(
1163 prefs::kPromptForDownload, false);
1164 IncreasePrerenderMemory();
1165 if (autostart_test_server_)
1166 ASSERT_TRUE(test_server()->Start());
1167 ChromeResourceDispatcherHostDelegate::
1168 SetExternalProtocolHandlerDelegateForTesting(
1169 &external_protocol_handler_delegate_);
1171 PrerenderManager* prerender_manager = GetPrerenderManager();
1172 ASSERT_TRUE(prerender_manager);
1173 prerender_manager->mutable_config().rate_limit_enabled = false;
1174 ASSERT_TRUE(prerender_contents_factory_ == NULL);
1175 prerender_contents_factory_ = new TestPrerenderContentsFactory;
1176 prerender_manager->SetPrerenderContentsFactory(prerender_contents_factory_);
1179 // Convenience function to get the currently active WebContents in
1180 // current_browser().
1181 WebContents* GetActiveWebContents() const {
1182 return current_browser()->tab_strip_model()->GetActiveWebContents();
1185 // Overload for a single expected final status
1186 scoped_ptr<TestPrerender> PrerenderTestURL(
1187 const std::string& html_file,
1188 FinalStatus expected_final_status,
1189 int expected_number_of_loads) {
1190 GURL url = test_server()->GetURL(html_file);
1191 return PrerenderTestURL(url,
1192 expected_final_status,
1193 expected_number_of_loads);
1196 ScopedVector<TestPrerender> PrerenderTestURL(
1197 const std::string& html_file,
1198 const std::vector<FinalStatus>& expected_final_status_queue,
1199 int expected_number_of_loads) {
1200 GURL url = test_server()->GetURL(html_file);
1201 return PrerenderTestURLImpl(url,
1202 expected_final_status_queue,
1203 expected_number_of_loads);
1206 scoped_ptr<TestPrerender> PrerenderTestURL(
1208 FinalStatus expected_final_status,
1209 int expected_number_of_loads) {
1210 std::vector<FinalStatus> expected_final_status_queue(
1211 1, expected_final_status);
1212 std::vector<TestPrerender*> prerenders;
1213 PrerenderTestURLImpl(url,
1214 expected_final_status_queue,
1215 expected_number_of_loads).release(&prerenders);
1216 CHECK_EQ(1u, prerenders.size());
1217 return scoped_ptr<TestPrerender>(prerenders[0]);
1220 // Navigates to a URL, unrelated to prerendering
1221 void NavigateStraightToURL(const std::string dest_html_file) {
1222 ui_test_utils::NavigateToURL(current_browser(),
1223 test_server()->GetURL(dest_html_file));
1226 void NavigateToDestURL() const {
1227 NavigateToDestURLWithDisposition(CURRENT_TAB, true);
1230 // Opens the url in a new tab, with no opener.
1231 void NavigateToDestURLWithDisposition(
1232 WindowOpenDisposition disposition,
1233 bool expect_swap_to_succeed) const {
1234 NavigateToURLWithParams(
1235 content::OpenURLParams(dest_url_, Referrer(), disposition,
1236 ui::PAGE_TRANSITION_TYPED, false),
1237 expect_swap_to_succeed);
1240 void NavigateToURL(const std::string& dest_html_file) const {
1241 NavigateToURLWithDisposition(dest_html_file, CURRENT_TAB, true);
1244 void NavigateToURLWithDisposition(const std::string& dest_html_file,
1245 WindowOpenDisposition disposition,
1246 bool expect_swap_to_succeed) const {
1247 GURL dest_url = test_server()->GetURL(dest_html_file);
1248 NavigateToURLWithDisposition(dest_url, disposition, expect_swap_to_succeed);
1251 void NavigateToURLWithDisposition(const GURL& dest_url,
1252 WindowOpenDisposition disposition,
1253 bool expect_swap_to_succeed) const {
1254 NavigateToURLWithParams(
1255 content::OpenURLParams(dest_url, Referrer(), disposition,
1256 ui::PAGE_TRANSITION_TYPED, false),
1257 expect_swap_to_succeed);
1260 void NavigateToURLWithParams(const content::OpenURLParams& params,
1261 bool expect_swap_to_succeed) const {
1262 NavigateToURLImpl(params, expect_swap_to_succeed);
1265 void OpenDestURLViaClick() const {
1266 OpenURLViaClick(dest_url_);
1269 void OpenURLViaClick(const GURL& url) const {
1270 OpenURLWithJSImpl("Click", url, GURL(), false);
1273 void OpenDestURLViaClickTarget() const {
1274 OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true);
1277 void OpenDestURLViaClickPing(const GURL& ping_url) const {
1278 OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false);
1281 void OpenDestURLViaClickNewWindow() const {
1282 OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true);
1285 void OpenDestURLViaClickNewForegroundTab() const {
1286 #if defined(OS_MACOSX)
1287 OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true);
1289 OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true);
1293 void OpenDestURLViaClickNewBackgroundTab() const {
1294 #if defined(OS_MACOSX)
1295 OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true);
1297 OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true);
1301 void OpenDestURLViaWindowOpen() const {
1302 OpenURLViaWindowOpen(dest_url_);
1305 void OpenURLViaWindowOpen(const GURL& url) const {
1306 OpenURLWithJSImpl("WindowOpen", url, GURL(), true);
1309 void RemoveLinkElement(int i) const {
1310 GetActiveWebContents()->GetMainFrame()->ExecuteJavaScript(
1311 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i)));
1314 void ClickToNextPageAfterPrerender() {
1315 TestNavigationObserver nav_observer(GetActiveWebContents());
1316 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame();
1317 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("ClickOpenLink()"));
1318 nav_observer.Wait();
1321 void NavigateToNextPageAfterPrerender() const {
1322 ui_test_utils::NavigateToURL(
1324 test_server()->GetURL("files/prerender/prerender_page.html"));
1327 // Called after the prerendered page has been navigated to and then away from.
1328 // Navigates back through the history to the prerendered page.
1329 void GoBackToPrerender() {
1330 TestNavigationObserver back_nav_observer(GetActiveWebContents());
1331 chrome::GoBack(current_browser(), CURRENT_TAB);
1332 back_nav_observer.Wait();
1333 bool original_prerender_page = false;
1334 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1335 GetActiveWebContents(),
1336 "window.domAutomationController.send(IsOriginalPrerenderPage())",
1337 &original_prerender_page));
1338 EXPECT_TRUE(original_prerender_page);
1341 // Goes back to the page that was active before the prerender was swapped
1342 // in. This must be called when the prerendered page is the current page
1343 // in the active tab.
1344 void GoBackToPageBeforePrerender() {
1345 WebContents* tab = GetActiveWebContents();
1347 EXPECT_FALSE(tab->IsLoading());
1348 TestNavigationObserver back_nav_observer(tab);
1349 chrome::GoBack(current_browser(), CURRENT_TAB);
1350 back_nav_observer.Wait();
1352 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1354 "window.domAutomationController.send(DidBackToOriginalPagePass())",
1356 EXPECT_TRUE(js_result);
1359 bool UrlIsInPrerenderManager(const std::string& html_file) const {
1360 return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
1363 bool UrlIsInPrerenderManager(const GURL& url) const {
1364 return GetPrerenderManager()->FindPrerenderData(
1365 url, GetSessionStorageNamespace()) != NULL;
1368 void UseHttpsSrcServer() {
1369 if (https_src_server_)
1371 https_src_server_.reset(
1372 new net::SpawnedTestServer(
1373 net::SpawnedTestServer::TYPE_HTTPS,
1374 net::SpawnedTestServer::kLocalhost,
1375 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
1376 CHECK(https_src_server_->Start());
1379 void DisableJavascriptCalls() {
1380 call_javascript_ = false;
1383 void DisableLoadEventCheck() {
1384 check_load_events_ = false;
1387 TaskManagerModel* GetModel() const {
1388 return TaskManager::GetInstance()->model();
1391 PrerenderManager* GetPrerenderManager() const {
1392 PrerenderManager* prerender_manager =
1393 PrerenderManagerFactory::GetForProfile(current_browser()->profile());
1394 return prerender_manager;
1397 const PrerenderLinkManager* GetPrerenderLinkManager() const {
1398 PrerenderLinkManager* prerender_link_manager =
1399 PrerenderLinkManagerFactory::GetForProfile(
1400 current_browser()->profile());
1401 return prerender_link_manager;
1404 int GetPrerenderEventCount(int index, const std::string& type) const {
1406 std::string expression = base::StringPrintf(
1407 "window.domAutomationController.send("
1408 " GetPrerenderEventCount(%d, '%s'))", index, type.c_str());
1410 CHECK(content::ExecuteScriptAndExtractInt(
1411 GetActiveWebContents(), expression, &event_count));
1415 bool DidReceivePrerenderStartEventForLinkNumber(int index) const {
1416 return GetPrerenderEventCount(index, "webkitprerenderstart") > 0;
1419 int GetPrerenderLoadEventCountForLinkNumber(int index) const {
1420 return GetPrerenderEventCount(index, "webkitprerenderload");
1423 int GetPrerenderDomContentLoadedEventCountForLinkNumber(int index) const {
1424 return GetPrerenderEventCount(index, "webkitprerenderdomcontentloaded");
1427 bool DidReceivePrerenderStopEventForLinkNumber(int index) const {
1428 return GetPrerenderEventCount(index, "webkitprerenderstop") > 0;
1431 void WaitForPrerenderEventCount(int index,
1432 const std::string& type,
1435 std::string expression = base::StringPrintf(
1436 "WaitForPrerenderEventCount(%d, '%s', %d,"
1437 " window.domAutomationController.send.bind("
1438 " window.domAutomationController, 0))",
1439 index, type.c_str(), count);
1441 CHECK(content::ExecuteScriptAndExtractInt(
1442 GetActiveWebContents(), expression, &dummy));
1446 bool HadPrerenderEventErrors() const {
1447 bool had_prerender_event_errors;
1448 CHECK(content::ExecuteScriptAndExtractBool(
1449 GetActiveWebContents(),
1450 "window.domAutomationController.send(Boolean("
1451 " hadPrerenderEventErrors))",
1452 &had_prerender_event_errors));
1453 return had_prerender_event_errors;
1456 // Asserting on this can result in flaky tests. PrerenderHandles are
1457 // removed from the PrerenderLinkManager when the prerender is canceled from
1458 // the browser, when the prerenders are cancelled from the renderer process,
1459 // or the channel for the renderer process is closed on the IO thread. In the
1460 // last case, the code must be careful to wait for the channel to close, as it
1461 // is done asynchronously after swapping out the old process. See
1462 // ChannelDestructionWatcher.
1463 bool IsEmptyPrerenderLinkManager() const {
1464 return GetPrerenderLinkManager()->IsEmpty();
1467 size_t GetLinkPrerenderCount() const {
1468 return GetPrerenderLinkManager()->prerenders_.size();
1471 size_t GetRunningLinkPrerenderCount() const {
1472 return GetPrerenderLinkManager()->CountRunningPrerenders();
1475 // Returns length of |prerender_manager_|'s history, or -1 on failure.
1476 int GetHistoryLength() const {
1477 scoped_ptr<base::DictionaryValue> prerender_dict(
1478 static_cast<base::DictionaryValue*>(
1479 GetPrerenderManager()->GetAsValue()));
1480 if (!prerender_dict.get())
1482 base::ListValue* history_list;
1483 if (!prerender_dict->GetList("history", &history_list))
1485 return static_cast<int>(history_list->GetSize());
1488 #if defined(FULL_SAFE_BROWSING)
1489 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() {
1490 return safe_browsing_factory_->most_recent_service()->
1491 fake_database_manager();
1495 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const {
1496 PrerenderManager::PrerenderData* prerender_data =
1497 GetPrerenderManager()->FindPrerenderData(url, NULL);
1498 return static_cast<TestPrerenderContents*>(
1499 prerender_data ? prerender_data->contents() : NULL);
1502 void SetLoaderHostOverride(const std::string& host) {
1503 loader_host_override_ = host;
1504 host_resolver()->AddRule(host, "127.0.0.1");
1507 void set_loader_path(const std::string& path) {
1508 loader_path_ = path;
1511 void set_loader_query(const std::string& query) {
1512 loader_query_ = query;
1515 GURL GetCrossDomainTestUrl(const std::string& path) {
1516 static const std::string secondary_domain = "www.foo.com";
1517 host_resolver()->AddRule(secondary_domain, "127.0.0.1");
1518 std::string url_str(base::StringPrintf(
1520 secondary_domain.c_str(),
1521 test_server()->host_port_pair().port(),
1523 return GURL(url_str);
1526 void set_browser(Browser* browser) {
1527 explicitly_set_browser_ = browser;
1530 Browser* current_browser() const {
1531 return explicitly_set_browser_ ? explicitly_set_browser_ : browser();
1534 const GURL& dest_url() const {
1538 void IncreasePrerenderMemory() {
1539 // Increase the memory allowed in a prerendered page above normal settings.
1540 // Debug build bots occasionally run against the default limit, and tests
1541 // were failing because the prerender was canceled due to memory exhaustion.
1542 // http://crbug.com/93076
1543 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024;
1546 bool DidPrerenderPass(WebContents* web_contents) const {
1547 bool prerender_test_result = false;
1548 if (!content::ExecuteScriptAndExtractBool(
1550 "window.domAutomationController.send(DidPrerenderPass())",
1551 &prerender_test_result))
1553 return prerender_test_result;
1556 bool DidDisplayPass(WebContents* web_contents) const {
1557 bool display_test_result = false;
1558 if (!content::ExecuteScriptAndExtractBool(
1560 "window.domAutomationController.send(DidDisplayPass())",
1561 &display_test_result))
1563 return display_test_result;
1566 scoped_ptr<TestPrerender> ExpectPrerender(FinalStatus expected_final_status) {
1567 return prerender_contents_factory_->ExpectPrerenderContents(
1568 expected_final_status);
1571 void AddPrerender(const GURL& url, int index) {
1572 std::string javascript = base::StringPrintf(
1573 "AddPrerender('%s', %d)", url.spec().c_str(), index);
1574 RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame();
1575 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
1578 // Returns a string for pattern-matching TaskManager tab entries.
1579 base::string16 MatchTaskManagerTab(const char* page_title) {
1580 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX,
1581 base::ASCIIToUTF16(page_title));
1584 // Returns a string for pattern-matching TaskManager prerender entries.
1585 base::string16 MatchTaskManagerPrerender(const char* page_title) {
1586 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX,
1587 base::ASCIIToUTF16(page_title));
1590 void RunJSReturningString(const char* js, std::string* result) {
1592 content::ExecuteScriptAndExtractString(
1593 GetActiveWebContents(),
1594 base::StringPrintf("window.domAutomationController.send(%s)",
1599 void RunJS(const char* js) {
1600 ASSERT_TRUE(content::ExecuteScript(
1601 GetActiveWebContents(),
1602 base::StringPrintf("window.domAutomationController.send(%s)",
1606 const base::HistogramTester& histogram_tester() { return histogram_tester_; }
1609 bool autostart_test_server_;
1612 // TODO(davidben): Remove this altogether so the tests don't globally assume
1613 // only one prerender.
1614 TestPrerenderContents* GetPrerenderContents() const {
1615 return GetPrerenderContentsFor(dest_url_);
1618 ScopedVector<TestPrerender> PrerenderTestURLImpl(
1619 const GURL& prerender_url,
1620 const std::vector<FinalStatus>& expected_final_status_queue,
1621 int expected_number_of_loads) {
1622 dest_url_ = prerender_url;
1624 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
1625 replacement_text.push_back(
1626 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
1627 std::string replacement_path;
1628 CHECK(net::SpawnedTestServer::GetFilePathWithReplacements(
1631 &replacement_path));
1633 const net::SpawnedTestServer* src_server = test_server();
1634 if (https_src_server_)
1635 src_server = https_src_server_.get();
1636 GURL loader_url = src_server->GetURL(
1637 replacement_path + "&" + loader_query_);
1639 GURL::Replacements loader_replacements;
1640 if (!loader_host_override_.empty())
1641 loader_replacements.SetHostStr(loader_host_override_);
1642 loader_url = loader_url.ReplaceComponents(loader_replacements);
1644 VLOG(1) << "Running test with queue length " <<
1645 expected_final_status_queue.size();
1646 CHECK(!expected_final_status_queue.empty());
1647 ScopedVector<TestPrerender> prerenders;
1648 for (size_t i = 0; i < expected_final_status_queue.size(); i++) {
1649 prerenders.push_back(
1650 prerender_contents_factory_->ExpectPrerenderContents(
1651 expected_final_status_queue[i]).release());
1654 FinalStatus expected_final_status = expected_final_status_queue.front();
1656 // Navigate to the loader URL and then wait for the first prerender to be
1658 ui_test_utils::NavigateToURL(current_browser(), loader_url);
1659 prerenders[0]->WaitForCreate();
1660 prerenders[0]->WaitForLoads(expected_number_of_loads);
1662 if (ShouldAbortPrerenderBeforeSwap(expected_final_status)) {
1663 // The prerender will abort on its own. Assert it does so correctly.
1664 prerenders[0]->WaitForStop();
1665 EXPECT_FALSE(prerenders[0]->contents());
1666 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
1668 // Otherwise, check that it prerendered correctly.
1669 TestPrerenderContents* prerender_contents = prerenders[0]->contents();
1671 CHECK_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1672 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
1673 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1675 if (call_javascript_) {
1676 // Check if page behaves as expected while in prerendered state.
1677 EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents()));
1681 // Test that the referring page received the right start and load events.
1682 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1683 if (check_load_events_) {
1684 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads());
1685 EXPECT_EQ(expected_number_of_loads,
1686 GetPrerenderLoadEventCountForLinkNumber(0));
1688 EXPECT_FALSE(HadPrerenderEventErrors());
1690 return prerenders.Pass();
1693 void NavigateToURLImpl(const content::OpenURLParams& params,
1694 bool expect_swap_to_succeed) const {
1695 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager());
1696 // Make sure in navigating we have a URL to use in the PrerenderManager.
1697 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
1699 WebContents* web_contents = GetPrerenderContents()->prerender_contents();
1701 // Navigate and wait for either the load to finish normally or for a swap to
1703 // TODO(davidben): The only handles CURRENT_TAB navigations, which is the
1704 // only case tested or prerendered right now.
1705 CHECK_EQ(CURRENT_TAB, params.disposition);
1706 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
1707 GetActiveWebContents());
1708 WebContents* target_web_contents = current_browser()->OpenURL(params);
1709 swap_observer.Wait();
1711 if (web_contents && expect_swap_to_succeed) {
1712 EXPECT_EQ(web_contents, target_web_contents);
1713 if (call_javascript_)
1714 EXPECT_TRUE(DidDisplayPass(web_contents));
1718 // Opens the prerendered page using javascript functions in the loader
1719 // page. |javascript_function_name| should be a 0 argument function which is
1720 // invoked. |new_web_contents| is true if the navigation is expected to
1721 // happen in a new WebContents via OpenURL.
1722 void OpenURLWithJSImpl(const std::string& javascript_function_name,
1724 const GURL& ping_url,
1725 bool new_web_contents) const {
1726 WebContents* web_contents = GetActiveWebContents();
1727 RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
1728 // Extra arguments in JS are ignored.
1729 std::string javascript = base::StringPrintf(
1730 "%s('%s', '%s')", javascript_function_name.c_str(),
1731 url.spec().c_str(), ping_url.spec().c_str());
1733 if (new_web_contents) {
1734 NewTabNavigationOrSwapObserver observer;
1736 ExecuteJavaScriptForTests(base::ASCIIToUTF16(javascript));
1739 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
1741 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
1746 TestPrerenderContentsFactory* prerender_contents_factory_;
1747 #if defined(FULL_SAFE_BROWSING)
1748 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_;
1750 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_;
1752 scoped_ptr<net::SpawnedTestServer> https_src_server_;
1753 bool call_javascript_;
1754 bool check_load_events_;
1755 std::string loader_host_override_;
1756 std::string loader_path_;
1757 std::string loader_query_;
1758 Browser* explicitly_set_browser_;
1759 base::HistogramTester histogram_tester_;
1760 scoped_ptr<base::FieldTrialList> field_trial_list_;
1763 // Checks that a page is correctly prerendered in the case of a
1764 // <link rel=prerender> tag and then loaded into a tab in response to a
1766 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
1767 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1768 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
1769 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
1770 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
1771 histogram_tester().ExpectTotalCount(
1772 "Prerender.none_PerceivedPLTMatchedComplete", 0);
1773 histogram_tester().ExpectTotalCount(
1774 "Prerender.websame_PrerenderNotSwappedInPLT", 1);
1776 ChannelDestructionWatcher channel_close_watcher;
1777 channel_close_watcher.WatchChannel(
1778 GetActiveWebContents()->GetRenderProcessHost());
1779 NavigateToDestURL();
1780 channel_close_watcher.WaitForChannelClose();
1782 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
1783 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLTMatched",
1785 histogram_tester().ExpectTotalCount(
1786 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
1788 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1791 // Checks that cross-domain prerenders emit the correct histograms.
1792 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageCrossDomain) {
1793 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
1794 FINAL_STATUS_USED, 1);
1795 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
1796 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
1797 histogram_tester().ExpectTotalCount(
1798 "Prerender.none_PerceivedPLTMatchedComplete", 0);
1799 histogram_tester().ExpectTotalCount(
1800 "Prerender.webcross_PrerenderNotSwappedInPLT", 1);
1802 NavigateToDestURL();
1803 histogram_tester().ExpectTotalCount("Prerender.webcross_PerceivedPLT", 1);
1804 histogram_tester().ExpectTotalCount("Prerender.webcross_PerceivedPLTMatched",
1806 histogram_tester().ExpectTotalCount(
1807 "Prerender.webcross_PerceivedPLTMatchedComplete", 1);
1810 // Checks that pending prerenders launch and receive proper event treatment.
1811 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPagePending) {
1812 scoped_ptr<TestPrerender> prerender =
1813 PrerenderTestURL("files/prerender/prerender_page_pending.html",
1814 FINAL_STATUS_USED, 1);
1816 // Navigate to the prerender.
1817 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
1818 NavigateToDestURL();
1819 // Abort early if the original prerender didn't swap, so as not to hang.
1820 ASSERT_FALSE(prerender->contents());
1822 // Wait for the new prerender to be ready.
1823 prerender2->WaitForStart();
1824 prerender2->WaitForLoads(1);
1826 const GURL prerender_page_url =
1827 test_server()->GetURL("files/prerender/prerender_page.html");
1828 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1829 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL),
1830 GetPrerenderContentsFor(prerender_page_url));
1832 // Now navigate to our target page.
1833 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
1834 GetActiveWebContents());
1835 ui_test_utils::NavigateToURLWithDisposition(
1836 current_browser(), prerender_page_url, CURRENT_TAB,
1837 ui_test_utils::BROWSER_TEST_NONE);
1838 swap_observer.Wait();
1840 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1843 // Checks that pending prerenders which are canceled before they are launched
1844 // never get started.
1845 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) {
1846 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html",
1847 FINAL_STATUS_USED, 1);
1849 ChannelDestructionWatcher channel_close_watcher;
1850 channel_close_watcher.WatchChannel(
1851 GetActiveWebContents()->GetRenderProcessHost());
1852 NavigateToDestURL();
1853 channel_close_watcher.WaitForChannelClose();
1855 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1));
1856 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1857 EXPECT_FALSE(HadPrerenderEventErrors());
1858 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1859 // calls did a thread/process hop to the renderer which insured pending
1860 // renderer events have arrived.
1861 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1864 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovingLink) {
1865 scoped_ptr<TestPrerender> prerender =
1866 PrerenderTestURL("files/prerender/prerender_page.html",
1867 FINAL_STATUS_CANCELLED, 1);
1869 // No ChannelDestructionWatcher is needed here, since prerenders in the
1870 // PrerenderLinkManager should be deleted by removing the links, rather than
1871 // shutting down the renderer process.
1872 RemoveLinkElement(0);
1873 prerender->WaitForStop();
1875 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1876 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1877 EXPECT_FALSE(HadPrerenderEventErrors());
1878 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1879 // calls did a thread/process hop to the renderer which insured pending
1880 // renderer events have arrived.
1881 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1884 IN_PROC_BROWSER_TEST_F(
1885 PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinks) {
1886 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1887 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1889 set_loader_query("links_to_insert=2");
1890 scoped_ptr<TestPrerender> prerender =
1891 PrerenderTestURL("files/prerender/prerender_page.html",
1892 FINAL_STATUS_CANCELLED, 1);
1893 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1894 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1895 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1896 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1898 RemoveLinkElement(0);
1899 RemoveLinkElement(1);
1900 prerender->WaitForStop();
1902 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1903 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1904 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1905 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1906 EXPECT_FALSE(HadPrerenderEventErrors());
1907 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1908 // calls did a thread/process hop to the renderer which insured pending
1909 // renderer events have arrived.
1910 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1913 IN_PROC_BROWSER_TEST_F(
1914 PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinksOneLate) {
1915 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1916 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1918 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
1919 scoped_ptr<TestPrerender> prerender =
1920 PrerenderTestURL(url, FINAL_STATUS_CANCELLED, 1);
1922 // Add a second prerender for the same link. It reuses the prerender, so only
1923 // the start event fires here.
1924 AddPrerender(url, 1);
1925 WaitForPrerenderEventCount(1, "webkitprerenderstart", 1);
1926 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1927 EXPECT_EQ(0, GetPrerenderLoadEventCountForLinkNumber(1));
1928 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1930 RemoveLinkElement(0);
1931 RemoveLinkElement(1);
1932 prerender->WaitForStop();
1934 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1935 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1936 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1937 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1938 EXPECT_FALSE(HadPrerenderEventErrors());
1939 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1940 // calls did a thread/process hop to the renderer which insured pending
1941 // renderer events have arrived.
1942 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1945 IN_PROC_BROWSER_TEST_F(
1946 PrerenderBrowserTest,
1947 PrerenderPageRemovingLinkWithTwoLinksRemovingOne) {
1948 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1949 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1950 set_loader_query("links_to_insert=2");
1951 PrerenderTestURL("files/prerender/prerender_page.html",
1952 FINAL_STATUS_USED, 1);
1953 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1954 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1955 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1956 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1958 RemoveLinkElement(0);
1959 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1960 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1961 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1962 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1963 EXPECT_FALSE(HadPrerenderEventErrors());
1964 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1965 // calls did a thread/process hop to the renderer which insured pending
1966 // renderer events have arrived.
1967 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1969 ChannelDestructionWatcher channel_close_watcher;
1970 channel_close_watcher.WatchChannel(
1971 GetActiveWebContents()->GetRenderProcessHost());
1972 NavigateToDestURL();
1973 channel_close_watcher.WaitForChannelClose();
1975 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1978 // Checks that the visibility API works.
1979 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) {
1980 PrerenderTestURL("files/prerender/prerender_visibility.html",
1983 NavigateToDestURL();
1986 // Checks that the prerendering of a page is canceled correctly if we try to
1987 // swap it in before it commits.
1988 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) {
1989 // Navigate to a page that triggers a prerender for a URL that never commits.
1990 const GURL kNoCommitUrl("http://never-respond.example.com");
1991 base::FilePath file(GetTestPath("prerender_page.html"));
1993 base::RunLoop prerender_start_loop;
1994 BrowserThread::PostTask(
1995 BrowserThread::IO, FROM_HERE,
1996 base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl, file,
1997 prerender_start_loop.QuitClosure()));
1998 DisableJavascriptCalls();
1999 PrerenderTestURL(kNoCommitUrl,
2000 FINAL_STATUS_NAVIGATION_UNCOMMITTED,
2002 // Wait for the hanging request to be scheduled.
2003 prerender_start_loop.Run();
2005 // Navigate to the URL, but assume the contents won't be swapped in.
2006 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
2009 // Checks that client redirects don't add alias URLs until after they commit.
2010 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) {
2011 // Navigate to a page that then navigates to a URL that never commits.
2012 const GURL kNoCommitUrl("http://never-respond.example.com");
2013 base::FilePath file(GetTestPath("prerender_page.html"));
2015 base::RunLoop prerender_start_loop;
2016 BrowserThread::PostTask(
2017 BrowserThread::IO, FROM_HERE,
2018 base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl, file,
2019 prerender_start_loop.QuitClosure()));
2020 DisableJavascriptCalls();
2021 PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()),
2022 FINAL_STATUS_APP_TERMINATING, 1);
2023 // Wait for the hanging request to be scheduled.
2024 prerender_start_loop.Run();
2026 // Navigating to the second URL should not swap.
2027 NavigateToURLWithDisposition(kNoCommitUrl, CURRENT_TAB, false);
2030 // Checks that the prerendering of a page is canceled correctly when a
2031 // Javascript alert is called.
2032 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
2033 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
2034 FINAL_STATUS_JAVASCRIPT_ALERT,
2038 // Checks that the prerendering of a page is canceled correctly when a
2039 // Javascript alert is called.
2040 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
2041 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
2042 FINAL_STATUS_JAVASCRIPT_ALERT,
2046 // Checks that plugins are not loaded while a page is being preloaded, but
2047 // are loaded when the page is displayed.
2048 #if defined(USE_AURA) && !defined(OS_WIN)
2049 // http://crbug.com/103496
2050 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
2051 #elif defined(OS_MACOSX)
2052 // http://crbug.com/100514
2053 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
2054 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
2055 // TODO(jschuh): Failing plugin tests. crbug.com/244653
2056 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
2057 #elif defined(OS_LINUX)
2058 // http://crbug.com/306715
2059 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
2061 #define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin
2063 // http://crbug.com/306715
2064 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) {
2065 PrerenderTestURL("files/prerender/plugin_delay_load.html",
2068 NavigateToDestURL();
2071 // Checks that plugins are not loaded on prerendering pages when click-to-play
2073 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) {
2074 // Enable click-to-play.
2075 HostContentSettingsMap* content_settings_map =
2076 current_browser()->profile()->GetHostContentSettingsMap();
2077 content_settings_map->SetDefaultContentSetting(
2078 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK);
2080 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html",
2083 NavigateToDestURL();
2086 // Checks that we don't load a NaCl plugin when NaCl is disabled.
2087 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) {
2088 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html",
2091 NavigateToDestURL();
2094 // Run this check again. When we try to load aa ppapi plugin, the
2095 // "loadstart" event is asynchronously posted to a message loop.
2096 // It's possible that earlier call could have been run before the
2097 // the "loadstart" event was posted.
2098 // TODO(mmenke): While this should reliably fail on regressions, the
2099 // reliability depends on the specifics of ppapi plugin
2100 // loading. It would be great if we could avoid that.
2101 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
2104 // Checks that plugins in an iframe are not loaded while a page is
2105 // being preloaded, but are loaded when the page is displayed.
2106 #if defined(USE_AURA) && !defined(OS_WIN)
2107 // http://crbug.com/103496
2108 #define MAYBE_PrerenderIframeDelayLoadPlugin \
2109 DISABLED_PrerenderIframeDelayLoadPlugin
2110 #elif defined(OS_MACOSX)
2111 // http://crbug.com/100514
2112 #define MAYBE_PrerenderIframeDelayLoadPlugin \
2113 DISABLED_PrerenderIframeDelayLoadPlugin
2114 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
2115 // TODO(jschuh): Failing plugin tests. crbug.com/244653
2116 #define MAYBE_PrerenderIframeDelayLoadPlugin \
2117 DISABLED_PrerenderIframeDelayLoadPlugin
2119 #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin
2121 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2122 MAYBE_PrerenderIframeDelayLoadPlugin) {
2123 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
2126 NavigateToDestURL();
2129 // Renders a page that contains a prerender link to a page that contains an
2130 // iframe with a source that requires http authentication. This should not
2131 // prerender successfully.
2132 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
2133 PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
2134 FINAL_STATUS_AUTH_NEEDED,
2138 // Checks that client-issued redirects work with prerendering.
2139 // This version navigates to the page which issues the redirection, rather
2140 // than the final destination page.
2141 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2142 PrerenderClientRedirectNavigateToFirst) {
2143 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
2146 NavigateToDestURL();
2149 // Checks that client-issued redirects work with prerendering.
2150 // This version navigates to the final destination page, rather than the
2151 // page which does the redirection.
2152 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2153 PrerenderClientRedirectNavigateToSecond) {
2154 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
2157 NavigateToURL("files/prerender/prerender_page.html");
2160 // Checks that redirects with location.replace do not cancel a prerender and
2161 // and swap when navigating to the first page.
2162 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2163 PrerenderLocationReplaceNavigateToFirst) {
2164 PrerenderTestURL("files/prerender/prerender_location_replace.html",
2167 NavigateToDestURL();
2170 // Checks that redirects with location.replace do not cancel a prerender and
2171 // and swap when navigating to the second.
2172 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2173 PrerenderLocationReplaceNavigateToSecond) {
2174 PrerenderTestURL("files/prerender/prerender_location_replace.html",
2177 NavigateToURL("files/prerender/prerender_page.html");
2180 // Checks that we get the right PPLT histograms for client redirect prerenders
2181 // and navigations when the referring page is Google.
2182 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2183 PrerenderLocationReplaceGWSHistograms) {
2184 DisableJavascriptCalls();
2186 // The loader page should look like Google.
2187 const std::string kGoogleDotCom("www.google.com");
2188 SetLoaderHostOverride(kGoogleDotCom);
2189 set_loader_path("files/prerender/prerender_loader_with_replace_state.html");
2191 GURL dest_url = GetCrossDomainTestUrl(
2192 "files/prerender/prerender_deferred_image.html");
2194 GURL prerender_url = test_server()->GetURL(
2195 "files/prerender/prerender_location_replace.html?" +
2196 net::EscapeQueryParamValue(dest_url.spec(), false) +
2198 GURL::Replacements replacements;
2199 replacements.SetHostStr(kGoogleDotCom);
2200 prerender_url = prerender_url.ReplaceComponents(replacements);
2202 // The prerender will not completely load until after the swap, so wait for a
2203 // title change before calling DidPrerenderPass.
2204 scoped_ptr<TestPrerender> prerender =
2205 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
2206 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
2207 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
2208 EXPECT_EQ(1, prerender->number_of_loads());
2210 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
2211 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
2212 histogram_tester().ExpectTotalCount(
2213 "Prerender.none_PerceivedPLTMatchedComplete", 0);
2214 // Although there is a client redirect, it is dropped from histograms because
2215 // it is a Google URL. The target page itself does not load until after the
2217 histogram_tester().ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT",
2220 GURL navigate_url = test_server()->GetURL(
2221 "files/prerender/prerender_location_replace.html?" +
2222 net::EscapeQueryParamValue(dest_url.spec(), false) +
2224 navigate_url = navigate_url.ReplaceComponents(replacements);
2226 NavigationOrSwapObserver swap_observer(
2227 current_browser()->tab_strip_model(),
2228 GetActiveWebContents(), 2);
2229 current_browser()->OpenURL(OpenURLParams(
2230 navigate_url, Referrer(), CURRENT_TAB,
2231 ui::PAGE_TRANSITION_TYPED, false));
2232 swap_observer.Wait();
2234 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
2236 histogram_tester().ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT",
2238 histogram_tester().ExpectTotalCount("Prerender.gws_PerceivedPLT", 1);
2239 histogram_tester().ExpectTotalCount("Prerender.gws_PerceivedPLTMatched", 1);
2240 histogram_tester().ExpectTotalCount(
2241 "Prerender.gws_PerceivedPLTMatchedComplete", 1);
2243 // The client redirect does /not/ count as a miss because it's a Google URL.
2244 histogram_tester().ExpectTotalCount("Prerender.PerceivedPLTFirstAfterMiss",
2248 // Checks that client-issued redirects work with prerendering.
2249 // This version navigates to the final destination page, rather than the
2250 // page which does the redirection via a mouse click.
2251 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2252 PrerenderClientRedirectNavigateToSecondViaClick) {
2253 GURL prerender_url = test_server()->GetURL(
2254 CreateClientRedirect("files/prerender/prerender_page.html"));
2255 GURL destination_url = test_server()->GetURL(
2256 "files/prerender/prerender_page.html");
2257 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 2);
2258 OpenURLViaClick(destination_url);
2261 // Checks that a page served over HTTPS is correctly prerendered.
2262 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) {
2263 net::SpawnedTestServer https_server(
2264 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2265 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2266 ASSERT_TRUE(https_server.Start());
2267 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2268 PrerenderTestURL(https_url,
2271 NavigateToDestURL();
2274 // Checks that client-issued redirects within an iframe in a prerendered
2275 // page will not count as an "alias" for the prerendered page.
2276 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2277 PrerenderClientRedirectInIframe) {
2278 std::string redirect_path = CreateClientRedirect(
2279 "/files/prerender/prerender_embedded_content.html");
2280 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2281 replacement_text.push_back(
2282 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2283 std::string replacement_path;
2284 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2285 "files/prerender/prerender_with_iframe.html",
2287 &replacement_path));
2288 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
2289 EXPECT_FALSE(UrlIsInPrerenderManager(
2290 "files/prerender/prerender_embedded_content.html"));
2291 NavigateToDestURL();
2294 // Checks that server-issued redirects work with prerendering.
2295 // This version navigates to the page which issues the redirection, rather
2296 // than the final destination page.
2297 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2298 PrerenderServerRedirectNavigateToFirst) {
2299 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2302 NavigateToDestURL();
2305 // Checks that server-issued redirects work with prerendering.
2306 // This version navigates to the final destination page, rather than the
2307 // page which does the redirection.
2308 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2309 PrerenderServerRedirectNavigateToSecond) {
2310 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2313 NavigateToURL("files/prerender/prerender_page.html");
2316 // Checks that server-issued redirects work with prerendering.
2317 // This version navigates to the final destination page, rather than the
2318 // page which does the redirection via a mouse click.
2319 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2320 PrerenderServerRedirectNavigateToSecondViaClick) {
2321 GURL prerender_url = test_server()->GetURL(
2322 CreateServerRedirect("files/prerender/prerender_page.html"));
2323 GURL destination_url = test_server()->GetURL(
2324 "files/prerender/prerender_page.html");
2325 PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
2326 OpenURLViaClick(destination_url);
2329 // Checks that server-issued redirects within an iframe in a prerendered
2330 // page will not count as an "alias" for the prerendered page.
2331 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
2332 std::string redirect_path = CreateServerRedirect(
2333 "/files/prerender/prerender_embedded_content.html");
2334 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2335 replacement_text.push_back(
2336 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2337 std::string replacement_path;
2338 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2339 "files/prerender/prerender_with_iframe.html",
2341 &replacement_path));
2342 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2343 EXPECT_FALSE(UrlIsInPrerenderManager(
2344 "files/prerender/prerender_embedded_content.html"));
2345 NavigateToDestURL();
2348 // Prerenders a page that contains an automatic download triggered through an
2349 // iframe. This should not prerender successfully.
2350 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) {
2351 PrerenderTestURL("files/prerender/prerender_download_iframe.html",
2352 FINAL_STATUS_DOWNLOAD,
2356 // Prerenders a page that contains an automatic download triggered through
2357 // Javascript changing the window.location. This should not prerender
2359 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
2360 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
2361 FINAL_STATUS_DOWNLOAD,
2365 // Prerenders a page that contains an automatic download triggered through a
2366 // client-issued redirect. This should not prerender successfully.
2367 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
2368 PrerenderTestURL("files/prerender/prerender_download_refresh.html",
2369 FINAL_STATUS_DOWNLOAD,
2373 // Checks that the referrer is set when prerendering.
2374 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
2375 PrerenderTestURL("files/prerender/prerender_referrer.html",
2378 NavigateToDestURL();
2381 // Checks that the referrer is not set when prerendering and the source page is
2383 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2384 PrerenderNoSSLReferrer) {
2385 UseHttpsSrcServer();
2386 PrerenderTestURL("files/prerender/prerender_no_referrer.html",
2389 NavigateToDestURL();
2392 // Checks that the referrer is set when prerendering is cancelled.
2393 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrer) {
2394 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
2395 new TestContentBrowserClient);
2396 content::ContentBrowserClient* original_browser_client =
2397 content::SetBrowserClientForTesting(test_content_browser_client.get());
2399 PrerenderTestURL("files/prerender/prerender_referrer.html",
2400 FINAL_STATUS_CANCELLED,
2402 OpenDestURLViaClick();
2404 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
2406 content::SetBrowserClientForTesting(original_browser_client);
2409 // Checks that popups on a prerendered page cause cancellation.
2410 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
2411 PrerenderTestURL("files/prerender/prerender_popup.html",
2412 FINAL_STATUS_CREATE_NEW_WINDOW,
2416 // Checks that registering a protocol handler causes cancellation.
2417 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) {
2418 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html",
2419 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER,
2423 // Checks that renderers using excessive memory will be terminated.
2424 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
2425 ASSERT_TRUE(GetPrerenderManager());
2426 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024;
2427 // The excessive memory kill may happen before or after the load event as it
2428 // happens asynchronously with IPC calls. Even if the test does not start
2429 // allocating until after load, the browser process might notice before the
2430 // message gets through. This happens on XP debug bots because they're so
2431 // slow. Instead, don't bother checking the load event count.
2432 DisableLoadEventCheck();
2433 PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
2434 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 0);
2437 // Checks shutdown code while a prerender is active.
2438 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
2439 DisableJavascriptCalls();
2440 DisableLoadEventCheck();
2441 PrerenderTestURL("files/prerender/prerender_page.html",
2442 FINAL_STATUS_APP_TERMINATING,
2446 // Checks that we don't prerender in an infinite loop.
2447 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
2448 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
2449 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
2451 std::vector<FinalStatus> expected_final_status_queue;
2452 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2453 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2455 ScopedVector<TestPrerender> prerenders =
2456 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2457 ASSERT_TRUE(prerenders[0]->contents());
2458 // Assert that the pending prerender is in there already. This relies on the
2459 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
2460 // the page load one.
2461 EXPECT_EQ(2U, GetLinkPrerenderCount());
2462 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2464 // Next url should be in pending list but not an active entry.
2465 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2467 NavigateToDestURL();
2469 // Make sure the PrerenderContents for the next url is now in the manager and
2470 // not pending. This relies on pending prerenders being resolved in the same
2471 // event loop iteration as OnPrerenderStop.
2472 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
2473 EXPECT_EQ(1U, GetLinkPrerenderCount());
2474 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2477 // Checks that we don't prerender in an infinite loop and multiple links are
2478 // handled correctly.
2479 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2480 PrerenderInfiniteLoopMultiple) {
2481 const char* const kHtmlFileA =
2482 "files/prerender/prerender_infinite_a_multiple.html";
2483 const char* const kHtmlFileB =
2484 "files/prerender/prerender_infinite_b_multiple.html";
2485 const char* const kHtmlFileC =
2486 "files/prerender/prerender_infinite_c_multiple.html";
2488 // This test is conceptually simplest if concurrency is at two, since we
2489 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
2490 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
2491 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
2493 std::vector<FinalStatus> expected_final_status_queue;
2494 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2495 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2496 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2498 ScopedVector<TestPrerender> prerenders =
2499 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2500 ASSERT_TRUE(prerenders[0]->contents());
2502 // Next url should be in pending list but not an active entry. This relies on
2503 // the fact that the renderer sends out the AddLinkRelPrerender IPC before
2504 // sending the page load one.
2505 EXPECT_EQ(3U, GetLinkPrerenderCount());
2506 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2507 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2508 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
2510 NavigateToDestURL();
2512 // Make sure the PrerenderContents for the next urls are now in the manager
2513 // and not pending. One and only one of the URLs (the last seen) should be the
2514 // active entry. This relies on pending prerenders being resolved in the same
2515 // event loop iteration as OnPrerenderStop.
2516 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
2517 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
2518 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
2519 EXPECT_EQ(2U, GetLinkPrerenderCount());
2520 EXPECT_EQ(2U, GetRunningLinkPrerenderCount());
2523 // Checks that pending prerenders are aborted (and never launched) when launched
2524 // by a prerender that itself gets aborted.
2525 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) {
2526 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
2527 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
2529 scoped_ptr<TestPrerender> prerender =
2530 PrerenderTestURL(kHtmlFileA, FINAL_STATUS_CANCELLED, 1);
2531 ASSERT_TRUE(prerender->contents());
2532 // Assert that the pending prerender is in there already. This relies on the
2533 // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
2534 // the page load one.
2535 EXPECT_EQ(2U, GetLinkPrerenderCount());
2536 EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
2538 // Next url should be in pending list but not an active entry.
2539 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2541 // Cancel the prerender.
2542 GetPrerenderManager()->CancelAllPrerenders();
2543 prerender->WaitForStop();
2545 // All prerenders are now gone.
2546 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
2549 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerBeforePrerender) {
2550 const base::string16 any_prerender = MatchTaskManagerPrerender("*");
2551 const base::string16 any_tab = MatchTaskManagerTab("*");
2552 const base::string16 original = MatchTaskManagerTab("Preloader");
2553 const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page");
2554 const base::string16 final = MatchTaskManagerTab("Prerender Page");
2556 // Show the task manager. This populates the model.
2557 chrome::OpenTaskManager(current_browser());
2558 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2559 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
2561 // Prerender a page in addition to the original tab.
2562 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2564 // A TaskManager entry should appear like "Prerender: Prerender Page"
2565 // alongside the original tab entry. There should be just these two entries.
2566 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender));
2567 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original));
2568 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final));
2569 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender));
2570 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2572 // Swap in the prerendered content.
2573 NavigateToDestURL();
2575 // The "Prerender: " TaskManager entry should disappear, being replaced by a
2576 // "Tab: Prerender Page" entry, and nothing else.
2577 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender));
2578 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original));
2579 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
2580 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2581 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
2584 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterPrerender) {
2585 const base::string16 any_prerender = MatchTaskManagerPrerender("*");
2586 const base::string16 any_tab = MatchTaskManagerTab("*");
2587 const base::string16 original = MatchTaskManagerTab("Preloader");
2588 const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page");
2589 const base::string16 final = MatchTaskManagerTab("Prerender Page");
2591 // Start with two resources.
2592 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2594 // Show the task manager. This populates the model. Importantly, we're doing
2595 // this after the prerender WebContents already exists - the task manager
2596 // needs to find it, it can't just listen for creation.
2597 chrome::OpenTaskManager(current_browser());
2599 // A TaskManager entry should appear like "Prerender: Prerender Page"
2600 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender));
2601 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original));
2602 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final));
2603 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender));
2604 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2607 NavigateToDestURL();
2609 // The "Prerender: Prerender Page" TaskManager row should disappear, being
2610 // replaced by "Tab: Prerender Page"
2611 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender));
2612 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original));
2613 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
2614 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2615 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
2618 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterSwapIn) {
2619 const base::string16 any_prerender = MatchTaskManagerPrerender("*");
2620 const base::string16 any_tab = MatchTaskManagerTab("*");
2621 const base::string16 final = MatchTaskManagerTab("Prerender Page");
2623 // Prerender, and swap it in.
2624 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2625 NavigateToDestURL();
2627 // Show the task manager. This populates the model. Importantly, we're doing
2628 // this after the prerender has been swapped in.
2629 chrome::OpenTaskManager(current_browser());
2631 // We should not see a prerender resource in the task manager, just a normal
2633 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
2634 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
2635 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
2638 // Checks that audio loads are deferred on prerendering.
2639 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Audio) {
2640 PrerenderTestURL("files/prerender/prerender_html5_audio.html",
2643 NavigateToDestURL();
2644 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2647 // Checks that audio loads are deferred on prerendering and played back when
2648 // the prerender is swapped in if autoplay is set.
2649 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioAutoplay) {
2650 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html",
2653 NavigateToDestURL();
2654 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2657 // Checks that audio loads are deferred on prerendering and played back when
2658 // the prerender is swapped in if js starts playing.
2659 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioJsplay) {
2660 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html",
2663 NavigateToDestURL();
2664 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2667 // Checks that video loads are deferred on prerendering.
2668 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) {
2669 PrerenderTestURL("files/prerender/prerender_html5_video.html",
2672 NavigateToDestURL();
2673 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2676 // Checks that video tags inserted by javascript are deferred and played
2677 // correctly on swap in.
2678 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) {
2679 PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
2682 NavigateToDestURL();
2683 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2686 // Checks for correct network events by using a busy sleep the javascript.
2687 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoNetwork) {
2688 DisableJavascriptCalls();
2689 scoped_ptr<TestPrerender> prerender =
2690 PrerenderTestURL("files/prerender/prerender_html5_video_network.html",
2693 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
2694 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
2695 NavigateToDestURL();
2696 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
2699 // Checks that scripts can retrieve the correct window size while prerendering.
2700 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
2701 PrerenderTestURL("files/prerender/prerender_size.html",
2704 NavigateToDestURL();
2707 // TODO(jam): http://crbug.com/350550
2708 #if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER))
2710 // Checks that prerenderers will terminate when the RenderView crashes.
2711 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRendererCrash) {
2712 scoped_ptr<TestPrerender> prerender =
2713 PrerenderTestURL("files/prerender/prerender_page.html",
2714 FINAL_STATUS_RENDERER_CRASHED,
2717 // Navigate to about:crash and then wait for the renderer to crash.
2718 ASSERT_TRUE(prerender->contents());
2719 ASSERT_TRUE(prerender->contents()->prerender_contents());
2720 prerender->contents()->prerender_contents()->GetController().
2722 GURL(content::kChromeUICrashURL),
2723 content::Referrer(),
2724 ui::PAGE_TRANSITION_TYPED,
2726 prerender->WaitForStop();
2730 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2731 PrerenderPageWithFragment) {
2732 PrerenderTestURL("files/prerender/prerender_page.html#fragment",
2736 ChannelDestructionWatcher channel_close_watcher;
2737 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2738 GetActiveWebContents()->GetRenderProcessHost());
2739 NavigateToDestURL();
2740 channel_close_watcher.WaitForChannelClose();
2742 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2745 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2746 PrerenderPageWithRedirectedFragment) {
2748 CreateClientRedirect("files/prerender/prerender_page.html#fragment"),
2752 ChannelDestructionWatcher channel_close_watcher;
2753 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2754 GetActiveWebContents()->GetRenderProcessHost());
2755 NavigateToDestURL();
2756 channel_close_watcher.WaitForChannelClose();
2758 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2761 // Checks that we do not use a prerendered page when navigating from
2762 // the main page to a fragment.
2763 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2764 PrerenderPageNavigateFragment) {
2765 PrerenderTestURL("files/prerender/no_prerender_page.html",
2766 FINAL_STATUS_APP_TERMINATING,
2768 NavigateToURLWithDisposition(
2769 "files/prerender/no_prerender_page.html#fragment",
2770 CURRENT_TAB, false);
2773 // Checks that we do not use a prerendered page when we prerender a fragment
2774 // but navigate to the main page.
2775 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2776 PrerenderFragmentNavigatePage) {
2777 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment",
2778 FINAL_STATUS_APP_TERMINATING,
2780 NavigateToURLWithDisposition(
2781 "files/prerender/no_prerender_page.html",
2782 CURRENT_TAB, false);
2785 // Checks that we do not use a prerendered page when we prerender a fragment
2786 // but navigate to a different fragment on the same page.
2787 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2788 PrerenderFragmentNavigateFragment) {
2789 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment",
2790 FINAL_STATUS_APP_TERMINATING,
2792 NavigateToURLWithDisposition(
2793 "files/prerender/no_prerender_page.html#fragment",
2794 CURRENT_TAB, false);
2797 // Checks that we do not use a prerendered page when the page uses a client
2798 // redirect to refresh from a fragment on the same page.
2799 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2800 PrerenderClientRedirectFromFragment) {
2802 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"),
2803 FINAL_STATUS_APP_TERMINATING,
2805 NavigateToURLWithDisposition(
2806 "files/prerender/no_prerender_page.html",
2807 CURRENT_TAB, false);
2810 // Checks that we do not use a prerendered page when the page uses a client
2811 // redirect to refresh to a fragment on the same page.
2812 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2813 PrerenderClientRedirectToFragment) {
2815 CreateClientRedirect("files/prerender/no_prerender_page.html"),
2816 FINAL_STATUS_APP_TERMINATING,
2818 NavigateToURLWithDisposition(
2819 "files/prerender/no_prerender_page.html#fragment",
2820 CURRENT_TAB, false);
2823 // Checks that we correctly use a prerendered page when the page uses JS to set
2824 // the window.location.hash to a fragment on the same page.
2825 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2826 PrerenderPageChangeFragmentLocationHash) {
2827 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html",
2830 NavigateToURL("files/prerender/prerender_fragment_location_hash.html");
2833 // Checks that prerendering a PNG works correctly.
2834 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) {
2835 DisableJavascriptCalls();
2836 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1);
2837 NavigateToDestURL();
2840 // Checks that prerendering a JPG works correctly.
2841 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) {
2842 DisableJavascriptCalls();
2843 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1);
2844 NavigateToDestURL();
2847 // Checks that a prerender of a CRX will result in a cancellation due to
2849 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) {
2850 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 0);
2853 // Checks that xhr GET requests allow prerenders.
2854 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) {
2855 PrerenderTestURL("files/prerender/prerender_xhr_get.html",
2858 NavigateToDestURL();
2861 // Checks that xhr HEAD requests allow prerenders.
2862 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) {
2863 PrerenderTestURL("files/prerender/prerender_xhr_head.html",
2866 NavigateToDestURL();
2869 // Checks that xhr OPTIONS requests allow prerenders.
2870 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) {
2871 PrerenderTestURL("files/prerender/prerender_xhr_options.html",
2874 NavigateToDestURL();
2877 // Checks that xhr TRACE requests allow prerenders.
2878 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) {
2879 PrerenderTestURL("files/prerender/prerender_xhr_trace.html",
2882 NavigateToDestURL();
2885 // Checks that xhr POST requests allow prerenders.
2886 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) {
2887 PrerenderTestURL("files/prerender/prerender_xhr_post.html",
2890 NavigateToDestURL();
2893 // Checks that xhr PUT cancels prerenders.
2894 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) {
2895 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
2896 FINAL_STATUS_INVALID_HTTP_METHOD,
2900 // Checks that xhr DELETE cancels prerenders.
2901 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) {
2902 PrerenderTestURL("files/prerender/prerender_xhr_delete.html",
2903 FINAL_STATUS_INVALID_HTTP_METHOD,
2907 // Checks that a top-level page which would trigger an SSL error is canceled.
2908 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) {
2909 net::SpawnedTestServer::SSLOptions ssl_options;
2910 ssl_options.server_certificate =
2911 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2912 net::SpawnedTestServer https_server(
2913 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2914 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2915 ASSERT_TRUE(https_server.Start());
2916 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2917 PrerenderTestURL(https_url,
2918 FINAL_STATUS_SSL_ERROR,
2922 // Checks that an SSL error that comes from a subresource does not cancel
2923 // the page. Non-main-frame requests are simply cancelled if they run into
2925 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) {
2926 net::SpawnedTestServer::SSLOptions ssl_options;
2927 ssl_options.server_certificate =
2928 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2929 net::SpawnedTestServer https_server(
2930 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2931 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2932 ASSERT_TRUE(https_server.Start());
2933 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2934 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2935 replacement_text.push_back(
2936 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2937 std::string replacement_path;
2938 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2939 "files/prerender/prerender_with_image.html",
2941 &replacement_path));
2942 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2943 NavigateToDestURL();
2946 // Checks that an SSL error that comes from an iframe does not cancel
2947 // the page. Non-main-frame requests are simply cancelled if they run into
2949 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) {
2950 net::SpawnedTestServer::SSLOptions ssl_options;
2951 ssl_options.server_certificate =
2952 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2953 net::SpawnedTestServer https_server(
2954 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2955 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2956 ASSERT_TRUE(https_server.Start());
2957 GURL https_url = https_server.GetURL(
2958 "files/prerender/prerender_embedded_content.html");
2959 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2960 replacement_text.push_back(
2961 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2962 std::string replacement_path;
2963 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2964 "files/prerender/prerender_with_iframe.html",
2966 &replacement_path));
2967 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2968 NavigateToDestURL();
2971 // Checks that we cancel correctly when window.print() is called.
2972 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
2973 DisableLoadEventCheck();
2974 PrerenderTestURL("files/prerender/prerender_print.html",
2975 FINAL_STATUS_WINDOW_PRINT,
2979 // Checks that if a page is opened in a new window by javascript and both the
2980 // pages are in the same domain, the prerendered page is not used, due to
2981 // there being other tabs in the same browsing instance.
2982 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2983 PrerenderSameDomainWindowOpenerWindowOpen) {
2984 PrerenderTestURL("files/prerender/prerender_page.html",
2985 FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
2987 OpenDestURLViaWindowOpen();
2990 // Checks that if a page is opened due to click on a href with target="_blank"
2991 // and both pages are in the same domain the prerendered page is not used, due
2992 // there being other tabs in the same browsing instance.
2993 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2994 PrerenderSameDomainWindowOpenerClickTarget) {
2995 PrerenderTestURL("files/prerender/prerender_page.html",
2996 FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
2998 OpenDestURLViaClickTarget();
3001 // Checks that prerenders do not get swapped into target pages that have opened
3002 // a popup, even if the target page itself does not have an opener.
3003 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderTargetHasPopup) {
3004 PrerenderTestURL("files/prerender/prerender_page.html",
3005 FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
3007 OpenURLViaWindowOpen(GURL(url::kAboutBlankURL));
3008 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3011 class TestClientCertStore : public net::ClientCertStore {
3013 TestClientCertStore() {}
3014 ~TestClientCertStore() override {}
3016 // net::ClientCertStore:
3017 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
3018 net::CertificateList* selected_certs,
3019 const base::Closure& callback) override {
3020 *selected_certs = net::CertificateList(
3021 1, scoped_refptr<net::X509Certificate>(
3022 new net::X509Certificate("test", "test", base::Time(), base::Time())));
3027 scoped_ptr<net::ClientCertStore> CreateCertStore() {
3028 return scoped_ptr<net::ClientCertStore>(new TestClientCertStore);
3031 // Checks that a top-level page which would normally request an SSL client
3032 // certificate will never be seen since it's an https top-level resource.
3033 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3034 PrerenderSSLClientCertTopLevel) {
3035 ProfileIOData::FromResourceContext(
3036 current_browser()->profile()->GetResourceContext())->
3037 set_client_cert_store_factory_for_testing(
3038 base::Bind(&CreateCertStore));
3039 net::SpawnedTestServer::SSLOptions ssl_options;
3040 ssl_options.request_client_certificate = true;
3041 net::SpawnedTestServer https_server(
3042 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
3043 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
3044 ASSERT_TRUE(https_server.Start());
3045 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
3046 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0);
3049 // Checks that an SSL Client Certificate request that originates from a
3050 // subresource will cancel the prerendered page.
3051 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3052 PrerenderSSLClientCertSubresource) {
3053 ProfileIOData::FromResourceContext(
3054 current_browser()->profile()->GetResourceContext())->
3055 set_client_cert_store_factory_for_testing(
3056 base::Bind(&CreateCertStore));
3057 net::SpawnedTestServer::SSLOptions ssl_options;
3058 ssl_options.request_client_certificate = true;
3059 net::SpawnedTestServer https_server(
3060 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
3061 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
3062 ASSERT_TRUE(https_server.Start());
3063 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
3064 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3065 replacement_text.push_back(
3066 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
3067 std::string replacement_path;
3068 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3069 "files/prerender/prerender_with_image.html",
3071 &replacement_path));
3072 PrerenderTestURL(replacement_path,
3073 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
3077 // Checks that an SSL Client Certificate request that originates from an
3078 // iframe will cancel the prerendered page.
3079 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) {
3080 ProfileIOData::FromResourceContext(
3081 current_browser()->profile()->GetResourceContext())->
3082 set_client_cert_store_factory_for_testing(
3083 base::Bind(&CreateCertStore));
3084 net::SpawnedTestServer::SSLOptions ssl_options;
3085 ssl_options.request_client_certificate = true;
3086 net::SpawnedTestServer https_server(
3087 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
3088 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
3089 ASSERT_TRUE(https_server.Start());
3090 GURL https_url = https_server.GetURL(
3091 "files/prerender/prerender_embedded_content.html");
3092 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3093 replacement_text.push_back(
3094 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
3095 std::string replacement_path;
3096 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3097 "files/prerender/prerender_with_iframe.html",
3099 &replacement_path));
3100 PrerenderTestURL(replacement_path,
3101 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
3105 #if defined(FULL_SAFE_BROWSING)
3106 // Ensures that we do not prerender pages with a safe browsing
3108 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) {
3109 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
3110 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
3111 url, SB_THREAT_TYPE_URL_MALWARE);
3112 PrerenderTestURL("files/prerender/prerender_page.html",
3113 FINAL_STATUS_SAFE_BROWSING, 0);
3116 // Ensures that server redirects to a malware page will cancel prerenders.
3117 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3118 PrerenderSafeBrowsingServerRedirect) {
3119 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
3120 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
3121 url, SB_THREAT_TYPE_URL_MALWARE);
3122 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
3123 FINAL_STATUS_SAFE_BROWSING,
3127 // Ensures that client redirects to a malware page will cancel prerenders.
3128 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3129 PrerenderSafeBrowsingClientRedirect) {
3130 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
3131 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
3132 url, SB_THREAT_TYPE_URL_MALWARE);
3133 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
3134 FINAL_STATUS_SAFE_BROWSING,
3138 // Ensures that we do not prerender pages which have a malware subresource.
3139 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) {
3140 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg");
3141 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
3142 image_url, SB_THREAT_TYPE_URL_MALWARE);
3143 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3144 replacement_text.push_back(
3145 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3146 std::string replacement_path;
3147 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3148 "files/prerender/prerender_with_image.html",
3150 &replacement_path));
3151 PrerenderTestURL(replacement_path,
3152 FINAL_STATUS_SAFE_BROWSING,
3156 // Ensures that we do not prerender pages which have a malware iframe.
3157 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) {
3158 GURL iframe_url = test_server()->GetURL(
3159 "files/prerender/prerender_embedded_content.html");
3160 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
3161 iframe_url, SB_THREAT_TYPE_URL_MALWARE);
3162 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3163 replacement_text.push_back(
3164 std::make_pair("REPLACE_WITH_URL", iframe_url.spec()));
3165 std::string replacement_path;
3166 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3167 "files/prerender/prerender_with_iframe.html",
3169 &replacement_path));
3170 PrerenderTestURL(replacement_path,
3171 FINAL_STATUS_SAFE_BROWSING,
3177 // Checks that a local storage read will not cause prerender to fail.
3178 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) {
3179 PrerenderTestURL("files/prerender/prerender_localstorage_read.html",
3182 NavigateToDestURL();
3185 // Checks that a local storage write will not cause prerender to fail.
3186 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) {
3187 PrerenderTestURL("files/prerender/prerender_localstorage_write.html",
3190 NavigateToDestURL();
3193 // Checks that the favicon is properly loaded on prerender.
3194 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) {
3195 scoped_ptr<TestPrerender> prerender =
3196 PrerenderTestURL("files/prerender/prerender_favicon.html",
3199 NavigateToDestURL();
3201 if (!FaviconTabHelper::FromWebContents(
3202 GetActiveWebContents())->FaviconIsValid()) {
3203 // If the favicon has not been set yet, wait for it to be.
3204 content::WindowedNotificationObserver favicon_update_watcher(
3205 chrome::NOTIFICATION_FAVICON_UPDATED,
3206 content::Source<WebContents>(GetActiveWebContents()));
3207 favicon_update_watcher.Wait();
3209 EXPECT_TRUE(FaviconTabHelper::FromWebContents(
3210 GetActiveWebContents())->FaviconIsValid());
3213 // Checks that when a prerendered page is swapped in to a referring page, the
3214 // unload handlers on the referring page are executed.
3215 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderUnload) {
3216 // Matches URL in prerender_loader_with_unload.html.
3217 const GURL unload_url("http://unload-url.test");
3218 base::FilePath empty_file = ui_test_utils::GetTestFilePath(
3219 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
3220 RequestCounter unload_counter;
3221 BrowserThread::PostTask(
3222 BrowserThread::IO, FROM_HERE,
3223 base::Bind(&CreateCountingInterceptorOnIO,
3224 unload_url, empty_file, unload_counter.AsWeakPtr()));
3226 set_loader_path("files/prerender/prerender_loader_with_unload.html");
3227 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3228 NavigateToDestURL();
3229 unload_counter.WaitForCount(1);
3232 // Checks that a hanging unload on the referring page of a prerender swap does
3233 // not crash the browser on exit.
3234 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHangingUnload) {
3235 // Matches URL in prerender_loader_with_unload.html.
3236 const GURL hang_url("http://unload-url.test");
3237 base::FilePath empty_file = ui_test_utils::GetTestFilePath(
3238 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
3239 BrowserThread::PostTask(
3240 BrowserThread::IO, FROM_HERE,
3241 base::Bind(&CreateHangingFirstRequestInterceptorOnIO,
3242 hang_url, empty_file,
3245 set_loader_path("files/prerender/prerender_loader_with_unload.html");
3246 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3247 NavigateToDestURL();
3251 // Checks that when the history is cleared, prerendering is cancelled and
3252 // prerendering history is cleared.
3253 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) {
3254 scoped_ptr<TestPrerender> prerender =
3255 PrerenderTestURL("files/prerender/prerender_page.html",
3256 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
3259 ClearBrowsingData(current_browser(), BrowsingDataRemover::REMOVE_HISTORY);
3260 prerender->WaitForStop();
3262 // Make sure prerender history was cleared.
3263 EXPECT_EQ(0, GetHistoryLength());
3266 // Checks that when the cache is cleared, prerenders are cancelled but
3267 // prerendering history is not cleared.
3268 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearCache) {
3269 scoped_ptr<TestPrerender> prerender =
3270 PrerenderTestURL("files/prerender/prerender_page.html",
3271 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
3274 ClearBrowsingData(current_browser(), BrowsingDataRemover::REMOVE_CACHE);
3275 prerender->WaitForStop();
3277 // Make sure prerender history was not cleared. Not a vital behavior, but
3278 // used to compare with PrerenderClearHistory test.
3279 EXPECT_EQ(1, GetHistoryLength());
3282 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) {
3283 scoped_ptr<TestPrerender> prerender =
3284 PrerenderTestURL("files/prerender/prerender_page.html",
3285 FINAL_STATUS_CANCELLED,
3288 GetPrerenderManager()->CancelAllPrerenders();
3289 prerender->WaitForStop();
3291 EXPECT_FALSE(prerender->contents());
3294 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) {
3295 scoped_ptr<TestPrerender> prerender =
3296 PrerenderTestURL("files/prerender/prerender_page.html",
3297 FINAL_STATUS_CANCELLED, 1);
3299 GetPrerenderManager()->CancelAllPrerenders();
3300 prerender->WaitForStop();
3302 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
3303 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
3304 EXPECT_FALSE(HadPrerenderEventErrors());
3307 // Cancels the prerender of a page with its own prerender. The second prerender
3308 // should never be started.
3309 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3310 PrerenderCancelPrerenderWithPrerender) {
3311 scoped_ptr<TestPrerender> prerender =
3312 PrerenderTestURL("files/prerender/prerender_infinite_a.html",
3313 FINAL_STATUS_CANCELLED,
3316 GetPrerenderManager()->CancelAllPrerenders();
3317 prerender->WaitForStop();
3319 EXPECT_FALSE(prerender->contents());
3322 // Prerendering and history tests.
3323 // The prerendered page is navigated to in several ways [navigate via
3324 // omnibox, click on link, key-modified click to open in background tab, etc],
3325 // followed by a navigation to another page from the prerendered page, followed
3326 // by a back navigation.
3328 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) {
3329 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3332 NavigateToDestURL();
3333 ClickToNextPageAfterPrerender();
3334 GoBackToPrerender();
3337 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateNavigateGoBack) {
3338 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3341 NavigateToDestURL();
3342 NavigateToNextPageAfterPrerender();
3343 GoBackToPrerender();
3346 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) {
3347 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3350 OpenDestURLViaClick();
3351 ClickToNextPageAfterPrerender();
3352 GoBackToPrerender();
3355 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNavigateGoBack) {
3356 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3359 OpenDestURLViaClick();
3360 NavigateToNextPageAfterPrerender();
3361 GoBackToPrerender();
3364 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
3365 // Prerender currently doesn't interpose on this navigation.
3366 // http://crbug.com/345474.
3367 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3370 OpenDestURLViaClickNewWindow();
3373 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
3374 // Prerender currently doesn't interpose on this navigation.
3375 // http://crbug.com/345474.
3376 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3379 OpenDestURLViaClickNewForegroundTab();
3382 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) {
3383 // Prerender currently doesn't interpose on this navigation.
3384 // http://crbug.com/345474.
3385 scoped_ptr<TestPrerender> prerender =
3386 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3389 ASSERT_TRUE(prerender->contents());
3390 prerender->contents()->set_should_be_shown(false);
3391 OpenDestURLViaClickNewBackgroundTab();
3394 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3395 NavigateToPrerenderedPageWhenDevToolsAttached) {
3396 DisableJavascriptCalls();
3397 WebContents* web_contents =
3398 current_browser()->tab_strip_model()->GetActiveWebContents();
3399 scoped_refptr<DevToolsAgentHost> agent(
3400 DevToolsAgentHost::GetOrCreateFor(web_contents));
3401 FakeDevToolsClient client;
3402 agent->AttachClient(&client);
3403 const char* url = "files/prerender/prerender_page.html";
3404 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1);
3405 NavigateToURLWithDisposition(url, CURRENT_TAB, false);
3406 agent->DetachClient();
3409 // Validate that the sessionStorage namespace remains the same when swapping
3410 // in a prerendered page.
3411 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) {
3412 set_loader_path("files/prerender/prerender_loader_with_session_storage.html");
3413 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
3416 NavigateToDestURL();
3417 GoBackToPageBeforePrerender();
3420 // Checks that the control group works. An XHR PUT cannot be detected in the
3422 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroup) {
3423 RestorePrerenderMode restore_prerender_mode;
3424 PrerenderManager::SetMode(
3425 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
3426 DisableJavascriptCalls();
3427 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3428 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
3429 NavigateToDestURL();
3432 // Checks that the control group correctly hits WOULD_HAVE_BEEN_USED
3433 // renderer-initiated navigations. (This verifies that the ShouldFork logic
3434 // behaves correctly.)
3435 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroupRendererInitiated) {
3436 RestorePrerenderMode restore_prerender_mode;
3437 PrerenderManager::SetMode(
3438 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
3439 DisableJavascriptCalls();
3440 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3441 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
3442 OpenDestURLViaClick();
3445 // Make sure that the MatchComplete dummy works in the normal case. Once
3446 // a prerender is cancelled because of a script, a dummy must be created to
3447 // account for the MatchComplete case, and it must have a final status of
3448 // FINAL_STATUS_WOULD_HAVE_BEEN_USED.
3449 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MatchCompleteDummy) {
3450 RestorePrerenderMode restore_prerender_mode;
3451 PrerenderManager::SetMode(
3452 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
3454 std::vector<FinalStatus> expected_final_status_queue;
3455 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
3456 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
3457 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3458 expected_final_status_queue, 1);
3459 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3460 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3461 histogram_tester().ExpectTotalCount(
3462 "Prerender.none_PerceivedPLTMatchedComplete", 0);
3463 histogram_tester().ExpectTotalCount(
3464 "Prerender.websame_PrerenderNotSwappedInPLT", 1);
3466 NavigateToDestURL();
3467 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3468 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLTMatched",
3470 histogram_tester().ExpectTotalCount(
3471 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3474 // Verify that a navigation that hits a MatchComplete dummy while another is in
3475 // progress does not also classify the previous navigation as a MatchComplete.
3476 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3477 MatchCompleteDummyCancelNavigation) {
3478 RestorePrerenderMode restore_prerender_mode;
3479 PrerenderManager::SetMode(
3480 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
3482 // Arrange for a URL to hang.
3483 const GURL kNoCommitUrl("http://never-respond.example.com");
3484 base::FilePath file(FILE_PATH_LITERAL(
3485 "chrome/test/data/prerender/prerender_page.html"));
3486 base::RunLoop hang_loop;
3487 BrowserThread::PostTask(
3488 BrowserThread::IO, FROM_HERE,
3489 base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl,
3490 file, hang_loop.QuitClosure()));
3492 // First, fire a prerender that aborts after it completes its load.
3493 std::vector<FinalStatus> expected_final_status_queue;
3494 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
3495 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
3496 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3497 expected_final_status_queue, 1);
3498 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3499 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3500 histogram_tester().ExpectTotalCount(
3501 "Prerender.none_PerceivedPLTMatchedComplete", 0);
3502 histogram_tester().ExpectTotalCount(
3503 "Prerender.websame_PrerenderNotSwappedInPLT", 1);
3505 // Open the hanging URL in a new tab. Wait for both the new tab to open and
3506 // the hanging request to be scheduled.
3507 ui_test_utils::NavigateToURLWithDisposition(
3508 current_browser(), kNoCommitUrl, NEW_FOREGROUND_TAB,
3509 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
3512 // Now interrupt that navigation and navigate to the destination URL. This
3513 // should forcibly complete the previous navigation and also complete a
3514 // WOULD_HAVE_BEEN_PRERENDERED navigation.
3515 NavigateToDestURL();
3516 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 2);
3517 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3518 histogram_tester().ExpectTotalCount(
3519 "Prerender.none_PerceivedPLTMatchedComplete", 0);
3520 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3521 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLTMatched",
3523 histogram_tester().ExpectTotalCount(
3524 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3527 class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest {
3529 PrerenderBrowserTestWithNaCl() {}
3530 ~PrerenderBrowserTestWithNaCl() override {}
3532 void SetUpCommandLine(CommandLine* command_line) override {
3533 PrerenderBrowserTest::SetUpCommandLine(command_line);
3534 command_line->AppendSwitch(switches::kEnableNaCl);
3538 // Check that NaCl plugins work when enabled, with prerendering.
3539 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
3540 PrerenderNaClPluginEnabled) {
3541 #if defined(OS_WIN) && defined(USE_ASH)
3542 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
3543 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
3547 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
3550 NavigateToDestURL();
3552 // To avoid any chance of a race, we have to let the script send its response
3554 WebContents* web_contents =
3555 browser()->tab_strip_model()->GetActiveWebContents();
3556 bool display_test_result = false;
3557 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents,
3558 "DidDisplayReallyPass()",
3559 &display_test_result));
3560 ASSERT_TRUE(display_test_result);
3563 // Checks that the referrer policy is used when prerendering.
3564 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) {
3565 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3566 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3569 NavigateToDestURL();
3572 // Checks that the referrer policy is used when prerendering on HTTPS.
3573 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3574 PrerenderSSLReferrerPolicy) {
3575 UseHttpsSrcServer();
3576 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3577 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3580 NavigateToDestURL();
3583 // Checks that the referrer policy is used when prerendering is cancelled.
3584 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrerPolicy) {
3585 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
3586 new TestContentBrowserClient);
3587 content::ContentBrowserClient* original_browser_client =
3588 content::SetBrowserClientForTesting(test_content_browser_client.get());
3590 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3591 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3592 FINAL_STATUS_CANCELLED,
3594 OpenDestURLViaClick();
3596 bool display_test_result = false;
3597 WebContents* web_contents =
3598 browser()->tab_strip_model()->GetActiveWebContents();
3599 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
3601 "window.domAutomationController.send(DidDisplayPass())",
3602 &display_test_result));
3603 EXPECT_TRUE(display_test_result);
3605 content::SetBrowserClientForTesting(original_browser_client);
3608 // Test interaction of the webNavigation and tabs API with prerender.
3609 class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest,
3610 public ExtensionApiTest {
3612 PrerenderBrowserTestWithExtensions() {
3613 // The individual tests start the test server through ExtensionApiTest, so
3614 // the port number can be passed through to the extension.
3615 autostart_test_server_ = false;
3618 void SetUp() override { PrerenderBrowserTest::SetUp(); }
3620 void SetUpCommandLine(CommandLine* command_line) override {
3621 PrerenderBrowserTest::SetUpCommandLine(command_line);
3622 ExtensionApiTest::SetUpCommandLine(command_line);
3625 void SetUpInProcessBrowserTestFixture() override {
3626 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
3627 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
3630 void TearDownInProcessBrowserTestFixture() override {
3631 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
3632 ExtensionApiTest::TearDownInProcessBrowserTestFixture();
3635 void SetUpOnMainThread() override {
3636 PrerenderBrowserTest::SetUpOnMainThread();
3640 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) {
3641 ASSERT_TRUE(StartSpawnedTestServer());
3642 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3644 // Wait for the extension to set itself up and return control to us.
3645 ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_;
3647 extensions::ResultCatcher catcher;
3649 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3651 ChannelDestructionWatcher channel_close_watcher;
3652 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3653 GetActiveWebContents()->GetRenderProcessHost());
3654 NavigateToDestURL();
3655 channel_close_watcher.WaitForChannelClose();
3657 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3658 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3661 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, TabsApi) {
3662 ASSERT_TRUE(StartSpawnedTestServer());
3663 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3665 // Wait for the extension to set itself up and return control to us.
3666 ASSERT_TRUE(RunExtensionTest("tabs/on_replaced")) << message_;
3668 extensions::ResultCatcher catcher;
3670 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3672 ChannelDestructionWatcher channel_close_watcher;
3673 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3674 GetActiveWebContents()->GetRenderProcessHost());
3675 NavigateToDestURL();
3676 channel_close_watcher.WaitForChannelClose();
3678 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3679 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3682 // Test that prerenders abort when navigating to a stream.
3683 // See chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
3684 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, StreamsTest) {
3685 RestorePrerenderMode restore_prerender_mode;
3686 PrerenderManager::SetMode(
3687 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
3689 ASSERT_TRUE(StartSpawnedTestServer());
3691 const extensions::Extension* extension = LoadExtension(
3692 test_data_dir_.AppendASCII("streams_private/handle_mime_type"));
3693 ASSERT_TRUE(extension);
3694 EXPECT_EQ(std::string(extension_misc::kStreamsPrivateTestExtensionId),
3696 MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
3697 ASSERT_TRUE(handler);
3698 EXPECT_TRUE(handler->CanHandleMIMEType("application/msword"));
3700 PrerenderTestURL("files/prerender/document.doc", FINAL_STATUS_DOWNLOAD, 0);
3702 // Sanity-check that the extension would have picked up the stream in a normal
3703 // navigation had prerender not intercepted it.
3704 // streams_private/handle_mime_type reports success if it has handled the
3705 // application/msword type.
3706 extensions::ResultCatcher catcher;
3707 NavigateToDestURL();
3708 EXPECT_TRUE(catcher.GetNextResult());
3711 // Checks that non-http/https/chrome-extension subresource cancels the
3713 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3714 PrerenderCancelSubresourceUnsupportedScheme) {
3715 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg");
3716 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3717 replacement_text.push_back(
3718 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3719 std::string replacement_path;
3720 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3721 "files/prerender/prerender_with_image.html",
3723 &replacement_path));
3724 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3727 // Ensure that about:blank is permitted for any subresource.
3728 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3729 PrerenderAllowAboutBlankSubresource) {
3730 GURL image_url = GURL("about:blank");
3731 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3732 replacement_text.push_back(
3733 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3734 std::string replacement_path;
3735 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3736 "files/prerender/prerender_with_image.html",
3738 &replacement_path));
3739 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3740 NavigateToDestURL();
3743 // Checks that non-http/https/chrome-extension subresource cancels the prerender
3745 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3746 PrerenderCancelSubresourceRedirectUnsupportedScheme) {
3747 GURL image_url = test_server()->GetURL(
3748 CreateServerRedirect("invalidscheme://www.google.com/test.jpg"));
3749 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3750 replacement_text.push_back(
3751 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3752 std::string replacement_path;
3753 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3754 "files/prerender/prerender_with_image.html",
3756 &replacement_path));
3757 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3760 // Checks that chrome-extension subresource does not cancel the prerender.
3761 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3762 PrerenderKeepSubresourceExtensionScheme) {
3763 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg");
3764 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3765 replacement_text.push_back(
3766 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3767 std::string replacement_path;
3768 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3769 "files/prerender/prerender_with_image.html",
3771 &replacement_path));
3772 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3773 NavigateToDestURL();
3776 // Checks that redirect to chrome-extension subresource does not cancel the
3778 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3779 PrerenderKeepSubresourceRedirectExtensionScheme) {
3780 GURL image_url = test_server()->GetURL(
3781 CreateServerRedirect("chrome-extension://abcdefg/test.jpg"));
3782 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3783 replacement_text.push_back(
3784 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3785 std::string replacement_path;
3786 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3787 "files/prerender/prerender_with_image.html",
3789 &replacement_path));
3790 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3791 NavigateToDestURL();
3794 // Checks that non-http/https main page redirects cancel the prerender.
3795 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3796 PrerenderCancelMainFrameRedirectUnsupportedScheme) {
3797 GURL url = test_server()->GetURL(
3798 CreateServerRedirect("invalidscheme://www.google.com/test.html"));
3799 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3802 // Checks that media source video loads are deferred on prerendering.
3803 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) {
3804 PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html",
3807 NavigateToDestURL();
3808 WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
3811 // Checks that a prerender that creates an audio stream (via a WebAudioDevice)
3813 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWebAudioDevice) {
3814 DisableLoadEventCheck();
3815 PrerenderTestURL("files/prerender/prerender_web_audio_device.html",
3816 FINAL_STATUS_CREATING_AUDIO_STREAM, 0);
3819 // Checks that prerenders do not swap in to WebContents being captured.
3820 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) {
3821 PrerenderTestURL("files/prerender/prerender_page.html",
3822 FINAL_STATUS_PAGE_BEING_CAPTURED, 1);
3823 WebContents* web_contents = GetActiveWebContents();
3824 web_contents->IncrementCapturerCount(gfx::Size());
3825 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3826 web_contents->DecrementCapturerCount();
3829 // Checks that prerenders are aborted on cross-process navigation from
3830 // a server redirect.
3831 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3832 PrerenderCrossProcessServerRedirect) {
3833 // Force everything to be a process swap.
3834 SwapProcessesContentBrowserClient test_browser_client;
3835 content::ContentBrowserClient* original_browser_client =
3836 content::SetBrowserClientForTesting(&test_browser_client);
3839 CreateServerRedirect("files/prerender/prerender_page.html"),
3840 FINAL_STATUS_OPEN_URL, 0);
3842 content::SetBrowserClientForTesting(original_browser_client);
3845 // Checks that URLRequests for prerenders being aborted on cross-process
3846 // navigation from a server redirect are cleaned up, so they don't keep cache
3848 // See http://crbug.com/341134
3849 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3850 PrerenderCrossProcessServerRedirectNoHang) {
3851 const char kDestPath[] = "files/prerender/prerender_page.html";
3852 // Force everything to be a process swap.
3853 SwapProcessesContentBrowserClient test_browser_client;
3854 content::ContentBrowserClient* original_browser_client =
3855 content::SetBrowserClientForTesting(&test_browser_client);
3857 PrerenderTestURL(CreateServerRedirect(kDestPath), FINAL_STATUS_OPEN_URL, 0);
3859 ui_test_utils::NavigateToURL(
3861 test_server()->GetURL(kDestPath));
3863 content::SetBrowserClientForTesting(original_browser_client);
3866 // Checks that prerenders are aborted on cross-process navigation from
3867 // a client redirect.
3868 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3869 PrerenderCrossProcessClientRedirect) {
3870 // Cross-process navigation logic for renderer-initiated navigations
3871 // is partially controlled by the renderer, namely
3872 // ChromeContentRendererClient. This test instead relies on the Web
3873 // Store triggering such navigations.
3874 std::string webstore_url = extension_urls::GetWebstoreLaunchURL();
3876 // Mock out requests to the Web Store.
3877 base::FilePath file(GetTestPath("prerender_page.html"));
3878 BrowserThread::PostTask(
3879 BrowserThread::IO, FROM_HERE,
3880 base::Bind(&CreateMockInterceptorOnIO, GURL(webstore_url), file));
3882 PrerenderTestURL(CreateClientRedirect(webstore_url),
3883 FINAL_STATUS_OPEN_URL, 1);
3886 // Checks that canceling a MatchComplete dummy doesn't result in two
3888 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelMatchCompleteDummy) {
3889 RestorePrerenderMode restore_prerender_mode;
3890 PrerenderManager::SetMode(
3891 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
3893 std::vector<FinalStatus> expected_final_status_queue;
3894 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT);
3895 expected_final_status_queue.push_back(FINAL_STATUS_CANCELLED);
3896 ScopedVector<TestPrerender> prerenders =
3897 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
3898 expected_final_status_queue, 0);
3900 // Cancel the MatchComplete dummy.
3901 GetPrerenderManager()->CancelAllPrerenders();
3902 prerenders[1]->WaitForStop();
3904 // Check the referring page only got one copy of the event.
3905 EXPECT_FALSE(HadPrerenderEventErrors());
3908 // Checks that a deferred redirect to an image is not loaded until the page is
3909 // visible. Also test the right histogram events are emitted in this case.
3910 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredImage) {
3911 DisableJavascriptCalls();
3913 // The prerender will not completely load until after the swap, so wait for a
3914 // title change before calling DidPrerenderPass.
3915 scoped_ptr<TestPrerender> prerender =
3917 "files/prerender/prerender_deferred_image.html",
3918 FINAL_STATUS_USED, 0);
3919 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
3920 EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
3921 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
3922 EXPECT_EQ(0, prerender->number_of_loads());
3923 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
3924 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
3925 histogram_tester().ExpectTotalCount(
3926 "Prerender.none_PerceivedPLTMatchedComplete", 0);
3927 histogram_tester().ExpectTotalCount(
3928 "Prerender.websame_PrerenderNotSwappedInPLT", 0);
3931 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
3932 GetActiveWebContents());
3933 ui_test_utils::NavigateToURLWithDisposition(
3934 current_browser(), dest_url(), CURRENT_TAB,
3935 ui_test_utils::BROWSER_TEST_NONE);
3936 swap_observer.Wait();
3938 // The prerender never observes the final load.
3939 EXPECT_EQ(0, prerender->number_of_loads());
3941 // Now check DidDisplayPass.
3942 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3944 histogram_tester().ExpectTotalCount(
3945 "Prerender.websame_PrerenderNotSwappedInPLT", 0);
3946 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
3947 histogram_tester().ExpectTotalCount("Prerender.websame_PerceivedPLTMatched",
3949 histogram_tester().ExpectTotalCount(
3950 "Prerender.websame_PerceivedPLTMatchedComplete", 1);
3953 // Checks that a deferred redirect to an image is not loaded until the
3954 // page is visible, even after another redirect.
3955 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3956 PrerenderDeferredImageAfterRedirect) {
3957 DisableJavascriptCalls();
3959 // The prerender will not completely load until after the swap, so wait for a
3960 // title change before calling DidPrerenderPass.
3961 scoped_ptr<TestPrerender> prerender =
3963 "files/prerender/prerender_deferred_image.html",
3964 FINAL_STATUS_USED, 0);
3965 WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
3966 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
3967 EXPECT_EQ(0, prerender->number_of_loads());
3970 NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
3971 GetActiveWebContents());
3972 ui_test_utils::NavigateToURLWithDisposition(
3973 current_browser(), dest_url(), CURRENT_TAB,
3974 ui_test_utils::BROWSER_TEST_NONE);
3975 swap_observer.Wait();
3977 // The prerender never observes the final load.
3978 EXPECT_EQ(0, prerender->number_of_loads());
3980 // Now check DidDisplayPass.
3981 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
3984 // Checks that deferred redirects in the main frame are followed.
3985 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredMainFrame) {
3986 DisableJavascriptCalls();
3988 "files/prerender/image-deferred.png",
3989 FINAL_STATUS_USED, 1);
3990 NavigateToDestURL();
3993 // Checks that deferred redirects in the main frame are followed, even
3994 // with a double-redirect.
3995 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3996 PrerenderDeferredMainFrameAfterRedirect) {
3997 DisableJavascriptCalls();
3999 CreateServerRedirect("files/prerender/image-deferred.png"),
4000 FINAL_STATUS_USED, 1);
4001 NavigateToDestURL();
4004 // Checks that deferred redirects in a synchronous XHR abort the
4006 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredSynchronousXHR) {
4007 RestorePrerenderMode restore_prerender_mode;
4008 PrerenderManager::SetMode(
4009 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
4010 PrerenderTestURL("files/prerender/prerender_deferred_sync_xhr.html",
4011 FINAL_STATUS_BAD_DEFERRED_REDIRECT, 0);
4012 NavigateToDestURL();
4015 // Checks that prerenders are not swapped for navigations with extra headers.
4016 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExtraHeadersNoSwap) {
4017 PrerenderTestURL("files/prerender/prerender_page.html",
4018 FINAL_STATUS_APP_TERMINATING, 1);
4020 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
4021 ui::PAGE_TRANSITION_TYPED, false);
4022 params.extra_headers = "X-Custom-Header: 42\r\n";
4023 NavigateToURLWithParams(params, false);
4026 // Checks that prerenders are not swapped for navigations with browser-initiated
4028 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4029 PrerenderBrowserInitiatedPostNoSwap) {
4030 PrerenderTestURL("files/prerender/prerender_page.html",
4031 FINAL_STATUS_APP_TERMINATING, 1);
4033 std::string post_data = "DATA";
4034 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
4035 ui::PAGE_TRANSITION_TYPED, false);
4036 params.uses_post = true;
4037 params.browser_initiated_post_data =
4038 base::RefCountedString::TakeString(&post_data);
4039 NavigateToURLWithParams(params, false);
4042 // Checks that the prerendering of a page is canceled correctly when the
4043 // prerendered page tries to make a second navigation entry.
4044 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) {
4045 PrerenderTestURL("files/prerender/prerender_new_entry.html",
4046 FINAL_STATUS_NEW_NAVIGATION_ENTRY,
4050 // Attempt a swap-in in a new tab, verifying that session storage namespace
4052 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) {
4053 // Mock out some URLs and count the number of requests to one of them. Both
4054 // prerender_session_storage.html and init_session_storage.html need to be
4055 // mocked so they are same-origin.
4056 const GURL kInitURL("http://prerender.test/init_session_storage.html");
4057 base::FilePath init_file = GetTestPath("init_session_storage.html");
4058 BrowserThread::PostTask(
4059 BrowserThread::IO, FROM_HERE,
4060 base::Bind(&CreateMockInterceptorOnIO, kInitURL, init_file));
4062 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
4063 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
4064 RequestCounter counter;
4065 BrowserThread::PostTask(
4066 BrowserThread::IO, FROM_HERE,
4067 base::Bind(&CreateCountingInterceptorOnIO,
4068 kTestURL, test_file, counter.AsWeakPtr()));
4070 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
4072 // Open a new tab to navigate in.
4073 ui_test_utils::NavigateToURLWithDisposition(
4074 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
4075 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4077 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
4078 // the swap does not occur synchronously.
4080 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
4081 // return value assertion and let this go through the usual successful-swap
4083 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
4085 // Verify DidDisplayPass manually since the previous call skipped it.
4086 EXPECT_TRUE(DidDisplayPass(
4087 current_browser()->tab_strip_model()->GetActiveWebContents()));
4089 // Only one request to the test URL started.
4091 // TODO(davidben): Re-enable this check when the races in attaching the
4092 // throttle are resolved. http://crbug.com/335835
4093 // EXPECT_EQ(1, counter.count());
4096 // Attempt a swap-in in a new tab, verifying that session storage namespace
4097 // merging works. Unlike the above test, the swap is for a navigation that would
4098 // normally be cross-process.
4099 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) {
4100 base::FilePath test_data_dir;
4101 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
4103 // Mock out some URLs and count the number of requests to one of them. Both
4104 // prerender_session_storage.html and init_session_storage.html need to be
4105 // mocked so they are same-origin.
4106 const GURL kInitURL("http://prerender.test/init_session_storage.html");
4107 base::FilePath init_file = GetTestPath("init_session_storage.html");
4108 BrowserThread::PostTask(
4109 BrowserThread::IO, FROM_HERE,
4110 base::Bind(&CreateMockInterceptorOnIO, kInitURL, init_file));
4112 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
4113 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
4114 RequestCounter counter;
4115 BrowserThread::PostTask(
4116 BrowserThread::IO, FROM_HERE,
4117 base::Bind(&CreateCountingInterceptorOnIO,
4118 kTestURL, test_file, counter.AsWeakPtr()));
4120 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
4122 // Open a new tab to navigate in.
4123 ui_test_utils::NavigateToURLWithDisposition(
4124 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
4125 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4127 // Navigate to about:blank so the next navigation is cross-process.
4128 ui_test_utils::NavigateToURL(current_browser(), GURL(url::kAboutBlankURL));
4130 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
4131 // the swap does not occur synchronously.
4133 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
4134 // return value assertion and let this go through the usual successful-swap
4136 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
4138 // Verify DidDisplayPass manually since the previous call skipped it.
4139 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
4141 // Only one request to the test URL started.
4143 // TODO(davidben): Re-enable this check when the races in attaching the
4144 // throttle are resolved. http://crbug.com/335835
4145 // EXPECT_EQ(1, counter.count());
4148 // Verify that session storage conflicts don't merge.
4149 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) {
4150 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html",
4151 FINAL_STATUS_APP_TERMINATING, 1);
4153 // Open a new tab to navigate in.
4154 ui_test_utils::NavigateToURLWithDisposition(
4156 test_server()->GetURL("files/prerender/init_session_storage.html"),
4158 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4160 // Now navigate in the new tab.
4161 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
4163 // Verify DidDisplayPass in the new tab.
4164 EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
4167 // Checks that prerenders honor |should_replace_current_entry|.
4168 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReplaceCurrentEntry) {
4169 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
4171 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
4172 ui::PAGE_TRANSITION_TYPED, false);
4173 params.should_replace_current_entry = true;
4174 NavigateToURLWithParams(params, false);
4176 const NavigationController& controller =
4177 GetActiveWebContents()->GetController();
4178 // First entry is about:blank, second is prerender_page.html.
4179 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
4180 EXPECT_EQ(2, controller.GetEntryCount());
4181 EXPECT_EQ(GURL(url::kAboutBlankURL), controller.GetEntryAtIndex(0)->GetURL());
4182 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL());
4185 // Checks prerender does not hit DCHECKs and behaves properly if two pending
4186 // swaps occur in a row.
4187 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDoublePendingSwap) {
4188 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
4189 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
4191 GURL url1 = test_server()->GetURL("files/prerender/prerender_page.html?1");
4192 scoped_ptr<TestPrerender> prerender1 =
4193 PrerenderTestURL(url1, FINAL_STATUS_APP_TERMINATING, 1);
4195 GURL url2 = test_server()->GetURL("files/prerender/prerender_page.html?2");
4196 scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
4197 AddPrerender(url2, 1);
4198 prerender2->WaitForStart();
4199 prerender2->WaitForLoads(1);
4201 // There's no reason the second prerender can't be used, but the swap races
4202 // with didStartProvisionalLoad and didFailProvisionalLoad from the previous
4203 // navigation. The current logic will conservatively fail to swap under such
4204 // races. However, if the renderer is slow enough, it's possible for the
4205 // prerender to still be used, so don't program in either expectation.
4206 ASSERT_TRUE(prerender2->contents());
4207 prerender2->contents()->set_skip_final_checks(true);
4209 // Open a new tab to navigate in.
4210 ui_test_utils::NavigateToURLWithDisposition(
4212 GURL(url::kAboutBlankURL),
4214 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4216 // Fire off two navigations, without running the event loop between them.
4217 NavigationOrSwapObserver swap_observer(
4218 current_browser()->tab_strip_model(),
4219 GetActiveWebContents(), 2);
4220 current_browser()->OpenURL(OpenURLParams(
4221 url1, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));
4222 current_browser()->OpenURL(OpenURLParams(
4223 url2, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));
4224 swap_observer.Wait();
4226 // The WebContents should be on url2. There may be 2 or 3 entries, depending
4227 // on whether the first one managed to complete.
4229 // TODO(davidben): When http://crbug.com/335835 is fixed, the 3 entry case
4230 // shouldn't be possible because it's throttled by the pending swap that
4232 const NavigationController& controller =
4233 GetActiveWebContents()->GetController();
4234 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
4235 EXPECT_LE(2, controller.GetEntryCount());
4236 EXPECT_GE(3, controller.GetEntryCount());
4237 EXPECT_EQ(GURL(url::kAboutBlankURL), controller.GetEntryAtIndex(0)->GetURL());
4238 EXPECT_EQ(url2, controller.GetEntryAtIndex(
4239 controller.GetEntryCount() - 1)->GetURL());
4242 // Verify that pending swaps get aborted on new navigations.
4243 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4244 PrerenderPendingSwapNewNavigation) {
4245 PrerenderManager::HangSessionStorageMergesForTesting();
4247 PrerenderTestURL("files/prerender/prerender_page.html",
4248 FINAL_STATUS_APP_TERMINATING, 1);
4250 // Open a new tab to navigate in.
4251 ui_test_utils::NavigateToURLWithDisposition(
4253 GURL(url::kAboutBlankURL),
4255 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
4257 // Navigate to the URL. Wait for DidStartLoading, just so it's definitely
4258 // progressed somewhere.
4259 content::WindowedNotificationObserver page_load_observer(
4260 content::NOTIFICATION_LOAD_START,
4261 content::Source<NavigationController>(
4262 &GetActiveWebContents()->GetController()));
4263 current_browser()->OpenURL(OpenURLParams(
4264 dest_url(), Referrer(), CURRENT_TAB,
4265 ui::PAGE_TRANSITION_TYPED, false));
4266 page_load_observer.Wait();
4268 // Navigate somewhere else. This should succeed and abort the pending swap.
4269 TestNavigationObserver nav_observer(GetActiveWebContents());
4270 current_browser()->OpenURL(OpenURLParams(GURL(url::kAboutBlankURL),
4273 ui::PAGE_TRANSITION_TYPED,
4275 nav_observer.Wait();
4278 // Checks that <a ping> requests are not dropped in prerender.
4279 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPing) {
4280 // Count hits to a certain URL.
4281 const GURL kPingURL("http://prerender.test/ping");
4282 base::FilePath empty_file = ui_test_utils::GetTestFilePath(
4283 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
4284 RequestCounter ping_counter;
4285 BrowserThread::PostTask(
4286 BrowserThread::IO, FROM_HERE,
4287 base::Bind(&CreateCountingInterceptorOnIO,
4288 kPingURL, empty_file, ping_counter.AsWeakPtr()));
4290 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
4291 OpenDestURLViaClickPing(kPingURL);
4293 ping_counter.WaitForCount(1);
4296 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPPLTNormalNavigation) {
4297 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
4298 ui_test_utils::NavigateToURL(current_browser(), url);
4299 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
4300 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
4301 histogram_tester().ExpectTotalCount(
4302 "Prerender.none_PerceivedPLTMatchedComplete", 0);
4305 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4306 PrerenderCookieChangeConflictTest) {
4307 NavigateStraightToURL(
4308 "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
4310 GURL url = test_server()->GetURL(
4311 "files/prerender/prerender_cookie.html?set=1&key=c&value=2");
4313 scoped_ptr<TestPrerender> prerender =
4314 ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
4315 AddPrerender(url, 1);
4316 prerender->WaitForStart();
4317 prerender->WaitForLoads(1);
4318 // Ensure that in the prerendered page, querying the cookie again
4319 // via javascript yields the same value that was set during load.
4320 EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
4322 // The prerender has loaded. Ensure that the change is not visible
4325 RunJSReturningString("GetCookie('c')", &value);
4326 ASSERT_EQ(value, "1");
4328 // Make a conflicting cookie change, which should cancel the prerender.
4329 RunJS("SetCookie('c', '3')");
4330 prerender->WaitForStop();
4333 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCookieChangeUseTest) {
4334 // Permit 2 concurrent prerenders.
4335 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
4336 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
4338 // Go to a first URL setting the cookie to value "1".
4339 NavigateStraightToURL(
4340 "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
4342 // Prerender a URL setting the cookie to value "2".
4343 GURL url = test_server()->GetURL(
4344 "files/prerender/prerender_cookie.html?set=1&key=c&value=2");
4346 scoped_ptr<TestPrerender> prerender1 = ExpectPrerender(FINAL_STATUS_USED);
4347 AddPrerender(url, 1);
4348 prerender1->WaitForStart();
4349 prerender1->WaitForLoads(1);
4351 // Launch a second prerender, setting the cookie to value "3".
4352 scoped_ptr<TestPrerender> prerender2 =
4353 ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
4354 AddPrerender(test_server()->GetURL(
4355 "files/prerender/prerender_cookie.html?set=1&key=c&value=3"), 1);
4356 prerender2->WaitForStart();
4357 prerender2->WaitForLoads(1);
4359 // Both prerenders have loaded. Ensure that the visible tab is still
4360 // unchanged and cannot see their changes.
4363 RunJSReturningString("GetCookie('c')", &value);
4364 ASSERT_EQ(value, "1");
4366 // Navigate to the prerendered URL. The first prerender should be swapped in,
4367 // and the changes should now be visible. The second prerender should
4368 // be cancelled due to the conflict.
4369 ui_test_utils::NavigateToURLWithDisposition(
4373 ui_test_utils::BROWSER_TEST_NONE);
4374 RunJSReturningString("GetCookie('c')", &value);
4375 ASSERT_EQ(value, "2");
4376 prerender2->WaitForStop();
4379 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4380 PrerenderCookieChangeConflictHTTPHeaderTest) {
4381 NavigateStraightToURL(
4382 "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
4384 GURL url = test_server()->GetURL("set-cookie?c=2");
4385 scoped_ptr<TestPrerender> prerender =
4386 ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
4387 AddPrerender(url, 1);
4388 prerender->WaitForStart();
4389 prerender->WaitForLoads(1);
4391 // The prerender has loaded. Ensure that the change is not visible
4394 RunJSReturningString("GetCookie('c')", &value);
4395 ASSERT_EQ(value, "1");
4397 // Make a conflicting cookie change, which should cancel the prerender.
4398 RunJS("SetCookie('c', '3')");
4399 prerender->WaitForStop();
4402 // Checks that a prerender which calls window.close() on itself is aborted.
4403 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowClose) {
4404 DisableLoadEventCheck();
4405 PrerenderTestURL("files/prerender/prerender_window_close.html",
4406 FINAL_STATUS_CLOSED, 0);
4409 class PrerenderIncognitoBrowserTest : public PrerenderBrowserTest {
4411 void SetUpOnMainThread() override {
4412 Profile* normal_profile = current_browser()->profile();
4413 set_browser(ui_test_utils::OpenURLOffTheRecord(
4414 normal_profile, GURL("about:blank")));
4415 PrerenderBrowserTest::SetUpOnMainThread();
4419 // Checks that prerendering works in incognito mode.
4420 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) {
4421 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
4422 NavigateToDestURL();
4425 // Checks that prerenders are aborted when an incognito profile is closed.
4426 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest,
4427 PrerenderIncognitoClosed) {
4428 scoped_ptr<TestPrerender> prerender =
4429 PrerenderTestURL("files/prerender/prerender_page.html",
4430 FINAL_STATUS_PROFILE_DESTROYED, 1);
4431 current_browser()->window()->Close();
4432 prerender->WaitForStop();
4435 class PrerenderOmniboxBrowserTest : public PrerenderBrowserTest {
4437 LocationBar* GetLocationBar() {
4438 return current_browser()->window()->GetLocationBar();
4441 OmniboxView* GetOmniboxView() {
4442 return GetLocationBar()->GetOmniboxView();
4445 void WaitForAutocompleteDone(OmniboxView* omnibox_view) {
4446 AutocompleteController* controller =
4447 omnibox_view->model()->popup_model()->autocomplete_controller();
4448 while (!controller->done()) {
4449 content::WindowedNotificationObserver ready_observer(
4450 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
4451 content::Source<AutocompleteController>(controller));
4452 ready_observer.Wait();
4456 predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() {
4457 Profile* profile = current_browser()->profile();
4458 return predictors::AutocompleteActionPredictorFactory::GetForProfile(
4462 scoped_ptr<TestPrerender> StartOmniboxPrerender(
4464 FinalStatus expected_final_status) {
4465 scoped_ptr<TestPrerender> prerender =
4466 ExpectPrerender(expected_final_status);
4467 WebContents* web_contents = GetActiveWebContents();
4468 GetAutocompleteActionPredictor()->StartPrerendering(
4470 web_contents->GetController().GetSessionStorageNamespaceMap(),
4472 prerender->WaitForStart();
4473 return prerender.Pass();
4477 // Checks that closing the omnibox popup cancels an omnibox prerender.
4478 // http://crbug.com/395152
4479 IN_PROC_BROWSER_TEST_F(PrerenderOmniboxBrowserTest,
4480 DISABLED_PrerenderOmniboxCancel) {
4481 // Ensure the cookie store has been loaded.
4482 if (!GetPrerenderManager()->cookie_store_loaded()) {
4484 GetPrerenderManager()->set_on_cookie_store_loaded_cb_for_testing(
4485 loop.QuitClosure());
4489 // Fake an omnibox prerender.
4490 scoped_ptr<TestPrerender> prerender = StartOmniboxPrerender(
4491 test_server()->GetURL("files/empty.html"),
4492 FINAL_STATUS_CANCELLED);
4494 // Revert the location bar. This should cancel the prerender.
4495 GetLocationBar()->Revert();
4496 prerender->WaitForStop();
4499 // Checks that accepting omnibox input abandons an omnibox prerender.
4500 // http://crbug.com/394592
4501 IN_PROC_BROWSER_TEST_F(PrerenderOmniboxBrowserTest,
4502 DISABLED_PrerenderOmniboxAbandon) {
4503 // Set the abandon timeout to something high so it does not introduce
4504 // flakiness if the prerender times out before the test completes.
4505 GetPrerenderManager()->mutable_config().abandon_time_to_live =
4506 base::TimeDelta::FromDays(999);
4508 // Ensure the cookie store has been loaded.
4509 if (!GetPrerenderManager()->cookie_store_loaded()) {
4511 GetPrerenderManager()->set_on_cookie_store_loaded_cb_for_testing(
4512 loop.QuitClosure());
4516 // Enter a URL into the Omnibox.
4517 OmniboxView* omnibox_view = GetOmniboxView();
4518 omnibox_view->OnBeforePossibleChange();
4519 omnibox_view->SetUserText(
4520 base::UTF8ToUTF16(test_server()->GetURL("files/empty.html?1").spec()));
4521 omnibox_view->OnAfterPossibleChange();
4522 WaitForAutocompleteDone(omnibox_view);
4524 // Fake an omnibox prerender for a different URL.
4525 scoped_ptr<TestPrerender> prerender = StartOmniboxPrerender(
4526 test_server()->GetURL("files/empty.html?2"),
4527 FINAL_STATUS_APP_TERMINATING);
4529 // The final status may be either FINAL_STATUS_APP_TERMINATING or
4530 // FINAL_STATUS_CANCELLED. Although closing the omnibox will not cancel an
4531 // abandoned prerender, the AutocompleteActionPredictor will cancel the
4532 // predictor on destruction.
4533 prerender->contents()->set_skip_final_checks(true);
4535 // Navigate to the URL entered.
4536 omnibox_view->model()->AcceptInput(CURRENT_TAB, false);
4538 // Prerender should be running, but abandoned.
4540 GetAutocompleteActionPredictor()->IsPrerenderAbandonedForTesting());
4543 // Prefetch should be allowed depending on preference and network type.
4544 // This test is for the bsae case: no Finch overrides should never disable.
4545 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4546 LocalPredictorDisableWorksBaseCase) {
4547 TestShouldDisableLocalPredictorPreferenceNetworkMatrix(
4548 false /*preference_wifi_network_wifi*/,
4549 false /*preference_wifi_network_4g*/,
4550 false /*preference_always_network_wifi*/,
4551 false /*preference_always_network_4g*/,
4552 false /*preference_never_network_wifi*/,
4553 false /*preference_never_network_4g*/);
4556 // Prefetch should be allowed depending on preference and network type.
4557 // LocalPredictorOnCellularOnly should disable all wifi cases.
4558 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4559 LocalPredictorDisableWorksCellularOnly) {
4560 CreateTestFieldTrial("PrerenderLocalPredictorSpec",
4561 "LocalPredictorOnCellularOnly=Enabled");
4562 TestShouldDisableLocalPredictorPreferenceNetworkMatrix(
4563 true /*preference_wifi_network_wifi*/,
4564 false /*preference_wifi_network_4g*/,
4565 true /*preference_always_network_wifi*/,
4566 false /*preference_always_network_4g*/,
4567 true /*preference_never_network_wifi*/,
4568 false /*preference_never_network_4g*/);
4571 // Prefetch should be allowed depending on preference and network type.
4572 // LocalPredictorNetworkPredictionEnabledOnly should disable whenever
4573 // network predictions will not be exercised.
4574 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4575 LocalPredictorDisableWorksNetworkPredictionEnableOnly) {
4576 CreateTestFieldTrial("PrerenderLocalPredictorSpec",
4577 "LocalPredictorNetworkPredictionEnabledOnly=Enabled");
4578 TestShouldDisableLocalPredictorPreferenceNetworkMatrix(
4579 false /*preference_wifi_network_wifi*/,
4580 true /*preference_wifi_network_4g*/,
4581 false /*preference_always_network_wifi*/,
4582 false /*preference_always_network_4g*/,
4583 true /*preference_never_network_wifi*/,
4584 true /*preference_never_network_4g*/);
4587 // Prefetch should be allowed depending on preference and network type.
4588 // If LocalPredictorNetworkPredictionEnabledOnly and
4589 // LocalPredictorOnCellularOnly are both selected, we must disable whenever
4590 // network predictions are not exercised, or when we are on wifi.
4591 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
4592 LocalPredictorDisableWorksBothOptions) {
4593 CreateTestFieldTrial("PrerenderLocalPredictorSpec",
4594 "LocalPredictorOnCellularOnly=Enabled:"
4595 "LocalPredictorNetworkPredictionEnabledOnly=Enabled");
4596 TestShouldDisableLocalPredictorPreferenceNetworkMatrix(
4597 true /*preference_wifi_network_wifi*/,
4598 true /*preference_wifi_network_4g*/,
4599 true /*preference_always_network_wifi*/,
4600 false /*preference_always_network_4g*/,
4601 true /*preference_never_network_wifi*/,
4602 true /*preference_never_network_4g*/);
4605 } // namespace prerender