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