test_navigation_observer.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.h" 9#include "base/run_loop.h" 10#include "content/public/browser/notification_service.h" 11#include "content/public/browser/notification_types.h" 12#include "content/public/browser/render_view_host_observer.h" 13#include "content/public/test/js_injection_ready_observer.h" 14#include "content/public/test/test_utils.h" 15#include "testing/gtest/include/gtest/gtest.h" 16 17namespace content { 18 19// This class observes |render_view_host| and calls OnJsInjectionReady() of 20// |js_injection_ready_observer| when the time is right to inject JavaScript 21// into the page. 22class TestNavigationObserver::RVHOSendJS : public RenderViewHostObserver { 23 public: 24 RVHOSendJS(RenderViewHost* render_view_host, 25 JsInjectionReadyObserver* js_injection_ready_observer) 26 : RenderViewHostObserver(render_view_host), 27 js_injection_ready_observer_(js_injection_ready_observer) { 28 } 29 30 private: 31 // RenderViewHostObserver implementation. 32 virtual void RenderViewHostInitialized() OVERRIDE { 33 if (js_injection_ready_observer_) 34 js_injection_ready_observer_->OnJsInjectionReady(render_view_host()); 35 } 36 37 JsInjectionReadyObserver* js_injection_ready_observer_; 38 39 DISALLOW_COPY_AND_ASSIGN(RVHOSendJS); 40}; 41 42TestNavigationObserver::TestNavigationObserver( 43 const NotificationSource& source, 44 JsInjectionReadyObserver* js_injection_ready_observer, 45 int number_of_navigations) 46 : navigation_started_(false), 47 navigations_completed_(0), 48 number_of_navigations_(number_of_navigations), 49 js_injection_ready_observer_(js_injection_ready_observer), 50 done_(false), 51 running_(false) { 52 // When javascript injection is requested, register for RenderViewHost 53 // creation. 54 if (js_injection_ready_observer_) { 55 registrar_.Add(this, NOTIFICATION_RENDER_VIEW_HOST_CREATED, 56 NotificationService::AllSources()); 57 } 58 RegisterAsObserver(source); 59} 60 61TestNavigationObserver::TestNavigationObserver( 62 const NotificationSource& source) 63 : navigation_started_(false), 64 navigations_completed_(0), 65 number_of_navigations_(1), 66 js_injection_ready_observer_(NULL), 67 done_(false), 68 running_(false) { 69 RegisterAsObserver(source); 70} 71 72TestNavigationObserver::~TestNavigationObserver() { 73} 74 75void TestNavigationObserver::WaitForObservation( 76 const base::Closure& wait_loop_callback, 77 const base::Closure& done_callback) { 78 if (done_) 79 return; 80 81 EXPECT_FALSE(running_); 82 running_ = true; 83 done_callback_ = done_callback; 84 wait_loop_callback.Run(); 85 EXPECT_TRUE(done_); 86} 87 88void TestNavigationObserver::Wait() { 89 base::RunLoop run_loop; 90 WaitForObservation( 91 base::Bind(&base::RunLoop::Run, base::Unretained(&run_loop)), 92 GetQuitTaskForRunLoop(&run_loop)); 93} 94 95TestNavigationObserver::TestNavigationObserver( 96 JsInjectionReadyObserver* js_injection_ready_observer, 97 int number_of_navigations) 98 : navigation_started_(false), 99 navigations_completed_(0), 100 number_of_navigations_(number_of_navigations), 101 js_injection_ready_observer_(js_injection_ready_observer), 102 done_(false), 103 running_(false) { 104 // When javascript injection is requested, register for RenderViewHost 105 // creation. 106 if (js_injection_ready_observer_) { 107 registrar_.Add(this, NOTIFICATION_RENDER_VIEW_HOST_CREATED, 108 NotificationService::AllSources()); 109 } 110} 111 112void TestNavigationObserver::RegisterAsObserver( 113 const NotificationSource& source) { 114 // Register for events to know when we've finished loading the page and are 115 // ready to quit the current message loop to return control back to the 116 // waiting test. 117 registrar_.Add(this, NOTIFICATION_NAV_ENTRY_COMMITTED, source); 118 registrar_.Add(this, NOTIFICATION_LOAD_START, source); 119 registrar_.Add(this, NOTIFICATION_LOAD_STOP, source); 120} 121 122void TestNavigationObserver::Observe( 123 int type, const NotificationSource& source, 124 const NotificationDetails& details) { 125 switch (type) { 126 case NOTIFICATION_NAV_ENTRY_COMMITTED: 127 case NOTIFICATION_LOAD_START: 128 navigation_started_ = true; 129 break; 130 case NOTIFICATION_LOAD_STOP: 131 if (navigation_started_ && 132 ++navigations_completed_ == number_of_navigations_) { 133 navigation_started_ = false; 134 done_ = true; 135 if (running_) { 136 running_ = false; 137 done_callback_.Run(); 138 } 139 } 140 break; 141 case NOTIFICATION_RENDER_VIEW_HOST_CREATED: 142 rvho_send_js_.reset(new RVHOSendJS( 143 Source<RenderViewHost>(source).ptr(), 144 js_injection_ready_observer_)); 145 break; 146 default: 147 NOTREACHED(); 148 } 149} 150 151} // namespace content 152