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