prerender_browsertest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright (c) 2012 The Chromium Authors. All rights reserved.
27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Use of this source code is governed by a BSD-style license that can be
37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// found in the LICENSE file.
47faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include <deque>
67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include <vector>
77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/command_line.h"
97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/path_service.h"
107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/prefs/pref_service.h"
117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/string_util.h"
127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/stringprintf.h"
137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/test/test_timeouts.h"
147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/utf_string_conversions.h"
157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "base/values.h"
167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/browsing_data/browsing_data_helper.h"
177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/browsing_data/browsing_data_remover.h"
187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/content_settings/host_content_settings_map.h"
197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/extensions/extension_apitest.h"
217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/favicon/favicon_tab_helper.h"
227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_contents.h"
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_handle.h"
247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_link_manager.h"
257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_link_manager_factory.h"
267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_manager.h"
277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/prerender/prerender_manager_factory.h"
287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/profiles/profile.h"
297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/safe_browsing/database_manager.h"
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/safe_browsing/safe_browsing_service.h"
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/safe_browsing/safe_browsing_util.h"
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/task_manager/task_manager.h"
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/task_manager/task_manager_browsertest_util.h"
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/ui/browser.h"
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/ui/browser_commands.h"
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/ui/browser_finder.h"
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/ui/browser_window.h"
387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/browser/ui/tabs/tab_strip_model.h"
397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/common/chrome_notification_types.h"
407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/common/chrome_paths.h"
417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/common/chrome_switches.h"
427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/common/pref_names.h"
437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/test/base/in_process_browser_test.h"
447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "chrome/test/base/ui_test_utils.h"
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/browser_message_filter.h"
467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/devtools_agent_host.h"
477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/devtools_client_host.h"
487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/devtools_manager.h"
497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/notification_service.h"
507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/render_process_host.h"
517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/render_view_host.h"
527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/browser/web_contents.h"
537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/common/url_constants.h"
547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/test/browser_test_utils.h"
557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/test/test_navigation_observer.h"
567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "content/public/test/test_utils.h"
577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "googleurl/src/gurl.h"
587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "grit/generated_resources.h"
597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "net/dns/mock_host_resolver.h"
607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "net/url_request/url_request_context.h"
617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "net/url_request/url_request_context_getter.h"
627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "ui/base/l10n/l10n_util.h"
637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::BrowserThread;
657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::DevToolsAgentHost;
667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::DevToolsClientHost;
677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::DevToolsManager;
687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::NavigationController;
697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::OpenURLParams;
707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::Referrer;
717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::RenderViewHost;
727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::RenderWidgetHost;
737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing content::WebContents;
747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Prerender tests work as follows:
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// A page with a prefetch link to the test page is loaded.  Once prerendered,
787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// its Javascript function DidPrerenderPass() is called, which returns true if
797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// the page behaves as expected when prerendered.
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// The prerendered page is then displayed on a tab.  The Javascript function
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// DidDisplayPass() is called, and returns true if the page behaved as it
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// should while being displayed.
847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace prerender {
867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace {
887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Constants used in the test HTML files.
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic const char* kReadyTitle = "READY";
917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic const char* kPassTitle = "PASS";
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstd::string CreateClientRedirect(const std::string& dest_url) {
947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char* const kClientRedirectBase = "client-redirect?";
957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return kClientRedirectBase + dest_url;
967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstd::string CreateServerRedirect(const std::string& dest_url) {
997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char* const kServerRedirectBase = "server-redirect?";
1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return kServerRedirectBase + dest_url;
1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Clears the specified data using BrowsingDataRemover.
1047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid ClearBrowsingData(Browser* browser, int remove_mask) {
1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  BrowsingDataRemover* remover =
1067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // BrowsingDataRemover deletes itself.
1097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid CancelAllPrerenders(PrerenderManager* prerender_manager) {
1127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  prerender_manager->CancelAllPrerenders();
1137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Returns true if and only if the final status is one in which the prerendered
1167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// page should prerender correctly. The page still may not be used.
1177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezbool ShouldRenderPrerenderedPageCorrectly(FinalStatus status) {
1187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  switch (status) {
1197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_USED:
1207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_WINDOW_OPENER:
1217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_APP_TERMINATING:
1227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
1237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // We'll crash the renderer after it's loaded.
1247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_RENDERER_CRASHED:
1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_CANCELLED:
1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    case FINAL_STATUS_DEVTOOLS_ATTACHED:
1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return true;
1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    default:
1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return false;
1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Waits for the destruction of a RenderProcessHost's IPC channel.
1347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Used to make sure the PrerenderLinkManager's OnChannelClosed function has
1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// been called, before checking its state.
1367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass ChannelDestructionWatcher {
1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
1387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  ChannelDestructionWatcher() : channel_destroyed_(false),
1397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                waiting_for_channel_destruction_(false) {
1407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  ~ChannelDestructionWatcher() {
1437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void WatchChannel(content::RenderProcessHost* host) {
1467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    host->GetChannel()->AddFilter(new DestructionMessageFilter(this));
1477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void WaitForChannelClose() {
1507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ASSERT_FALSE(waiting_for_channel_destruction_);
1517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (channel_destroyed_)
1537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return;
1547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    waiting_for_channel_destruction_ = true;
1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    content::RunMessageLoop();
1567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EXPECT_FALSE(waiting_for_channel_destruction_);
1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EXPECT_TRUE(channel_destroyed_);
1597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
1627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed.
1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Ignores all messages.
1647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  class DestructionMessageFilter : public content::BrowserMessageFilter {
1657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez   public:
1667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez     explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher)
1677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez         : watcher_(watcher) {
1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez   private:
1717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual ~DestructionMessageFilter() {
1727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      content::BrowserThread::PostTask(
1737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          content::BrowserThread::UI, FROM_HERE,
1747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
1757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                     base::Unretained(watcher_)));
1767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual bool OnMessageReceived(const IPC::Message& message,
1797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                   bool* message_was_ok) OVERRIDE {
1807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return false;
1817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ChannelDestructionWatcher* watcher_;
1847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter);
1867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  };
1877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void OnChannelDestroyed() {
1897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EXPECT_FALSE(channel_destroyed_);
1927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    channel_destroyed_ = true;
1937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (waiting_for_channel_destruction_) {
1947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      waiting_for_channel_destruction_ = false;
1957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      MessageLoop::current()->Quit();
1967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
1987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool channel_destroyed_;
2007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool waiting_for_channel_destruction_;
2017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher);
2037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
2047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// PrerenderContents that stops the UI message loop on DidStopLoading().
2067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass TestPrerenderContents : public PrerenderContents {
2077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
2087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  TestPrerenderContents(
2097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      PrerenderManager* prerender_manager,
2107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      Profile* profile,
2117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const GURL& url,
2127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const content::Referrer& referrer,
2137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      Origin origin,
2147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      int expected_number_of_loads,
2157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      FinalStatus expected_final_status,
2167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      bool prerender_should_wait_for_ready_title)
2177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : PrerenderContents(prerender_manager, profile, url,
2187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          referrer, origin, PrerenderManager::kNoExperiment),
2197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        number_of_loads_(0),
2207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        expected_number_of_loads_(expected_number_of_loads),
2217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        expected_final_status_(expected_final_status),
2227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        new_render_view_host_(NULL),
2237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        was_hidden_(false),
2247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        was_shown_(false),
2257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        should_be_shown_(expected_final_status == FINAL_STATUS_USED),
2267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        quit_message_loop_on_destruction_(
2277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            expected_final_status != FINAL_STATUS_APP_TERMINATING &&
2287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            expected_final_status != FINAL_STATUS_MAX),
2297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        expected_pending_prerenders_(0),
2307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        prerender_should_wait_for_ready_title_(
2317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            prerender_should_wait_for_ready_title) {
2327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (expected_number_of_loads == 0)
2337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      MessageLoopForUI::current()->Quit();
2347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
2357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~TestPrerenderContents() {
2377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (expected_final_status_ == FINAL_STATUS_MAX) {
2387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      EXPECT_EQ(match_complete_status(), MATCH_COMPLETE_REPLACEMENT);
2397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    } else {
2407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      EXPECT_EQ(expected_final_status_, final_status()) <<
2417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          " when testing URL " << prerender_url().path() <<
2427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
2437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          ", Actual: " << NameFromFinalStatus(final_status()) << ")";
2447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
2457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // Prerendering RenderViewHosts should be hidden before the first
2467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // navigation, so this should be happen for every PrerenderContents for
2477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // which a RenderViewHost is created, regardless of whether or not it's
2487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // used.
2497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (new_render_view_host_)
2507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      EXPECT_TRUE(was_hidden_);
2517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // A used PrerenderContents will only be destroyed when we swap out
2537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // WebContents, at the end of a navigation caused by a call to
2547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // NavigateToURLImpl().
2557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (final_status() == FINAL_STATUS_USED)
2567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      EXPECT_TRUE(new_render_view_host_);
2577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EXPECT_EQ(should_be_shown_, was_shown_);
2597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // When the PrerenderContents is destroyed, quit the UI message loop.
2617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // This happens on navigation to used prerendered pages, and soon
2627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // after cancellation of unused prerendered pages.
2637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (quit_message_loop_on_destruction_) {
2647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      // The message loop may not be running if this is swapped in
2657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      // synchronously on a Navigation.
2667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      MessageLoop* loop = MessageLoopForUI::current();
2677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      if (loop->is_running())
2687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        loop->Quit();
2697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
2707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
2717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
2737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // On quit, it's possible to end up here when render processes are closed
2747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // before the PrerenderManager is destroyed.  As a result, it's possible to
2757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
2767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // on quit.
2777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    //
2787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // It's also possible for this to be called after we've been notified of
2797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // app termination, but before we've been deleted, which is why the second
2807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // check is needed.
2817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
2827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        final_status() != expected_final_status_) {
2837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
2847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
2857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PrerenderContents::RenderViewGone(status);
2877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
2887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual bool AddAliasURL(const GURL& url) OVERRIDE {
2907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
2917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // the PrerenderRendererCrash test.
2927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (url.spec() != content::kChromeUICrashURL)
2937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return PrerenderContents::AddAliasURL(url);
2947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return true;
2957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
2967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
2987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PrerenderContents::DidStopLoading(render_view_host);
2997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ++number_of_loads_;
3007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (ShouldRenderPrerenderedPageCorrectly(expected_final_status_) &&
3017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        number_of_loads_ == expected_number_of_loads_) {
3027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      MessageLoopForUI::current()->Quit();
3037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void AddPendingPrerender(
3077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      scoped_ptr<PendingPrerenderInfo> pending_prerender_info) OVERRIDE {
3087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PrerenderContents::AddPendingPrerender(pending_prerender_info.Pass());
3097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (expected_pending_prerenders_ > 0 &&
3107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        pending_prerender_count() == expected_pending_prerenders_) {
3117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      MessageLoop::current()->Quit();
3127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual WebContents* CreateWebContents(
3167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      content::SessionStorageNamespace* session_storage_namespace) OVERRIDE {
3177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    WebContents* web_contents = PrerenderContents::CreateWebContents(
3187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        session_storage_namespace);
3197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    string16 ready_title = ASCIIToUTF16(kReadyTitle);
3207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (prerender_should_wait_for_ready_title_)
3217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      ready_title_watcher_.reset(new content::TitleWatcher(
3227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          web_contents, ready_title));
3237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return web_contents;
3247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void WaitForPrerenderToHaveReadyTitleIfRequired() {
3277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (ready_title_watcher_.get()) {
3287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      string16 ready_title = ASCIIToUTF16(kReadyTitle);
3297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      ASSERT_EQ(ready_title, ready_title_watcher_->WaitAndGetTitle());
3307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Waits until the prerender has |expected_pending_prerenders| pending
3347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // prerenders.
3357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void WaitForPendingPrerenders(size_t expected_pending_prerenders) {
3367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (pending_prerender_count() < expected_pending_prerenders) {
3377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      expected_pending_prerenders_ = expected_pending_prerenders;
3387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      content::RunMessageLoop();
3397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      expected_pending_prerenders_ = 0;
3407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EXPECT_EQ(expected_pending_prerenders, pending_prerender_count());
3437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // For tests that open the prerender in a new background tab, the RenderView
3467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // will not have been made visible when the PrerenderContents is destroyed
3477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // even though it is used.
3487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void set_should_be_shown(bool value) { should_be_shown_ = value; }
3497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  int number_of_loads() const { return number_of_loads_; }
3517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FinalStatus expected_final_status() const { return expected_final_status_; }
3537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool quit_message_loop_on_destruction() const {
3557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return quit_message_loop_on_destruction_;
3567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
3597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void OnRenderViewHostCreated(
3607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      RenderViewHost* new_render_view_host) OVERRIDE {
3617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // Used to make sure the RenderViewHost is hidden and, if used,
3627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // subsequently shown.
3637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    notification_registrar().Add(
3647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        this,
3657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
3667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        content::Source<RenderWidgetHost>(new_render_view_host));
3677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    new_render_view_host_ = new_render_view_host;
3697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
3717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void Observe(int type,
3747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                       const content::NotificationSource& source,
3757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                       const content::NotificationDetails& details) OVERRIDE {
3767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (type ==
3777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
3787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      EXPECT_EQ(new_render_view_host_,
3797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                content::Source<RenderWidgetHost>(source).ptr());
3807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      bool is_visible = *content::Details<bool>(details).ptr();
3817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      if (!is_visible) {
3837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        was_hidden_ = true;
3847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      } else if (is_visible && was_hidden_) {
3857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // Once hidden, a prerendered RenderViewHost should only be shown after
3867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // being removed from the PrerenderContents for display.
3877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        EXPECT_FALSE(GetRenderViewHost());
3887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        was_shown_ = true;
3897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      }
3907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return;
3917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PrerenderContents::Observe(type, source, details);
3937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
3947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  int number_of_loads_;
3967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  int expected_number_of_loads_;
3977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FinalStatus expected_final_status_;
3987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // The RenderViewHost created for the prerender, if any.
4007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  RenderViewHost* new_render_view_host_;
4017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Set to true when the prerendering RenderWidget is hidden.
4027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool was_hidden_;
4037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Set to true when the prerendering RenderWidget is shown, after having been
4047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // hidden.
4057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool was_shown_;
4067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Expected final value of was_shown_.  Defaults to true for
4077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // FINAL_STATUS_USED, and false otherwise.
4087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool should_be_shown_;
4097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // If true, quits message loop on destruction of |this|.
4117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool quit_message_loop_on_destruction_;
4127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Total number of pending prerenders we're currently waiting for.  Zero
4147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // indicates we currently aren't waiting for any.
4157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  size_t expected_pending_prerenders_;
4167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // If true, before calling DidPrerenderPass, will wait for the title of the
4187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // prerendered page to turn to "READY".
4197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool prerender_should_wait_for_ready_title_;
4207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  scoped_ptr<content::TitleWatcher> ready_title_watcher_;
4217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
4227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// PrerenderManager that uses TestPrerenderContents.
4247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
4257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
4267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  WaitForLoadPrerenderContentsFactory(
4277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      int expected_number_of_loads,
4287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const std::deque<FinalStatus>& expected_final_status_queue,
4297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      bool prerender_should_wait_for_ready_title)
4307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : expected_number_of_loads_(expected_number_of_loads),
4317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        expected_final_status_queue_(expected_final_status_queue),
4327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        prerender_should_wait_for_ready_title_(
4337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            prerender_should_wait_for_ready_title) {
4347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    VLOG(1) << "Factory created with queue length " <<
4357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez               expected_final_status_queue_.size();
4367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
4377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual PrerenderContents* CreatePrerenderContents(
4397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      PrerenderManager* prerender_manager,
4407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      Profile* profile,
4417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const GURL& url,
4427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const content::Referrer& referrer,
4437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      Origin origin,
4447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      uint8 experiment_id) OVERRIDE {
4457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    FinalStatus expected_final_status = FINAL_STATUS_MAX;
4467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (!expected_final_status_queue_.empty()) {
4477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      expected_final_status = expected_final_status_queue_.front();
4487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      expected_final_status_queue_.pop_front();
4497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
4507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    VLOG(1) << "Creating prerender contents for " << url.path() <<
4517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez               " with expected final status " << expected_final_status;
4527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    VLOG(1) << expected_final_status_queue_.size() << " left in the queue.";
4537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return new TestPrerenderContents(prerender_manager,
4547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     profile, url, referrer, origin,
4557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     expected_number_of_loads_,
4567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     expected_final_status,
4577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     prerender_should_wait_for_ready_title_);
4587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
4597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
4617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  int expected_number_of_loads_;
4627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  std::deque<FinalStatus> expected_final_status_queue_;
4637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  bool prerender_should_wait_for_ready_title_;
4647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
4657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if defined(FULL_SAFE_BROWSING)
4677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// A SafeBrowsingDatabaseManager implementation that returns a fixed result for
4687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// a given URL.
4697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass FakeSafeBrowsingDatabaseManager :  public SafeBrowsingDatabaseManager {
4707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
4717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
4727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : SafeBrowsingDatabaseManager(service),
4737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        threat_type_(SB_THREAT_TYPE_SAFE) { }
4747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Called on the IO thread to check if the given url is safe or not.  If we
4767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // can synchronously determine that the url is safe, CheckUrl returns true.
4777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Otherwise it returns false, and "client" is called asynchronously with the
4787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // result when it is ready.
4797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Returns true, indicating a SAFE result, unless the URL is the fixed URL
4807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // specified by the user, and the user-specified result is not SAFE
4817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // (in which that result will be communicated back via a call into the
4827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // client, and false will be returned).
4837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Overrides SafeBrowsingService::CheckBrowseUrl.
4847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE {
4857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
4867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return true;
4877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    BrowserThread::PostTask(
4897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        BrowserThread::IO, FROM_HERE,
4907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
4917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                   this, gurl, client));
4927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return false;
4937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
4947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) {
4967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    url_ = url;
4977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    threat_type_ = threat_type;
4987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
4997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
5017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~FakeSafeBrowsingDatabaseManager() {}
5027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
5047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
5057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        std::vector<GURL>(1, gurl),
5067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        std::vector<SBFullHash>(),
5077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        client,
5087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        safe_browsing_util::MALWARE);
5097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    sb_check.url_results[0] = threat_type_;
5107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    client->OnSafeBrowsingResult(sb_check);
5117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  GURL url_;
5147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  SBThreatType threat_type_;
5157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
5167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
5177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass FakeSafeBrowsingService : public SafeBrowsingService {
5197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
5207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeSafeBrowsingService() { }
5217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Returned pointer has the same lifespan as the database_manager_ refcounted
5237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // object.
5247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeSafeBrowsingDatabaseManager* fake_database_manager() {
5257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return fake_database_manager_;
5267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez protected:
5297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~FakeSafeBrowsingService() { }
5307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
5327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
5337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return fake_database_manager_;
5347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
5377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeSafeBrowsingDatabaseManager* fake_database_manager_;
5387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
5407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
5417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Factory that creates FakeSafeBrowsingService instances.
5437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
5447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
5457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  TestSafeBrowsingServiceFactory() :
5467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      most_recent_service_(NULL) { }
5477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~TestSafeBrowsingServiceFactory() { }
5487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
5507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    most_recent_service_ =  new FakeSafeBrowsingService();
5517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return most_recent_service_;
5527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeSafeBrowsingService* most_recent_service() const {
5557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return most_recent_service_;
5567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
5597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeSafeBrowsingService* most_recent_service_;
5607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
5617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
5627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass FakeDevToolsClientHost : public DevToolsClientHost {
5647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
5657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  FakeDevToolsClientHost() {}
5667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~FakeDevToolsClientHost() {}
5677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void InspectedContentsClosing() OVERRIDE {}
5687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {}
5697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void ReplacedWithAnotherClient() OVERRIDE {}
5707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
5717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass RestorePrerenderMode {
5737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
5747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
5757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
5767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
5787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez private:
5797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  PrerenderManager::PrerenderManagerMode prev_mode_;
5807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
5817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}  // namespace
5837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass PrerenderBrowserTest : virtual public InProcessBrowserTest {
5857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
5867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  PrerenderBrowserTest()
5877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : autostart_test_server_(true),
5887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        prerender_contents_factory_(NULL),
5897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if defined(FULL_SAFE_BROWSING)
5907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
5917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
5927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        use_https_src_server_(false),
5937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        call_javascript_(true),
5947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        loader_path_("files/prerender/prerender_loader.html"),
5957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        explicitly_set_browser_(NULL) {}
5967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual ~PrerenderBrowserTest() {}
5987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  content::SessionStorageNamespace* GetSessionStorageNamespace() const {
6007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    WebContents* web_contents =
6017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        current_browser()->tab_strip_model()->GetActiveWebContents();
6027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (!web_contents)
6037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return NULL;
6047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return web_contents->GetController().GetDefaultSessionStorageNamespace();
6057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
6067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
6087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if defined(FULL_SAFE_BROWSING)
6097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
6107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
6117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
6127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
6147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    command_line->AppendSwitchASCII(switches::kPrerenderMode,
6157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                    switches::kPrerenderModeSwitchValueEnabled);
6167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if defined(OS_MACOSX)
6177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // The plugins directory isn't read by default on the Mac, so it needs to be
6187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // explicitly registered.
6197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    base::FilePath app_dir;
6207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PathService::Get(chrome::DIR_APP, &app_dir);
6217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    command_line->AppendSwitchPath(
6227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        switches::kExtraPluginDir,
6237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        app_dir.Append(FILE_PATH_LITERAL("plugins")));
6247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
625    command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
626  }
627
628  virtual void SetUpOnMainThread() OVERRIDE {
629    current_browser()->profile()->GetPrefs()->SetBoolean(
630        prefs::kPromptForDownload, false);
631    IncreasePrerenderMemory();
632    if (autostart_test_server_)
633      ASSERT_TRUE(test_server()->Start());
634  }
635
636  // Overload for a single expected final status
637  void PrerenderTestURL(const std::string& html_file,
638                        FinalStatus expected_final_status,
639                        int expected_number_of_loads) {
640    PrerenderTestURL(html_file,
641                     expected_final_status,
642                     expected_number_of_loads,
643                     false);
644  }
645
646  void PrerenderTestURL(const std::string& html_file,
647                        FinalStatus expected_final_status,
648                        int expected_number_of_loads,
649                        bool prerender_should_wait_for_ready_title) {
650    std::deque<FinalStatus> expected_final_status_queue(1,
651                                                        expected_final_status);
652    PrerenderTestURL(html_file,
653                     expected_final_status_queue,
654                     expected_number_of_loads,
655                     prerender_should_wait_for_ready_title);
656  }
657
658  void PrerenderTestURL(
659      const std::string& html_file,
660      const std::deque<FinalStatus>& expected_final_status_queue,
661      int expected_number_of_loads,
662      bool prerender_should_wait_for_ready_title) {
663    GURL url = test_server()->GetURL(html_file);
664    PrerenderTestURLImpl(url, url,
665                         expected_final_status_queue,
666                         expected_number_of_loads,
667                         prerender_should_wait_for_ready_title);
668  }
669
670  void PrerenderTestURL(
671      const std::string& html_file,
672      const std::deque<FinalStatus>& expected_final_status_queue,
673      int expected_number_of_loads) {
674    PrerenderTestURL(html_file, expected_final_status_queue,
675                     expected_number_of_loads, false);
676  }
677
678  void PrerenderTestURL(
679      const GURL& url,
680      FinalStatus expected_final_status,
681      int expected_number_of_loads) {
682    std::deque<FinalStatus> expected_final_status_queue(1,
683                                                        expected_final_status);
684    PrerenderTestURLImpl(url, url,
685                         expected_final_status_queue,
686                         expected_number_of_loads,
687                         false);
688  }
689
690  void PrerenderTestURL(
691      const GURL& prerender_url,
692      const GURL& destination_url,
693      FinalStatus expected_final_status,
694      int expected_number_of_loads) {
695    std::deque<FinalStatus> expected_final_status_queue(1,
696                                                        expected_final_status);
697    PrerenderTestURLImpl(prerender_url, destination_url,
698                         expected_final_status_queue,
699                         expected_number_of_loads,
700                         false);
701  }
702
703  void NavigateToDestURL() const {
704    NavigateToDestURLWithDisposition(CURRENT_TAB);
705  }
706
707  // Opens the url in a new tab, with no opener.
708  void NavigateToDestURLWithDisposition(
709      WindowOpenDisposition disposition) const {
710    NavigateToURLImpl(dest_url_, disposition);
711  }
712
713  void OpenDestURLViaClick() const {
714    OpenDestURLWithJSImpl("Click()");
715  }
716
717  void OpenDestURLViaClickTarget() const {
718    OpenDestURLWithJSImpl("ClickTarget()");
719  }
720
721  void OpenDestURLViaClickNewWindow() const {
722    OpenDestURLWithJSImpl("ShiftClick()");
723  }
724
725  void OpenDestURLViaClickNewForegroundTab() const {
726#if defined(OS_MACOSX)
727    OpenDestURLWithJSImpl("MetaShiftClick()");
728#else
729    OpenDestURLWithJSImpl("CtrlShiftClick()");
730#endif
731  }
732
733  void OpenDestURLViaClickNewBackgroundTab() const {
734    TestPrerenderContents* prerender_contents = GetPrerenderContents();
735    ASSERT_TRUE(prerender_contents != NULL);
736    prerender_contents->set_should_be_shown(false);
737#if defined(OS_MACOSX)
738    OpenDestURLWithJSImpl("MetaClick()");
739#else
740    OpenDestURLWithJSImpl("CtrlClick()");
741#endif
742  }
743
744  void OpenDestURLViaWindowOpen() const {
745    OpenDestURLWithJSImpl("WindowOpen()");
746  }
747
748  void RemoveLinkElement(int i) const {
749    current_browser()->tab_strip_model()->GetActiveWebContents()->
750        GetRenderViewHost()->ExecuteJavascriptInWebFrame(
751            string16(),
752            ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i)));
753  }
754
755  void ClickToNextPageAfterPrerender() {
756    content::WindowedNotificationObserver new_page_observer(
757        content::NOTIFICATION_NAV_ENTRY_COMMITTED,
758        content::NotificationService::AllSources());
759    RenderViewHost* render_view_host = current_browser()->tab_strip_model()->
760        GetActiveWebContents()->GetRenderViewHost();
761    render_view_host->ExecuteJavascriptInWebFrame(
762        string16(),
763        ASCIIToUTF16("ClickOpenLink()"));
764    new_page_observer.Wait();
765  }
766
767  void NavigateToNextPageAfterPrerender() const {
768    ui_test_utils::NavigateToURL(
769        current_browser(),
770        test_server()->GetURL("files/prerender/prerender_page.html"));
771  }
772
773  void NavigateToDestUrlAndWaitForPassTitle() {
774    string16 expected_title = ASCIIToUTF16(kPassTitle);
775    content::TitleWatcher title_watcher(
776        GetPrerenderContents()->prerender_contents(),
777        expected_title);
778    NavigateToDestURL();
779    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
780  }
781
782  // Called after the prerendered page has been navigated to and then away from.
783  // Navigates back through the history to the prerendered page.
784  void GoBackToPrerender() {
785    content::WindowedNotificationObserver back_nav_observer(
786        content::NOTIFICATION_NAV_ENTRY_COMMITTED,
787        content::NotificationService::AllSources());
788    chrome::GoBack(current_browser(), CURRENT_TAB);
789    back_nav_observer.Wait();
790    bool original_prerender_page = false;
791    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
792        current_browser()->tab_strip_model()->GetActiveWebContents(),
793        "window.domAutomationController.send(IsOriginalPrerenderPage())",
794        &original_prerender_page));
795    EXPECT_TRUE(original_prerender_page);
796  }
797
798  // Goes back to the page that was active before the prerender was swapped
799  // in. This must be called when the prerendered page is the current page
800  // in the active tab.
801  void GoBackToPageBeforePrerender() {
802    WebContents* tab =
803        current_browser()->tab_strip_model()->GetActiveWebContents();
804    ASSERT_TRUE(tab);
805    EXPECT_FALSE(tab->IsLoading());
806    content::WindowedNotificationObserver back_nav_observer(
807        content::NOTIFICATION_LOAD_STOP,
808        content::Source<NavigationController>(&tab->GetController()));
809    chrome::GoBack(current_browser(), CURRENT_TAB);
810    back_nav_observer.Wait();
811    bool js_result;
812    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
813        tab,
814        "window.domAutomationController.send(DidBackToOriginalPagePass())",
815        &js_result));
816    EXPECT_TRUE(js_result);
817  }
818
819  void NavigateToURL(const std::string& dest_html_file) const {
820    GURL dest_url = test_server()->GetURL(dest_html_file);
821    NavigateToURLImpl(dest_url, CURRENT_TAB);
822  }
823
824  bool UrlIsInPrerenderManager(const std::string& html_file) const {
825    return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
826  }
827
828  bool UrlIsInPrerenderManager(const GURL& url) const {
829    return GetPrerenderManager()->FindPrerenderData(
830        url, GetSessionStorageNamespace()) != NULL;
831  }
832
833  void set_use_https_src(bool use_https_src_server) {
834    use_https_src_server_ = use_https_src_server;
835  }
836
837  void DisableJavascriptCalls() {
838    call_javascript_ = false;
839  }
840
841  TaskManagerModel* GetModel() const {
842    return TaskManager::GetInstance()->model();
843  }
844
845  PrerenderManager* GetPrerenderManager() const {
846    PrerenderManager* prerender_manager =
847        PrerenderManagerFactory::GetForProfile(current_browser()->profile());
848    return prerender_manager;
849  }
850
851  const PrerenderLinkManager* GetPrerenderLinkManager() const {
852    PrerenderLinkManager* prerender_link_manager =
853        PrerenderLinkManagerFactory::GetForProfile(
854            current_browser()->profile());
855    return prerender_link_manager;
856  }
857
858  bool DidReceivePrerenderStartEventForLinkNumber(int index) const {
859    bool received_prerender_started;
860    std::string expression = base::StringPrintf(
861        "window.domAutomationController.send(Boolean("
862            "receivedPrerenderStartEvents[%d]))", index);
863
864    CHECK(content::ExecuteScriptAndExtractBool(
865        current_browser()->tab_strip_model()->GetActiveWebContents(),
866        expression,
867        &received_prerender_started));
868    return received_prerender_started;
869  }
870
871  bool DidReceivePrerenderLoadEventForLinkNumber(int index) const {
872    bool received_prerender_loaded;
873    std::string expression = base::StringPrintf(
874        "window.domAutomationController.send(Boolean("
875            "receivedPrerenderLoadEvents[%d]))", index);
876
877    CHECK(content::ExecuteScriptAndExtractBool(
878        current_browser()->tab_strip_model()->GetActiveWebContents(),
879        expression,
880        &received_prerender_loaded));
881    return received_prerender_loaded;
882  }
883
884  bool DidReceivePrerenderStopEventForLinkNumber(int index) const {
885    bool received_prerender_stopped;
886    std::string expression = base::StringPrintf(
887        "window.domAutomationController.send(Boolean("
888            "receivedPrerenderStopEvents[%d]))", index);
889
890    CHECK(content::ExecuteScriptAndExtractBool(
891        current_browser()->tab_strip_model()->GetActiveWebContents(),
892        expression,
893        &received_prerender_stopped));
894    return received_prerender_stopped;
895  }
896
897  bool HadPrerenderEventErrors() const {
898    bool had_prerender_event_errors;
899    CHECK(content::ExecuteScriptAndExtractBool(
900        current_browser()->tab_strip_model()->GetActiveWebContents(),
901        "window.domAutomationController.send(Boolean("
902        "    hadPrerenderEventErrors))",
903        &had_prerender_event_errors));
904    return had_prerender_event_errors;
905  }
906
907  // Asserting on this can result in flaky tests.  PrerenderHandles are
908  // removed from the PrerenderLinkManager when the prerender is canceled from
909  // the browser, when the prerenders are cancelled from the renderer process,
910  // or the channel for the renderer process is closed on the IO thread.  In the
911  // last case, the code must be careful to wait for the channel to close, as it
912  // is done asynchronously after swapping out the old process.  See
913  // ChannelDestructionWatcher.
914  bool IsEmptyPrerenderLinkManager() const {
915    return GetPrerenderLinkManager()->IsEmpty();
916  }
917
918  // Returns length of |prerender_manager_|'s history, or -1 on failure.
919  int GetHistoryLength() const {
920    scoped_ptr<DictionaryValue> prerender_dict(
921        static_cast<DictionaryValue*>(GetPrerenderManager()->GetAsValue()));
922    if (!prerender_dict.get())
923      return -1;
924    ListValue* history_list;
925    if (!prerender_dict->GetList("history", &history_list))
926      return -1;
927    return static_cast<int>(history_list->GetSize());
928  }
929
930#if defined(FULL_SAFE_BROWSING)
931  FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() {
932    return safe_browsing_factory_->most_recent_service()->
933        fake_database_manager();
934  }
935#endif
936
937  TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const {
938    PrerenderManager::PrerenderData* prerender_data =
939        GetPrerenderManager()->FindPrerenderData(
940            url, GetSessionStorageNamespace());
941    return static_cast<TestPrerenderContents*>(
942        prerender_data ? prerender_data->contents() : NULL);
943  }
944
945  TestPrerenderContents* GetPrerenderContents() const {
946    return GetPrerenderContentsFor(dest_url_);
947  }
948
949  void set_loader_path(const std::string& path) {
950    loader_path_ = path;
951  }
952
953  void set_loader_query_and_fragment(const std::string& query_and_fragment) {
954    loader_query_and_fragment_ = query_and_fragment;
955  }
956
957  GURL GetCrossDomainTestUrl(const std::string& path) {
958    static const std::string secondary_domain = "www.foo.com";
959    host_resolver()->AddRule(secondary_domain, "127.0.0.1");
960    std::string url_str(base::StringPrintf(
961        "http://%s:%d/%s",
962        secondary_domain.c_str(),
963        test_server()->host_port_pair().port(),
964        path.c_str()));
965    return GURL(url_str);
966  }
967
968  void set_browser(Browser* browser) {
969    explicitly_set_browser_ = browser;
970  }
971
972  Browser* current_browser() const {
973    return explicitly_set_browser_ ? explicitly_set_browser_ : browser();
974  }
975
976  void IncreasePrerenderMemory() {
977    // Increase the memory allowed in a prerendered page above normal settings.
978    // Debug build bots occasionally run against the default limit, and tests
979    // were failing because the prerender was canceled due to memory exhaustion.
980    // http://crbug.com/93076
981    GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024;
982  }
983
984 protected:
985  bool autostart_test_server_;
986
987 private:
988  void PrerenderTestURLImpl(
989      const GURL& prerender_url,
990      const GURL& destination_url,
991      const std::deque<FinalStatus>& expected_final_status_queue,
992      int expected_number_of_loads,
993      bool prerender_should_wait_for_ready_title) {
994    dest_url_ = destination_url;
995
996    std::vector<net::TestServer::StringPair> replacement_text;
997    replacement_text.push_back(
998        make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
999    replacement_text.push_back(
1000        make_pair("REPLACE_WITH_DESTINATION_URL", destination_url.spec()));
1001    std::string replacement_path;
1002    ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
1003        loader_path_,
1004        replacement_text,
1005        &replacement_path));
1006
1007    const net::TestServer* src_server = test_server();
1008    scoped_ptr<net::TestServer> https_src_server;
1009    if (use_https_src_server_) {
1010      https_src_server.reset(
1011          new net::TestServer(
1012                  net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1013                  base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
1014      ASSERT_TRUE(https_src_server->Start());
1015      src_server = https_src_server.get();
1016    }
1017    GURL loader_url = src_server->GetURL(replacement_path +
1018                                         loader_query_and_fragment_);
1019
1020    PrerenderManager* prerender_manager = GetPrerenderManager();
1021    ASSERT_TRUE(prerender_manager);
1022    prerender_manager->mutable_config().rate_limit_enabled = false;
1023    prerender_manager->mutable_config().https_allowed = true;
1024    ASSERT_TRUE(prerender_contents_factory_ == NULL);
1025    prerender_contents_factory_ =
1026        new WaitForLoadPrerenderContentsFactory(
1027            expected_number_of_loads,
1028            expected_final_status_queue,
1029            prerender_should_wait_for_ready_title);
1030    prerender_manager->SetPrerenderContentsFactory(
1031        prerender_contents_factory_);
1032    FinalStatus expected_final_status = expected_final_status_queue.front();
1033
1034    // We construct launch_nav_observer so that we can be certain our loader
1035    // page has finished loading before continuing. This prevents ambiguous
1036    // NOTIFICATION_LOAD_STOP events from making tests flaky.
1037    WebContents* web_contents =
1038        current_browser()->tab_strip_model()->GetActiveWebContents();
1039    content::WindowedNotificationObserver loader_nav_observer(
1040        content::NOTIFICATION_LOAD_STOP,
1041        content::Source<NavigationController>(
1042            &web_contents->GetController()));
1043
1044    // ui_test_utils::NavigateToURL uses its own observer and message loop.
1045    // Since the test needs to wait until the prerendered page has stopped
1046    // loading, rather than the page directly navigated to, need to
1047    // handle browser navigation directly.
1048    current_browser()->OpenURL(OpenURLParams(
1049        loader_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED,
1050        false));
1051
1052    content::RunMessageLoop();
1053    // Now that we've run the prerender until it stopped loading, we can now
1054    // also make sure the launcher has finished loading.
1055    loader_nav_observer.Wait();
1056
1057    TestPrerenderContents* prerender_contents = GetPrerenderContents();
1058
1059    if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) {
1060      ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1061      EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
1062
1063      if (call_javascript_ && expected_number_of_loads > 0) {
1064        // Wait for the prerendered page to change title to signal it is ready
1065        // if required.
1066        prerender_contents->WaitForPrerenderToHaveReadyTitleIfRequired();
1067
1068        // Check if page behaves as expected while in prerendered state.
1069        bool prerender_test_result = false;
1070        ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1071            prerender_contents->GetRenderViewHostMutable(),
1072            "window.domAutomationController.send(DidPrerenderPass())",
1073            &prerender_test_result));
1074        EXPECT_TRUE(prerender_test_result);
1075      }
1076    } else {
1077      // In the failure case, we should have removed |dest_url_| from the
1078      // prerender_manager.  We ignore dummy PrerenderContents (as indicated
1079      // by not having started), and PrerenderContents that are expected to
1080      // be left in the manager until the test finishes.
1081      EXPECT_TRUE(prerender_contents == NULL ||
1082                  !prerender_contents->prerendering_has_started());
1083    }
1084  }
1085
1086  void NavigateToURLImpl(const GURL& dest_url,
1087                         WindowOpenDisposition disposition) const {
1088    ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager());
1089    // Make sure in navigating we have a URL to use in the PrerenderManager.
1090    ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
1091
1092    // If opening the page in a background tab, it won't be shown when swapped
1093    // in.
1094    if (disposition == NEW_BACKGROUND_TAB)
1095      GetPrerenderContents()->set_should_be_shown(false);
1096
1097    scoped_ptr<content::WindowedNotificationObserver> page_load_observer;
1098    WebContents* web_contents = NULL;
1099
1100    if (GetPrerenderContents()->prerender_contents()) {
1101      // In the case of zero loads, need to wait for the page load to complete
1102      // before running any Javascript.
1103      web_contents = GetPrerenderContents()->prerender_contents();
1104      if (GetPrerenderContents()->number_of_loads() == 0) {
1105        page_load_observer.reset(
1106            new content::WindowedNotificationObserver(
1107                content::NOTIFICATION_LOAD_STOP,
1108                content::Source<NavigationController>(
1109                    &web_contents->GetController())));
1110      }
1111    }
1112
1113    // Navigate to the prerendered URL, but don't run the message loop. Browser
1114    // issued navigations to prerendered pages will synchronously swap in the
1115    // prerendered page.
1116    ui_test_utils::NavigateToURLWithDisposition(
1117        current_browser(), dest_url, disposition,
1118        ui_test_utils::BROWSER_TEST_NONE);
1119
1120    // Make sure the PrerenderContents found earlier was used or removed.
1121    EXPECT_EQ(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
1122
1123    if (call_javascript_ && web_contents) {
1124      if (page_load_observer.get())
1125        page_load_observer->Wait();
1126
1127      bool display_test_result = false;
1128      ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1129          web_contents,
1130          "window.domAutomationController.send(DidDisplayPass())",
1131          &display_test_result));
1132      EXPECT_TRUE(display_test_result);
1133    }
1134  }
1135
1136  // Opens the prerendered page using javascript functions in the
1137  // loader page. |javascript_function_name| should be a 0 argument function
1138  // which is invoked.
1139  void OpenDestURLWithJSImpl(const std::string& javascript_function_name)
1140      const {
1141    TestPrerenderContents* prerender_contents = GetPrerenderContents();
1142    ASSERT_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
1143
1144    RenderViewHost* render_view_host = current_browser()->tab_strip_model()->
1145        GetActiveWebContents()->GetRenderViewHost();
1146
1147    render_view_host->ExecuteJavascriptInWebFrame(
1148        string16(), ASCIIToUTF16(javascript_function_name));
1149
1150    if (prerender_contents->quit_message_loop_on_destruction()) {
1151      // Run message loop until the prerender contents is destroyed.
1152      content::RunMessageLoop();
1153    } else {
1154      // We don't expect to pick up a running prerender, so instead
1155      // observe one navigation.
1156      content::TestNavigationObserver observer(
1157          content::NotificationService::AllSources(), 1);
1158      base::RunLoop run_loop;
1159      observer.WaitForObservation(
1160          base::Bind(&content::RunThisRunLoop,
1161                     base::Unretained(&run_loop)),
1162          content::GetQuitTaskForRunLoop(&run_loop));
1163    }
1164  }
1165
1166  WaitForLoadPrerenderContentsFactory* prerender_contents_factory_;
1167#if defined(FULL_SAFE_BROWSING)
1168  scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_;
1169#endif
1170  GURL dest_url_;
1171  bool use_https_src_server_;
1172  bool call_javascript_;
1173  std::string loader_path_;
1174  std::string loader_query_and_fragment_;
1175  Browser* explicitly_set_browser_;
1176};
1177
1178// Checks that a page is correctly prerendered in the case of a
1179// <link rel=prerender> tag and then loaded into a tab in response to a
1180// navigation.
1181IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
1182  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1183
1184  ChannelDestructionWatcher channel_close_watcher;
1185  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1186      GetActiveWebContents()->GetRenderProcessHost());
1187  NavigateToDestURL();
1188  channel_close_watcher.WaitForChannelClose();
1189
1190  ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1191}
1192
1193// Checks that pending prerenders launch and receive proper event treatment.
1194// Disabled due to http://crbug.com/167792
1195IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderPagePending) {
1196  std::deque<FinalStatus> expected_final_status_queue;
1197  expected_final_status_queue.push_back(FINAL_STATUS_USED);
1198  expected_final_status_queue.push_back(FINAL_STATUS_USED);
1199  PrerenderTestURL("files/prerender/prerender_page_pending.html",
1200                   expected_final_status_queue, 1);
1201
1202  ChannelDestructionWatcher first_channel_close_watcher;
1203
1204  first_channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1205      GetActiveWebContents()->GetRenderProcessHost());
1206  NavigateToDestURL();
1207  // NavigateToDestURL doesn't run a message loop. Normally that's fine, but in
1208  // this case, we need the pending prerenders to start.
1209  content::RunMessageLoop();
1210  first_channel_close_watcher.WaitForChannelClose();
1211
1212  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1213  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1214  EXPECT_FALSE(HadPrerenderEventErrors());
1215
1216  const GURL prerender_page_url =
1217      test_server()->GetURL("files/prerender/prerender_page.html");
1218  EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1219  EXPECT_NE(static_cast<TestPrerenderContents*>(NULL),
1220            GetPrerenderContentsFor(prerender_page_url));
1221
1222  // Now navigate to our target page.
1223  ChannelDestructionWatcher second_channel_close_watcher;
1224  second_channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1225      GetActiveWebContents()->GetRenderProcessHost());
1226  ui_test_utils::NavigateToURLWithDisposition(
1227      current_browser(), prerender_page_url, CURRENT_TAB,
1228      ui_test_utils::BROWSER_TEST_NONE);
1229  second_channel_close_watcher.WaitForChannelClose();
1230
1231  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1232}
1233
1234// Checks that pending prerenders which are canceled before they are launched
1235// never get started.
1236IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) {
1237  PrerenderTestURL("files/prerender/prerender_page_removes_pending.html",
1238                   FINAL_STATUS_USED, 1);
1239
1240  ChannelDestructionWatcher channel_close_watcher;
1241  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1242      GetActiveWebContents()->GetRenderProcessHost());
1243  NavigateToDestURL();
1244  channel_close_watcher.WaitForChannelClose();
1245
1246  EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1));
1247  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1248  EXPECT_FALSE(HadPrerenderEventErrors());
1249  // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1250  // calls did a thread/process hop to the renderer which insured pending
1251  // renderer events have arrived.
1252  ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1253}
1254
1255// Flaky, http://crbug.com/167340.
1256IN_PROC_BROWSER_TEST_F(
1257    PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLink) {
1258  set_loader_path("files/prerender/prerender_loader_removing_links.html");
1259  set_loader_query_and_fragment("?links_to_insert=1");
1260  PrerenderTestURL("files/prerender/prerender_page.html",
1261                   FINAL_STATUS_CANCELLED, 1);
1262  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1263  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1264
1265  // No ChannelDestructionWatcher is needed here, since prerenders in the
1266  // PrerenderLinkManager should be deleted by removing the links, rather than
1267  // shutting down the renderer process.
1268  RemoveLinkElement(0);
1269  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1270  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1271  EXPECT_FALSE(HadPrerenderEventErrors());
1272  // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1273  // calls did a thread/process hop to the renderer which insured pending
1274  // renderer events have arrived.
1275  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1276}
1277
1278// Flaky, http://crbug.com/167340.
1279IN_PROC_BROWSER_TEST_F(
1280    PrerenderBrowserTest, DISABLED_PrerenderPageRemovingLinkWithTwoLinks) {
1281  GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1282  GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1283
1284  set_loader_path("files/prerender/prerender_loader_removing_links.html");
1285  set_loader_query_and_fragment("?links_to_insert=2");
1286  PrerenderTestURL("files/prerender/prerender_page.html",
1287                   FINAL_STATUS_CANCELLED, 1);
1288  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1289  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1290  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1291  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1292
1293  RemoveLinkElement(0);
1294  RemoveLinkElement(1);
1295  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1296  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1297  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1298  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1299  EXPECT_FALSE(HadPrerenderEventErrors());
1300  // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1301  // calls did a thread/process hop to the renderer which insured pending
1302  // renderer events have arrived.
1303  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1304}
1305
1306#if defined(OS_WIN)
1307// TODO(gavinp): Fails on XP Rel - http://crbug.com/128841
1308#define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1309    DISABLED_PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1310#else
1311#define MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne \
1312    PrerenderPageRemovingLinkWithTwoLinksRemovingOne
1313#endif  // defined(OS_WIN)
1314IN_PROC_BROWSER_TEST_F(
1315    PrerenderBrowserTest,
1316    MAYBE_PrerenderPageRemovingLinkWithTwoLinksRemovingOne) {
1317  GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1318  GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1319  set_loader_path("files/prerender/prerender_loader_removing_links.html");
1320  set_loader_query_and_fragment("?links_to_insert=2");
1321  PrerenderTestURL("files/prerender/prerender_page.html",
1322                   FINAL_STATUS_USED, 1);
1323  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1324  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1325  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1326  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1327
1328  RemoveLinkElement(0);
1329  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
1330  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
1331  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
1332  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
1333  EXPECT_FALSE(HadPrerenderEventErrors());
1334  // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
1335  // calls did a thread/process hop to the renderer which insured pending
1336  // renderer events have arrived.
1337  EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1338
1339  ChannelDestructionWatcher channel_close_watcher;
1340  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1341      GetActiveWebContents()->GetRenderProcessHost());
1342  NavigateToDestURL();
1343  channel_close_watcher.WaitForChannelClose();
1344
1345  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1346}
1347
1348// Checks that prerendering works in incognito mode.
1349IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIncognito) {
1350  Profile* normal_profile = current_browser()->profile();
1351  set_browser(
1352      ui_test_utils::OpenURLOffTheRecord(normal_profile, GURL("about:blank")));
1353  // Increase memory expectations on the incognito PrerenderManager.
1354  IncreasePrerenderMemory();
1355  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1356  NavigateToDestURL();
1357}
1358
1359// Checks that the visibility API works.
1360IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) {
1361  PrerenderTestURL("files/prerender/prerender_visibility.html",
1362                   FINAL_STATUS_USED,
1363                   1);
1364  NavigateToDestURL();
1365}
1366
1367// Checks that the visibility API works when the prerender is quickly opened
1368// in a new tab before it stops loading.
1369IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityQuickSwitch) {
1370  PrerenderTestURL("files/prerender/prerender_visibility_quick.html",
1371                   FINAL_STATUS_USED, 0);
1372  NavigateToDestURL();
1373}
1374
1375// Checks that the prerendering of a page is canceled correctly when a
1376// Javascript alert is called.
1377IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
1378  PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
1379                   FINAL_STATUS_JAVASCRIPT_ALERT,
1380                   1);
1381}
1382
1383// Checks that the prerendering of a page is canceled correctly when a
1384// Javascript alert is called.
1385IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
1386  PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
1387                   FINAL_STATUS_JAVASCRIPT_ALERT,
1388                   1);
1389}
1390
1391// Checks that plugins are not loaded while a page is being preloaded, but
1392// are loaded when the page is displayed.
1393#if defined(USE_AURA)
1394// http://crbug.com/103496
1395#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1396#elif defined(OS_MACOSX)
1397// http://crbug.com/100514
1398#define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
1399#else
1400#define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin
1401#endif
1402IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) {
1403  PrerenderTestURL("files/prerender/plugin_delay_load.html",
1404                   FINAL_STATUS_USED,
1405                   1);
1406  NavigateToDestURL();
1407}
1408
1409// Checks that plugins are not loaded on prerendering pages when click-to-play
1410// is enabled.
1411IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) {
1412  // Enable click-to-play.
1413  HostContentSettingsMap* content_settings_map =
1414      current_browser()->profile()->GetHostContentSettingsMap();
1415  content_settings_map->SetDefaultContentSetting(
1416      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK);
1417
1418  PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html",
1419                   FINAL_STATUS_USED,
1420                   1);
1421  NavigateToDestURL();
1422}
1423
1424// Checks that we don't load a NaCl plugin when NaCl is disabled.
1425IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) {
1426  PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html",
1427                   FINAL_STATUS_USED,
1428                   1);
1429  NavigateToDestURL();
1430
1431
1432  // Run this check again.  When we try to load aa ppapi plugin, the
1433  // "loadstart" event is asynchronously posted to a message loop.
1434  // It's possible that earlier call could have been run before the
1435  // the "loadstart" event was posted.
1436  // TODO(mmenke):  While this should reliably fail on regressions, the
1437  //                reliability depends on the specifics of ppapi plugin
1438  //                loading.  It would be great if we could avoid that.
1439  WebContents* web_contents =
1440      browser()->tab_strip_model()->GetActiveWebContents();
1441  bool display_test_result = false;
1442  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1443      web_contents,
1444      "window.domAutomationController.send(DidDisplayPass())",
1445      &display_test_result));
1446  EXPECT_TRUE(display_test_result);
1447}
1448
1449// Checks that plugins in an iframe are not loaded while a page is
1450// being preloaded, but are loaded when the page is displayed.
1451#if defined(USE_AURA)
1452// http://crbug.com/103496
1453#define MAYBE_PrerenderIframeDelayLoadPlugin \
1454        DISABLED_PrerenderIframeDelayLoadPlugin
1455#elif defined(OS_MACOSX)
1456// http://crbug.com/100514
1457#define MAYBE_PrerenderIframeDelayLoadPlugin \
1458        DISABLED_PrerenderIframeDelayLoadPlugin
1459#else
1460#define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin
1461#endif
1462IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1463                       MAYBE_PrerenderIframeDelayLoadPlugin) {
1464  PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
1465                   FINAL_STATUS_USED,
1466                   1);
1467  NavigateToDestURL();
1468}
1469
1470// Renders a page that contains a prerender link to a page that contains an
1471// iframe with a source that requires http authentication. This should not
1472// prerender successfully.
1473IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
1474  PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
1475                   FINAL_STATUS_AUTH_NEEDED,
1476                   1);
1477}
1478
1479// Checks that client-issued redirects work with prerendering.
1480// This version navigates to the page which issues the redirection, rather
1481// than the final destination page.
1482IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1483                       PrerenderClientRedirectNavigateToFirst) {
1484  PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1485                   FINAL_STATUS_USED,
1486                   2);
1487  NavigateToDestURL();
1488}
1489
1490// Checks that client-issued redirects work with prerendering.
1491// This version navigates to the final destination page, rather than the
1492// page which does the redirection.
1493IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1494                       PrerenderClientRedirectNavigateToSecond) {
1495  PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
1496                   FINAL_STATUS_USED,
1497                   2);
1498  NavigateToURL("files/prerender/prerender_page.html");
1499}
1500
1501// Checks that client-issued redirects work with prerendering.
1502// This version navigates to the final destination page, rather than the
1503// page which does the redirection via a mouse click.
1504IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1505                       PrerenderClientRedirectNavigateToSecondViaClick) {
1506  GURL prerender_url = test_server()->GetURL(
1507      CreateClientRedirect("files/prerender/prerender_page.html"));
1508  GURL destination_url = test_server()->GetURL(
1509      "files/prerender/prerender_page.html");
1510  PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 2);
1511  OpenDestURLViaClick();
1512}
1513
1514// Checks that a prerender for an https will prevent a prerender from happening.
1515IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) {
1516  net::TestServer https_server(
1517      net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1518      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1519  ASSERT_TRUE(https_server.Start());
1520  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
1521  PrerenderTestURL(https_url,
1522                   FINAL_STATUS_USED,
1523                   1);
1524  NavigateToDestURL();
1525}
1526
1527// Checks that client-issued redirects to an https page will cancel prerenders.
1528IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectToHttps) {
1529  net::TestServer https_server(
1530      net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1531      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1532  ASSERT_TRUE(https_server.Start());
1533  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
1534  PrerenderTestURL(CreateClientRedirect(https_url.spec()),
1535                   FINAL_STATUS_USED,
1536                   2);
1537  NavigateToDestURL();
1538}
1539
1540// Checks that client-issued redirects within an iframe in a prerendered
1541// page will not count as an "alias" for the prerendered page.
1542IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectInIframe) {
1543  std::string redirect_path = CreateClientRedirect(
1544      "/files/prerender/prerender_embedded_content.html");
1545  std::vector<net::TestServer::StringPair> replacement_text;
1546  replacement_text.push_back(
1547      std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
1548  std::string replacement_path;
1549  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
1550      "files/prerender/prerender_with_iframe.html",
1551      replacement_text,
1552      &replacement_path));
1553  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
1554  EXPECT_FALSE(UrlIsInPrerenderManager(
1555      "files/prerender/prerender_embedded_content.html"));
1556  NavigateToDestURL();
1557}
1558
1559// Checks that client-issued redirects within an iframe in a prerendered
1560// page to an https page will not cancel the prerender, nor will it
1561// count as an "alias" for the prerendered page.
1562IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1563                       PrerenderClientRedirectToHttpsInIframe) {
1564  net::TestServer https_server(
1565      net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1566      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1567  ASSERT_TRUE(https_server.Start());
1568  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
1569  std::string redirect_path = CreateClientRedirect(https_url.spec());
1570  std::vector<net::TestServer::StringPair> replacement_text;
1571  replacement_text.push_back(
1572      std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
1573  std::string replacement_path;
1574  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
1575      "files/prerender/prerender_with_iframe.html",
1576      replacement_text,
1577      &replacement_path));
1578  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
1579  EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
1580  NavigateToDestURL();
1581}
1582
1583// Checks that server-issued redirects work with prerendering.
1584// This version navigates to the page which issues the redirection, rather
1585// than the final destination page.
1586IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1587                       PrerenderServerRedirectNavigateToFirst) {
1588  PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
1589                   FINAL_STATUS_USED,
1590                   1);
1591  NavigateToDestURL();
1592}
1593
1594// Checks that server-issued redirects work with prerendering.
1595// This version navigates to the final destination page, rather than the
1596// page which does the redirection.
1597IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1598                       PrerenderServerRedirectNavigateToSecond) {
1599  PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
1600                   FINAL_STATUS_USED,
1601                   1);
1602  NavigateToURL("files/prerender/prerender_page.html");
1603}
1604
1605// Checks that server-issued redirects work with prerendering.
1606// This version navigates to the final destination page, rather than the
1607// page which does the redirection via a mouse click.
1608IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1609                       PrerenderServerRedirectNavigateToSecondViaClick) {
1610  GURL prerender_url = test_server()->GetURL(
1611      CreateServerRedirect("files/prerender/prerender_page.html"));
1612  GURL destination_url = test_server()->GetURL(
1613      "files/prerender/prerender_page.html");
1614  PrerenderTestURL(prerender_url, destination_url, FINAL_STATUS_USED, 1);
1615  OpenDestURLViaClick();
1616}
1617
1618// Checks that server-issued redirects from an http to an https
1619// location will cancel prerendering.
1620IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1621                       PrerenderServerRedirectToHttps) {
1622  net::TestServer https_server(
1623      net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1624      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1625  ASSERT_TRUE(https_server.Start());
1626  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
1627  PrerenderTestURL(CreateServerRedirect(https_url.spec()),
1628                   FINAL_STATUS_USED,
1629                   1);
1630  NavigateToDestURL();
1631}
1632
1633// Checks that server-issued redirects within an iframe in a prerendered
1634// page will not count as an "alias" for the prerendered page.
1635IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
1636  std::string redirect_path = CreateServerRedirect(
1637      "/files/prerender/prerender_embedded_content.html");
1638  std::vector<net::TestServer::StringPair> replacement_text;
1639  replacement_text.push_back(
1640      std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
1641  std::string replacement_path;
1642  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
1643      "files/prerender/prerender_with_iframe.html",
1644      replacement_text,
1645      &replacement_path));
1646  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
1647  EXPECT_FALSE(UrlIsInPrerenderManager(
1648      "files/prerender/prerender_embedded_content.html"));
1649  NavigateToDestURL();
1650}
1651
1652// Checks that server-issued redirects within an iframe in a prerendered
1653// page to an https page will not cancel the prerender, nor will it
1654// count as an "alias" for the prerendered page.
1655IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1656                       PrerenderServerRedirectToHttpsInIframe) {
1657  net::TestServer https_server(
1658      net::TestServer::TYPE_HTTPS, net::TestServer::kLocalhost,
1659      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1660  ASSERT_TRUE(https_server.Start());
1661  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
1662  std::string redirect_path = CreateServerRedirect(https_url.spec());
1663  std::vector<net::TestServer::StringPair> replacement_text;
1664  replacement_text.push_back(
1665      std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
1666  std::string replacement_path;
1667  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
1668      "files/prerender/prerender_with_iframe.html",
1669      replacement_text,
1670      &replacement_path));
1671  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
1672  EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
1673  NavigateToDestURL();
1674}
1675
1676// Prerenders a page that contains an automatic download triggered through an
1677// iframe. This should not prerender successfully.
1678IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) {
1679  PrerenderTestURL("files/prerender/prerender_download_iframe.html",
1680                   FINAL_STATUS_DOWNLOAD,
1681                   1);
1682}
1683
1684// Prerenders a page that contains an automatic download triggered through
1685// Javascript changing the window.location. This should not prerender
1686// successfully
1687IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
1688  PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
1689                   FINAL_STATUS_DOWNLOAD,
1690                   1);
1691}
1692
1693// Prerenders a page that contains an automatic download triggered through a
1694// client-issued redirect. This should not prerender successfully.
1695IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
1696  PrerenderTestURL("files/prerender/prerender_download_refresh.html",
1697                   FINAL_STATUS_DOWNLOAD,
1698                   1);
1699}
1700
1701// Checks that the referrer is set when prerendering.
1702IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
1703  PrerenderTestURL("files/prerender/prerender_referrer.html",
1704                   FINAL_STATUS_USED,
1705                   1);
1706  NavigateToDestURL();
1707}
1708
1709// Checks that the referrer is not set when prerendering and the source page is
1710// HTTPS.
1711IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoSSLReferrer) {
1712  set_use_https_src(true);
1713  PrerenderTestURL("files/prerender/prerender_no_referrer.html",
1714                   FINAL_STATUS_USED,
1715                   1);
1716  NavigateToDestURL();
1717}
1718
1719// Checks that popups on a prerendered page cause cancellation.
1720IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
1721  PrerenderTestURL("files/prerender/prerender_popup.html",
1722                   FINAL_STATUS_CREATE_NEW_WINDOW,
1723                   1);
1724}
1725
1726// Checks that registering a protocol handler causes cancellation.
1727IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) {
1728  PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html",
1729                   FINAL_STATUS_REGISTER_PROTOCOL_HANDLER,
1730                   1);
1731}
1732
1733// Checks that renderers using excessive memory will be terminated.
1734IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
1735  ASSERT_TRUE(GetPrerenderManager());
1736  GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024;
1737  PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
1738                   FINAL_STATUS_MEMORY_LIMIT_EXCEEDED,
1739                   1);
1740}
1741
1742// Checks shutdown code while a prerender is active.
1743IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
1744  PrerenderTestURL("files/prerender/prerender_page.html",
1745                   FINAL_STATUS_APP_TERMINATING,
1746                   0);
1747}
1748
1749// TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test.
1750// Checks that we don't prerender in an infinite loop.
1751IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) {
1752  const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
1753  const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
1754
1755  std::deque<FinalStatus> expected_final_status_queue;
1756  expected_final_status_queue.push_back(FINAL_STATUS_USED);
1757  expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
1758
1759  PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
1760  ASSERT_TRUE(GetPrerenderContents());
1761  GetPrerenderContents()->WaitForPendingPrerenders(1u);
1762
1763  // Next url should be in pending list but not an active entry.
1764  EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
1765
1766  NavigateToDestURL();
1767
1768  // Make sure the PrerenderContents for the next url is now in the manager
1769  // and not pending.
1770  EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
1771}
1772
1773// TODO(gavinp,sreeram): Fix http://crbug.com/145248 and deflake this test.
1774// Checks that we don't prerender in an infinite loop and multiple links are
1775// handled correctly.
1776IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1777                       DISABLED_PrerenderInfiniteLoopMultiple) {
1778  const char* const kHtmlFileA =
1779      "files/prerender/prerender_infinite_a_multiple.html";
1780  const char* const kHtmlFileB =
1781      "files/prerender/prerender_infinite_b_multiple.html";
1782  const char* const kHtmlFileC =
1783      "files/prerender/prerender_infinite_c_multiple.html";
1784
1785  // This test is conceptually simplest if concurrency is at two, since we
1786  // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
1787  GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
1788  GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
1789
1790  std::deque<FinalStatus> expected_final_status_queue;
1791  expected_final_status_queue.push_back(FINAL_STATUS_USED);
1792  expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
1793  expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
1794
1795  PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
1796  ASSERT_TRUE(GetPrerenderContents());
1797  GetPrerenderContents()->WaitForPendingPrerenders(2u);
1798
1799  // Next url should be in pending list but not an active entry.
1800  EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
1801  EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
1802
1803  NavigateToDestURL();
1804
1805  // Make sure the PrerenderContents for the next urls are now in the manager
1806  // and not pending. One and only one of the URLs (the last seen) should be the
1807  // active entry.
1808  bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
1809  bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
1810  EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
1811}
1812
1813// See crbug.com/131836.
1814IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderTaskManager) {
1815  // Show the task manager. This populates the model.
1816  chrome::OpenTaskManager(current_browser(), false);
1817  // Wait for the model of task manager to start.
1818  TaskManagerBrowserTestUtil::WaitForWebResourceChange(1);
1819
1820  // Start with two resources.
1821  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
1822
1823  // One of the resources that has a WebContents associated with it should have
1824  // the Prerender prefix.
1825  const string16 prefix =
1826      l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX, string16());
1827  string16 prerender_title;
1828  int num_prerender_tabs = 0;
1829
1830  const TaskManagerModel* model = GetModel();
1831  for (int i = 0; i < model->ResourceCount(); ++i) {
1832    if (model->GetResourceWebContents(i)) {
1833      prerender_title = model->GetResourceTitle(i);
1834      if (StartsWith(prerender_title, prefix, true))
1835        ++num_prerender_tabs;
1836    }
1837  }
1838  EXPECT_EQ(1, num_prerender_tabs);
1839  const string16 prerender_page_title = prerender_title.substr(prefix.length());
1840
1841  NavigateToDestURL();
1842
1843  // There should be no tabs with the Prerender prefix.
1844  const string16 tab_prefix =
1845      l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, string16());
1846  num_prerender_tabs = 0;
1847  int num_tabs_with_prerender_page_title = 0;
1848  for (int i = 0; i < model->ResourceCount(); ++i) {
1849    if (model->GetResourceWebContents(i)) {
1850      string16 tab_title = model->GetResourceTitle(i);
1851      if (StartsWith(tab_title, prefix, true)) {
1852        ++num_prerender_tabs;
1853      } else {
1854        EXPECT_TRUE(StartsWith(tab_title, tab_prefix, true));
1855
1856        // The prerender tab should now be a normal tab but the title should be
1857        // the same. Depending on timing, there may be more than one of these.
1858        const string16 tab_page_title = tab_title.substr(tab_prefix.length());
1859        if (prerender_page_title.compare(tab_page_title) == 0)
1860          ++num_tabs_with_prerender_page_title;
1861      }
1862    }
1863  }
1864  EXPECT_EQ(0, num_prerender_tabs);
1865
1866  // We may have deleted the prerender tab, but the swapped in tab should be
1867  // active.
1868  EXPECT_GE(num_tabs_with_prerender_page_title, 1);
1869  EXPECT_LE(num_tabs_with_prerender_page_title, 2);
1870}
1871
1872// Checks that audio loads are deferred on prerendering.
1873// Times out under AddressSanitizer, see http://crbug.com/108402
1874#if defined(ADDRESS_SANITIZER)
1875#define MAYBE_PrerenderHTML5Audio DISABLED_PrerenderHTML5Audio
1876#else
1877#define MAYBE_PrerenderHTML5Audio PrerenderHTML5Audio
1878#endif
1879IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderHTML5Audio) {
1880  PrerenderTestURL("files/prerender/prerender_html5_audio.html",
1881                  FINAL_STATUS_USED,
1882                  1);
1883  NavigateToDestUrlAndWaitForPassTitle();
1884}
1885
1886// Checks that audio loads are deferred on prerendering and played back when
1887// the prerender is swapped in if autoplay is set.
1888// Periodically fails on chrome-os.  See http://crbug.com/145263
1889#if defined(OS_CHROMEOS)
1890#define MAYBE_PrerenderHTML5AudioAutoplay DISABLED_PrerenderHTML5AudioAutoplay
1891#else
1892#define MAYBE_PrerenderHTML5AudioAutoplay PrerenderHTML5AudioAutoplay
1893#endif
1894IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1895                       MAYBE_PrerenderHTML5AudioAutoplay) {
1896  PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html",
1897                   FINAL_STATUS_USED,
1898                   1);
1899  NavigateToDestUrlAndWaitForPassTitle();
1900}
1901
1902// Checks that audio loads are deferred on prerendering and played back when
1903// the prerender is swapped in if js starts playing.
1904IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioJsplay) {
1905  PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html",
1906                   FINAL_STATUS_USED,
1907                   1);
1908  NavigateToDestUrlAndWaitForPassTitle();
1909}
1910
1911// Checks that video loads are deferred on prerendering.
1912IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) {
1913  PrerenderTestURL("files/prerender/prerender_html5_video.html",
1914                   FINAL_STATUS_USED,
1915                   1);
1916  NavigateToDestUrlAndWaitForPassTitle();
1917}
1918
1919// Checks that video tags inserted by javascript are deferred and played
1920// correctly on swap in.
1921IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) {
1922  PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
1923                   FINAL_STATUS_USED,
1924                   1);
1925  NavigateToDestUrlAndWaitForPassTitle();
1926}
1927
1928// Checks for correct network events by using a busy sleep the javascript.
1929IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoNetwork) {
1930  PrerenderTestURL("files/prerender/prerender_html5_video_network.html",
1931                   FINAL_STATUS_USED,
1932                   1,
1933                   true);
1934  NavigateToDestUrlAndWaitForPassTitle();
1935}
1936
1937// Checks that scripts can retrieve the correct window size while prerendering.
1938#if defined(TOOLKIT_VIEWS)
1939// TODO(beng): Widget hierarchy split causes this to fail http://crbug.com/82363
1940IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWindowSize) {
1941#else
1942IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
1943#endif
1944  PrerenderTestURL("files/prerender/prerender_size.html",
1945                   FINAL_STATUS_USED,
1946                   1);
1947  NavigateToDestURL();
1948}
1949
1950#if defined(OS_CHROMEOS)
1951// Flakily times out: http://crbug.com/171546
1952#define MAYBE_PrerenderRendererCrash DISABLED_PrerenderRendererCrash
1953#else
1954#define MAYBE_PrerenderRendererCrash PrerenderRendererCrash
1955#endif
1956
1957// Checks that prerenderers will terminate when the RenderView crashes.
1958IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderRendererCrash) {
1959  PrerenderTestURL("files/prerender/prerender_page.html",
1960                   FINAL_STATUS_RENDERER_CRASHED,
1961                   1);
1962
1963  // Navigate to about:crash and then wait for the renderer to crash.
1964  ASSERT_TRUE(GetPrerenderContents());
1965  ASSERT_TRUE(GetPrerenderContents()->prerender_contents());
1966  GetPrerenderContents()->prerender_contents()->GetController().
1967      LoadURL(
1968          GURL(content::kChromeUICrashURL),
1969          content::Referrer(),
1970          content::PAGE_TRANSITION_TYPED,
1971          std::string());
1972  content::RunMessageLoop();
1973}
1974
1975IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1976                       PrerenderPageWithFragment) {
1977  PrerenderTestURL("files/prerender/prerender_page.html#fragment",
1978                   FINAL_STATUS_USED,
1979                   1);
1980
1981  ChannelDestructionWatcher channel_close_watcher;
1982  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
1983      GetActiveWebContents()->GetRenderProcessHost());
1984  NavigateToDestURL();
1985  channel_close_watcher.WaitForChannelClose();
1986
1987  ASSERT_TRUE(IsEmptyPrerenderLinkManager());
1988}
1989
1990// Checks that we correctly use a prerendered page when navigating to a
1991// fragment.
1992// DISABLED: http://crbug.com/84154
1993IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
1994                       DISABLED_PrerenderPageNavigateFragment) {
1995  PrerenderTestURL("files/prerender/no_prerender_page.html",
1996                   FINAL_STATUS_APP_TERMINATING,
1997                   1);
1998  NavigateToURL("files/prerender/no_prerender_page.html#fragment");
1999}
2000
2001// Checks that we correctly use a prerendered page when we prerender a fragment
2002// but navigate to the main page.
2003// http://crbug.com/83901
2004IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2005                       DISABLED_PrerenderFragmentNavigatePage) {
2006  PrerenderTestURL("files/prerender/no_prerender_page.html#fragment",
2007                   FINAL_STATUS_APP_TERMINATING,
2008                   1);
2009  NavigateToURL("files/prerender/no_prerender_page.html");
2010}
2011
2012// Checks that we correctly use a prerendered page when we prerender a fragment
2013// but navigate to a different fragment on the same page.
2014// DISABLED: http://crbug.com/84154
2015IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2016                       DISABLED_PrerenderFragmentNavigateFragment) {
2017  PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment",
2018                   FINAL_STATUS_APP_TERMINATING,
2019                   1);
2020  NavigateToURL("files/prerender/no_prerender_page.html#fragment");
2021}
2022
2023// Checks that we correctly use a prerendered page when the page uses a client
2024// redirect to refresh from a fragment on the same page.
2025// http://crbug.com/83901
2026IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2027                       DISABLED_PrerenderClientRedirectFromFragment) {
2028  PrerenderTestURL(
2029      CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"),
2030      FINAL_STATUS_APP_TERMINATING,
2031      2);
2032  NavigateToURL("files/prerender/no_prerender_page.html");
2033}
2034
2035// Checks that we correctly use a prerendered page when the page uses a client
2036// redirect to refresh to a fragment on the same page.
2037// DISABLED: http://crbug.com/84154
2038IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2039                       DISABLED_PrerenderClientRedirectToFragment) {
2040  PrerenderTestURL(
2041      CreateClientRedirect("files/prerender/no_prerender_page.html"),
2042      FINAL_STATUS_APP_TERMINATING,
2043      2);
2044  NavigateToURL("files/prerender/no_prerender_page.html#fragment");
2045}
2046
2047// Checks that we correctly use a prerendered page when the page uses JS to set
2048// the window.location.hash to a fragment on the same page.
2049IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2050                       PrerenderPageChangeFragmentLocationHash) {
2051  PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html",
2052                   FINAL_STATUS_USED,
2053                   1);
2054  NavigateToURL("files/prerender/prerender_fragment_location_hash.html");
2055}
2056
2057// Checks that prerendering a PNG works correctly.
2058IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) {
2059  DisableJavascriptCalls();
2060  PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1);
2061  NavigateToDestURL();
2062}
2063
2064// Checks that prerendering a JPG works correctly.
2065IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) {
2066  DisableJavascriptCalls();
2067  PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1);
2068  NavigateToDestURL();
2069}
2070
2071// Checks that a prerender of a CRX will result in a cancellation due to
2072// download.
2073IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) {
2074  PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 1);
2075}
2076
2077// Checks that xhr GET requests allow prerenders.
2078IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) {
2079  PrerenderTestURL("files/prerender/prerender_xhr_get.html",
2080                   FINAL_STATUS_USED,
2081                   1);
2082  NavigateToDestURL();
2083}
2084
2085// Checks that xhr HEAD requests allow prerenders.
2086IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) {
2087  PrerenderTestURL("files/prerender/prerender_xhr_head.html",
2088                   FINAL_STATUS_USED,
2089                   1);
2090  NavigateToDestURL();
2091}
2092
2093// Checks that xhr OPTIONS requests allow prerenders.
2094IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) {
2095  PrerenderTestURL("files/prerender/prerender_xhr_options.html",
2096                   FINAL_STATUS_USED,
2097                   1);
2098  NavigateToDestURL();
2099}
2100
2101// Checks that xhr TRACE requests allow prerenders.
2102IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) {
2103  PrerenderTestURL("files/prerender/prerender_xhr_trace.html",
2104                   FINAL_STATUS_USED,
2105                   1);
2106  NavigateToDestURL();
2107}
2108
2109// Checks that xhr POST requests allow prerenders.
2110IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) {
2111  PrerenderTestURL("files/prerender/prerender_xhr_post.html",
2112                   FINAL_STATUS_USED,
2113                   1);
2114  NavigateToDestURL();
2115}
2116
2117// Checks that xhr PUT cancels prerenders.
2118IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) {
2119  PrerenderTestURL("files/prerender/prerender_xhr_put.html",
2120                   FINAL_STATUS_INVALID_HTTP_METHOD,
2121                   1);
2122}
2123
2124// Checks that xhr DELETE cancels prerenders.
2125IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) {
2126  PrerenderTestURL("files/prerender/prerender_xhr_delete.html",
2127                   FINAL_STATUS_INVALID_HTTP_METHOD,
2128                   1);
2129}
2130
2131// Checks that a top-level page which would trigger an SSL error is canceled.
2132IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) {
2133  net::TestServer::SSLOptions ssl_options;
2134  ssl_options.server_certificate =
2135      net::TestServer::SSLOptions::CERT_MISMATCHED_NAME;
2136    net::TestServer https_server(
2137        net::TestServer::TYPE_HTTPS, ssl_options,
2138        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2139  ASSERT_TRUE(https_server.Start());
2140  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2141  PrerenderTestURL(https_url,
2142                   FINAL_STATUS_SSL_ERROR,
2143                   1);
2144}
2145
2146// Checks that an SSL error that comes from a subresource does not cancel
2147// the page. Non-main-frame requests are simply cancelled if they run into
2148// an SSL problem.
2149IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) {
2150  net::TestServer::SSLOptions ssl_options;
2151  ssl_options.server_certificate =
2152      net::TestServer::SSLOptions::CERT_MISMATCHED_NAME;
2153    net::TestServer https_server(
2154        net::TestServer::TYPE_HTTPS, ssl_options,
2155        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2156  ASSERT_TRUE(https_server.Start());
2157  GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2158  std::vector<net::TestServer::StringPair> replacement_text;
2159  replacement_text.push_back(
2160      std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2161  std::string replacement_path;
2162  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2163      "files/prerender/prerender_with_image.html",
2164      replacement_text,
2165      &replacement_path));
2166  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2167  NavigateToDestURL();
2168}
2169
2170// Checks that an SSL error that comes from an iframe does not cancel
2171// the page. Non-main-frame requests are simply cancelled if they run into
2172// an SSL problem.
2173IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) {
2174  net::TestServer::SSLOptions ssl_options;
2175  ssl_options.server_certificate =
2176      net::TestServer::SSLOptions::CERT_MISMATCHED_NAME;
2177    net::TestServer https_server(
2178        net::TestServer::TYPE_HTTPS, ssl_options,
2179        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2180  ASSERT_TRUE(https_server.Start());
2181  GURL https_url = https_server.GetURL(
2182      "files/prerender/prerender_embedded_content.html");
2183  std::vector<net::TestServer::StringPair> replacement_text;
2184  replacement_text.push_back(
2185      std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2186  std::string replacement_path;
2187  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2188      "files/prerender/prerender_with_iframe.html",
2189      replacement_text,
2190      &replacement_path));
2191  PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
2192  NavigateToDestURL();
2193}
2194
2195// Checks that we cancel correctly when window.print() is called.
2196IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
2197  PrerenderTestURL("files/prerender/prerender_print.html",
2198                   FINAL_STATUS_WINDOW_PRINT,
2199                   1);
2200}
2201
2202// Checks that if a page is opened in a new window by javascript and both the
2203// pages are in the same domain, the prerendered page is not used.
2204IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2205                       PrerenderSameDomainWindowOpenerWindowOpen) {
2206  PrerenderTestURL("files/prerender/prerender_page.html",
2207                   FINAL_STATUS_APP_TERMINATING,
2208                   1);
2209  OpenDestURLViaWindowOpen();
2210}
2211
2212// Checks that if a page is opened due to click on a href with target="_blank"
2213// and both pages are in the same domain the prerendered page is not used.
2214IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2215                       PrerenderSameDomainWindowOpenerClickTarget) {
2216  PrerenderTestURL("files/prerender/prerender_page.html",
2217                   FINAL_STATUS_APP_TERMINATING,
2218                   1);
2219  OpenDestURLViaClickTarget();
2220}
2221
2222// Checks that a top-level page which would normally request an SSL client
2223// certificate will never be seen since it's an https top-level resource.
2224IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertTopLevel) {
2225  net::TestServer::SSLOptions ssl_options;
2226  ssl_options.request_client_certificate = true;
2227    net::TestServer https_server(
2228        net::TestServer::TYPE_HTTPS, ssl_options,
2229        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2230  ASSERT_TRUE(https_server.Start());
2231  GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
2232  PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 1);
2233}
2234
2235// Checks that an SSL Client Certificate request that originates from a
2236// subresource will cancel the prerendered page.
2237IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2238                       PrerenderSSLClientCertSubresource) {
2239  net::TestServer::SSLOptions ssl_options;
2240  ssl_options.request_client_certificate = true;
2241    net::TestServer https_server(
2242        net::TestServer::TYPE_HTTPS, ssl_options,
2243        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2244  ASSERT_TRUE(https_server.Start());
2245  GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
2246  std::vector<net::TestServer::StringPair> replacement_text;
2247  replacement_text.push_back(
2248      std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
2249  std::string replacement_path;
2250  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2251      "files/prerender/prerender_with_image.html",
2252      replacement_text,
2253      &replacement_path));
2254  PrerenderTestURL(replacement_path,
2255                   FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2256                   1);
2257}
2258
2259// Checks that an SSL Client Certificate request that originates from an
2260// iframe will cancel the prerendered page.
2261IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) {
2262  net::TestServer::SSLOptions ssl_options;
2263  ssl_options.request_client_certificate = true;
2264    net::TestServer https_server(
2265        net::TestServer::TYPE_HTTPS, ssl_options,
2266        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2267  ASSERT_TRUE(https_server.Start());
2268  GURL https_url = https_server.GetURL(
2269      "files/prerender/prerender_embedded_content.html");
2270  std::vector<net::TestServer::StringPair> replacement_text;
2271  replacement_text.push_back(
2272      std::make_pair("REPLACE_WITH_URL", https_url.spec()));
2273  std::string replacement_path;
2274  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2275      "files/prerender/prerender_with_iframe.html",
2276      replacement_text,
2277      &replacement_path));
2278  PrerenderTestURL(replacement_path,
2279                   FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
2280                   1);
2281}
2282
2283#if defined(FULL_SAFE_BROWSING)
2284// Ensures that we do not prerender pages with a safe browsing
2285// interstitial.
2286IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) {
2287  GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2288  GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2289      url, SB_THREAT_TYPE_URL_MALWARE);
2290  PrerenderTestURL("files/prerender/prerender_page.html",
2291                   FINAL_STATUS_SAFE_BROWSING, 1);
2292}
2293
2294// Ensures that server redirects to a malware page will cancel prerenders.
2295IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2296                       PrerenderSafeBrowsingServerRedirect) {
2297  GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2298  GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2299      url, SB_THREAT_TYPE_URL_MALWARE);
2300  PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
2301                   FINAL_STATUS_SAFE_BROWSING,
2302                   1);
2303}
2304
2305// Ensures that client redirects to a malware page will cancel prerenders.
2306IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2307                       PrerenderSafeBrowsingClientRedirect) {
2308  GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
2309  GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2310      url, SB_THREAT_TYPE_URL_MALWARE);
2311  PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
2312                   FINAL_STATUS_SAFE_BROWSING,
2313                   1);
2314}
2315
2316// Ensures that we do not prerender pages which have a malware subresource.
2317IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) {
2318  GURL image_url = test_server()->GetURL("files/prerender/image.jpeg");
2319  GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2320      image_url, SB_THREAT_TYPE_URL_MALWARE);
2321  std::vector<net::TestServer::StringPair> replacement_text;
2322  replacement_text.push_back(
2323      std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
2324  std::string replacement_path;
2325  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2326      "files/prerender/prerender_with_image.html",
2327      replacement_text,
2328      &replacement_path));
2329  PrerenderTestURL(replacement_path,
2330                   FINAL_STATUS_SAFE_BROWSING,
2331                   1);
2332}
2333
2334// Ensures that we do not prerender pages which have a malware iframe.
2335IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) {
2336  GURL iframe_url = test_server()->GetURL(
2337      "files/prerender/prerender_embedded_content.html");
2338  GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
2339      iframe_url, SB_THREAT_TYPE_URL_MALWARE);
2340  std::vector<net::TestServer::StringPair> replacement_text;
2341  replacement_text.push_back(
2342      std::make_pair("REPLACE_WITH_URL", iframe_url.spec()));
2343  std::string replacement_path;
2344  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2345      "files/prerender/prerender_with_iframe.html",
2346      replacement_text,
2347      &replacement_path));
2348  PrerenderTestURL(replacement_path,
2349                   FINAL_STATUS_SAFE_BROWSING,
2350                   1);
2351}
2352
2353#endif
2354
2355// Checks that a local storage read will not cause prerender to fail.
2356IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) {
2357  PrerenderTestURL("files/prerender/prerender_localstorage_read.html",
2358                   FINAL_STATUS_USED,
2359                   1);
2360  NavigateToDestURL();
2361}
2362
2363// Checks that a local storage write will not cause prerender to fail.
2364IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) {
2365  PrerenderTestURL("files/prerender/prerender_localstorage_write.html",
2366                   FINAL_STATUS_USED,
2367                   1);
2368  NavigateToDestURL();
2369}
2370
2371// Checks that the favicon is properly loaded on prerender.
2372IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) {
2373  PrerenderTestURL("files/prerender/prerender_favicon.html",
2374                   FINAL_STATUS_USED,
2375                   1);
2376  TestPrerenderContents* prerender_contents = GetPrerenderContents();
2377  ASSERT_TRUE(prerender_contents != NULL);
2378  content::WindowedNotificationObserver favicon_update_watcher(
2379      chrome::NOTIFICATION_FAVICON_UPDATED,
2380      content::Source<WebContents>(prerender_contents->prerender_contents()));
2381  NavigateToDestURL();
2382  favicon_update_watcher.Wait();
2383}
2384
2385// Checks that when a prerendered page is swapped in to a referring page, the
2386// unload handlers on the referring page are executed.
2387// Fails about 50% on CrOS, 5-10% on linux, win, mac. http://crbug.com/128986
2388IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderUnload) {
2389  set_loader_path("files/prerender/prerender_loader_with_unload.html");
2390  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2391  string16 expected_title = ASCIIToUTF16("Unloaded");
2392  content::TitleWatcher title_watcher(
2393      current_browser()->tab_strip_model()->GetActiveWebContents(),
2394      expected_title);
2395  NavigateToDestURL();
2396  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
2397}
2398
2399// Checks that when the history is cleared, prerendering is cancelled and
2400// prerendering history is cleared.
2401IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) {
2402  PrerenderTestURL("files/prerender/prerender_page.html",
2403                   FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
2404                   1);
2405
2406  // Post a task to clear the history, and run the message loop until it
2407  // destroys the prerender.
2408  MessageLoop::current()->PostTask(
2409      FROM_HERE,
2410      base::Bind(&ClearBrowsingData, current_browser(),
2411                 BrowsingDataRemover::REMOVE_HISTORY));
2412  content::RunMessageLoop();
2413
2414  // Make sure prerender history was cleared.
2415  EXPECT_EQ(0, GetHistoryLength());
2416}
2417
2418// Checks that when the cache is cleared, prerenders are cancelled but
2419// prerendering history is not cleared.
2420IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearCache) {
2421  PrerenderTestURL("files/prerender/prerender_page.html",
2422                   FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
2423                   1);
2424
2425  // Post a task to clear the cache, and run the message loop until it
2426  // destroys the prerender.
2427  MessageLoop::current()->PostTask(FROM_HERE,
2428      base::Bind(&ClearBrowsingData, current_browser(),
2429                 BrowsingDataRemover::REMOVE_CACHE));
2430  content::RunMessageLoop();
2431
2432  // Make sure prerender history was not cleared.  Not a vital behavior, but
2433  // used to compare with PrerenderClearHistory test.
2434  EXPECT_EQ(1, GetHistoryLength());
2435}
2436
2437IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) {
2438  PrerenderTestURL("files/prerender/prerender_page.html",
2439                   FINAL_STATUS_CANCELLED,
2440                   1);
2441  // Post a task to cancel all the prerenders.
2442  MessageLoop::current()->PostTask(
2443      FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager()));
2444  content::RunMessageLoop();
2445  EXPECT_TRUE(GetPrerenderContents() == NULL);
2446}
2447
2448IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) {
2449  PrerenderTestURL("files/prerender/prerender_page.html",
2450                   FINAL_STATUS_CANCELLED, 1);
2451  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
2452  EXPECT_TRUE(DidReceivePrerenderLoadEventForLinkNumber(0));
2453  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
2454
2455  MessageLoop::current()->PostTask(
2456      FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager()));
2457  content::RunMessageLoop();
2458
2459  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
2460  EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
2461  EXPECT_FALSE(HadPrerenderEventErrors());
2462}
2463
2464// Cancels the prerender of a page with its own prerender.  The second prerender
2465// should never be started.
2466IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2467                       PrerenderCancelPrerenderWithPrerender) {
2468  PrerenderTestURL("files/prerender/prerender_infinite_a.html",
2469                   FINAL_STATUS_CANCELLED,
2470                   1);
2471  // Post a task to cancel all the prerenders.
2472  MessageLoop::current()->PostTask(
2473      FROM_HERE, base::Bind(&CancelAllPrerenders, GetPrerenderManager()));
2474  content::RunMessageLoop();
2475  EXPECT_TRUE(GetPrerenderContents() == NULL);
2476}
2477
2478// PrerenderBrowserTest.PrerenderEventsNoLoad may pass flakily on regression,
2479// so please be aggressive about filing bugs when this test is failing.
2480IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEventsNoLoad) {
2481  // This should be canceled.
2482  PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
2483                   FINAL_STATUS_AUTH_NEEDED,
2484                   1);
2485  EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
2486  EXPECT_FALSE(DidReceivePrerenderLoadEventForLinkNumber(0));
2487  EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
2488  EXPECT_FALSE(HadPrerenderEventErrors());
2489}
2490
2491// Prerendering and history tests.
2492// The prerendered page is navigated to in several ways [navigate via
2493// omnibox, click on link, key-modified click to open in background tab, etc],
2494// followed by a navigation to another page from the prerendered page, followed
2495// by a back navigation.
2496
2497IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) {
2498  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2499                   FINAL_STATUS_USED,
2500                   1);
2501  NavigateToDestURL();
2502  ClickToNextPageAfterPrerender();
2503  GoBackToPrerender();
2504}
2505
2506// Disabled due to timeouts on commit queue.
2507// http://crbug.com/121130
2508IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2509                       DISABLED_PrerenderNavigateNavigateGoBack) {
2510  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2511                   FINAL_STATUS_USED,
2512                   1);
2513  NavigateToDestURL();
2514  NavigateToNextPageAfterPrerender();
2515  GoBackToPrerender();
2516}
2517
2518IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) {
2519  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2520                   FINAL_STATUS_USED,
2521                   1);
2522  OpenDestURLViaClick();
2523  ClickToNextPageAfterPrerender();
2524  GoBackToPrerender();
2525}
2526
2527// Disabled due to timeouts on commit queue.
2528// http://crbug.com/121130
2529IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2530                       DISABLED_PrerenderClickNavigateGoBack) {
2531  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2532                   FINAL_STATUS_USED,
2533                   1);
2534  OpenDestURLViaClick();
2535  NavigateToNextPageAfterPrerender();
2536  GoBackToPrerender();
2537}
2538
2539IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
2540  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2541                   FINAL_STATUS_APP_TERMINATING,
2542                   1);
2543  OpenDestURLViaClickNewWindow();
2544}
2545
2546IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
2547  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2548                   FINAL_STATUS_APP_TERMINATING,
2549                   1);
2550  OpenDestURLViaClickNewForegroundTab();
2551}
2552
2553IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) {
2554  PrerenderTestURL("files/prerender/prerender_page_with_link.html",
2555                   FINAL_STATUS_APP_TERMINATING,
2556                   1);
2557  OpenDestURLViaClickNewBackgroundTab();
2558}
2559
2560IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2561                       NavigateToPrerenderedPageWhenDevToolsAttached) {
2562  DisableJavascriptCalls();
2563  WebContents* web_contents =
2564      current_browser()->tab_strip_model()->GetActiveWebContents();
2565  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
2566      web_contents->GetRenderViewHost()));
2567  DevToolsManager* manager = DevToolsManager::GetInstance();
2568  FakeDevToolsClientHost client_host;
2569  manager->RegisterDevToolsClientHostFor(agent, &client_host);
2570  const char* url = "files/prerender/prerender_page.html";
2571  PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1);
2572  NavigateToURL(url);
2573  manager->ClientHostClosing(&client_host);
2574}
2575
2576// Validate that the sessionStorage namespace remains the same when swapping
2577// in a prerendered page.
2578IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) {
2579  set_loader_path("files/prerender/prerender_loader_with_session_storage.html");
2580  PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
2581                   FINAL_STATUS_USED,
2582                   1);
2583  NavigateToDestURL();
2584  GoBackToPageBeforePrerender();
2585}
2586
2587#if defined(OS_MACOSX)
2588// http://crbug.com/142535 - Times out on Chrome Mac release builder
2589#define MAYBE_ControlGroup DISABLED_ControlGroup
2590#else
2591#define MAYBE_ControlGroup ControlGroup
2592#endif
2593// Checks that the control group works.  A JS alert cannot be detected in the
2594// control group.
2595IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_ControlGroup) {
2596  RestorePrerenderMode restore_prerender_mode;
2597  PrerenderManager::SetMode(
2598      PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
2599  PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
2600                   FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
2601  NavigateToDestURL();
2602}
2603
2604// Make sure that the MatchComplete dummy works in the normal case.  Once
2605// a prerender is cancelled because of a script, a dummy must be created to
2606// account for the MatchComplete case, and it must have a final status of
2607// FINAL_STATUS_WOULD_HAVE_BEEN_USED.
2608#if defined(OS_MACOSX)
2609// http://crbug.com/142912 - Times out on Chrome Mac release builder
2610#define MAYBE_MatchCompleteDummy DISABLED_MatchCompleteDummy
2611#else
2612#define MAYBE_MatchCompleteDummy MatchCompleteDummy
2613#endif
2614IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_MatchCompleteDummy) {
2615  std::deque<FinalStatus> expected_final_status_queue;
2616  expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT);
2617  expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
2618  PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
2619                   expected_final_status_queue, 1);
2620  NavigateToDestURL();
2621}
2622
2623class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest {
2624 public:
2625  PrerenderBrowserTestWithNaCl() {}
2626  virtual ~PrerenderBrowserTestWithNaCl() {}
2627
2628  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
2629    PrerenderBrowserTest::SetUpCommandLine(command_line);
2630    command_line->AppendSwitch(switches::kEnableNaCl);
2631  }
2632};
2633
2634// Check that NaCl plugins work when enabled, with prerendering.
2635IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
2636                       PrerenderNaClPluginEnabled) {
2637  PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
2638                   FINAL_STATUS_USED,
2639                   1);
2640  NavigateToDestURL();
2641
2642  // To avoid any chance of a race, we have to let the script send its response
2643  // asynchronously.
2644  WebContents* web_contents =
2645      browser()->tab_strip_model()->GetActiveWebContents();
2646  bool display_test_result = false;
2647  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents,
2648                                                   "DidDisplayReallyPass()",
2649                                                   &display_test_result));
2650  ASSERT_TRUE(display_test_result);
2651}
2652
2653// Checks that the referrer policy is used when prerendering.
2654IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) {
2655  set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
2656  PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
2657                   FINAL_STATUS_USED,
2658                   1);
2659  NavigateToDestURL();
2660}
2661
2662// Checks that the referrer policy is used when prerendering on HTTPS.
2663IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLReferrerPolicy) {
2664  set_use_https_src(true);
2665  set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
2666  PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
2667                   FINAL_STATUS_USED,
2668                   1);
2669  NavigateToDestURL();
2670}
2671
2672// Test interaction of the webNavigation and tabs API with prerender.
2673class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest,
2674                                           public ExtensionApiTest {
2675 public:
2676  PrerenderBrowserTestWithExtensions() {
2677    autostart_test_server_ = false;
2678  }
2679  virtual ~PrerenderBrowserTestWithExtensions() {}
2680
2681  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
2682    PrerenderBrowserTest::SetUpCommandLine(command_line);
2683    ExtensionApiTest::SetUpCommandLine(command_line);
2684  }
2685
2686  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
2687    PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
2688    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
2689  }
2690
2691  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
2692    PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
2693    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
2694  }
2695
2696  virtual void SetUpOnMainThread() OVERRIDE {
2697    PrerenderBrowserTest::SetUpOnMainThread();
2698  }
2699};
2700
2701IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) {
2702  ASSERT_TRUE(StartTestServer());
2703  extensions::FrameNavigationState::set_allow_extension_scheme(true);
2704
2705  CommandLine::ForCurrentProcess()->AppendSwitch(
2706      switches::kAllowLegacyExtensionManifests);
2707
2708  // Wait for the extension to set itself up and return control to us.
2709  ASSERT_TRUE(
2710      RunExtensionSubtest("webnavigation", "test_prerender.html")) << message_;
2711
2712  ResultCatcher catcher;
2713
2714  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2715
2716  ChannelDestructionWatcher channel_close_watcher;
2717  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2718      GetActiveWebContents()->GetRenderProcessHost());
2719  NavigateToDestURL();
2720  channel_close_watcher.WaitForChannelClose();
2721
2722  ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2723  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
2724}
2725
2726IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, TabsApi) {
2727  ASSERT_TRUE(StartTestServer());
2728  extensions::FrameNavigationState::set_allow_extension_scheme(true);
2729
2730  // Wait for the extension to set itself up and return control to us.
2731  ASSERT_TRUE(RunExtensionSubtest("tabs/on_replaced", "on_replaced.html"))
2732      << message_;
2733
2734  ResultCatcher catcher;
2735
2736  PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
2737
2738  ChannelDestructionWatcher channel_close_watcher;
2739  channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
2740      GetActiveWebContents()->GetRenderProcessHost());
2741  NavigateToDestURL();
2742  channel_close_watcher.WaitForChannelClose();
2743
2744  ASSERT_TRUE(IsEmptyPrerenderLinkManager());
2745  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
2746}
2747
2748// Checks that non-http/https subresource cancels the prerender.
2749IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2750                       PrerenderCancelSubresourceUnsupportedScheme) {
2751  GURL image_url = GURL("invalidscheme://www.google.com/test.jpg");
2752  std::vector<net::TestServer::StringPair> replacement_text;
2753  replacement_text.push_back(
2754      std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
2755  std::string replacement_path;
2756  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2757      "files/prerender/prerender_with_image.html",
2758      replacement_text,
2759      &replacement_path));
2760  PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1);
2761  NavigateToDestURL();
2762}
2763
2764// Checks that non-http/https subresource cancels the prerender on redirect.
2765IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2766                       PrerenderCancelSubresourceRedirectUnsupportedScheme) {
2767  GURL image_url = test_server()->GetURL(
2768      CreateServerRedirect("invalidscheme://www.google.com/test.jpg"));
2769  std::vector<net::TestServer::StringPair> replacement_text;
2770  replacement_text.push_back(
2771      std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
2772  std::string replacement_path;
2773  ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
2774      "files/prerender/prerender_with_image.html",
2775      replacement_text,
2776      &replacement_path));
2777  PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 1);
2778  NavigateToDestURL();
2779}
2780
2781// Checks that non-http/https main page redirects cancel the prerender.
2782IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
2783                       PrerenderCancelMainFrameRedirectUnsupportedScheme) {
2784  GURL url = test_server()->GetURL(
2785      CreateServerRedirect("invalidscheme://www.google.com/test.html"));
2786  PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 1);
2787  NavigateToDestURL();
2788}
2789
2790}  // namespace prerender
2791