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 WebContentsDestroyed(WebContents* web_contents) OVERRIDE { 34 parent_->OnWebContentsDestroyed(this, web_contents); 35 } 36 37 virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE { 38 parent_->OnDidStartLoading(web_contents()); 39 } 40 41 virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE { 42 parent_->OnDidStopLoading(web_contents()); 43 } 44 45 TestNavigationObserver* parent_; 46 47 DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver); 48 }; 49 50 TestNavigationObserver::TestNavigationObserver( 51 WebContents* web_contents, 52 int number_of_navigations) 53 : navigation_started_(false), 54 navigations_completed_(0), 55 number_of_navigations_(number_of_navigations), 56 message_loop_runner_(new MessageLoopRunner), 57 web_contents_created_callback_( 58 base::Bind( 59 &TestNavigationObserver::OnWebContentsCreated, 60 base::Unretained(this))) { 61 if (web_contents) 62 RegisterAsObserver(web_contents); 63 } 64 65 TestNavigationObserver::TestNavigationObserver( 66 WebContents* web_contents) 67 : navigation_started_(false), 68 navigations_completed_(0), 69 number_of_navigations_(1), 70 message_loop_runner_(new MessageLoopRunner), 71 web_contents_created_callback_( 72 base::Bind( 73 &TestNavigationObserver::OnWebContentsCreated, 74 base::Unretained(this))) { 75 if (web_contents) 76 RegisterAsObserver(web_contents); 77 } 78 79 TestNavigationObserver::~TestNavigationObserver() { 80 StopWatchingNewWebContents(); 81 82 STLDeleteContainerPointers(web_contents_observers_.begin(), 83 web_contents_observers_.end()); 84 } 85 86 void TestNavigationObserver::Wait() { 87 message_loop_runner_->Run(); 88 } 89 90 void TestNavigationObserver::StartWatchingNewWebContents() { 91 WebContentsImpl::AddCreatedCallback(web_contents_created_callback_); 92 } 93 94 void TestNavigationObserver::StopWatchingNewWebContents() { 95 WebContentsImpl::RemoveCreatedCallback(web_contents_created_callback_); 96 } 97 98 void TestNavigationObserver::RegisterAsObserver(WebContents* web_contents) { 99 web_contents_observers_.insert( 100 new TestWebContentsObserver(this, web_contents)); 101 } 102 103 void TestNavigationObserver::OnWebContentsCreated(WebContents* web_contents) { 104 RegisterAsObserver(web_contents); 105 } 106 107 void TestNavigationObserver::OnWebContentsDestroyed( 108 TestWebContentsObserver* observer, 109 WebContents* web_contents) { 110 web_contents_observers_.erase(observer); 111 delete observer; 112 } 113 114 void TestNavigationObserver::OnNavigationEntryCommitted( 115 TestWebContentsObserver* observer, 116 WebContents* web_contents, 117 const LoadCommittedDetails& load_details) { 118 navigation_started_ = true; 119 } 120 121 void TestNavigationObserver::OnDidStartLoading(WebContents* web_contents) { 122 navigation_started_ = true; 123 } 124 125 void TestNavigationObserver::OnDidStopLoading(WebContents* web_contents) { 126 if (!navigation_started_) 127 return; 128 129 ++navigations_completed_; 130 if (navigations_completed_ == number_of_navigations_) { 131 navigation_started_ = false; 132 message_loop_runner_->Quit(); 133 } 134 } 135 136 } // namespace content 137