Home | History | Annotate | Download | only in prerender
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/command_line.h"
      6 #include "base/path_service.h"
      7 #include "base/string_util.h"
      8 #include "chrome/browser/prerender/prerender_contents.h"
      9 #include "chrome/browser/prerender/prerender_manager.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/task_manager/task_manager.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/browser_window.h"
     14 #include "chrome/common/chrome_paths.h"
     15 #include "chrome/common/chrome_switches.h"
     16 #include "chrome/test/in_process_browser_test.h"
     17 #include "chrome/test/ui_test_utils.h"
     18 #include "content/browser/tab_contents/tab_contents.h"
     19 #include "grit/generated_resources.h"
     20 #include "net/url_request/url_request_context.h"
     21 #include "net/url_request/url_request_context_getter.h"
     22 #include "ui/base/l10n/l10n_util.h"
     23 
     24 #include <deque>
     25 
     26 // Prerender tests work as follows:
     27 //
     28 // A page with a prefetch link to the test page is loaded.  Once prerendered,
     29 // its Javascript function DidPrerenderPass() is called, which returns true if
     30 // the page behaves as expected when prerendered.
     31 //
     32 // The prerendered page is then displayed on a tab.  The Javascript function
     33 // DidDisplayPass() is called, and returns true if the page behaved as it
     34 // should while being displayed.
     35 
     36 namespace prerender {
     37 
     38 namespace {
     39 
     40 std::string CreateClientRedirect(const std::string& dest_url) {
     41   const char* const kClientRedirectBase = "client-redirect?";
     42   return kClientRedirectBase + dest_url;
     43 }
     44 
     45 std::string CreateServerRedirect(const std::string& dest_url) {
     46   const char* const kServerRedirectBase = "server-redirect?";
     47   return kServerRedirectBase + dest_url;
     48 }
     49 
     50 // PrerenderContents that stops the UI message loop on DidStopLoading().
     51 class TestPrerenderContents : public PrerenderContents {
     52  public:
     53   TestPrerenderContents(
     54       PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
     55       const std::vector<GURL>& alias_urls,
     56       const GURL& referrer,
     57       int number_of_loads,
     58       FinalStatus expected_final_status)
     59       : PrerenderContents(prerender_manager, profile, url, alias_urls,
     60                           referrer),
     61         number_of_loads_(0),
     62         expected_number_of_loads_(number_of_loads),
     63         expected_final_status_(expected_final_status) {
     64   }
     65 
     66   virtual ~TestPrerenderContents() {
     67     EXPECT_EQ(expected_final_status_, final_status()) <<
     68         " when testing URL " << prerender_url().path();
     69     // In the event we are destroyed, say if the prerender was canceled, quit
     70     // the UI message loop.
     71     MessageLoopForUI::current()->Quit();
     72   }
     73 
     74   virtual void DidStopLoading() {
     75     PrerenderContents::DidStopLoading();
     76     ++number_of_loads_;
     77     if (expected_final_status_ == FINAL_STATUS_USED &&
     78         number_of_loads_ >= expected_number_of_loads_) {
     79       MessageLoopForUI::current()->Quit();
     80     }
     81   }
     82 
     83  private:
     84   int number_of_loads_;
     85   int expected_number_of_loads_;
     86   FinalStatus expected_final_status_;
     87 };
     88 
     89 // PrerenderManager that uses TestPrerenderContents.
     90 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
     91  public:
     92   WaitForLoadPrerenderContentsFactory(
     93       int number_of_loads,
     94       const std::deque<FinalStatus>& expected_final_status_queue)
     95       : number_of_loads_(number_of_loads) {
     96     expected_final_status_queue_.resize(expected_final_status_queue.size());
     97     std::copy(expected_final_status_queue.begin(),
     98               expected_final_status_queue.end(),
     99               expected_final_status_queue_.begin());
    100     LOG(INFO) << "Factory created with queue length " <<
    101                  expected_final_status_queue_.size();
    102   }
    103 
    104   virtual PrerenderContents* CreatePrerenderContents(
    105       PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
    106       const std::vector<GURL>& alias_urls, const GURL& referrer) {
    107     CHECK(!expected_final_status_queue_.empty()) <<
    108           "Creating prerender contents for " << url.path() <<
    109           " with no expected final status";
    110     FinalStatus expected_final_status = expected_final_status_queue_.front();
    111     expected_final_status_queue_.pop_front();
    112     LOG(INFO) << "Creating prerender contents for " << url.path() <<
    113                  " with expected final status " << expected_final_status;
    114     LOG(INFO) << expected_final_status_queue_.size() << " left in the queue.";
    115     return new TestPrerenderContents(prerender_manager, profile, url,
    116                                      alias_urls, referrer,
    117                                      number_of_loads_,
    118                                      expected_final_status);
    119   }
    120 
    121  private:
    122   int number_of_loads_;
    123   std::deque<FinalStatus> expected_final_status_queue_;
    124 };
    125 
    126 }  // namespace
    127 
    128 class PrerenderBrowserTest : public InProcessBrowserTest {
    129  public:
    130   PrerenderBrowserTest()
    131       : prc_factory_(NULL),
    132         use_https_src_server_(false) {
    133     EnableDOMAutomation();
    134   }
    135 
    136   virtual void SetUpCommandLine(CommandLine* command_line) {
    137     command_line->AppendSwitchASCII(switches::kPrerender,
    138                                     switches::kPrerenderSwitchValueEnabled);
    139 #if defined(OS_MACOSX)
    140     // The plugins directory isn't read by default on the Mac, so it needs to be
    141     // explicitly registered.
    142     FilePath app_dir;
    143     PathService::Get(chrome::DIR_APP, &app_dir);
    144     command_line->AppendSwitchPath(
    145         switches::kExtraPluginDir,
    146         app_dir.Append(FILE_PATH_LITERAL("plugins")));
    147 #endif
    148   }
    149 
    150   // Overload for a single expected final status
    151   void PrerenderTestURL(const std::string& html_file,
    152                         FinalStatus expected_final_status,
    153                         int total_navigations) {
    154     std::deque<FinalStatus> expected_final_status_queue(1,
    155                                                         expected_final_status);
    156     PrerenderTestURLImpl(html_file,
    157                          expected_final_status_queue,
    158                          total_navigations);
    159   }
    160 
    161   void PrerenderTestURL(
    162       const std::string& html_file,
    163       const std::deque<FinalStatus>& expected_final_status_queue,
    164       int total_navigations) {
    165     PrerenderTestURLImpl(html_file,
    166                          expected_final_status_queue,
    167                          total_navigations);
    168   }
    169 
    170   void NavigateToDestURL() const {
    171     ui_test_utils::NavigateToURL(browser(), dest_url_);
    172 
    173     // Make sure the PrerenderContents found earlier was used or removed
    174     EXPECT_TRUE(prerender_manager()->FindEntry(dest_url_) == NULL);
    175 
    176     // Check if page behaved as expected when actually displayed.
    177     bool display_test_result = false;
    178     ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    179         browser()->GetSelectedTabContents()->render_view_host(), L"",
    180         L"window.domAutomationController.send(DidDisplayPass())",
    181         &display_test_result));
    182     EXPECT_TRUE(display_test_result);
    183   }
    184 
    185   bool UrlIsInPrerenderManager(const std::string& html_file) {
    186     GURL dest_url = test_server()->GetURL(html_file);
    187     return (prerender_manager()->FindEntry(dest_url) != NULL);
    188   }
    189 
    190   bool UrlIsInPrerenderManager(const GURL& url) {
    191     return (prerender_manager()->FindEntry(url) != NULL);
    192   }
    193 
    194   bool UrlIsPendingInPrerenderManager(const std::string& html_file) {
    195     GURL dest_url = test_server()->GetURL(html_file);
    196     return (prerender_manager()->FindPendingEntry(dest_url) != NULL);
    197   }
    198 
    199   void set_use_https_src(bool use_https_src_server) {
    200     use_https_src_server_ = use_https_src_server;
    201   }
    202 
    203   TaskManagerModel* model() const {
    204     return TaskManager::GetInstance()->model();
    205   }
    206 
    207   void set_dest_url(const GURL& dest_url) { dest_url_ = dest_url; }
    208 
    209  private:
    210   void PrerenderTestURLImpl(
    211       const std::string& html_file,
    212       const std::deque<FinalStatus>& expected_final_status_queue,
    213       int total_navigations) {
    214     ASSERT_TRUE(test_server()->Start());
    215     dest_url_ = test_server()->GetURL(html_file);
    216 
    217     std::vector<net::TestServer::StringPair> replacement_text;
    218     replacement_text.push_back(
    219         make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec()));
    220     std::string replacement_path;
    221     ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
    222         "files/prerender/prerender_loader.html",
    223         replacement_text,
    224         &replacement_path));
    225 
    226     net::TestServer* src_server = test_server();
    227     scoped_ptr<net::TestServer> https_src_server;
    228     if (use_https_src_server_) {
    229       https_src_server.reset(
    230           new net::TestServer(net::TestServer::TYPE_HTTPS,
    231                               FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
    232       ASSERT_TRUE(https_src_server->Start());
    233       src_server = https_src_server.get();
    234     }
    235     GURL src_url = src_server->GetURL(replacement_path);
    236 
    237     // This is needed to exit the event loop once the prerendered page has
    238     // stopped loading or was cancelled.
    239     ASSERT_TRUE(prerender_manager());
    240     prerender_manager()->rate_limit_enabled_ = false;
    241     ASSERT_TRUE(prc_factory_ == NULL);
    242     prc_factory_ =
    243         new WaitForLoadPrerenderContentsFactory(total_navigations,
    244                                                 expected_final_status_queue);
    245     prerender_manager()->SetPrerenderContentsFactory(prc_factory_);
    246     FinalStatus expected_final_status = expected_final_status_queue.front();
    247 
    248     // ui_test_utils::NavigateToURL uses its own observer and message loop.
    249     // Since the test needs to wait until the prerendered page has stopped
    250     // loading, rathather than the page directly navigated to, need to
    251     // handle browser navigation directly.
    252     browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
    253 
    254     TestPrerenderContents* prerender_contents = NULL;
    255     ui_test_utils::RunMessageLoop();
    256 
    257     prerender_contents =
    258         static_cast<TestPrerenderContents*>(
    259             prerender_manager()->FindEntry(dest_url_));
    260 
    261     switch (expected_final_status) {
    262       case FINAL_STATUS_USED: {
    263         ASSERT_TRUE(prerender_contents != NULL);
    264 
    265         // Check if page behaves as expected while in prerendered state.
    266         bool prerender_test_result = false;
    267         ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    268             prerender_contents->render_view_host(), L"",
    269             L"window.domAutomationController.send(DidPrerenderPass())",
    270             &prerender_test_result));
    271         EXPECT_TRUE(prerender_test_result);
    272         break;
    273       }
    274       default:
    275         // In the failure case, we should have removed dest_url_ from the
    276         // prerender_manager.
    277         EXPECT_TRUE(prerender_contents == NULL);
    278         break;
    279     }
    280   }
    281 
    282   PrerenderManager* prerender_manager() const {
    283     Profile* profile = browser()->GetSelectedTabContents()->profile();
    284     PrerenderManager* prerender_manager = profile->GetPrerenderManager();
    285     return prerender_manager;
    286   }
    287 
    288   WaitForLoadPrerenderContentsFactory* prc_factory_;
    289   GURL dest_url_;
    290   bool use_https_src_server_;
    291 };
    292 
    293 // Checks that a page is correctly prerendered in the case of a
    294 // <link rel=prefetch> tag and then loaded into a tab in response to a
    295 // navigation.
    296 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
    297   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
    298   NavigateToDestURL();
    299 }
    300 
    301 // Checks that the prerendering of a page is canceled correctly when a
    302 // Javascript alert is called.
    303 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
    304   PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
    305                    FINAL_STATUS_JAVASCRIPT_ALERT,
    306                    1);
    307 }
    308 
    309 // Checks that the prerendering of a page is canceled correctly when a
    310 // Javascript alert is called.
    311 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
    312   PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
    313                    FINAL_STATUS_JAVASCRIPT_ALERT,
    314                    1);
    315 }
    316 
    317 // Checks that plugins are not loaded while a page is being preloaded, but
    318 // are loaded when the page is displayed.
    319 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) {
    320   PrerenderTestURL("files/prerender/plugin_delay_load.html",
    321                    FINAL_STATUS_USED,
    322                    1);
    323   NavigateToDestURL();
    324 }
    325 
    326 // Checks that plugins in an iframe are not loaded while a page is
    327 // being preloaded, but are loaded when the page is displayed.
    328 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIframeDelayLoadPlugin) {
    329   PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
    330                    FINAL_STATUS_USED,
    331                    1);
    332   NavigateToDestURL();
    333 }
    334 
    335 // Renders a page that contains a prerender link to a page that contains an
    336 // iframe with a source that requires http authentication. This should not
    337 // prerender successfully.
    338 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
    339   PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
    340                    FINAL_STATUS_AUTH_NEEDED,
    341                    1);
    342 }
    343 
    344 // Checks that client-issued redirects work with prerendering.
    345 // This version navigates to the page which issues the redirection, rather
    346 // than the final destination page.
    347 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    348                        PrerenderClientRedirectNavigateToFirst) {
    349   PrerenderTestURL(
    350       CreateClientRedirect("files/prerender/prerender_page.html"),
    351       FINAL_STATUS_USED,
    352       2);
    353   NavigateToDestURL();
    354 }
    355 
    356 // Checks that client-issued redirects work with prerendering.
    357 // This version navigates to the final destination page, rather than the
    358 // page which does the redirection.
    359 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    360                        PrerenderClientRedirectNavigateToSecond) {
    361   PrerenderTestURL(
    362       CreateClientRedirect("files/prerender/prerender_page.html"),
    363       FINAL_STATUS_USED,
    364       2);
    365   set_dest_url(test_server()->GetURL("files/prerender/prerender_page.html"));
    366   NavigateToDestURL();
    367 }
    368 
    369 // Checks that client-issued redirects to an https page will cancel prerenders.
    370 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectToHttps) {
    371   net::TestServer https_server(net::TestServer::TYPE_HTTPS,
    372                                FilePath(FILE_PATH_LITERAL("chrome/test/data")));
    373   ASSERT_TRUE(https_server.Start());
    374   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
    375   PrerenderTestURL(CreateClientRedirect(https_url.spec()),
    376                    FINAL_STATUS_HTTPS,
    377                    1);
    378 }
    379 
    380 // Checks that client-issued redirects within an iframe in a prerendered
    381 // page will not count as an "alias" for the prerendered page.
    382 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClientRedirectInIframe) {
    383   std::string redirect_path = CreateClientRedirect(
    384       "/files/prerender/prerender_embedded_content.html");
    385   std::vector<net::TestServer::StringPair> replacement_text;
    386   replacement_text.push_back(
    387       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
    388   std::string replacement_path;
    389   ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
    390       "files/prerender/prerender_with_iframe.html",
    391       replacement_text,
    392       &replacement_path));
    393   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
    394   EXPECT_FALSE(UrlIsInPrerenderManager(
    395       "files/prerender/prerender_embedded_content.html"));
    396   NavigateToDestURL();
    397 }
    398 
    399 // Checks that client-issued redirects within an iframe in a prerendered
    400 // page to an https page will not cancel the prerender, nor will it
    401 // count as an "alias" for the prerendered page.
    402 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    403                        PrerenderClientRedirectToHttpsInIframe) {
    404   net::TestServer https_server(net::TestServer::TYPE_HTTPS,
    405                                FilePath(FILE_PATH_LITERAL("chrome/test/data")));
    406   ASSERT_TRUE(https_server.Start());
    407   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
    408   std::string redirect_path = CreateClientRedirect(https_url.spec());
    409   std::vector<net::TestServer::StringPair> replacement_text;
    410   replacement_text.push_back(
    411       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
    412   std::string replacement_path;
    413   ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
    414       "files/prerender/prerender_with_iframe.html",
    415       replacement_text,
    416       &replacement_path));
    417   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
    418   EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
    419   NavigateToDestURL();
    420 }
    421 
    422 // Checks that server-issued redirects work with prerendering.
    423 // This version navigates to the page which issues the redirection, rather
    424 // than the final destination page.
    425 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    426                        PrerenderServerRedirectNavigateToFirst) {
    427   PrerenderTestURL(
    428       CreateServerRedirect("files/prerender/prerender_page.html"),
    429       FINAL_STATUS_USED,
    430       1);
    431   NavigateToDestURL();
    432 }
    433 
    434 // Checks that server-issued redirects work with prerendering.
    435 // This version navigates to the final destination page, rather than the
    436 // page which does the redirection.
    437 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    438                        PrerenderServerRedirectNavigateToSecond) {
    439   std::string redirect_path;
    440   PrerenderTestURL(
    441       CreateServerRedirect("files/prerender/prerender_page.html"),
    442       FINAL_STATUS_USED,
    443       1);
    444   set_dest_url(test_server()->GetURL("files/prerender/prerender_page.html"));
    445   NavigateToDestURL();
    446 }
    447 
    448 // TODO(cbentzel): Add server-redirect-to-https test. http://crbug.com/79182
    449 
    450 // Checks that server-issued redirects within an iframe in a prerendered
    451 // page will not count as an "alias" for the prerendered page.
    452 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
    453   std::string redirect_path = CreateServerRedirect(
    454       "/files/prerender/prerender_embedded_content.html");
    455   std::vector<net::TestServer::StringPair> replacement_text;
    456   replacement_text.push_back(
    457       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
    458   std::string replacement_path;
    459   ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
    460       "files/prerender/prerender_with_iframe.html",
    461       replacement_text,
    462       &replacement_path));
    463   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
    464   EXPECT_FALSE(UrlIsInPrerenderManager(
    465       "files/prerender/prerender_embedded_content.html"));
    466   NavigateToDestURL();
    467 }
    468 
    469 // Checks that server-issued redirects within an iframe in a prerendered
    470 // page to an https page will not cancel the prerender, nor will it
    471 // count as an "alias" for the prerendered page.
    472 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    473                        PrerenderServerRedirectToHttpsInIframe) {
    474   net::TestServer https_server(net::TestServer::TYPE_HTTPS,
    475                                FilePath(FILE_PATH_LITERAL("chrome/test/data")));
    476   ASSERT_TRUE(https_server.Start());
    477   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
    478   std::string redirect_path = CreateServerRedirect(https_url.spec());
    479   std::vector<net::TestServer::StringPair> replacement_text;
    480   replacement_text.push_back(
    481       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
    482   std::string replacement_path;
    483   ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements(
    484       "files/prerender/prerender_with_iframe.html",
    485       replacement_text,
    486       &replacement_path));
    487   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
    488   EXPECT_FALSE(UrlIsInPrerenderManager(https_url));
    489   NavigateToDestURL();
    490 }
    491 
    492 // Prerenders a page that contains an automatic download triggered through an
    493 // iframe. This should not prerender successfully.
    494 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIFrame) {
    495   PrerenderTestURL("files/prerender/prerender_download_iframe.html",
    496                    FINAL_STATUS_DOWNLOAD,
    497                    1);
    498 }
    499 
    500 // Prerenders a page that contains an automatic download triggered through
    501 // Javascript changing the window.location. This should not prerender
    502 // successfully.
    503 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
    504   PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
    505                    FINAL_STATUS_DOWNLOAD,
    506                    1);
    507 }
    508 
    509 // Prerenders a page that contains an automatic download triggered through a
    510 // client-issued redirect. This should not prerender successfully.
    511 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
    512   PrerenderTestURL("files/prerender/prerender_download_refresh.html",
    513                    FINAL_STATUS_DOWNLOAD,
    514                    1);
    515 }
    516 
    517 // Checks that the referrer is set when prerendering.
    518 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
    519   PrerenderTestURL("files/prerender/prerender_referrer.html",
    520                    FINAL_STATUS_USED,
    521                    1);
    522   NavigateToDestURL();
    523 }
    524 
    525 // Checks that the referrer is not set when prerendering and the source page is
    526 // HTTPS.
    527 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoSSLReferrer) {
    528   set_use_https_src(true);
    529   PrerenderTestURL("files/prerender/prerender_no_referrer.html",
    530                    FINAL_STATUS_USED,
    531                    1);
    532   NavigateToDestURL();
    533 }
    534 
    535 // Checks that popups on a prerendered page cause cancellation.
    536 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
    537   PrerenderTestURL("files/prerender/prerender_popup.html",
    538                    FINAL_STATUS_CREATE_NEW_WINDOW,
    539                    1);
    540 }
    541 
    542 
    543 
    544 // Checks that renderers using excessive memory will be terminated.
    545 // Disabled, http://crbug.com/77870.
    546 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    547                        DISABLED_PrerenderExcessiveMemory) {
    548   PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
    549                    FINAL_STATUS_MEMORY_LIMIT_EXCEEDED,
    550                    1);
    551 }
    552 
    553 // Checks that we don't prerender in an infinite loop.
    554 // Disabled, http://crbug.com/77870.
    555 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderInfiniteLoop) {
    556   const char* const kHtmlFileA = "prerender_infinite_a.html";
    557   const char* const kHtmlFileB = "prerender_infinite_b.html";
    558 
    559   std::deque<FinalStatus> expected_final_status_queue;
    560   expected_final_status_queue.push_back(FINAL_STATUS_USED);
    561   expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
    562 
    563   PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
    564 
    565   // Next url should be in pending list but not an active entry.
    566   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
    567   EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
    568 
    569   NavigateToDestURL();
    570 
    571   // Make sure the PrerenderContents for the next url is now in the manager
    572   // and not pending.
    573   EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
    574   EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
    575 }
    576 
    577 // Checks that we don't prerender in an infinite loop and multiple links are
    578 // handled correctly.
    579 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
    580                        FLAKY_PrerenderInfiniteLoopMultiple) {
    581   const char* const kHtmlFileA =
    582       "files/prerender/prerender_infinite_a_multiple.html";
    583   const char* const kHtmlFileB =
    584       "files/prerender/prerender_infinite_b_multiple.html";
    585   const char* const kHtmlFileC =
    586       "files/prerender/prerender_infinite_c_multiple.html";
    587 
    588   // We need to set the final status to expect here before starting any
    589   // prerenders. We set them on a queue so whichever we see first is expected to
    590   // be evicted, and the second should stick around until we exit.
    591   std::deque<FinalStatus> expected_final_status_queue;
    592   expected_final_status_queue.push_back(FINAL_STATUS_USED);
    593   expected_final_status_queue.push_back(FINAL_STATUS_EVICTED);
    594   expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
    595 
    596   PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
    597 
    598   // Next url should be in pending list but not an active entry.
    599   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
    600   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
    601   EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileB));
    602   EXPECT_TRUE(UrlIsPendingInPrerenderManager(kHtmlFileC));
    603 
    604   NavigateToDestURL();
    605 
    606   // Make sure the PrerenderContents for the next urls are now in the manager
    607   // and not pending. One and only one of the URLs (the last seen) should be the
    608   // active entry.
    609   bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
    610   bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
    611   EXPECT_TRUE((url_b_is_active_prerender || url_c_is_active_prerender) &&
    612               !(url_b_is_active_prerender && url_c_is_active_prerender));
    613   EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileB));
    614   EXPECT_FALSE(UrlIsPendingInPrerenderManager(kHtmlFileC));
    615 }
    616 
    617 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TaskManager) {
    618   // Show the task manager. This populates the model.
    619   browser()->window()->ShowTaskManager();
    620 
    621   // Start with two resources.
    622   EXPECT_EQ(2, model()->ResourceCount());
    623   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
    624 
    625   // The prerender makes three.
    626   EXPECT_EQ(3, model()->ResourceCount());
    627 
    628   // It shouldn't have a TabContents associated with it.
    629   ASSERT_TRUE(model()->GetResourceTabContents(1) == NULL);
    630 
    631   // The prefix should be "Prerender:"
    632   string16 prefix =
    633       l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX,
    634                                  string16());
    635   ASSERT_TRUE(StartsWith(model()->GetResourceTitle(1), prefix, true));
    636 
    637   NavigateToDestURL();
    638 
    639   // Prerender task should be killed and removed from the Task Manager.
    640   EXPECT_EQ(2, model()->ResourceCount());
    641 }
    642 
    643 // Checks that prerenderers will terminate when an audio tag is encountered.
    644 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Audio) {
    645   PrerenderTestURL("files/prerender/prerender_html5_audio.html",
    646                    FINAL_STATUS_HTML5_MEDIA,
    647                    1);
    648 }
    649 
    650 // Checks that prerenderers will terminate when a video tag is encountered.
    651 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) {
    652   PrerenderTestURL("files/prerender/prerender_html5_video.html",
    653                    FINAL_STATUS_HTML5_MEDIA,
    654                    1);
    655 }
    656 
    657 // Checks that prerenderers will terminate when a video tag is inserted via
    658 // javascript.
    659 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) {
    660   PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
    661                    FINAL_STATUS_HTML5_MEDIA,
    662                    1);
    663 }
    664 
    665 }  // namespace prerender
    666