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 15namespace content { 16 17class 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 54TestNavigationObserver::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 69TestNavigationObserver::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 83TestNavigationObserver::~TestNavigationObserver() { 84 StopWatchingNewWebContents(); 85 86 STLDeleteContainerPointers(web_contents_observers_.begin(), 87 web_contents_observers_.end()); 88} 89 90void TestNavigationObserver::Wait() { 91 message_loop_runner_->Run(); 92} 93 94void TestNavigationObserver::StartWatchingNewWebContents() { 95 WebContentsImpl::AddCreatedCallback(web_contents_created_callback_); 96} 97 98void TestNavigationObserver::StopWatchingNewWebContents() { 99 WebContentsImpl::RemoveCreatedCallback(web_contents_created_callback_); 100} 101 102void TestNavigationObserver::RegisterAsObserver(WebContents* web_contents) { 103 web_contents_observers_.insert( 104 new TestWebContentsObserver(this, web_contents)); 105} 106 107void TestNavigationObserver::OnWebContentsCreated(WebContents* web_contents) { 108 RegisterAsObserver(web_contents); 109} 110 111void TestNavigationObserver::OnWebContentsDestroyed( 112 TestWebContentsObserver* observer, 113 WebContents* web_contents) { 114 web_contents_observers_.erase(observer); 115 delete observer; 116} 117 118void TestNavigationObserver::OnNavigationEntryCommitted( 119 TestWebContentsObserver* observer, 120 WebContents* web_contents, 121 const LoadCommittedDetails& load_details) { 122 navigation_started_ = true; 123} 124 125void 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 132void TestNavigationObserver::OnDidStartLoading(WebContents* web_contents) { 133 navigation_started_ = true; 134} 135 136void 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