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