Home | History | Annotate | Download | only in test
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/public/test/test_navigation_observer.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/run_loop.h"
     10 #include "base/stl_util.h"
     11 #include "content/browser/web_contents/web_contents_impl.h"
     12 #include "content/public/browser/web_contents_observer.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace content {
     16 
     17 class TestNavigationObserver::TestWebContentsObserver
     18     : public WebContentsObserver {
     19  public:
     20   TestWebContentsObserver(TestNavigationObserver* parent,
     21                           WebContents* web_contents)
     22       : WebContentsObserver(web_contents),
     23         parent_(parent) {
     24   }
     25 
     26  private:
     27   // WebContentsObserver:
     28   virtual void NavigationEntryCommitted(
     29       const LoadCommittedDetails& load_details) OVERRIDE {
     30     parent_->OnNavigationEntryCommitted(this, web_contents(), load_details);
     31   }
     32 
     33   virtual void DidAttachInterstitialPage() OVERRIDE {
     34     parent_->OnDidAttachInterstitialPage(web_contents());
     35   }
     36 
     37   virtual void WebContentsDestroyed() OVERRIDE {
     38     parent_->OnWebContentsDestroyed(this, web_contents());
     39   }
     40 
     41   virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE {
     42     parent_->OnDidStartLoading(web_contents());
     43   }
     44 
     45   virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
     46     parent_->OnDidStopLoading(web_contents());
     47   }
     48 
     49   TestNavigationObserver* parent_;
     50 
     51   DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
     52 };
     53 
     54 TestNavigationObserver::TestNavigationObserver(
     55     WebContents* web_contents,
     56     int number_of_navigations)
     57     : navigation_started_(false),
     58       navigations_completed_(0),
     59       number_of_navigations_(number_of_navigations),
     60       message_loop_runner_(new MessageLoopRunner),
     61       web_contents_created_callback_(
     62           base::Bind(
     63               &TestNavigationObserver::OnWebContentsCreated,
     64               base::Unretained(this))) {
     65   if (web_contents)
     66     RegisterAsObserver(web_contents);
     67 }
     68 
     69 TestNavigationObserver::TestNavigationObserver(
     70     WebContents* web_contents)
     71     : navigation_started_(false),
     72       navigations_completed_(0),
     73       number_of_navigations_(1),
     74       message_loop_runner_(new MessageLoopRunner),
     75       web_contents_created_callback_(
     76           base::Bind(
     77               &TestNavigationObserver::OnWebContentsCreated,
     78               base::Unretained(this))) {
     79   if (web_contents)
     80     RegisterAsObserver(web_contents);
     81 }
     82 
     83 TestNavigationObserver::~TestNavigationObserver() {
     84   StopWatchingNewWebContents();
     85 
     86   STLDeleteContainerPointers(web_contents_observers_.begin(),
     87                              web_contents_observers_.end());
     88 }
     89 
     90 void TestNavigationObserver::Wait() {
     91   message_loop_runner_->Run();
     92 }
     93 
     94 void TestNavigationObserver::StartWatchingNewWebContents() {
     95   WebContentsImpl::AddCreatedCallback(web_contents_created_callback_);
     96 }
     97 
     98 void TestNavigationObserver::StopWatchingNewWebContents() {
     99   WebContentsImpl::RemoveCreatedCallback(web_contents_created_callback_);
    100 }
    101 
    102 void TestNavigationObserver::RegisterAsObserver(WebContents* web_contents) {
    103   web_contents_observers_.insert(
    104       new TestWebContentsObserver(this, web_contents));
    105 }
    106 
    107 void TestNavigationObserver::OnWebContentsCreated(WebContents* web_contents) {
    108   RegisterAsObserver(web_contents);
    109 }
    110 
    111 void TestNavigationObserver::OnWebContentsDestroyed(
    112     TestWebContentsObserver* observer,
    113     WebContents* web_contents) {
    114   web_contents_observers_.erase(observer);
    115   delete observer;
    116 }
    117 
    118 void TestNavigationObserver::OnNavigationEntryCommitted(
    119     TestWebContentsObserver* observer,
    120     WebContents* web_contents,
    121     const LoadCommittedDetails& load_details) {
    122   navigation_started_ = true;
    123 }
    124 
    125 void TestNavigationObserver::OnDidAttachInterstitialPage(
    126     WebContents* web_contents) {
    127   // Going to an interstitial page does not trigger NavigationEntryCommitted,
    128   // but has the same meaning for us here.
    129   navigation_started_ = true;
    130 }
    131 
    132 void TestNavigationObserver::OnDidStartLoading(WebContents* web_contents) {
    133   navigation_started_ = true;
    134 }
    135 
    136 void TestNavigationObserver::OnDidStopLoading(WebContents* web_contents) {
    137   if (!navigation_started_)
    138     return;
    139 
    140   ++navigations_completed_;
    141   if (navigations_completed_ == number_of_navigations_) {
    142     navigation_started_ = false;
    143     message_loop_runner_->Quit();
    144   }
    145 }
    146 
    147 }  // namespace content
    148