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