Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / prerender / prerender_browsertest.cc
blob9b503376443156b5b26d6f518ab801276218b931
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.
5 #include <deque>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/test/test_timeouts.h"
21 #include "base/values.h"
22 #include "chrome/browser/browsing_data/browsing_data_helper.h"
23 #include "chrome/browser/browsing_data/browsing_data_remover.h"
24 #include "chrome/browser/chrome_content_browser_client.h"
25 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/content_settings/host_content_settings_map.h"
27 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
28 #include "chrome/browser/extensions/extension_apitest.h"
29 #include "chrome/browser/external_protocol/external_protocol_handler.h"
30 #include "chrome/browser/favicon/favicon_tab_helper.h"
31 #include "chrome/browser/prerender/prerender_contents.h"
32 #include "chrome/browser/prerender/prerender_handle.h"
33 #include "chrome/browser/prerender/prerender_link_manager.h"
34 #include "chrome/browser/prerender/prerender_link_manager_factory.h"
35 #include "chrome/browser/prerender/prerender_manager.h"
36 #include "chrome/browser/prerender/prerender_manager_factory.h"
37 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/profiles/profile_io_data.h"
39 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
40 #include "chrome/browser/safe_browsing/database_manager.h"
41 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
42 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
43 #include "chrome/browser/task_manager/task_manager.h"
44 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
45 #include "chrome/browser/ui/browser.h"
46 #include "chrome/browser/ui/browser_commands.h"
47 #include "chrome/browser/ui/browser_finder.h"
48 #include "chrome/browser/ui/browser_navigator.h"
49 #include "chrome/browser/ui/browser_window.h"
50 #include "chrome/browser/ui/tabs/tab_strip_model.h"
51 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
52 #include "chrome/common/chrome_paths.h"
53 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/extensions/extension_constants.h"
55 #include "chrome/common/pref_names.h"
56 #include "chrome/test/base/in_process_browser_test.h"
57 #include "chrome/test/base/test_switches.h"
58 #include "chrome/test/base/ui_test_utils.h"
59 #include "content/public/browser/browser_message_filter.h"
60 #include "content/public/browser/devtools_agent_host.h"
61 #include "content/public/browser/devtools_client_host.h"
62 #include "content/public/browser/devtools_manager.h"
63 #include "content/public/browser/navigation_controller.h"
64 #include "content/public/browser/navigation_entry.h"
65 #include "content/public/browser/notification_service.h"
66 #include "content/public/browser/render_process_host.h"
67 #include "content/public/browser/render_view_host.h"
68 #include "content/public/browser/site_instance.h"
69 #include "content/public/browser/web_contents.h"
70 #include "content/public/browser/web_contents_observer.h"
71 #include "content/public/common/url_constants.h"
72 #include "content/public/test/browser_test_utils.h"
73 #include "content/public/test/test_navigation_observer.h"
74 #include "content/public/test/test_utils.h"
75 #include "content/test/net/url_request_mock_http_job.h"
76 #include "extensions/common/switches.h"
77 #include "grit/generated_resources.h"
78 #include "net/base/escape.h"
79 #include "net/cert/x509_certificate.h"
80 #include "net/dns/mock_host_resolver.h"
81 #include "net/ssl/client_cert_store.h"
82 #include "net/ssl/ssl_cert_request_info.h"
83 #include "net/url_request/url_request_context.h"
84 #include "net/url_request/url_request_context_getter.h"
85 #include "net/url_request/url_request_filter.h"
86 #include "net/url_request/url_request_job.h"
87 #include "ui/base/l10n/l10n_util.h"
88 #include "url/gurl.h"
90 using content::BrowserThread;
91 using content::DevToolsAgentHost;
92 using content::DevToolsClientHost;
93 using content::DevToolsManager;
94 using content::NavigationController;
95 using content::OpenURLParams;
96 using content::Referrer;
97 using content::RenderViewHost;
98 using content::RenderWidgetHost;
99 using content::TestNavigationObserver;
100 using content::WebContents;
101 using content::WebContentsObserver;
103 // Prerender tests work as follows:
105 // A page with a prefetch link to the test page is loaded. Once prerendered,
106 // its Javascript function DidPrerenderPass() is called, which returns true if
107 // the page behaves as expected when prerendered.
109 // The prerendered page is then displayed on a tab. The Javascript function
110 // DidDisplayPass() is called, and returns true if the page behaved as it
111 // should while being displayed.
113 namespace prerender {
115 namespace {
117 // Constants used in the test HTML files.
118 const char* kReadyTitle = "READY";
119 const char* kPassTitle = "PASS";
121 std::string CreateClientRedirect(const std::string& dest_url) {
122 const char* const kClientRedirectBase = "client-redirect?";
123 return kClientRedirectBase + net::EscapeQueryParamValue(dest_url, false);
126 std::string CreateServerRedirect(const std::string& dest_url) {
127 const char* const kServerRedirectBase = "server-redirect?";
128 return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false);
131 // Clears the specified data using BrowsingDataRemover.
132 void ClearBrowsingData(Browser* browser, int remove_mask) {
133 BrowsingDataRemover* remover =
134 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
135 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
136 // BrowsingDataRemover deletes itself.
139 // Returns true if the prerender is expected to abort on its own, before
140 // attempting to swap it.
141 bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) {
142 switch (status) {
143 case FINAL_STATUS_USED:
144 case FINAL_STATUS_WINDOW_OPENER:
145 case FINAL_STATUS_APP_TERMINATING:
146 case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
147 // We'll crash the renderer after it's loaded.
148 case FINAL_STATUS_RENDERER_CRASHED:
149 case FINAL_STATUS_CANCELLED:
150 case FINAL_STATUS_DEVTOOLS_ATTACHED:
151 case FINAL_STATUS_PAGE_BEING_CAPTURED:
152 case FINAL_STATUS_NAVIGATION_UNCOMMITTED:
153 case FINAL_STATUS_WOULD_HAVE_BEEN_USED:
154 return false;
155 default:
156 return true;
160 // Waits for the destruction of a RenderProcessHost's IPC channel.
161 // Used to make sure the PrerenderLinkManager's OnChannelClosed function has
162 // been called, before checking its state.
163 class ChannelDestructionWatcher {
164 public:
165 ChannelDestructionWatcher() : channel_destroyed_(false) {
168 ~ChannelDestructionWatcher() {
171 void WatchChannel(content::RenderProcessHost* host) {
172 host->AddFilter(new DestructionMessageFilter(this));
175 void WaitForChannelClose() {
176 run_loop_.Run();
177 EXPECT_TRUE(channel_destroyed_);
180 private:
181 // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed.
182 // Ignores all messages.
183 class DestructionMessageFilter : public content::BrowserMessageFilter {
184 public:
185 explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher)
186 : watcher_(watcher) {
189 private:
190 virtual ~DestructionMessageFilter() {
191 content::BrowserThread::PostTask(
192 content::BrowserThread::UI, FROM_HERE,
193 base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
194 base::Unretained(watcher_)));
197 virtual bool OnMessageReceived(const IPC::Message& message,
198 bool* message_was_ok) OVERRIDE {
199 return false;
202 ChannelDestructionWatcher* watcher_;
204 DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter);
207 void OnChannelDestroyed() {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210 EXPECT_FALSE(channel_destroyed_);
211 channel_destroyed_ = true;
212 run_loop_.Quit();
215 bool channel_destroyed_;
216 base::RunLoop run_loop_;
218 DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher);
221 // A simple observer to wait on either a load or a swap of a WebContents.
222 class NavigationOrSwapObserver : public WebContentsObserver,
223 public TabStripModelObserver {
224 public:
225 // Waits for either a load or a swap of |tab_strip_model|'s active
226 // WebContents.
227 NavigationOrSwapObserver(TabStripModel* tab_strip_model,
228 WebContents* web_contents)
229 : WebContentsObserver(web_contents),
230 tab_strip_model_(tab_strip_model) {
231 CHECK_NE(TabStripModel::kNoTab,
232 tab_strip_model->GetIndexOfWebContents(web_contents));
233 tab_strip_model_->AddObserver(this);
236 virtual ~NavigationOrSwapObserver() {
237 tab_strip_model_->RemoveObserver(this);
240 void Wait() {
241 loop_.Run();
244 // WebContentsObserver implementation:
245 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
246 loop_.Quit();
249 // TabStripModelObserver implementation:
250 virtual void TabReplacedAt(TabStripModel* tab_strip_model,
251 WebContents* old_contents,
252 WebContents* new_contents,
253 int index) OVERRIDE {
254 if (old_contents != web_contents())
255 return;
256 loop_.Quit();
259 private:
260 TabStripModel* tab_strip_model_;
261 base::RunLoop loop_;
264 // Waits for a new tab to open and a navigation or swap in it.
265 class NewTabNavigationOrSwapObserver {
266 public:
267 NewTabNavigationOrSwapObserver()
268 : new_tab_observer_(
269 chrome::NOTIFICATION_TAB_ADDED,
270 base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded,
271 base::Unretained(this))) {
272 // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the
273 // NavigationOrSwapObserver can be attached synchronously and no events are
274 // missed.
277 void Wait() {
278 new_tab_observer_.Wait();
279 swap_observer_->Wait();
282 bool OnTabAdded(const content::NotificationSource& source,
283 const content::NotificationDetails& details) {
284 if (swap_observer_)
285 return true;
286 WebContents* new_tab = content::Details<WebContents>(details).ptr();
287 // Get the TabStripModel. Assume this is attached to a Browser.
288 TabStripModel* tab_strip_model =
289 static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model();
290 swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model,
291 new_tab));
292 return true;
295 private:
296 content::WindowedNotificationObserver new_tab_observer_;
297 scoped_ptr<NavigationOrSwapObserver> swap_observer_;
300 // PrerenderContents that stops the UI message loop on DidStopLoading().
301 class TestPrerenderContents : public PrerenderContents {
302 public:
303 TestPrerenderContents(
304 PrerenderManager* prerender_manager,
305 Profile* profile,
306 const GURL& url,
307 const content::Referrer& referrer,
308 Origin origin,
309 FinalStatus expected_final_status)
310 : PrerenderContents(prerender_manager, profile, url,
311 referrer, origin, PrerenderManager::kNoExperiment),
312 expected_final_status_(expected_final_status),
313 new_render_view_host_(NULL),
314 was_hidden_(false),
315 was_shown_(false),
316 should_be_shown_(expected_final_status == FINAL_STATUS_USED),
317 expected_pending_prerenders_(0) {
320 virtual ~TestPrerenderContents() {
321 if (expected_final_status_ == FINAL_STATUS_MAX) {
322 EXPECT_EQ(match_complete_status(), MATCH_COMPLETE_REPLACEMENT);
323 } else {
324 EXPECT_EQ(expected_final_status_, final_status()) <<
325 " when testing URL " << prerender_url().path() <<
326 " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
327 ", Actual: " << NameFromFinalStatus(final_status()) << ")";
329 // Prerendering RenderViewHosts should be hidden before the first
330 // navigation, so this should be happen for every PrerenderContents for
331 // which a RenderViewHost is created, regardless of whether or not it's
332 // used.
333 if (new_render_view_host_)
334 EXPECT_TRUE(was_hidden_);
336 // A used PrerenderContents will only be destroyed when we swap out
337 // WebContents, at the end of a navigation caused by a call to
338 // NavigateToURLImpl().
339 if (final_status() == FINAL_STATUS_USED)
340 EXPECT_TRUE(new_render_view_host_);
342 EXPECT_EQ(should_be_shown_, was_shown_);
345 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
346 // On quit, it's possible to end up here when render processes are closed
347 // before the PrerenderManager is destroyed. As a result, it's possible to
348 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
349 // on quit.
351 // It's also possible for this to be called after we've been notified of
352 // app termination, but before we've been deleted, which is why the second
353 // check is needed.
354 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
355 final_status() != expected_final_status_) {
356 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
359 PrerenderContents::RenderProcessGone(status);
362 virtual bool CheckURL(const GURL& url) OVERRIDE {
363 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
364 // the PrerenderRendererCrash test.
365 if (url.spec() != content::kChromeUICrashURL)
366 return PrerenderContents::CheckURL(url);
367 return true;
370 virtual void AddPendingPrerender(
371 scoped_ptr<PendingPrerenderInfo> pending_prerender_info) OVERRIDE {
372 PrerenderContents::AddPendingPrerender(pending_prerender_info.Pass());
373 if (expected_pending_prerenders_ > 0 &&
374 pending_prerender_count() == expected_pending_prerenders_) {
375 base::MessageLoop::current()->Quit();
379 virtual WebContents* CreateWebContents(
380 content::SessionStorageNamespace* session_storage_namespace) OVERRIDE {
381 WebContents* web_contents = PrerenderContents::CreateWebContents(
382 session_storage_namespace);
383 // Create a ready title watcher. (May or may not be used.)
384 base::string16 ready_title = base::ASCIIToUTF16(kReadyTitle);
385 ready_title_watcher_.reset(new content::TitleWatcher(
386 web_contents, ready_title));
387 return web_contents;
390 void WaitForPrerenderToHaveReadyTitle() {
391 base::string16 ready_title = base::ASCIIToUTF16(kReadyTitle);
392 ASSERT_EQ(ready_title, ready_title_watcher_->WaitAndGetTitle());
395 // Waits until the prerender has |expected_pending_prerenders| pending
396 // prerenders.
397 void WaitForPendingPrerenders(size_t expected_pending_prerenders) {
398 if (pending_prerender_count() < expected_pending_prerenders) {
399 expected_pending_prerenders_ = expected_pending_prerenders;
400 content::RunMessageLoop();
401 expected_pending_prerenders_ = 0;
404 EXPECT_EQ(expected_pending_prerenders, pending_prerender_count());
407 // For tests that open the prerender in a new background tab, the RenderView
408 // will not have been made visible when the PrerenderContents is destroyed
409 // even though it is used.
410 void set_should_be_shown(bool value) { should_be_shown_ = value; }
412 FinalStatus expected_final_status() const { return expected_final_status_; }
414 private:
415 virtual void OnRenderViewHostCreated(
416 RenderViewHost* new_render_view_host) OVERRIDE {
417 // Used to make sure the RenderViewHost is hidden and, if used,
418 // subsequently shown.
419 notification_registrar().Add(
420 this,
421 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
422 content::Source<RenderWidgetHost>(new_render_view_host));
424 new_render_view_host_ = new_render_view_host;
426 PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
429 virtual void Observe(int type,
430 const content::NotificationSource& source,
431 const content::NotificationDetails& details) OVERRIDE {
432 if (type ==
433 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
434 EXPECT_EQ(new_render_view_host_,
435 content::Source<RenderWidgetHost>(source).ptr());
436 bool is_visible = *content::Details<bool>(details).ptr();
438 if (!is_visible) {
439 was_hidden_ = true;
440 } else if (is_visible && was_hidden_) {
441 // Once hidden, a prerendered RenderViewHost should only be shown after
442 // being removed from the PrerenderContents for display.
443 EXPECT_FALSE(GetRenderViewHost());
444 was_shown_ = true;
446 return;
448 PrerenderContents::Observe(type, source, details);
451 FinalStatus expected_final_status_;
453 // The RenderViewHost created for the prerender, if any.
454 RenderViewHost* new_render_view_host_;
455 // Set to true when the prerendering RenderWidget is hidden.
456 bool was_hidden_;
457 // Set to true when the prerendering RenderWidget is shown, after having been
458 // hidden.
459 bool was_shown_;
460 // Expected final value of was_shown_. Defaults to true for
461 // FINAL_STATUS_USED, and false otherwise.
462 bool should_be_shown_;
464 // Total number of pending prerenders we're currently waiting for. Zero
465 // indicates we currently aren't waiting for any.
466 size_t expected_pending_prerenders_;
468 // Will wait for the title of the prerendered page to turn to "READY".
469 scoped_ptr<content::TitleWatcher> ready_title_watcher_;
472 // A handle to a TestPrerenderContents whose lifetime is under the caller's
473 // control. A PrerenderContents may be destroyed at any point. This allows
474 // tracking the final status, etc.
475 class TestPrerender : public PrerenderContents::Observer,
476 public base::SupportsWeakPtr<TestPrerender> {
477 public:
478 TestPrerender()
479 : contents_(NULL),
480 number_of_loads_(0),
481 expected_number_of_loads_(0) {
483 virtual ~TestPrerender() {
484 if (contents_)
485 contents_->RemoveObserver(this);
488 TestPrerenderContents* contents() const { return contents_; }
489 int number_of_loads() const { return number_of_loads_; }
491 void WaitForCreate() { create_loop_.Run(); }
492 void WaitForStart() { start_loop_.Run(); }
493 void WaitForStop() { stop_loop_.Run(); }
495 // Waits for |number_of_loads()| to be at least |expected_number_of_loads| OR
496 // for the prerender to stop running (just to avoid a timeout if the prerender
497 // dies). Note: this does not assert equality on the number of loads; the
498 // caller must do it instead.
499 void WaitForLoads(int expected_number_of_loads) {
500 DCHECK(!load_waiter_);
501 DCHECK(!expected_number_of_loads_);
502 if (number_of_loads_ < expected_number_of_loads) {
503 load_waiter_.reset(new base::RunLoop);
504 expected_number_of_loads_ = expected_number_of_loads;
505 load_waiter_->Run();
506 load_waiter_.reset();
507 expected_number_of_loads_ = 0;
509 EXPECT_LE(expected_number_of_loads, number_of_loads_);
512 void OnPrerenderCreated(TestPrerenderContents* contents) {
513 DCHECK(!contents_);
514 contents_ = contents;
515 contents_->AddObserver(this);
516 create_loop_.Quit();
519 // PrerenderContents::Observer implementation:
520 virtual void OnPrerenderStart(PrerenderContents* contents) OVERRIDE {
521 start_loop_.Quit();
524 virtual void OnPrerenderStopLoading(PrerenderContents* contents) OVERRIDE {
525 number_of_loads_++;
526 if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
527 load_waiter_->Quit();
530 virtual void OnPrerenderStop(PrerenderContents* contents) OVERRIDE {
531 DCHECK(contents_);
532 contents_ = NULL;
533 stop_loop_.Quit();
534 // If there is a WaitForLoads call and it has yet to see the expected number
535 // of loads, stop the loop so the test fails instead of timing out.
536 if (load_waiter_)
537 load_waiter_->Quit();
540 virtual void OnPrerenderCreatedMatchCompleteReplacement(
541 PrerenderContents* contents, PrerenderContents* replacement) OVERRIDE {
544 private:
545 TestPrerenderContents* contents_;
546 int number_of_loads_;
548 int expected_number_of_loads_;
549 scoped_ptr<base::RunLoop> load_waiter_;
551 base::RunLoop create_loop_;
552 base::RunLoop start_loop_;
553 base::RunLoop stop_loop_;
555 DISALLOW_COPY_AND_ASSIGN(TestPrerender);
558 // PrerenderManager that uses TestPrerenderContents.
559 class TestPrerenderContentsFactory : public PrerenderContents::Factory {
560 public:
561 TestPrerenderContentsFactory() {}
563 virtual ~TestPrerenderContentsFactory() {
564 EXPECT_TRUE(expected_contents_queue_.empty());
567 scoped_ptr<TestPrerender> ExpectPrerenderContents(FinalStatus final_status) {
568 scoped_ptr<TestPrerender> handle(new TestPrerender());
569 expected_contents_queue_.push_back(
570 ExpectedContents(final_status, handle->AsWeakPtr()));
571 return handle.Pass();
574 virtual PrerenderContents* CreatePrerenderContents(
575 PrerenderManager* prerender_manager,
576 Profile* profile,
577 const GURL& url,
578 const content::Referrer& referrer,
579 Origin origin,
580 uint8 experiment_id) OVERRIDE {
581 ExpectedContents expected;
582 if (!expected_contents_queue_.empty()) {
583 expected = expected_contents_queue_.front();
584 expected_contents_queue_.pop_front();
586 VLOG(1) << "Creating prerender contents for " << url.path() <<
587 " with expected final status " << expected.final_status;
588 VLOG(1) << expected_contents_queue_.size() << " left in the queue.";
589 TestPrerenderContents* contents =
590 new TestPrerenderContents(prerender_manager,
591 profile, url, referrer, origin,
592 expected.final_status);
593 if (expected.handle)
594 expected.handle->OnPrerenderCreated(contents);
595 return contents;
598 private:
599 struct ExpectedContents {
600 ExpectedContents() : final_status(FINAL_STATUS_MAX) { }
601 ExpectedContents(FinalStatus final_status,
602 const base::WeakPtr<TestPrerender>& handle)
603 : final_status(final_status),
604 handle(handle) {
607 FinalStatus final_status;
608 base::WeakPtr<TestPrerender> handle;
611 std::deque<ExpectedContents> expected_contents_queue_;
614 #if defined(FULL_SAFE_BROWSING)
615 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
616 // a given URL.
617 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
618 public:
619 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
620 : SafeBrowsingDatabaseManager(service),
621 threat_type_(SB_THREAT_TYPE_SAFE) { }
623 // Called on the IO thread to check if the given url is safe or not. If we
624 // can synchronously determine that the url is safe, CheckUrl returns true.
625 // Otherwise it returns false, and "client" is called asynchronously with the
626 // result when it is ready.
627 // Returns true, indicating a SAFE result, unless the URL is the fixed URL
628 // specified by the user, and the user-specified result is not SAFE
629 // (in which that result will be communicated back via a call into the
630 // client, and false will be returned).
631 // Overrides SafeBrowsingService::CheckBrowseUrl.
632 virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE {
633 if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
634 return true;
636 BrowserThread::PostTask(
637 BrowserThread::IO, FROM_HERE,
638 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
639 this, gurl, client));
640 return false;
643 void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) {
644 url_ = url;
645 threat_type_ = threat_type;
648 private:
649 virtual ~FakeSafeBrowsingDatabaseManager() {}
651 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
652 std::vector<SBThreatType> expected_threats;
653 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
654 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
655 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
656 std::vector<GURL>(1, gurl),
657 std::vector<SBFullHash>(),
658 client,
659 safe_browsing_util::MALWARE,
660 expected_threats);
661 sb_check.url_results[0] = threat_type_;
662 client->OnSafeBrowsingResult(sb_check);
665 GURL url_;
666 SBThreatType threat_type_;
667 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
670 class FakeSafeBrowsingService : public SafeBrowsingService {
671 public:
672 FakeSafeBrowsingService() { }
674 // Returned pointer has the same lifespan as the database_manager_ refcounted
675 // object.
676 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
677 return fake_database_manager_;
680 protected:
681 virtual ~FakeSafeBrowsingService() { }
683 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
684 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
685 return fake_database_manager_;
688 private:
689 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
691 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
694 // Factory that creates FakeSafeBrowsingService instances.
695 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
696 public:
697 TestSafeBrowsingServiceFactory() :
698 most_recent_service_(NULL) { }
699 virtual ~TestSafeBrowsingServiceFactory() { }
701 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
702 most_recent_service_ = new FakeSafeBrowsingService();
703 return most_recent_service_;
706 FakeSafeBrowsingService* most_recent_service() const {
707 return most_recent_service_;
710 private:
711 FakeSafeBrowsingService* most_recent_service_;
713 #endif
715 class FakeDevToolsClientHost : public DevToolsClientHost {
716 public:
717 FakeDevToolsClientHost() {}
718 virtual ~FakeDevToolsClientHost() {}
719 virtual void InspectedContentsClosing() OVERRIDE {}
720 virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {}
721 virtual void ReplacedWithAnotherClient() OVERRIDE {}
724 class RestorePrerenderMode {
725 public:
726 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
729 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
730 private:
731 PrerenderManager::PrerenderManagerMode prev_mode_;
734 // URLRequestJob (and associated handler) which hangs.
735 class HangingURLRequestJob : public net::URLRequestJob {
736 public:
737 HangingURLRequestJob(net::URLRequest* request,
738 net::NetworkDelegate* network_delegate)
739 : net::URLRequestJob(request, network_delegate) {
742 virtual void Start() OVERRIDE {}
744 private:
745 virtual ~HangingURLRequestJob() {}
748 class HangingFirstRequestProtocolHandler
749 : public net::URLRequestJobFactory::ProtocolHandler {
750 public:
751 HangingFirstRequestProtocolHandler(const base::FilePath& file,
752 base::Closure callback)
753 : file_(file),
754 callback_(callback),
755 first_run_(true) {
757 virtual ~HangingFirstRequestProtocolHandler() {}
759 virtual net::URLRequestJob* MaybeCreateJob(
760 net::URLRequest* request,
761 net::NetworkDelegate* network_delegate) const OVERRIDE {
762 if (first_run_) {
763 first_run_ = false;
764 BrowserThread::PostTask(
765 BrowserThread::UI, FROM_HERE, callback_);
766 return new HangingURLRequestJob(request, network_delegate);
768 return new content::URLRequestMockHTTPJob(request, network_delegate, file_);
771 private:
772 base::FilePath file_;
773 base::Closure callback_;
774 mutable bool first_run_;
777 // Makes |url| never respond on the first load, and then with the contents of
778 // |file| afterwards. When the first load has been scheduled, runs |callback| on
779 // the UI thread.
780 void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url,
781 const base::FilePath& file,
782 base::Closure callback) {
783 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
784 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler(
785 new HangingFirstRequestProtocolHandler(file, callback));
786 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
787 url, never_respond_handler.Pass());
790 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks.
791 class MockHTTPJob : public content::URLRequestMockHTTPJob {
792 public:
793 MockHTTPJob(net::URLRequest* request,
794 net::NetworkDelegate* delegate,
795 const base::FilePath& file)
796 : content::URLRequestMockHTTPJob(request, delegate, file) {
799 void set_start_callback(const base::Closure& start_callback) {
800 start_callback_ = start_callback;
803 virtual void Start() OVERRIDE {
804 if (!start_callback_.is_null())
805 start_callback_.Run();
806 content::URLRequestMockHTTPJob::Start();
809 private:
810 virtual ~MockHTTPJob() {}
812 base::Closure start_callback_;
815 // Dummy counter class to live on the UI thread for counting requests.
816 class RequestCounter : public base::SupportsWeakPtr<RequestCounter> {
817 public:
818 RequestCounter() : count_(0) {}
819 int count() const { return count_; }
820 void RequestStarted() { count_++; }
821 private:
822 int count_;
825 // Protocol handler which counts the number of requests that start.
826 class CountingProtocolHandler
827 : public net::URLRequestJobFactory::ProtocolHandler {
828 public:
829 CountingProtocolHandler(const base::FilePath& file,
830 const base::WeakPtr<RequestCounter>& counter)
831 : file_(file),
832 counter_(counter),
833 weak_factory_(this) {
835 virtual ~CountingProtocolHandler() {}
837 virtual net::URLRequestJob* MaybeCreateJob(
838 net::URLRequest* request,
839 net::NetworkDelegate* network_delegate) const OVERRIDE {
840 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
841 job->set_start_callback(base::Bind(&CountingProtocolHandler::RequestStarted,
842 weak_factory_.GetWeakPtr()));
843 return job;
846 void RequestStarted() {
847 BrowserThread::PostTask(
848 BrowserThread::UI, FROM_HERE,
849 base::Bind(&RequestCounter::RequestStarted, counter_));
852 private:
853 base::FilePath file_;
854 base::WeakPtr<RequestCounter> counter_;
855 mutable base::WeakPtrFactory<CountingProtocolHandler> weak_factory_;
858 // Makes |url| respond to requests with the contents of |file|, counting the
859 // number that start in |counter|.
860 void CreateCountingProtocolHandlerOnIO(
861 const GURL& url,
862 const base::FilePath& file,
863 const base::WeakPtr<RequestCounter>& counter) {
864 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
865 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> protocol_handler(
866 new CountingProtocolHandler(file, counter));
867 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
868 url, protocol_handler.Pass());
871 // Makes |url| respond to requests with the contents of |file|.
872 void CreateMockProtocolHandlerOnIO(const GURL& url,
873 const base::FilePath& file) {
874 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
875 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
876 url, content::URLRequestMockHTTPJob::CreateProtocolHandlerForSingleFile(
877 file));
880 // A ContentBrowserClient that cancels all prerenderers on OpenURL.
881 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
882 public:
883 TestContentBrowserClient() {}
884 virtual ~TestContentBrowserClient() {}
886 // chrome::ChromeContentBrowserClient implementation.
887 virtual bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
888 const GURL& url) OVERRIDE {
889 PrerenderManagerFactory::GetForProfile(
890 Profile::FromBrowserContext(site_instance->GetBrowserContext()))
891 ->CancelAllPrerenders();
892 return chrome::ChromeContentBrowserClient::ShouldAllowOpenURL(site_instance,
893 url);
896 private:
897 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
900 // A ContentBrowserClient that forces cross-process navigations.
901 class SwapProcessesContentBrowserClient
902 : public chrome::ChromeContentBrowserClient {
903 public:
904 SwapProcessesContentBrowserClient() {}
905 virtual ~SwapProcessesContentBrowserClient() {}
907 // chrome::ChromeContentBrowserClient implementation.
908 virtual bool ShouldSwapProcessesForRedirect(
909 content::ResourceContext* resource_context,
910 const GURL& current_url,
911 const GURL& new_url) OVERRIDE {
912 return true;
915 private:
916 DISALLOW_COPY_AND_ASSIGN(SwapProcessesContentBrowserClient);
919 // An ExternalProtocolHandler that blocks everything and asserts it never is
920 // called.
921 class NeverRunsExternalProtocolHandlerDelegate
922 : public ExternalProtocolHandler::Delegate {
923 public:
924 // ExternalProtocolHandler::Delegate implementation.
925 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
926 ShellIntegration::DefaultWebClientObserver* observer,
927 const std::string& protocol) OVERRIDE {
928 NOTREACHED();
929 // This will crash, but it shouldn't get this far with BlockState::BLOCK
930 // anyway.
931 return NULL;
933 virtual ExternalProtocolHandler::BlockState GetBlockState(
934 const std::string& scheme) OVERRIDE {
935 // Block everything and fail the test.
936 ADD_FAILURE();
937 return ExternalProtocolHandler::BLOCK;
939 virtual void BlockRequest() OVERRIDE { }
940 virtual void RunExternalProtocolDialog(const GURL& url,
941 int render_process_host_id,
942 int routing_id) OVERRIDE {
943 NOTREACHED();
945 virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE {
946 NOTREACHED();
948 virtual void FinishedProcessingCheck() OVERRIDE {
949 NOTREACHED();
953 base::FilePath GetTestPath(const std::string& file_name) {
954 return ui_test_utils::GetTestFilePath(
955 base::FilePath(FILE_PATH_LITERAL("prerender")),
956 base::FilePath().AppendASCII(file_name));
959 } // namespace
961 // Many of these tests are flaky. See http://crbug.com/249179
962 class PrerenderBrowserTest : virtual public InProcessBrowserTest {
963 public:
964 PrerenderBrowserTest()
965 : autostart_test_server_(true),
966 prerender_contents_factory_(NULL),
967 #if defined(FULL_SAFE_BROWSING)
968 safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
969 #endif
970 use_https_src_server_(false),
971 call_javascript_(true),
972 check_load_events_(true),
973 loader_path_("files/prerender/prerender_loader.html"),
974 explicitly_set_browser_(NULL) {}
976 virtual ~PrerenderBrowserTest() {}
978 content::SessionStorageNamespace* GetSessionStorageNamespace() const {
979 WebContents* web_contents =
980 current_browser()->tab_strip_model()->GetActiveWebContents();
981 if (!web_contents)
982 return NULL;
983 return web_contents->GetController().GetDefaultSessionStorageNamespace();
986 virtual void SetUp() OVERRIDE {
987 // TODO(danakj): The GPU Video Decoder needs real GL bindings.
988 // crbug.com/269087
989 UseRealGLBindings();
991 InProcessBrowserTest::SetUp();
994 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
995 #if defined(FULL_SAFE_BROWSING)
996 SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
997 #endif
1000 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
1001 #if defined(FULL_SAFE_BROWSING)
1002 SafeBrowsingService::RegisterFactory(NULL);
1003 #endif
1006 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1007 command_line->AppendSwitchASCII(switches::kPrerenderMode,
1008 switches::kPrerenderModeSwitchValueEnabled);
1009 #if defined(OS_MACOSX)
1010 // The plugins directory isn't read by default on the Mac, so it needs to be
1011 // explicitly registered.
1012 base::FilePath app_dir;
1013 PathService::Get(chrome::DIR_APP, &app_dir);
1014 command_line->AppendSwitchPath(
1015 switches::kExtraPluginDir,
1016 app_dir.Append(FILE_PATH_LITERAL("plugins")));
1017 #endif
1018 command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
1021 virtual void SetUpOnMainThread() OVERRIDE {
1022 current_browser()->profile()->GetPrefs()->SetBoolean(
1023 prefs::kPromptForDownload, false);
1024 IncreasePrerenderMemory();
1025 if (autostart_test_server_)
1026 ASSERT_TRUE(test_server()->Start());
1027 ChromeResourceDispatcherHostDelegate::
1028 SetExternalProtocolHandlerDelegateForTesting(
1029 &external_protocol_handler_delegate_);
1032 // Overload for a single expected final status
1033 scoped_ptr<TestPrerender> PrerenderTestURL(
1034 const std::string& html_file,
1035 FinalStatus expected_final_status,
1036 int expected_number_of_loads) {
1037 return PrerenderTestURL(html_file,
1038 expected_final_status,
1039 expected_number_of_loads,
1040 false);
1043 scoped_ptr<TestPrerender> PrerenderTestURL(
1044 const std::string& html_file,
1045 FinalStatus expected_final_status,
1046 int expected_number_of_loads,
1047 bool prerender_should_wait_for_ready_title) {
1048 std::vector<FinalStatus> expected_final_status_queue(
1049 1, expected_final_status);
1050 std::vector<TestPrerender*> prerenders;
1051 PrerenderTestURL(
1052 html_file,
1053 expected_final_status_queue,
1054 expected_number_of_loads,
1055 prerender_should_wait_for_ready_title).release(&prerenders);
1056 CHECK_EQ(1u, prerenders.size());
1057 return scoped_ptr<TestPrerender>(prerenders[0]);
1060 ScopedVector<TestPrerender> PrerenderTestURL(
1061 const std::string& html_file,
1062 const std::vector<FinalStatus>& expected_final_status_queue,
1063 int expected_number_of_loads,
1064 bool prerender_should_wait_for_ready_title) {
1065 GURL url = test_server()->GetURL(html_file);
1066 return PrerenderTestURLImpl(url, url,
1067 expected_final_status_queue,
1068 expected_number_of_loads,
1069 prerender_should_wait_for_ready_title);
1072 ScopedVector<TestPrerender> PrerenderTestURL(
1073 const std::string& html_file,
1074 const std::vector<FinalStatus>& expected_final_status_queue,
1075 int expected_number_of_loads) {
1076 return PrerenderTestURL(html_file, expected_final_status_queue,
1077 expected_number_of_loads, false);
1080 scoped_ptr<TestPrerender> PrerenderTestURL(
1081 const GURL& url,
1082 FinalStatus expected_final_status,
1083 int expected_number_of_loads) {
1084 std::vector<FinalStatus> expected_final_status_queue(
1085 1, expected_final_status);
1086 std::vector<TestPrerender*> prerenders;
1087 PrerenderTestURLImpl(url, url,
1088 expected_final_status_queue,
1089 expected_number_of_loads,
1090 false).release(&prerenders);
1091 CHECK_EQ(1u, prerenders.size());
1092 return scoped_ptr<TestPrerender>(prerenders[0]);
1095 scoped_ptr<TestPrerender> PrerenderTestURL(
1096 const GURL& prerender_url,
1097 const GURL& destination_url,
1098 FinalStatus expected_final_status,
1099 int expected_number_of_loads) {
1100 std::vector<FinalStatus> expected_final_status_queue(
1101 1, expected_final_status);
1102 std::vector<TestPrerender*> prerenders;
1103 PrerenderTestURLImpl(prerender_url, destination_url,
1104 expected_final_status_queue,
1105 expected_number_of_loads,
1106 false).release(&prerenders);
1107 CHECK_EQ(1u, prerenders.size());
1108 return scoped_ptr<TestPrerender>(prerenders[0]);
1111 void NavigateToDestURL() const {
1112 NavigateToDestURLWithDisposition(CURRENT_TAB, true);
1115 // Opens the url in a new tab, with no opener.
1116 void NavigateToDestURLWithDisposition(
1117 WindowOpenDisposition disposition,
1118 bool expect_swap_to_succeed) const {
1119 NavigateToURLWithParams(
1120 content::OpenURLParams(dest_url_, Referrer(), disposition,
1121 content::PAGE_TRANSITION_TYPED, false),
1122 expect_swap_to_succeed);
1125 void NavigateToDestUrlAndWaitForPassTitle() {
1126 base::string16 expected_title = base::ASCIIToUTF16(kPassTitle);
1127 content::TitleWatcher title_watcher(
1128 GetPrerenderContents()->prerender_contents(),
1129 expected_title);
1130 NavigateToDestURL();
1131 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1134 void NavigateToURL(const std::string& dest_html_file) const {
1135 NavigateToURLWithDisposition(dest_html_file, CURRENT_TAB, true);
1138 void NavigateToURLWithDisposition(const std::string& dest_html_file,
1139 WindowOpenDisposition disposition,
1140 bool expect_swap_to_succeed) const {
1141 GURL dest_url = test_server()->GetURL(dest_html_file);
1142 NavigateToURLWithDisposition(dest_url, disposition, expect_swap_to_succeed);
1145 void NavigateToURLWithDisposition(const GURL& dest_url,
1146 WindowOpenDisposition disposition,
1147 bool expect_swap_to_succeed) const {
1148 NavigateToURLWithParams(
1149 content::OpenURLParams(dest_url, Referrer(), disposition,
1150 content::PAGE_TRANSITION_TYPED, false),
1151 expect_swap_to_succeed);
1154 void NavigateToURLWithParams(const content::OpenURLParams& params,
1155 bool expect_swap_to_succeed) const {
1156 NavigateToURLImpl(params, expect_swap_to_succeed);
1159 void OpenDestURLViaClick() const {
1160 OpenDestURLWithJSImpl("Click()", false);
1163 void OpenDestURLViaClickTarget() const {
1164 OpenDestURLWithJSImpl("ClickTarget()", true);
1167 void OpenDestURLViaClickNewWindow() const {
1168 OpenDestURLWithJSImpl("ShiftClick()", true);
1171 void OpenDestURLViaClickNewForegroundTab() const {
1172 #if defined(OS_MACOSX)
1173 OpenDestURLWithJSImpl("MetaShiftClick()", true);
1174 #else
1175 OpenDestURLWithJSImpl("CtrlShiftClick()", true);
1176 #endif
1179 void OpenDestURLViaClickNewBackgroundTab() const {
1180 TestPrerenderContents* prerender_contents = GetPrerenderContents();
1181 ASSERT_TRUE(prerender_contents != NULL);
1182 prerender_contents->set_should_be_shown(false);
1183 #if defined(OS_MACOSX)
1184 OpenDestURLWithJSImpl("MetaClick()", true);
1185 #else
1186 OpenDestURLWithJSImpl("CtrlClick()", true);
1187 #endif
1190 void OpenDestURLViaWindowOpen() const {
1191 OpenDestURLWithJSImpl("WindowOpen()", true);
1194 void RemoveLinkElement(int i) const {
1195 current_browser()->tab_strip_model()->GetActiveWebContents()->
1196 GetRenderViewHost()->ExecuteJavascriptInWebFrame(
1197 base::string16(),
1198 base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i)));
1201 void ClickToNextPageAfterPrerender() {
1202 content::WindowedNotificationObserver new_page_observer(
1203 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
1204 content::NotificationService::AllSources());
1205 RenderViewHost* render_view_host = current_browser()->tab_strip_model()->
1206 GetActiveWebContents()->GetRenderViewHost();
1207 render_view_host->ExecuteJavascriptInWebFrame(
1208 base::string16(),
1209 base::ASCIIToUTF16("ClickOpenLink()"));
1210 new_page_observer.Wait();
1213 void NavigateToNextPageAfterPrerender() const {
1214 ui_test_utils::NavigateToURL(
1215 current_browser(),
1216 test_server()->GetURL("files/prerender/prerender_page.html"));
1219 // Called after the prerendered page has been navigated to and then away from.
1220 // Navigates back through the history to the prerendered page.
1221 void GoBackToPrerender() {
1222 content::WindowedNotificationObserver back_nav_observer(
1223 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
1224 content::NotificationService::AllSources());
1225 chrome::GoBack(current_browser(), CURRENT_TAB);
1226 back_nav_observer.Wait();
1227 bool original_prerender_page = false;
1228 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1229 current_browser()->tab_strip_model()->GetActiveWebContents(),
1230 "window.domAutomationController.send(IsOriginalPrerenderPage())",
1231 &original_prerender_page));
1232 EXPECT_TRUE(original_prerender_page);
1235 // Goes back to the page that was active before the prerender was swapped
1236 // in. This must be called when the prerendered page is the current page
1237 // in the active tab.
1238 void GoBackToPageBeforePrerender() {
1239 WebContents* tab =
1240 current_browser()->tab_strip_model()->GetActiveWebContents();
1241 ASSERT_TRUE(tab);
1242 EXPECT_FALSE(tab->IsLoading());
1243 TestNavigationObserver back_nav_observer(tab);
1244 chrome::GoBack(current_browser(), CURRENT_TAB);
1245 back_nav_observer.Wait();
1246 bool js_result;
1247 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1248 tab,
1249 "window.domAutomationController.send(DidBackToOriginalPagePass())",
1250 &js_result));
1251 EXPECT_TRUE(js_result);
1254 bool UrlIsInPrerenderManager(const std::string& html_file) const {
1255 return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
1258 bool UrlIsInPrerenderManager(const GURL& url) const {
1259 return GetPrerenderManager()->FindPrerenderData(
1260 url, GetSessionStorageNamespace()) != NULL;
1263 void set_use_https_src(bool use_https_src_server) {
1264 use_https_src_server_ = use_https_src_server;
1267 void DisableJavascriptCalls() {
1268 call_javascript_ = false;
1271 void DisableLoadEventCheck() {
1272 check_load_events_ = false;
1275 TaskManagerModel* GetModel() const {
1276 return TaskManager::GetInstance()->model();
1279 PrerenderManager* GetPrerenderManager() const {
1280 PrerenderManager* prerender_manager =
1281 PrerenderManagerFactory::GetForProfile(current_browser()->profile());
1282 return prerender_manager;
1285 const PrerenderLinkManager* GetPrerenderLinkManager() const {
1286 PrerenderLinkManager* prerender_link_manager =
1287 PrerenderLinkManagerFactory::GetForProfile(
1288 current_browser()->profile());
1289 return prerender_link_manager;
1292 bool DidReceivePrerenderStartEventForLinkNumber(int index) const {
1293 bool received_prerender_started;
1294 std::string expression = base::StringPrintf(
1295 "window.domAutomationController.send(Boolean("
1296 "receivedPrerenderStartEvents[%d]))", index);
1298 CHECK(content::ExecuteScriptAndExtractBool(
1299 current_browser()->tab_strip_model()->GetActiveWebContents(),
1300 expression,
1301 &received_prerender_started));
1302 return received_prerender_started;
1305 int GetPrerenderLoadEventCountForLinkNumber(int index) const {
1306 int load_event_count;
1307 std::string expression = base::StringPrintf(
1308 "window.domAutomationController.send("
1309 "receivedPrerenderLoadEvents[%d] || 0)", index);
1311 CHECK(content::ExecuteScriptAndExtractInt(
1312 current_browser()->tab_strip_model()->GetActiveWebContents(),
1313 expression,
1314 &load_event_count));
1315 return load_event_count;
1318 bool DidReceivePrerenderStopEventForLinkNumber(int index) const {
1319 bool received_prerender_stopped;
1320 std::string expression = base::StringPrintf(
1321 "window.domAutomationController.send(Boolean("
1322 "receivedPrerenderStopEvents[%d]))", index);
1324 CHECK(content::ExecuteScriptAndExtractBool(
1325 current_browser()->tab_strip_model()->GetActiveWebContents(),
1326 expression,
1327 &received_prerender_stopped));
1328 return received_prerender_stopped;
1331 bool HadPrerenderEventErrors() const {
1332 bool had_prerender_event_errors;
1333 CHECK(content::ExecuteScriptAndExtractBool(
1334 current_browser()->tab_strip_model()->GetActiveWebContents(),
1335 "window.domAutomationController.send(Boolean("
1336 " hadPrerenderEventErrors))",
1337 &had_prerender_event_errors));
1338 return had_prerender_event_errors;
1341 // Asserting on this can result in flaky tests. PrerenderHandles are
1342 // removed from the PrerenderLinkManager when the prerender is canceled from
1343 // the browser, when the prerenders are cancelled from the renderer process,
1344 // or the channel for the renderer process is closed on the IO thread. In the
1345 // last case, the code must be careful to wait for the channel to close, as it
1346 // is done asynchronously after swapping out the old process. See
1347 // ChannelDestructionWatcher.
1348 bool IsEmptyPrerenderLinkManager() const {
1349 return GetPrerenderLinkManager()->IsEmpty();
1352 // Returns length of |prerender_manager_|'s history, or -1 on failure.
1353 int GetHistoryLength() const {
1354 scoped_ptr<base::DictionaryValue> prerender_dict(
1355 static_cast<base::DictionaryValue*>(
1356 GetPrerenderManager()->GetAsValue()));
1357 if (!prerender_dict.get())
1358 return -1;
1359 base::ListValue* history_list;
1360 if (!prerender_dict->GetList("history", &history_list))
1361 return -1;
1362 return static_cast<int>(history_list->GetSize());
1365 #if defined(FULL_SAFE_BROWSING)
1366 FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() {
1367 return safe_browsing_factory_->most_recent_service()->
1368 fake_database_manager();
1370 #endif
1372 TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const {
1373 PrerenderManager::PrerenderData* prerender_data =
1374 GetPrerenderManager()->FindPrerenderData(url, NULL);
1375 return static_cast<TestPrerenderContents*>(
1376 prerender_data ? prerender_data->contents() : NULL);
1379 TestPrerenderContents* GetPrerenderContents() const {
1380 return GetPrerenderContentsFor(dest_url_);
1383 void set_loader_path(const std::string& path) {
1384 loader_path_ = path;
1387 void set_loader_query_and_fragment(const std::string& query_and_fragment) {
1388 loader_query_and_fragment_ = query_and_fragment;
1391 GURL GetCrossDomainTestUrl(const std::string& path) {
1392 static const std::string secondary_domain = "www.foo.com";
1393 host_resolver()->AddRule(secondary_domain, "127.0.0.1");
1394 std::string url_str(base::StringPrintf(
1395 "http://%s:%d/%s",
1396 secondary_domain.c_str(),
1397 test_server()->host_port_pair().port(),
1398 path.c_str()));
1399 return GURL(url_str);
1402 void set_browser(Browser* browser) {
1403 explicitly_set_browser_ = browser;
1406 Browser* current_browser() const {
1407 return explicitly_set_browser_ ? explicitly_set_browser_ : browser();
1410 const GURL& dest_url() const {
1411 return dest_url_;
1414 void IncreasePrerenderMemory() {
1415 // Increase the memory allowed in a prerendered page above normal settings.
1416 // Debug build bots occasionally run against the default limit, and tests
1417 // were failing because the prerender was canceled due to memory exhaustion.
1418 // http://crbug.com/93076
1419 GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024;
1422 bool DidPrerenderPass(WebContents* web_contents) const {
1423 bool prerender_test_result = false;
1424 if (!content::ExecuteScriptAndExtractBool(
1425 web_contents,
1426 "window.domAutomationController.send(DidPrerenderPass())",
1427 &prerender_test_result))
1428 return false;
1429 return prerender_test_result;
1432 bool DidDisplayPass(WebContents* web_contents) const {
1433 bool display_test_result = false;
1434 if (!content::ExecuteScriptAndExtractBool(
1435 web_contents,
1436 "window.domAutomationController.send(DidDisplayPass())",
1437 &display_test_result))
1438 return false;
1439 return display_test_result;
1442 protected:
1443 bool autostart_test_server_;
1445 private:
1446 ScopedVector<TestPrerender> PrerenderTestURLImpl(
1447 const GURL& prerender_url,
1448 const GURL& destination_url,
1449 const std::vector<FinalStatus>& expected_final_status_queue,
1450 int expected_number_of_loads,
1451 bool prerender_should_wait_for_ready_title) {
1452 dest_url_ = destination_url;
1454 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
1455 replacement_text.push_back(
1456 make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
1457 replacement_text.push_back(
1458 make_pair("REPLACE_WITH_DESTINATION_URL", destination_url.spec()));
1459 std::string replacement_path;
1460 CHECK(net::SpawnedTestServer::GetFilePathWithReplacements(
1461 loader_path_,
1462 replacement_text,
1463 &replacement_path));
1465 const net::SpawnedTestServer* src_server = test_server();
1466 scoped_ptr<net::SpawnedTestServer> https_src_server;
1467 if (use_https_src_server_) {
1468 https_src_server.reset(
1469 new net::SpawnedTestServer(
1470 net::SpawnedTestServer::TYPE_HTTPS,
1471 net::SpawnedTestServer::kLocalhost,
1472 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
1473 CHECK(https_src_server->Start());
1474 src_server = https_src_server.get();
1476 GURL loader_url = src_server->GetURL(replacement_path +
1477 loader_query_and_fragment_);
1479 PrerenderManager* prerender_manager = GetPrerenderManager();
1480 CHECK(prerender_manager);
1481 prerender_manager->mutable_config().rate_limit_enabled = false;
1482 CHECK(prerender_contents_factory_ == NULL);
1483 prerender_contents_factory_ = new TestPrerenderContentsFactory;
1484 prerender_manager->SetPrerenderContentsFactory(prerender_contents_factory_);
1486 VLOG(1) << "Running test with queue length " <<
1487 expected_final_status_queue.size();
1488 CHECK(!expected_final_status_queue.empty());
1489 ScopedVector<TestPrerender> prerenders;
1490 for (size_t i = 0; i < expected_final_status_queue.size(); i++) {
1491 prerenders.push_back(
1492 prerender_contents_factory_->ExpectPrerenderContents(
1493 expected_final_status_queue[i]).release());
1496 FinalStatus expected_final_status = expected_final_status_queue.front();
1498 // Navigate to the loader URL and then wait for the first prerender to be
1499 // created.
1500 ui_test_utils::NavigateToURL(current_browser(), loader_url);
1501 prerenders[0]->WaitForCreate();
1502 prerenders[0]->WaitForLoads(expected_number_of_loads);
1504 if (ShouldAbortPrerenderBeforeSwap(expected_final_status)) {
1505 // The prerender will abort on its own. Assert it does so correctly.
1506 prerenders[0]->WaitForStop();
1507 EXPECT_FALSE(prerenders[0]->contents());
1508 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
1509 } else {
1510 // Otherwise, check that it prerendered correctly.
1511 TestPrerenderContents* prerender_contents = prerenders[0]->contents();
1513 CHECK_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1514 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
1515 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1517 if (call_javascript_) {
1518 // Wait for the prerendered page to change title to signal it is ready
1519 // if required.
1520 if (prerender_should_wait_for_ready_title)
1521 prerender_contents->WaitForPrerenderToHaveReadyTitle();
1523 // Check if page behaves as expected while in prerendered state.
1524 EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents()));
1528 // Test that the referring page received the right start and load events.
1529 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1530 if (check_load_events_) {
1531 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads());
1532 EXPECT_EQ(expected_number_of_loads,
1533 GetPrerenderLoadEventCountForLinkNumber(0));
1535 EXPECT_FALSE(HadPrerenderEventErrors());
1537 return prerenders.Pass();
1540 void NavigateToURLImpl(const content::OpenURLParams& params,
1541 bool expect_swap_to_succeed) const {
1542 ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager());
1543 // Make sure in navigating we have a URL to use in the PrerenderManager.
1544 ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
1546 // If opening the page in a background tab, it won't be shown when swapped
1547 // in.
1548 if (params.disposition == NEW_BACKGROUND_TAB)
1549 GetPrerenderContents()->set_should_be_shown(false);
1551 WebContents* web_contents = GetPrerenderContents()->prerender_contents();
1553 // Navigate and wait for either the load to finish normally or for a swap to
1554 // occur.
1555 // TODO(davidben): The only handles CURRENT_TAB navigations, which is the
1556 // only case tested or prerendered right now.
1557 CHECK_EQ(CURRENT_TAB, params.disposition);
1558 NavigationOrSwapObserver swap_observer(
1559 current_browser()->tab_strip_model(),
1560 current_browser()->tab_strip_model()->GetActiveWebContents());
1561 WebContents* target_web_contents = current_browser()->OpenURL(params);
1562 swap_observer.Wait();
1564 if (web_contents && expect_swap_to_succeed) {
1565 EXPECT_EQ(web_contents, target_web_contents);
1566 if (call_javascript_)
1567 EXPECT_TRUE(DidDisplayPass(web_contents));
1571 // Opens the prerendered page using javascript functions in the loader
1572 // page. |javascript_function_name| should be a 0 argument function which is
1573 // invoked. |new_web_contents| is true if the navigation is expected to
1574 // happen in a new WebContents via OpenURL.
1575 void OpenDestURLWithJSImpl(const std::string& javascript_function_name,
1576 bool new_web_contents) const {
1577 TestPrerenderContents* prerender_contents = GetPrerenderContents();
1578 ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1580 WebContents* web_contents = current_browser()->tab_strip_model()->
1581 GetActiveWebContents();
1582 RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
1584 if (new_web_contents) {
1585 NewTabNavigationOrSwapObserver observer;
1586 render_view_host->ExecuteJavascriptInWebFrame(
1587 base::string16(), base::ASCIIToUTF16(javascript_function_name));
1588 observer.Wait();
1589 } else {
1590 NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
1591 web_contents);
1592 render_view_host->ExecuteJavascriptInWebFrame(
1593 base::string16(), base::ASCIIToUTF16(javascript_function_name));
1594 observer.Wait();
1598 TestPrerenderContentsFactory* prerender_contents_factory_;
1599 #if defined(FULL_SAFE_BROWSING)
1600 scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_;
1601 #endif
1602 NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_;
1603 GURL dest_url_;
1604 bool use_https_src_server_;
1605 bool call_javascript_;
1606 bool check_load_events_;
1607 std::string loader_path_;
1608 std::string loader_query_and_fragment_;
1609 Browser* explicitly_set_browser_;
1612 // Checks that a page is correctly prerendered in the case of a
1613 // <link rel=prerender> tag and then loaded into a tab in response to a
1614 // navigation.
1615 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
1616 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1618 ChannelDestructionWatcher channel_close_watcher;
1619 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1620 GetActiveWebContents()->GetRenderProcessHost());
1621 NavigateToDestURL();
1622 channel_close_watcher.WaitForChannelClose();
1624 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1627 // Checks that pending prerenders launch and receive proper event treatment.
1628 // Disabled due to http://crbug.com/167792
1629 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderPagePending) {
1630 std::vector<FinalStatus> expected_final_status_queue;
1631 expected_final_status_queue.push_back(FINAL_STATUS_USED);
1632 expected_final_status_queue.push_back(FINAL_STATUS_USED);
1633 PrerenderTestURL("files/prerender/prerender_page_pending.html",
1634 expected_final_status_queue, 1);
1636 ChannelDestructionWatcher first_channel_close_watcher;
1638 first_channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1639 GetActiveWebContents()->GetRenderProcessHost());
1640 NavigateToDestURL();
1641 // NavigateToDestURL doesn't run a message loop. Normally that's fine, but in
1642 // this case, we need the pending prerenders to start.
1643 content::RunMessageLoop();
1644 first_channel_close_watcher.WaitForChannelClose();
1646 const GURL prerender_page_url =
1647 test_server()->GetURL("files/prerender/prerender_page.html");
1648 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1649 EXPECT_NE(static_cast<TestPrerenderContents*>(NULL),
1650 GetPrerenderContentsFor(prerender_page_url));
1652 // Now navigate to our target page.
1653 ChannelDestructionWatcher second_channel_close_watcher;
1654 second_channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1655 GetActiveWebContents()->GetRenderProcessHost());
1656 ui_test_utils::NavigateToURLWithDisposition(
1657 current_browser(), prerender_page_url, CURRENT_TAB,
1658 ui_test_utils::BROWSER_TEST_NONE);
1659 second_channel_close_watcher.WaitForChannelClose();
1661 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1664 // Checks that pending prerenders which are canceled before they are launched
1665 // never get started.
1666 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) {
1667 PrerenderTestURL("files/prerender/prerender_page_removes_pending.html",
1668 FINAL_STATUS_USED, 1);
1670 ChannelDestructionWatcher channel_close_watcher;
1671 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1672 GetActiveWebContents()->GetRenderProcessHost());
1673 NavigateToDestURL();
1674 channel_close_watcher.WaitForChannelClose();
1676 EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1));
1677 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1678 EXPECT_FALSE(HadPrerenderEventErrors());
1679 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1680 // calls did a thread/process hop to the renderer which insured pending
1681 // renderer events have arrived.
1682 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1685 // Flaky, http://crbug.com/167340.
1686 IN_PROC_BROWSER_TEST_F(
1687 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLink) {
1688 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1689 set_loader_query_and_fragment("?links_to_insert=1");
1690 PrerenderTestURL("files/prerender/prerender_page.html",
1691 FINAL_STATUS_CANCELLED, 1);
1693 // No ChannelDestructionWatcher is needed here, since prerenders in the
1694 // PrerenderLinkManager should be deleted by removing the links, rather than
1695 // shutting down the renderer process.
1696 RemoveLinkElement(0);
1697 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1698 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1699 EXPECT_FALSE(HadPrerenderEventErrors());
1700 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1701 // calls did a thread/process hop to the renderer which insured pending
1702 // renderer events have arrived.
1703 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1706 // Flaky, http://crbug.com/167340.
1707 IN_PROC_BROWSER_TEST_F(
1708 PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLinkWithTwoLinks) {
1709 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1710 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1712 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1713 set_loader_query_and_fragment("?links_to_insert=2");
1714 PrerenderTestURL("files/prerender/prerender_page.html",
1715 FINAL_STATUS_CANCELLED, 1);
1716 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1717 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1718 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1719 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1721 RemoveLinkElement(0);
1722 RemoveLinkElement(1);
1723 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1724 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1725 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1726 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1727 EXPECT_FALSE(HadPrerenderEventErrors());
1728 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1729 // calls did a thread/process hop to the renderer which insured pending
1730 // renderer events have arrived.
1731 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1734 #if defined(OS_WIN)
1735 // TODO(gavinp): Fails on XP Rel - http://crbug.com/128841
1736 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1737 DISABLED_PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1738 #else
1739 #define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1740 PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1741 #endif // defined(OS_WIN)
1742 IN_PROC_BROWSER_TEST_F(
1743 PrerenderBrowserTest,
1744 MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne) {
1745 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1746 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1747 set_loader_path("files/prerender/prerender_loader_removing_links.html");
1748 set_loader_query_and_fragment("?links_to_insert=2");
1749 PrerenderTestURL("files/prerender/prerender_page.html",
1750 FINAL_STATUS_USED, 1);
1751 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1752 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1753 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1754 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1756 RemoveLinkElement(0);
1757 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1758 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1759 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1760 EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1761 EXPECT_FALSE(HadPrerenderEventErrors());
1762 // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1763 // calls did a thread/process hop to the renderer which insured pending
1764 // renderer events have arrived.
1765 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1767 ChannelDestructionWatcher channel_close_watcher;
1768 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1769 GetActiveWebContents()->GetRenderProcessHost());
1770 NavigateToDestURL();
1771 channel_close_watcher.WaitForChannelClose();
1773 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1776 // Checks that prerendering works in incognito mode.
1777 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIncognito) {
1778 Profile* normal_profile = current_browser()->profile();
1779 set_browser(
1780 ui_test_utils::OpenURLOffTheRecord(normal_profile, GURL("about:blank")));
1781 // Increase memory expectations on the incognito PrerenderManager.
1782 IncreasePrerenderMemory();
1783 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1784 NavigateToDestURL();
1787 // Checks that the visibility API works.
1788 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1789 DISABLED_PrerenderVisibility) {
1790 PrerenderTestURL("files/prerender/prerender_visibility.html",
1791 FINAL_STATUS_USED,
1793 NavigateToDestURL();
1796 // Checks that the prerendering of a page is canceled correctly if we try to
1797 // swap it in before it commits.
1798 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) {
1799 // Navigate to a page that triggers a prerender for a URL that never commits.
1800 const GURL kNoCommitUrl("http://never-respond.example.com");
1801 base::FilePath file(GetTestPath("prerender_page.html"));
1803 base::RunLoop prerender_start_loop;
1804 BrowserThread::PostTask(
1805 BrowserThread::IO, FROM_HERE,
1806 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO,
1807 kNoCommitUrl, file, prerender_start_loop.QuitClosure()));
1808 DisableJavascriptCalls();
1809 PrerenderTestURL(kNoCommitUrl,
1810 FINAL_STATUS_NAVIGATION_UNCOMMITTED,
1812 // Wait for the hanging request to be scheduled.
1813 prerender_start_loop.Run();
1815 // Navigate to the URL, but assume the contents won't be swapped in.
1816 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
1819 // Checks that client redirects don't add alias URLs until after they commit.
1820 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) {
1821 // Navigate to a page that then navigates to a URL that never commits.
1822 const GURL kNoCommitUrl("http://never-respond.example.com");
1823 base::FilePath file(GetTestPath("prerender_page.html"));
1825 base::RunLoop prerender_start_loop;
1826 BrowserThread::PostTask(
1827 BrowserThread::IO, FROM_HERE,
1828 base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO,
1829 kNoCommitUrl, file, prerender_start_loop.QuitClosure()));
1830 DisableJavascriptCalls();
1831 PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()),
1832 FINAL_STATUS_APP_TERMINATING, 1);
1833 // Wait for the hanging request to be scheduled.
1834 prerender_start_loop.Run();
1836 // Navigating to the second URL should not swap.
1837 NavigateToURLWithDisposition(kNoCommitUrl, CURRENT_TAB, false);
1840 // Checks that the prerendering of a page is canceled correctly when a
1841 // Javascript alert is called.
1842 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
1843 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
1844 FINAL_STATUS_JAVASCRIPT_ALERT,
1848 // Checks that the prerendering of a page is canceled correctly when a
1849 // Javascript alert is called.
1850 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
1851 PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
1852 FINAL_STATUS_JAVASCRIPT_ALERT,
1856 // Checks that plugins are not loaded while a page is being preloaded, but
1857 // are loaded when the page is displayed.
1858 #if defined(USE_AURA) && !defined(OS_WIN)
1859 // http://crbug.com/103496
1860 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1861 #elif defined(OS_MACOSX)
1862 // http://crbug.com/100514
1863 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1864 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
1865 // TODO(jschuh): Failing plugin tests. crbug.com/244653
1866 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1867 #elif defined(OS_LINUX)
1868 // http://crbug.com/306715
1869 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1870 #else
1871 #define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin
1872 #endif
1873 // http://crbug.com/306715
1874 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) {
1875 PrerenderTestURL("files/prerender/plugin_delay_load.html",
1876 FINAL_STATUS_USED,
1878 NavigateToDestURL();
1881 // Checks that plugins are not loaded on prerendering pages when click-to-play
1882 // is enabled.
1883 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) {
1884 // Enable click-to-play.
1885 HostContentSettingsMap* content_settings_map =
1886 current_browser()->profile()->GetHostContentSettingsMap();
1887 content_settings_map->SetDefaultContentSetting(
1888 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK);
1890 PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html",
1891 FINAL_STATUS_USED,
1893 NavigateToDestURL();
1896 // Checks that we don't load a NaCl plugin when NaCl is disabled.
1897 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) {
1898 PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html",
1899 FINAL_STATUS_USED,
1901 NavigateToDestURL();
1904 // Run this check again. When we try to load aa ppapi plugin, the
1905 // "loadstart" event is asynchronously posted to a message loop.
1906 // It's possible that earlier call could have been run before the
1907 // the "loadstart" event was posted.
1908 // TODO(mmenke): While this should reliably fail on regressions, the
1909 // reliability depends on the specifics of ppapi plugin
1910 // loading. It would be great if we could avoid that.
1911 WebContents* web_contents =
1912 browser()->tab_strip_model()->GetActiveWebContents();
1913 EXPECT_TRUE(DidDisplayPass(web_contents));
1916 // Checks that plugins in an iframe are not loaded while a page is
1917 // being preloaded, but are loaded when the page is displayed.
1918 #if defined(USE_AURA) && !defined(OS_WIN)
1919 // http://crbug.com/103496
1920 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1921 DISABLED_PrerenderIframeDelayLoadPlugin
1922 #elif defined(OS_MACOSX)
1923 // http://crbug.com/100514
1924 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1925 DISABLED_PrerenderIframeDelayLoadPlugin
1926 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
1927 // TODO(jschuh): Failing plugin tests. crbug.com/244653
1928 #define MAYBE_PrerenderIframeDelayLoadPlugin \
1929 DISABLED_PrerenderIframeDelayLoadPlugin
1930 #else
1931 #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin
1932 #endif
1933 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1934 MAYBE_PrerenderIframeDelayLoadPlugin) {
1935 PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
1936 FINAL_STATUS_USED,
1938 NavigateToDestURL();
1941 // Renders a page that contains a prerender link to a page that contains an
1942 // iframe with a source that requires http authentication. This should not
1943 // prerender successfully.
1944 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
1945 PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
1946 FINAL_STATUS_AUTH_NEEDED,
1950 // Checks that client-issued redirects work with prerendering.
1951 // This version navigates to the page which issues the redirection, rather
1952 // than the final destination page.
1953 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1954 DISABLED_PrerenderClientRedirectNavigateToFirst) {
1955 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1956 FINAL_STATUS_USED,
1958 NavigateToDestURL();
1961 // Checks that client-issued redirects work with prerendering.
1962 // This version navigates to the final destination page, rather than the
1963 // page which does the redirection.
1964 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1965 PrerenderClientRedirectNavigateToSecond) {
1966 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1967 FINAL_STATUS_USED,
1969 NavigateToURL("files/prerender/prerender_page.html");
1972 // Checks that redirects with location.replace do not cancel a prerender and
1973 // and swap when navigating to the first page.
1974 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1975 PrerenderLocationReplaceNavigateToFirst) {
1976 PrerenderTestURL("files/prerender/prerender_location_replace.html",
1977 FINAL_STATUS_USED,
1979 NavigateToDestURL();
1982 // Checks that redirects with location.replace do not cancel a prerender and
1983 // and swap when navigating to the second.
1984 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1985 PrerenderLocationReplaceNavigateToSecond) {
1986 PrerenderTestURL("files/prerender/prerender_location_replace.html",
1987 FINAL_STATUS_USED,
1989 NavigateToURL("files/prerender/prerender_page.html");
1992 // Checks that client-issued redirects work with prerendering.
1993 // This version navigates to the final destination page, rather than the
1994 // page which does the redirection via a mouse click.
1995 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1996 DISABLED_PrerenderClientRedirectNavigateToSecondViaClick) {
1997 GURL prerender_url = test_server()->GetURL(
1998 CreateClientRedirect("files/prerender/prerender_page.html"));
1999 GURL destination_url = test_server()->GetURL(
2000 "files/prerender/prerender_page.html");
2001 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 2);
2002 OpenDestURLViaClick();
2005 // Checks that a prerender for an https will prevent a prerender from happening.
2006 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) {
2007 net::SpawnedTestServer https_server(
2008 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2009 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2010 ASSERT_TRUE(https_server.Start());
2011 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2012 PrerenderTestURL(https_url,
2013 FINAL_STATUS_USED,
2015 NavigateToDestURL();
2018 // Checks that client-issued redirects to an https page will cancel prerenders.
2019 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2020 DISABLED_PrerenderClientRedirectToHttps) {
2021 net::SpawnedTestServer https_server(
2022 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2023 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2024 ASSERT_TRUE(https_server.Start());
2025 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2026 PrerenderTestURL(CreateClientRedirect(https_url.spec()),
2027 FINAL_STATUS_USED,
2029 NavigateToDestURL();
2032 // Checks that client-issued redirects within an iframe in a prerendered
2033 // page will not count as an "alias" for the prerendered page.
2034 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2035 DISABLED_PrerenderClientRedirectInIframe) {
2036 std::string redirect_path = CreateClientRedirect(
2037 "/files/prerender/prerender_embedded_content.html");
2038 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2039 replacement_text.push_back(
2040 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2041 std::string replacement_path;
2042 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2043 "files/prerender/prerender_with_iframe.html",
2044 replacement_text,
2045 &replacement_path));
2046 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
2047 EXPECT_FALSE(UrlIsInPrerenderManager(
2048 "files/prerender/prerender_embedded_content.html"));
2049 NavigateToDestURL();
2052 // Checks that client-issued redirects within an iframe in a prerendered
2053 // page to an https page will not cancel the prerender, nor will it
2054 // count as an "alias" for the prerendered page.
2055 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2056 DISABLED_PrerenderClientRedirectToHttpsInIframe) {
2057 net::SpawnedTestServer https_server(
2058 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2059 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2060 ASSERT_TRUE(https_server.Start());
2061 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2062 std::string redirect_path = CreateClientRedirect(https_url.spec());
2063 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2064 replacement_text.push_back(
2065 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2066 std::string replacement_path;
2067 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2068 "files/prerender/prerender_with_iframe.html",
2069 replacement_text,
2070 &replacement_path));
2071 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
2072 EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
2073 NavigateToDestURL();
2076 // Checks that server-issued redirects work with prerendering.
2077 // This version navigates to the page which issues the redirection, rather
2078 // than the final destination page.
2079 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2080 PrerenderServerRedirectNavigateToFirst) {
2081 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2082 FINAL_STATUS_USED,
2084 NavigateToDestURL();
2087 // Checks that server-issued redirects work with prerendering.
2088 // This version navigates to the final destination page, rather than the
2089 // page which does the redirection.
2090 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2091 PrerenderServerRedirectNavigateToSecond) {
2092 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2093 FINAL_STATUS_USED,
2095 NavigateToURL("files/prerender/prerender_page.html");
2098 // Checks that server-issued redirects work with prerendering.
2099 // This version navigates to the final destination page, rather than the
2100 // page which does the redirection via a mouse click.
2101 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2102 PrerenderServerRedirectNavigateToSecondViaClick) {
2103 GURL prerender_url = test_server()->GetURL(
2104 CreateServerRedirect("files/prerender/prerender_page.html"));
2105 GURL destination_url = test_server()->GetURL(
2106 "files/prerender/prerender_page.html");
2107 PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 1);
2108 OpenDestURLViaClick();
2111 // Checks that server-issued redirects from an http to an https
2112 // location will cancel prerendering.
2113 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2114 PrerenderServerRedirectToHttps) {
2115 net::SpawnedTestServer https_server(
2116 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2117 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2118 ASSERT_TRUE(https_server.Start());
2119 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2120 PrerenderTestURL(CreateServerRedirect(https_url.spec()),
2121 FINAL_STATUS_USED,
2123 NavigateToDestURL();
2126 // Checks that server-issued redirects within an iframe in a prerendered
2127 // page will not count as an "alias" for the prerendered page.
2128 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
2129 std::string redirect_path = CreateServerRedirect(
2130 "/files/prerender/prerender_embedded_content.html");
2131 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2132 replacement_text.push_back(
2133 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2134 std::string replacement_path;
2135 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2136 "files/prerender/prerender_with_iframe.html",
2137 replacement_text,
2138 &replacement_path));
2139 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2140 EXPECT_FALSE(UrlIsInPrerenderManager(
2141 "files/prerender/prerender_embedded_content.html"));
2142 NavigateToDestURL();
2145 // Checks that server-issued redirects within an iframe in a prerendered
2146 // page to an https page will not cancel the prerender, nor will it
2147 // count as an "alias" for the prerendered page.
2148 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2149 DISABLED_PrerenderServerRedirectToHttpsInIframe) {
2150 net::SpawnedTestServer https_server(
2151 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
2152 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2153 ASSERT_TRUE(https_server.Start());
2154 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2155 std::string redirect_path = CreateServerRedirect(https_url.spec());
2156 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2157 replacement_text.push_back(
2158 std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
2159 std::string replacement_path;
2160 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2161 "files/prerender/prerender_with_iframe.html",
2162 replacement_text,
2163 &replacement_path));
2164 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2165 EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
2166 NavigateToDestURL();
2169 // Prerenders a page that contains an automatic download triggered through an
2170 // iframe. This should not prerender successfully.
2171 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) {
2172 PrerenderTestURL("files/prerender/prerender_download_iframe.html",
2173 FINAL_STATUS_DOWNLOAD,
2177 // Prerenders a page that contains an automatic download triggered through
2178 // Javascript changing the window.location. This should not prerender
2179 // successfully
2180 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
2181 PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
2182 FINAL_STATUS_DOWNLOAD,
2186 // Prerenders a page that contains an automatic download triggered through a
2187 // client-issued redirect. This should not prerender successfully.
2188 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
2189 PrerenderTestURL("files/prerender/prerender_download_refresh.html",
2190 FINAL_STATUS_DOWNLOAD,
2194 // Checks that the referrer is set when prerendering.
2195 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
2196 PrerenderTestURL("files/prerender/prerender_referrer.html",
2197 FINAL_STATUS_USED,
2199 NavigateToDestURL();
2202 // Checks that the referrer is not set when prerendering and the source page is
2203 // HTTPS.
2204 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2205 PrerenderNoSSLReferrer) {
2206 set_use_https_src(true);
2207 PrerenderTestURL("files/prerender/prerender_no_referrer.html",
2208 FINAL_STATUS_USED,
2210 NavigateToDestURL();
2213 // Checks that the referrer is set when prerendering is cancelled.
2214 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrer) {
2215 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
2216 new TestContentBrowserClient);
2217 content::ContentBrowserClient* original_browser_client =
2218 content::SetBrowserClientForTesting(test_content_browser_client.get());
2220 PrerenderTestURL("files/prerender/prerender_referrer.html",
2221 FINAL_STATUS_CANCELLED,
2223 OpenDestURLViaClick();
2225 bool display_test_result = false;
2226 WebContents* web_contents =
2227 browser()->tab_strip_model()->GetActiveWebContents();
2228 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
2229 web_contents,
2230 "window.domAutomationController.send(DidDisplayPass())",
2231 &display_test_result));
2232 EXPECT_TRUE(display_test_result);
2234 content::SetBrowserClientForTesting(original_browser_client);
2237 // Checks that popups on a prerendered page cause cancellation.
2238 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
2239 PrerenderTestURL("files/prerender/prerender_popup.html",
2240 FINAL_STATUS_CREATE_NEW_WINDOW,
2244 // Checks that registering a protocol handler causes cancellation.
2245 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) {
2246 PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html",
2247 FINAL_STATUS_REGISTER_PROTOCOL_HANDLER,
2251 // Checks that renderers using excessive memory will be terminated.
2252 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
2253 ASSERT_TRUE(GetPrerenderManager());
2254 GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024;
2255 // The excessive memory kill may happen before or after the load event as it
2256 // happens asynchronously with IPC calls. Even if the test does not start
2257 // allocating until after load, the browser process might notice before the
2258 // message gets through. This happens on XP debug bots because they're so
2259 // slow. Instead, don't bother checking the load event count.
2260 DisableLoadEventCheck();
2261 PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
2262 FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 0);
2265 // Checks shutdown code while a prerender is active.
2266 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
2267 DisableJavascriptCalls();
2268 DisableLoadEventCheck();
2269 PrerenderTestURL("files/prerender/prerender_page.html",
2270 FINAL_STATUS_APP_TERMINATING,
2274 // TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test.
2275 // Checks that we don't prerender in an infinite loop.
2276 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) {
2277 const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
2278 const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
2280 std::vector<FinalStatus> expected_final_status_queue;
2281 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2282 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2284 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2285 ASSERT_TRUE(GetPrerenderContents());
2286 GetPrerenderContents()->WaitForPendingPrerenders(1u);
2288 // Next url should be in pending list but not an active entry.
2289 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2291 NavigateToDestURL();
2293 // Make sure the PrerenderContents for the next url is now in the manager
2294 // and not pending.
2295 EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
2298 // TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test.
2299 // Checks that we don't prerender in an infinite loop and multiple links are
2300 // handled correctly.
2301 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2302 DISABLED_PrerenderInfiniteLoopMultiple) {
2303 const char* const kHtmlFileA =
2304 "files/prerender/prerender_infinite_a_multiple.html";
2305 const char* const kHtmlFileB =
2306 "files/prerender/prerender_infinite_b_multiple.html";
2307 const char* const kHtmlFileC =
2308 "files/prerender/prerender_infinite_c_multiple.html";
2310 // This test is conceptually simplest if concurrency is at two, since we
2311 // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
2312 GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
2313 GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
2315 std::vector<FinalStatus> expected_final_status_queue;
2316 expected_final_status_queue.push_back(FINAL_STATUS_USED);
2317 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2318 expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
2320 PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
2321 ASSERT_TRUE(GetPrerenderContents());
2322 GetPrerenderContents()->WaitForPendingPrerenders(2u);
2324 // Next url should be in pending list but not an active entry.
2325 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
2326 EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
2328 NavigateToDestURL();
2330 // Make sure the PrerenderContents for the next urls are now in the manager
2331 // and not pending. One and only one of the URLs (the last seen) should be the
2332 // active entry.
2333 bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
2334 bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
2335 EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
2338 // See crbug.com/131836.
2339 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderTaskManager) {
2340 // Show the task manager. This populates the model.
2341 chrome::OpenTaskManager(current_browser());
2342 // Wait for the model of task manager to start.
2343 TaskManagerBrowserTestUtil::WaitForWebResourceChange(1);
2345 // Start with two resources.
2346 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2348 // One of the resources that has a WebContents associated with it should have
2349 // the Prerender prefix.
2350 const base::string16 prefix =
2351 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX,
2352 base::string16());
2353 base::string16 prerender_title;
2354 int num_prerender_tabs = 0;
2356 TaskManagerModel* model = GetModel();
2357 // The task manager caches values. Force the titles to be fresh.
2358 model->Refresh();
2359 for (int i = 0; i < model->ResourceCount(); ++i) {
2360 if (model->GetResourceWebContents(i)) {
2361 prerender_title = model->GetResourceTitle(i);
2362 if (StartsWith(prerender_title, prefix, true))
2363 ++num_prerender_tabs;
2366 EXPECT_EQ(1, num_prerender_tabs);
2367 const base::string16 prerender_page_title =
2368 prerender_title.substr(prefix.length());
2370 NavigateToDestURL();
2372 // There should be no tabs with the Prerender prefix.
2373 const base::string16 tab_prefix =
2374 l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, base::string16());
2375 num_prerender_tabs = 0;
2376 int num_tabs_with_prerender_page_title = 0;
2377 model->Refresh();
2378 for (int i = 0; i < model->ResourceCount(); ++i) {
2379 if (model->GetResourceWebContents(i)) {
2380 base::string16 tab_title = model->GetResourceTitle(i);
2381 if (StartsWith(tab_title, prefix, true)) {
2382 ++num_prerender_tabs;
2383 } else {
2384 EXPECT_TRUE(StartsWith(tab_title, tab_prefix, true));
2386 // The prerender tab should now be a normal tab but the title should be
2387 // the same. Depending on timing, there may be more than one of these.
2388 const base::string16 tab_page_title =
2389 tab_title.substr(tab_prefix.length());
2390 if (prerender_page_title.compare(tab_page_title) == 0)
2391 ++num_tabs_with_prerender_page_title;
2395 EXPECT_EQ(0, num_prerender_tabs);
2397 // We may have deleted the prerender tab, but the swapped in tab should be
2398 // active.
2399 EXPECT_GE(num_tabs_with_prerender_page_title, 1);
2400 EXPECT_LE(num_tabs_with_prerender_page_title, 2);
2403 // Checks that audio loads are deferred on prerendering.
2404 // Times out under AddressSanitizer, see http://crbug.com/108402
2405 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Audio) {
2406 PrerenderTestURL("files/prerender/prerender_html5_audio.html",
2407 FINAL_STATUS_USED,
2409 NavigateToDestUrlAndWaitForPassTitle();
2412 // Checks that audio loads are deferred on prerendering and played back when
2413 // the prerender is swapped in if autoplay is set.
2414 // Periodically fails on chrome-os. See http://crbug.com/145263
2415 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2416 DISABLED_PrerenderHTML5AudioAutoplay) {
2417 PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html",
2418 FINAL_STATUS_USED,
2420 NavigateToDestUrlAndWaitForPassTitle();
2423 // Checks that audio loads are deferred on prerendering and played back when
2424 // the prerender is swapped in if js starts playing.
2425 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2426 DISABLED_PrerenderHTML5AudioJsplay) {
2427 PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html",
2428 FINAL_STATUS_USED,
2430 NavigateToDestUrlAndWaitForPassTitle();
2433 // Checks that video loads are deferred on prerendering.
2434 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderHTML5Video) {
2435 PrerenderTestURL("files/prerender/prerender_html5_video.html",
2436 FINAL_STATUS_USED,
2438 NavigateToDestUrlAndWaitForPassTitle();
2441 // Checks that video tags inserted by javascript are deferred and played
2442 // correctly on swap in.
2443 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2444 DISABLED_PrerenderHTML5VideoJs) {
2445 PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
2446 FINAL_STATUS_USED,
2448 NavigateToDestUrlAndWaitForPassTitle();
2451 // Checks for correct network events by using a busy sleep the javascript.
2452 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2453 DISABLED_PrerenderHTML5VideoNetwork) {
2454 PrerenderTestURL("files/prerender/prerender_html5_video_network.html",
2455 FINAL_STATUS_USED,
2457 true);
2458 NavigateToDestUrlAndWaitForPassTitle();
2461 // Checks that scripts can retrieve the correct window size while prerendering.
2462 #if defined(TOOLKIT_VIEWS)
2463 // TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363
2464 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) {
2465 #else
2466 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
2467 #endif
2468 PrerenderTestURL("files/prerender/prerender_size.html",
2469 FINAL_STATUS_USED,
2471 NavigateToDestURL();
2474 // Flakily times out: http://crbug.com/171546
2475 // Checks that prerenderers will terminate when the RenderView crashes.
2476 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderRendererCrash) {
2477 scoped_ptr<TestPrerender> prerender =
2478 PrerenderTestURL("files/prerender/prerender_page.html",
2479 FINAL_STATUS_RENDERER_CRASHED,
2482 // Navigate to about:crash and then wait for the renderer to crash.
2483 ASSERT_TRUE(prerender->contents());
2484 ASSERT_TRUE(prerender->contents()->prerender_contents());
2485 prerender->contents()->prerender_contents()->GetController().
2486 LoadURL(
2487 GURL(content::kChromeUICrashURL),
2488 content::Referrer(),
2489 content::PAGE_TRANSITION_TYPED,
2490 std::string());
2491 prerender->WaitForStop();
2494 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2495 PrerenderPageWithFragment) {
2496 PrerenderTestURL("files/prerender/prerender_page.html#fragment",
2497 FINAL_STATUS_USED,
2500 ChannelDestructionWatcher channel_close_watcher;
2501 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2502 GetActiveWebContents()->GetRenderProcessHost());
2503 NavigateToDestURL();
2504 channel_close_watcher.WaitForChannelClose();
2506 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2509 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2510 PrerenderPageWithRedirectedFragment) {
2511 PrerenderTestURL(
2512 CreateClientRedirect("files/prerender/prerender_page.html#fragment"),
2513 FINAL_STATUS_USED,
2516 ChannelDestructionWatcher channel_close_watcher;
2517 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2518 GetActiveWebContents()->GetRenderProcessHost());
2519 NavigateToDestURL();
2520 channel_close_watcher.WaitForChannelClose();
2522 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2525 // Checks that we do not use a prerendered page when navigating from
2526 // the main page to a fragment.
2527 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2528 PrerenderPageNavigateFragment) {
2529 PrerenderTestURL("files/prerender/no_prerender_page.html",
2530 FINAL_STATUS_APP_TERMINATING,
2532 NavigateToURLWithDisposition(
2533 "files/prerender/no_prerender_page.html#fragment",
2534 CURRENT_TAB, false);
2537 // Checks that we do not use a prerendered page when we prerender a fragment
2538 // but navigate to the main page.
2539 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2540 PrerenderFragmentNavigatePage) {
2541 PrerenderTestURL("files/prerender/no_prerender_page.html#fragment",
2542 FINAL_STATUS_APP_TERMINATING,
2544 NavigateToURLWithDisposition(
2545 "files/prerender/no_prerender_page.html",
2546 CURRENT_TAB, false);
2549 // Checks that we do not use a prerendered page when we prerender a fragment
2550 // but navigate to a different fragment on the same page.
2551 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2552 PrerenderFragmentNavigateFragment) {
2553 PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment",
2554 FINAL_STATUS_APP_TERMINATING,
2556 NavigateToURLWithDisposition(
2557 "files/prerender/no_prerender_page.html#fragment",
2558 CURRENT_TAB, false);
2561 // Checks that we do not use a prerendered page when the page uses a client
2562 // redirect to refresh from a fragment on the same page.
2563 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2564 PrerenderClientRedirectFromFragment) {
2565 PrerenderTestURL(
2566 CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"),
2567 FINAL_STATUS_APP_TERMINATING,
2569 NavigateToURLWithDisposition(
2570 "files/prerender/no_prerender_page.html",
2571 CURRENT_TAB, false);
2574 // Checks that we do not use a prerendered page when the page uses a client
2575 // redirect to refresh to a fragment on the same page.
2576 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2577 PrerenderClientRedirectToFragment) {
2578 PrerenderTestURL(
2579 CreateClientRedirect("files/prerender/no_prerender_page.html"),
2580 FINAL_STATUS_APP_TERMINATING,
2582 NavigateToURLWithDisposition(
2583 "files/prerender/no_prerender_page.html#fragment",
2584 CURRENT_TAB, false);
2587 // Checks that we correctly use a prerendered page when the page uses JS to set
2588 // the window.location.hash to a fragment on the same page.
2589 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2590 PrerenderPageChangeFragmentLocationHash) {
2591 PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html",
2592 FINAL_STATUS_USED,
2594 NavigateToURL("files/prerender/prerender_fragment_location_hash.html");
2597 // Checks that prerendering a PNG works correctly.
2598 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) {
2599 DisableJavascriptCalls();
2600 PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1);
2601 NavigateToDestURL();
2604 // Checks that prerendering a JPG works correctly.
2605 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) {
2606 DisableJavascriptCalls();
2607 PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1);
2608 NavigateToDestURL();
2611 // Checks that a prerender of a CRX will result in a cancellation due to
2612 // download.
2613 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) {
2614 PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 0);
2617 // Checks that xhr GET requests allow prerenders.
2618 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) {
2619 PrerenderTestURL("files/prerender/prerender_xhr_get.html",
2620 FINAL_STATUS_USED,
2622 NavigateToDestURL();
2625 // Checks that xhr HEAD requests allow prerenders.
2626 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) {
2627 PrerenderTestURL("files/prerender/prerender_xhr_head.html",
2628 FINAL_STATUS_USED,
2630 NavigateToDestURL();
2633 // Checks that xhr OPTIONS requests allow prerenders.
2634 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) {
2635 PrerenderTestURL("files/prerender/prerender_xhr_options.html",
2636 FINAL_STATUS_USED,
2638 NavigateToDestURL();
2641 // Checks that xhr TRACE requests allow prerenders.
2642 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) {
2643 PrerenderTestURL("files/prerender/prerender_xhr_trace.html",
2644 FINAL_STATUS_USED,
2646 NavigateToDestURL();
2649 // Checks that xhr POST requests allow prerenders.
2650 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderXhrPost) {
2651 PrerenderTestURL("files/prerender/prerender_xhr_post.html",
2652 FINAL_STATUS_USED,
2654 NavigateToDestURL();
2657 // Checks that xhr PUT cancels prerenders.
2658 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) {
2659 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
2660 FINAL_STATUS_INVALID_HTTP_METHOD,
2664 // Checks that xhr DELETE cancels prerenders.
2665 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) {
2666 PrerenderTestURL("files/prerender/prerender_xhr_delete.html",
2667 FINAL_STATUS_INVALID_HTTP_METHOD,
2671 // Checks that a top-level page which would trigger an SSL error is canceled.
2672 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) {
2673 net::SpawnedTestServer::SSLOptions ssl_options;
2674 ssl_options.server_certificate =
2675 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2676 net::SpawnedTestServer https_server(
2677 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2678 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2679 ASSERT_TRUE(https_server.Start());
2680 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2681 PrerenderTestURL(https_url,
2682 FINAL_STATUS_SSL_ERROR,
2686 // Checks that an SSL error that comes from a subresource does not cancel
2687 // the page. Non-main-frame requests are simply cancelled if they run into
2688 // an SSL problem.
2689 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) {
2690 net::SpawnedTestServer::SSLOptions ssl_options;
2691 ssl_options.server_certificate =
2692 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2693 net::SpawnedTestServer https_server(
2694 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2695 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2696 ASSERT_TRUE(https_server.Start());
2697 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2698 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2699 replacement_text.push_back(
2700 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2701 std::string replacement_path;
2702 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2703 "files/prerender/prerender_with_image.html",
2704 replacement_text,
2705 &replacement_path));
2706 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2707 NavigateToDestURL();
2710 // Checks that an SSL error that comes from an iframe does not cancel
2711 // the page. Non-main-frame requests are simply cancelled if they run into
2712 // an SSL problem.
2713 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) {
2714 net::SpawnedTestServer::SSLOptions ssl_options;
2715 ssl_options.server_certificate =
2716 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2717 net::SpawnedTestServer https_server(
2718 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2719 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2720 ASSERT_TRUE(https_server.Start());
2721 GURL https_url = https_server.GetURL(
2722 "files/prerender/prerender_embedded_content.html");
2723 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2724 replacement_text.push_back(
2725 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2726 std::string replacement_path;
2727 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2728 "files/prerender/prerender_with_iframe.html",
2729 replacement_text,
2730 &replacement_path));
2731 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2732 NavigateToDestURL();
2735 // Checks that we cancel correctly when window.print() is called.
2736 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
2737 PrerenderTestURL("files/prerender/prerender_print.html",
2738 FINAL_STATUS_WINDOW_PRINT,
2742 // Checks that if a page is opened in a new window by javascript and both the
2743 // pages are in the same domain, the prerendered page is not used, due to
2744 // window.opener.
2745 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2746 PrerenderSameDomainWindowOpenerWindowOpen) {
2747 PrerenderTestURL("files/prerender/prerender_page.html",
2748 FINAL_STATUS_WINDOW_OPENER,
2750 OpenDestURLViaWindowOpen();
2753 // Checks that if a page is opened due to click on a href with target="_blank"
2754 // and both pages are in the same domain the prerendered page is not used, due
2755 // to window.opener.
2756 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2757 PrerenderSameDomainWindowOpenerClickTarget) {
2758 PrerenderTestURL("files/prerender/prerender_page.html",
2759 FINAL_STATUS_WINDOW_OPENER,
2761 OpenDestURLViaClickTarget();
2764 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
2765 // TODO(erg): linux_aura bringup: http://crbug.com/163931
2766 #define MAYBE_PrerenderSSLClientCertTopLevel DISABLED_PrerenderSSLClientCertTopLevel
2767 #else
2768 #define MAYBE_PrerenderSSLClientCertTopLevel PrerenderSSLClientCertTopLevel
2769 #endif
2771 class TestClientCertStore : public net::ClientCertStore {
2772 public:
2773 TestClientCertStore() {}
2774 virtual ~TestClientCertStore() {}
2776 // net::ClientCertStore:
2777 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
2778 net::CertificateList* selected_certs,
2779 const base::Closure& callback) OVERRIDE {
2780 *selected_certs = net::CertificateList(
2781 1, scoped_refptr<net::X509Certificate>(
2782 new net::X509Certificate("test", "test", base::Time(), base::Time())));
2783 callback.Run();
2787 scoped_ptr<net::ClientCertStore> CreateCertStore() {
2788 return scoped_ptr<net::ClientCertStore>(new TestClientCertStore);
2791 // Checks that a top-level page which would normally request an SSL client
2792 // certificate will never be seen since it's an https top-level resource.
2793 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2794 MAYBE_PrerenderSSLClientCertTopLevel) {
2795 ProfileIOData::FromResourceContext(
2796 current_browser()->profile()->GetResourceContext())->
2797 set_client_cert_store_factory_for_testing(
2798 base::Bind(&CreateCertStore));
2799 net::SpawnedTestServer::SSLOptions ssl_options;
2800 ssl_options.request_client_certificate = true;
2801 net::SpawnedTestServer https_server(
2802 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2803 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2804 ASSERT_TRUE(https_server.Start());
2805 GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2806 PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0);
2809 // Checks that an SSL Client Certificate request that originates from a
2810 // subresource will cancel the prerendered page.
2811 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2812 PrerenderSSLClientCertSubresource) {
2813 ProfileIOData::FromResourceContext(
2814 current_browser()->profile()->GetResourceContext())->
2815 set_client_cert_store_factory_for_testing(
2816 base::Bind(&CreateCertStore));
2817 net::SpawnedTestServer::SSLOptions ssl_options;
2818 ssl_options.request_client_certificate = true;
2819 net::SpawnedTestServer https_server(
2820 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2821 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2822 ASSERT_TRUE(https_server.Start());
2823 GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2824 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2825 replacement_text.push_back(
2826 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2827 std::string replacement_path;
2828 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2829 "files/prerender/prerender_with_image.html",
2830 replacement_text,
2831 &replacement_path));
2832 PrerenderTestURL(replacement_path,
2833 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2837 // Checks that an SSL Client Certificate request that originates from an
2838 // iframe will cancel the prerendered page.
2839 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) {
2840 ProfileIOData::FromResourceContext(
2841 current_browser()->profile()->GetResourceContext())->
2842 set_client_cert_store_factory_for_testing(
2843 base::Bind(&CreateCertStore));
2844 net::SpawnedTestServer::SSLOptions ssl_options;
2845 ssl_options.request_client_certificate = true;
2846 net::SpawnedTestServer https_server(
2847 net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
2848 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2849 ASSERT_TRUE(https_server.Start());
2850 GURL https_url = https_server.GetURL(
2851 "files/prerender/prerender_embedded_content.html");
2852 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2853 replacement_text.push_back(
2854 std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2855 std::string replacement_path;
2856 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2857 "files/prerender/prerender_with_iframe.html",
2858 replacement_text,
2859 &replacement_path));
2860 PrerenderTestURL(replacement_path,
2861 FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2865 #if defined(FULL_SAFE_BROWSING)
2866 // Ensures that we do not prerender pages with a safe browsing
2867 // interstitial.
2868 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) {
2869 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2870 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2871 url, SB_THREAT_TYPE_URL_MALWARE);
2872 PrerenderTestURL("files/prerender/prerender_page.html",
2873 FINAL_STATUS_SAFE_BROWSING, 0);
2876 // Ensures that server redirects to a malware page will cancel prerenders.
2877 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2878 PrerenderSafeBrowsingServerRedirect) {
2879 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2880 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2881 url, SB_THREAT_TYPE_URL_MALWARE);
2882 PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2883 FINAL_STATUS_SAFE_BROWSING,
2887 // Ensures that client redirects to a malware page will cancel prerenders.
2888 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2889 PrerenderSafeBrowsingClientRedirect) {
2890 GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2891 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2892 url, SB_THREAT_TYPE_URL_MALWARE);
2893 PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
2894 FINAL_STATUS_SAFE_BROWSING,
2898 // Ensures that we do not prerender pages which have a malware subresource.
2899 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) {
2900 GURL image_url = test_server()->GetURL("files/prerender/image.jpeg");
2901 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2902 image_url, SB_THREAT_TYPE_URL_MALWARE);
2903 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2904 replacement_text.push_back(
2905 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
2906 std::string replacement_path;
2907 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2908 "files/prerender/prerender_with_image.html",
2909 replacement_text,
2910 &replacement_path));
2911 PrerenderTestURL(replacement_path,
2912 FINAL_STATUS_SAFE_BROWSING,
2916 // Ensures that we do not prerender pages which have a malware iframe.
2917 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) {
2918 GURL iframe_url = test_server()->GetURL(
2919 "files/prerender/prerender_embedded_content.html");
2920 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2921 iframe_url, SB_THREAT_TYPE_URL_MALWARE);
2922 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
2923 replacement_text.push_back(
2924 std::make_pair("REPLACE_WITH_URL", iframe_url.spec()));
2925 std::string replacement_path;
2926 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
2927 "files/prerender/prerender_with_iframe.html",
2928 replacement_text,
2929 &replacement_path));
2930 PrerenderTestURL(replacement_path,
2931 FINAL_STATUS_SAFE_BROWSING,
2935 #endif
2937 // Checks that a local storage read will not cause prerender to fail.
2938 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) {
2939 PrerenderTestURL("files/prerender/prerender_localstorage_read.html",
2940 FINAL_STATUS_USED,
2942 NavigateToDestURL();
2945 // Checks that a local storage write will not cause prerender to fail.
2946 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) {
2947 PrerenderTestURL("files/prerender/prerender_localstorage_write.html",
2948 FINAL_STATUS_USED,
2950 NavigateToDestURL();
2953 // Checks that the favicon is properly loaded on prerender.
2954 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2955 DISABLED_PrerenderFavicon) {
2956 PrerenderTestURL("files/prerender/prerender_favicon.html",
2957 FINAL_STATUS_USED,
2959 TestPrerenderContents* prerender_contents = GetPrerenderContents();
2960 ASSERT_TRUE(prerender_contents != NULL);
2961 content::WindowedNotificationObserver favicon_update_watcher(
2962 chrome::NOTIFICATION_FAVICON_UPDATED,
2963 content::Source<WebContents>(prerender_contents->prerender_contents()));
2964 NavigateToDestURL();
2965 favicon_update_watcher.Wait();
2968 // Checks that when a prerendered page is swapped in to a referring page, the
2969 // unload handlers on the referring page are executed.
2970 // Fails about 50% on CrOS, 5-10% on linux, win, mac. http://crbug.com/128986
2971 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderUnload) {
2972 set_loader_path("files/prerender/prerender_loader_with_unload.html");
2973 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2974 base::string16 expected_title = base::ASCIIToUTF16("Unloaded");
2975 content::TitleWatcher title_watcher(
2976 current_browser()->tab_strip_model()->GetActiveWebContents(),
2977 expected_title);
2978 NavigateToDestURL();
2979 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
2982 // Checks that when the history is cleared, prerendering is cancelled and
2983 // prerendering history is cleared.
2984 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) {
2985 scoped_ptr<TestPrerender> prerender =
2986 PrerenderTestURL("files/prerender/prerender_page.html",
2987 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
2990 base::MessageLoop::current()->PostTask(
2991 FROM_HERE,
2992 base::Bind(&ClearBrowsingData, current_browser(),
2993 BrowsingDataRemover::REMOVE_HISTORY));
2994 prerender->WaitForStop();
2996 // Make sure prerender history was cleared.
2997 EXPECT_EQ(0, GetHistoryLength());
3000 // Disabled due to flakiness: crbug.com/316225
3001 // Checks that when the cache is cleared, prerenders are cancelled but
3002 // prerendering history is not cleared.
3003 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderClearCache) {
3004 scoped_ptr<TestPrerender> prerender =
3005 PrerenderTestURL("files/prerender/prerender_page.html",
3006 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
3009 base::MessageLoop::current()->PostTask(FROM_HERE,
3010 base::Bind(&ClearBrowsingData, current_browser(),
3011 BrowsingDataRemover::REMOVE_CACHE));
3012 prerender->WaitForStop();
3014 // Make sure prerender history was not cleared. Not a vital behavior, but
3015 // used to compare with PrerenderClearHistory test.
3016 EXPECT_EQ(1, GetHistoryLength());
3019 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) {
3020 scoped_ptr<TestPrerender> prerender =
3021 PrerenderTestURL("files/prerender/prerender_page.html",
3022 FINAL_STATUS_CANCELLED,
3025 GetPrerenderManager()->CancelAllPrerenders();
3026 prerender->WaitForStop();
3028 EXPECT_TRUE(GetPrerenderContents() == NULL);
3031 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) {
3032 scoped_ptr<TestPrerender> prerender =
3033 PrerenderTestURL("files/prerender/prerender_page.html",
3034 FINAL_STATUS_CANCELLED, 1);
3036 GetPrerenderManager()->CancelAllPrerenders();
3037 prerender->WaitForStop();
3039 EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
3040 EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
3041 EXPECT_FALSE(HadPrerenderEventErrors());
3044 // Cancels the prerender of a page with its own prerender. The second prerender
3045 // should never be started.
3046 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3047 PrerenderCancelPrerenderWithPrerender) {
3048 scoped_ptr<TestPrerender> prerender =
3049 PrerenderTestURL("files/prerender/prerender_infinite_a.html",
3050 FINAL_STATUS_CANCELLED,
3053 GetPrerenderManager()->CancelAllPrerenders();
3054 prerender->WaitForStop();
3056 EXPECT_TRUE(GetPrerenderContents() == NULL);
3059 // Prerendering and history tests.
3060 // The prerendered page is navigated to in several ways [navigate via
3061 // omnibox, click on link, key-modified click to open in background tab, etc],
3062 // followed by a navigation to another page from the prerendered page, followed
3063 // by a back navigation.
3065 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3066 DISABLED_PrerenderNavigateClickGoBack) {
3067 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3068 FINAL_STATUS_USED,
3070 NavigateToDestURL();
3071 ClickToNextPageAfterPrerender();
3072 GoBackToPrerender();
3075 // Disabled due to timeouts on commit queue.
3076 // http://crbug.com/121130
3077 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3078 DISABLED_PrerenderNavigateNavigateGoBack) {
3079 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3080 FINAL_STATUS_USED,
3082 NavigateToDestURL();
3083 NavigateToNextPageAfterPrerender();
3084 GoBackToPrerender();
3087 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3088 DISABLED_PrerenderClickClickGoBack) {
3089 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3090 FINAL_STATUS_USED,
3092 OpenDestURLViaClick();
3093 ClickToNextPageAfterPrerender();
3094 GoBackToPrerender();
3097 // Disabled due to timeouts on commit queue.
3098 // http://crbug.com/121130
3099 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3100 DISABLED_PrerenderClickNavigateGoBack) {
3101 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3102 FINAL_STATUS_USED,
3104 OpenDestURLViaClick();
3105 NavigateToNextPageAfterPrerender();
3106 GoBackToPrerender();
3109 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
3110 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3111 FINAL_STATUS_WINDOW_OPENER,
3113 OpenDestURLViaClickNewWindow();
3116 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
3117 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3118 FINAL_STATUS_WINDOW_OPENER,
3120 OpenDestURLViaClickNewForegroundTab();
3123 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3124 DISABLED_PrerenderClickNewBackgroundTab) {
3125 PrerenderTestURL("files/prerender/prerender_page_with_link.html",
3126 FINAL_STATUS_APP_TERMINATING,
3128 OpenDestURLViaClickNewBackgroundTab();
3131 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3132 NavigateToPrerenderedPageWhenDevToolsAttached) {
3133 DisableJavascriptCalls();
3134 WebContents* web_contents =
3135 current_browser()->tab_strip_model()->GetActiveWebContents();
3136 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
3137 web_contents->GetRenderViewHost()));
3138 DevToolsManager* manager = DevToolsManager::GetInstance();
3139 FakeDevToolsClientHost client_host;
3140 manager->RegisterDevToolsClientHostFor(agent.get(), &client_host);
3141 const char* url = "files/prerender/prerender_page.html";
3142 PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1);
3143 NavigateToURLWithDisposition(url, CURRENT_TAB, false);
3144 manager->ClientHostClosing(&client_host);
3147 // Validate that the sessionStorage namespace remains the same when swapping
3148 // in a prerendered page.
3149 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3150 DISABLED_PrerenderSessionStorage) {
3151 set_loader_path("files/prerender/prerender_loader_with_session_storage.html");
3152 PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
3153 FINAL_STATUS_USED,
3155 NavigateToDestURL();
3156 GoBackToPageBeforePrerender();
3159 // Checks that the control group works. An XHR PUT cannot be detected in the
3160 // control group.
3161 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroup) {
3162 RestorePrerenderMode restore_prerender_mode;
3163 PrerenderManager::SetMode(
3164 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
3165 DisableJavascriptCalls();
3166 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3167 FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
3168 NavigateToDestURL();
3171 // Make sure that the MatchComplete dummy works in the normal case. Once
3172 // a prerender is cancelled because of a script, a dummy must be created to
3173 // account for the MatchComplete case, and it must have a final status of
3174 // FINAL_STATUS_WOULD_HAVE_BEEN_USED.
3175 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MatchCompleteDummy) {
3176 std::vector<FinalStatus> expected_final_status_queue;
3177 expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
3178 expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
3179 PrerenderTestURL("files/prerender/prerender_xhr_put.html",
3180 expected_final_status_queue, 1);
3181 NavigateToDestURL();
3184 class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest {
3185 public:
3186 PrerenderBrowserTestWithNaCl() {}
3187 virtual ~PrerenderBrowserTestWithNaCl() {}
3189 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
3190 PrerenderBrowserTest::SetUpCommandLine(command_line);
3191 command_line->AppendSwitch(switches::kEnableNaCl);
3195 // Check that NaCl plugins work when enabled, with prerendering.
3196 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
3197 PrerenderNaClPluginEnabled) {
3198 #if defined(OS_WIN) && defined(USE_ASH)
3199 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
3200 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
3201 return;
3202 #endif
3204 PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
3205 FINAL_STATUS_USED,
3207 NavigateToDestURL();
3209 // To avoid any chance of a race, we have to let the script send its response
3210 // asynchronously.
3211 WebContents* web_contents =
3212 browser()->tab_strip_model()->GetActiveWebContents();
3213 bool display_test_result = false;
3214 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents,
3215 "DidDisplayReallyPass()",
3216 &display_test_result));
3217 ASSERT_TRUE(display_test_result);
3220 // Checks that the referrer policy is used when prerendering.
3221 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) {
3222 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3223 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3224 FINAL_STATUS_USED,
3226 NavigateToDestURL();
3229 // Checks that the referrer policy is used when prerendering on HTTPS.
3230 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3231 PrerenderSSLReferrerPolicy) {
3232 set_use_https_src(true);
3233 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3234 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3235 FINAL_STATUS_USED,
3237 NavigateToDestURL();
3240 // Checks that the referrer policy is used when prerendering is cancelled.
3241 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrerPolicy) {
3242 scoped_ptr<TestContentBrowserClient> test_content_browser_client(
3243 new TestContentBrowserClient);
3244 content::ContentBrowserClient* original_browser_client =
3245 content::SetBrowserClientForTesting(test_content_browser_client.get());
3247 set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
3248 PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
3249 FINAL_STATUS_CANCELLED,
3251 OpenDestURLViaClick();
3253 bool display_test_result = false;
3254 WebContents* web_contents =
3255 browser()->tab_strip_model()->GetActiveWebContents();
3256 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
3257 web_contents,
3258 "window.domAutomationController.send(DidDisplayPass())",
3259 &display_test_result));
3260 EXPECT_TRUE(display_test_result);
3262 content::SetBrowserClientForTesting(original_browser_client);
3265 // Test interaction of the webNavigation and tabs API with prerender.
3266 class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest,
3267 public ExtensionApiTest {
3268 public:
3269 PrerenderBrowserTestWithExtensions() {
3270 // The individual tests start the test server through ExtensionApiTest, so
3271 // the port number can be passed through to the extension.
3272 autostart_test_server_ = false;
3275 virtual void SetUp() OVERRIDE {
3276 PrerenderBrowserTest::SetUp();
3279 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
3280 PrerenderBrowserTest::SetUpCommandLine(command_line);
3281 ExtensionApiTest::SetUpCommandLine(command_line);
3284 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
3285 PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
3286 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
3289 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
3290 PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
3291 ExtensionApiTest::TearDownInProcessBrowserTestFixture();
3294 virtual void SetUpOnMainThread() OVERRIDE {
3295 PrerenderBrowserTest::SetUpOnMainThread();
3299 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) {
3300 ASSERT_TRUE(StartSpawnedTestServer());
3301 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3303 CommandLine::ForCurrentProcess()->AppendSwitch(
3304 extensions::switches::kAllowLegacyExtensionManifests);
3306 // Wait for the extension to set itself up and return control to us.
3307 ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_;
3309 ResultCatcher catcher;
3311 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3313 ChannelDestructionWatcher channel_close_watcher;
3314 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3315 GetActiveWebContents()->GetRenderProcessHost());
3316 NavigateToDestURL();
3317 channel_close_watcher.WaitForChannelClose();
3319 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3320 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3323 // Fails often on Windows dbg bots. http://crbug.com/177163
3324 #if defined(OS_WIN) && !defined(NDEBUG)
3325 #define MAYBE_TabsApi DISABLED_TabsApi
3326 #else
3327 #define MAYBE_TabsApi TabsApi
3328 #endif // defined(OS_WIN) && !defined(NDEBUG)
3329 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, MAYBE_TabsApi) {
3330 ASSERT_TRUE(StartSpawnedTestServer());
3331 extensions::FrameNavigationState::set_allow_extension_scheme(true);
3333 // Wait for the extension to set itself up and return control to us.
3334 ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html"))
3335 << message_;
3337 ResultCatcher catcher;
3339 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3341 ChannelDestructionWatcher channel_close_watcher;
3342 channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
3343 GetActiveWebContents()->GetRenderProcessHost());
3344 NavigateToDestURL();
3345 channel_close_watcher.WaitForChannelClose();
3347 ASSERT_TRUE(IsEmptyPrerenderLinkManager());
3348 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
3351 // Checks that non-http/https/chrome-extension subresource cancels the
3352 // prerender.
3353 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3354 PrerenderCancelSubresourceUnsupportedScheme) {
3355 GURL image_url = GURL("invalidscheme://www.google.com/test.jpg");
3356 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3357 replacement_text.push_back(
3358 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3359 std::string replacement_path;
3360 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3361 "files/prerender/prerender_with_image.html",
3362 replacement_text,
3363 &replacement_path));
3364 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3367 // Ensure that about:blank is permitted for any subresource.
3368 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3369 PrerenderAllowAboutBlankSubresource) {
3370 GURL image_url = GURL("about:blank");
3371 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3372 replacement_text.push_back(
3373 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3374 std::string replacement_path;
3375 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3376 "files/prerender/prerender_with_image.html",
3377 replacement_text,
3378 &replacement_path));
3379 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3380 NavigateToDestURL();
3383 // Checks that non-http/https/chrome-extension subresource cancels the prerender
3384 // on redirect.
3385 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3386 PrerenderCancelSubresourceRedirectUnsupportedScheme) {
3387 GURL image_url = test_server()->GetURL(
3388 CreateServerRedirect("invalidscheme://www.google.com/test.jpg"));
3389 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3390 replacement_text.push_back(
3391 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3392 std::string replacement_path;
3393 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3394 "files/prerender/prerender_with_image.html",
3395 replacement_text,
3396 &replacement_path));
3397 PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3400 // Checks that chrome-extension subresource does not cancel the prerender.
3401 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3402 PrerenderKeepSubresourceExtensionScheme) {
3403 GURL image_url = GURL("chrome-extension://abcdefg/test.jpg");
3404 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3405 replacement_text.push_back(
3406 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3407 std::string replacement_path;
3408 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3409 "files/prerender/prerender_with_image.html",
3410 replacement_text,
3411 &replacement_path));
3412 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3413 NavigateToDestURL();
3416 // Checks that redirect to chrome-extension subresource does not cancel the
3417 // prerender.
3418 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3419 PrerenderKeepSubresourceRedirectExtensionScheme) {
3420 GURL image_url = test_server()->GetURL(
3421 CreateServerRedirect("chrome-extension://abcdefg/test.jpg"));
3422 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
3423 replacement_text.push_back(
3424 std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
3425 std::string replacement_path;
3426 ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
3427 "files/prerender/prerender_with_image.html",
3428 replacement_text,
3429 &replacement_path));
3430 PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
3431 NavigateToDestURL();
3435 // Checks that non-http/https main page redirects cancel the prerender.
3436 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3437 PrerenderCancelMainFrameRedirectUnsupportedScheme) {
3438 GURL url = test_server()->GetURL(
3439 CreateServerRedirect("invalidscheme://www.google.com/test.html"));
3440 PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
3443 // Checks that media source video loads are deferred on prerendering.
3444 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) {
3445 PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html",
3446 FINAL_STATUS_USED,
3448 NavigateToDestUrlAndWaitForPassTitle();
3451 // Checks that a prerender that creates an audio stream (via a WebAudioDevice)
3452 // is cancelled.
3453 // http://crbug.com/261489
3454 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWebAudioDevice) {
3455 PrerenderTestURL("files/prerender/prerender_web_audio_device.html",
3456 FINAL_STATUS_CREATING_AUDIO_STREAM, 1);
3459 // Checks that prerenders do not swap in to WebContents being captured.
3460 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) {
3461 PrerenderTestURL("files/prerender/prerender_page.html",
3462 FINAL_STATUS_PAGE_BEING_CAPTURED, 1);
3463 WebContents* web_contents =
3464 current_browser()->tab_strip_model()->GetActiveWebContents();
3465 web_contents->IncrementCapturerCount();
3466 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3467 web_contents->DecrementCapturerCount();
3470 // Checks that prerenders are aborted on cross-process navigation from
3471 // a server redirect.
3472 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3473 PrerenderCrossProcessServerRedirect) {
3474 // Force everything to be a process swap.
3475 SwapProcessesContentBrowserClient test_browser_client;
3476 content::ContentBrowserClient* original_browser_client =
3477 content::SetBrowserClientForTesting(&test_browser_client);
3479 PrerenderTestURL(
3480 CreateServerRedirect("files/prerender/prerender_page.html"),
3481 FINAL_STATUS_OPEN_URL, 0);
3483 content::SetBrowserClientForTesting(original_browser_client);
3486 // Checks that prerenders are aborted on cross-process navigation from
3487 // a client redirect.
3488 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3489 PrerenderCrossProcessClientRedirect) {
3490 // Cross-process navigation logic for renderer-initiated navigations
3491 // is partially controlled by the renderer, namely
3492 // ChromeContentRendererClient. This test instead relies on the Web
3493 // Store triggering such navigations.
3494 std::string webstore_url = extension_urls::GetWebstoreLaunchURL();
3496 // Mock out requests to the Web Store.
3497 base::FilePath file(GetTestPath("prerender_page.html"));
3498 BrowserThread::PostTask(
3499 BrowserThread::IO, FROM_HERE,
3500 base::Bind(&CreateMockProtocolHandlerOnIO,
3501 GURL(webstore_url), file));
3503 PrerenderTestURL(CreateClientRedirect(webstore_url),
3504 FINAL_STATUS_OPEN_URL, 1);
3507 // Checks that canceling a MatchComplete dummy doesn't result in two
3508 // stop events.
3509 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelMatchCompleteDummy) {
3510 std::vector<FinalStatus> expected_final_status_queue;
3511 expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT);
3512 expected_final_status_queue.push_back(FINAL_STATUS_CANCELLED);
3513 ScopedVector<TestPrerender> prerenders =
3514 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
3515 expected_final_status_queue, 0);
3517 // Cancel the MatchComplete dummy.
3518 GetPrerenderManager()->CancelAllPrerenders();
3519 prerenders[1]->WaitForStop();
3521 // Check the referring page only got one copy of the event.
3522 EXPECT_FALSE(HadPrerenderEventErrors());
3525 // Checks that a deferred redirect to an image is not loaded until the
3526 // page is visible.
3527 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredImage) {
3528 // We do NOT wait for a load event, as the image will block the
3529 // load. Instead, wait for the title to change.
3530 scoped_ptr<TestPrerender> prerender =
3531 PrerenderTestURL("files/prerender/prerender_deferred_image.html",
3532 FINAL_STATUS_USED, 0, true);
3534 // The prerender hasn't loaded yet because its image is deferred.
3535 EXPECT_EQ(0, prerender->number_of_loads());
3537 // Navigate, waiting for both the swap and an extra load from the prerender.
3538 // The swap happens before the load, so |prerender->WaitForLoads(1)| doesn't
3539 // work.
3540 content::WindowedNotificationObserver page_load_observer(
3541 content::NOTIFICATION_LOAD_STOP,
3542 content::Source<NavigationController>(
3543 &prerender->contents()->prerender_contents()->GetController()));
3544 NavigationOrSwapObserver swap_observer(
3545 current_browser()->tab_strip_model(),
3546 current_browser()->tab_strip_model()->GetActiveWebContents());
3547 ui_test_utils::NavigateToURLWithDisposition(
3548 current_browser(), dest_url(), CURRENT_TAB,
3549 ui_test_utils::BROWSER_TEST_NONE);
3550 swap_observer.Wait();
3551 page_load_observer.Wait();
3553 // The prerender never observed the final load.
3554 EXPECT_EQ(0, prerender->number_of_loads());
3556 // Now check DidDisplayPass.
3557 EXPECT_TRUE(DidDisplayPass(
3558 current_browser()->tab_strip_model()->GetActiveWebContents()));
3561 // Checks that a deferred redirect to an image is not loaded until the
3562 // page is visible, even after another redirect.
3563 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3564 PrerenderDeferredImageAfterRedirect) {
3565 // We do NOT wait for a load event, as the image will block the
3566 // load. Instead, wait for the title to change.
3567 scoped_ptr<TestPrerender> prerender =
3568 PrerenderTestURL(
3569 "files/prerender/prerender_deferred_image.html#double_redirect",
3570 FINAL_STATUS_USED, 0, true);
3572 // The prerender hasn't loaded yet because its image is deferred.
3573 EXPECT_EQ(0, prerender->number_of_loads());
3575 // Navigate, waiting for both the swap and an extra load from the prerender.
3576 // The swap happens before the load, so |prerender->WaitForLoads(1)| doesn't
3577 // work.
3578 content::WindowedNotificationObserver page_load_observer(
3579 content::NOTIFICATION_LOAD_STOP,
3580 content::Source<NavigationController>(
3581 &prerender->contents()->prerender_contents()->GetController()));
3582 NavigationOrSwapObserver swap_observer(
3583 current_browser()->tab_strip_model(),
3584 current_browser()->tab_strip_model()->GetActiveWebContents());
3585 ui_test_utils::NavigateToURLWithDisposition(
3586 current_browser(), dest_url(), CURRENT_TAB,
3587 ui_test_utils::BROWSER_TEST_NONE);
3588 swap_observer.Wait();
3589 page_load_observer.Wait();
3591 // The prerender never observed the final load.
3592 EXPECT_EQ(0, prerender->number_of_loads());
3594 // Now check DidDisplayPass.
3595 EXPECT_TRUE(DidDisplayPass(
3596 current_browser()->tab_strip_model()->GetActiveWebContents()));
3599 // Checks that deferred redirects in the main frame are followed.
3600 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredMainFrame) {
3601 DisableJavascriptCalls();
3602 PrerenderTestURL(
3603 "files/prerender/image-deferred.png",
3604 FINAL_STATUS_USED, 1);
3605 NavigateToDestURL();
3608 // Checks that deferred redirects in the main frame are followed, even
3609 // with a double-redirect.
3610 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3611 PrerenderDeferredMainFrameAfterRedirect) {
3612 DisableJavascriptCalls();
3613 PrerenderTestURL(
3614 CreateServerRedirect("files/prerender/image-deferred.png"),
3615 FINAL_STATUS_USED, 1);
3616 NavigateToDestURL();
3619 // Checks that deferred redirects in a synchronous XHR abort the
3620 // prerender.
3621 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredSynchronousXHR) {
3622 PrerenderTestURL("files/prerender/prerender_deferred_sync_xhr.html",
3623 FINAL_STATUS_BAD_DEFERRED_REDIRECT, 0);
3624 NavigateToDestURL();
3627 // Checks that prerenders are not swapped for navigations with extra headers.
3628 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExtraHeadersNoSwap) {
3629 PrerenderTestURL("files/prerender/prerender_page.html",
3630 FINAL_STATUS_APP_TERMINATING, 1);
3632 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3633 content::PAGE_TRANSITION_TYPED, false);
3634 params.extra_headers = "X-Custom-Header: 42\r\n";
3635 NavigateToURLWithParams(params, false);
3638 // Checks that prerenders are not swapped for navigations with browser-initiated
3639 // POST data.
3640 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
3641 PrerenderBrowserInitiatedPostNoSwap) {
3642 PrerenderTestURL("files/prerender/prerender_page.html",
3643 FINAL_STATUS_APP_TERMINATING, 1);
3645 std::string post_data = "DATA";
3646 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3647 content::PAGE_TRANSITION_TYPED, false);
3648 params.uses_post = true;
3649 params.browser_initiated_post_data =
3650 base::RefCountedString::TakeString(&post_data);
3651 NavigateToURLWithParams(params, false);
3654 // Checks that the prerendering of a page is canceled correctly when the
3655 // prerendered page tries to make a second navigation entry.
3656 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) {
3657 PrerenderTestURL("files/prerender/prerender_new_entry.html",
3658 FINAL_STATUS_NEW_NAVIGATION_ENTRY,
3662 // Attempt a swap-in in a new tab, verifying that session storage namespace
3663 // merging works. Flaky - http://crbug.com/335835.
3664 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderPageNewTab) {
3665 // Mock out some URLs and count the number of requests to one of them. Both
3666 // prerender_session_storage.html and init_session_storage.html need to be
3667 // mocked so they are same-origin.
3668 const GURL kInitURL("http://prerender.test/init_session_storage.html");
3669 base::FilePath init_file = GetTestPath("init_session_storage.html");
3670 BrowserThread::PostTask(
3671 BrowserThread::IO, FROM_HERE,
3672 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file));
3674 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
3675 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
3676 RequestCounter counter;
3677 BrowserThread::PostTask(
3678 BrowserThread::IO, FROM_HERE,
3679 base::Bind(&CreateCountingProtocolHandlerOnIO,
3680 kTestURL, test_file, counter.AsWeakPtr()));
3682 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
3684 // Open a new tab to navigate in.
3685 ui_test_utils::NavigateToURLWithDisposition(
3686 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
3687 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3689 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
3690 // the swap does not occur synchronously.
3692 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
3693 // return value assertion and let this go through the usual successful-swap
3694 // codepath.
3695 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3697 // Verify DidDisplayPass manually since the previous call skipped it.
3698 EXPECT_TRUE(DidDisplayPass(
3699 current_browser()->tab_strip_model()->GetActiveWebContents()));
3701 // Only one request to the test URL started.
3702 EXPECT_EQ(1, counter.count());
3705 // Attempt a swap-in in a new tab, verifying that session storage namespace
3706 // merging works. Unlike the above test, the swap is for a navigation that would
3707 // normally be cross-process.
3708 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) {
3709 base::FilePath test_data_dir;
3710 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
3712 // Mock out some URLs and count the number of requests to one of them. Both
3713 // prerender_session_storage.html and init_session_storage.html need to be
3714 // mocked so they are same-origin.
3715 const GURL kInitURL("http://prerender.test/init_session_storage.html");
3716 base::FilePath init_file = GetTestPath("init_session_storage.html");
3717 BrowserThread::PostTask(
3718 BrowserThread::IO, FROM_HERE,
3719 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file));
3721 const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
3722 base::FilePath test_file = GetTestPath("prerender_session_storage.html");
3723 RequestCounter counter;
3724 BrowserThread::PostTask(
3725 BrowserThread::IO, FROM_HERE,
3726 base::Bind(&CreateCountingProtocolHandlerOnIO,
3727 kTestURL, test_file, counter.AsWeakPtr()));
3729 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
3731 // Open a new tab to navigate in.
3732 ui_test_utils::NavigateToURLWithDisposition(
3733 current_browser(), kInitURL, NEW_FOREGROUND_TAB,
3734 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3736 // Navigate to about:blank so the next navigation is cross-process.
3737 ui_test_utils::NavigateToURL(current_browser(),
3738 GURL(content::kAboutBlankURL));
3740 // Now navigate in the new tab. Set expect_swap_to_succeed to false because
3741 // the swap does not occur synchronously.
3743 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
3744 // return value assertion and let this go through the usual successful-swap
3745 // codepath.
3746 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3748 // Verify DidDisplayPass manually since the previous call skipped it.
3749 EXPECT_TRUE(DidDisplayPass(
3750 current_browser()->tab_strip_model()->GetActiveWebContents()));
3752 // Only one request to the test URL started.
3753 EXPECT_EQ(1, counter.count());
3756 // Verify that session storage conflicts don't merge.
3757 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) {
3758 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html",
3759 FINAL_STATUS_APP_TERMINATING, 1);
3761 // Open a new tab to navigate in.
3762 ui_test_utils::NavigateToURLWithDisposition(
3763 current_browser(),
3764 test_server()->GetURL("files/prerender/init_session_storage.html"),
3765 NEW_FOREGROUND_TAB,
3766 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3768 // Now navigate in the new tab.
3769 NavigateToDestURLWithDisposition(CURRENT_TAB, false);
3771 // Verify DidDisplayPass in the new tab.
3772 EXPECT_TRUE(DidDisplayPass(
3773 current_browser()->tab_strip_model()->GetActiveWebContents()));
3776 // Checks that prerenders honor |should_replace_current_entry|.
3777 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReplaceCurrentEntry) {
3778 PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
3780 content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
3781 content::PAGE_TRANSITION_TYPED, false);
3782 params.should_replace_current_entry = true;
3783 NavigateToURLWithParams(params, false);
3785 WebContents* web_contents =
3786 current_browser()->tab_strip_model()->GetActiveWebContents();
3787 const NavigationController& controller = web_contents->GetController();
3788 // First entry is about:blank, second is prerender_page.html.
3789 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
3790 EXPECT_EQ(2, controller.GetEntryCount());
3791 EXPECT_EQ(GURL(content::kAboutBlankURL),
3792 controller.GetEntryAtIndex(0)->GetURL());
3793 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL());
3796 } // namespace prerender