diff options
author | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 01:17:57 +0000 |
---|---|---|
committer | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 01:17:57 +0000 |
commit | 405af130489d96d7d4add7d7ace48d9593ff28a6 (patch) | |
tree | 152958bf1074cdb360f82a46ea314d2b157db3aa /content | |
parent | 9c9e2c65a1ea1c3075a8b5b44e5f6ee60504017b (diff) | |
download | chromium_src-405af130489d96d7d4add7d7ace48d9593ff28a6.zip chromium_src-405af130489d96d7d4add7d7ace48d9593ff28a6.tar.gz chromium_src-405af130489d96d7d4add7d7ace48d9593ff28a6.tar.bz2 |
Move chrome/test/base/test_navigation_observer.cc to content/test
Use bind::Closure to handle the idle & done callbacks as suggested by darin
in conversation with jar@ last week.
R= jar@chromium.org, phajdan.jr@chromium.org
BUG=105213
TEST=browser_test
Review URL: http://codereview.chromium.org/8772036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114331 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/content_tests.gypi | 3 | ||||
-rw-r--r-- | content/test/js_injection_ready_observer.h | 23 | ||||
-rw-r--r-- | content/test/test_navigation_observer.cc | 122 | ||||
-rw-r--r-- | content/test/test_navigation_observer.h | 89 |
4 files changed, 237 insertions, 0 deletions
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 38e858d..bf27619 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -73,6 +73,7 @@ 'test/browser_test_base.h', 'test/content_test_suite.cc', 'test/content_test_suite.h', + 'test/js_injection_ready_observer.h', 'test/mock_keyboard.cc', 'test/mock_keyboard.h', 'test/mock_keyboard_driver_win.cc', @@ -91,6 +92,8 @@ 'test/test_browser_thread.h', 'test/test_content_client.cc', 'test/test_content_client.h', + 'test/test_navigation_observer.cc', + 'test/test_navigation_observer.h', 'test/test_notification_tracker.cc', 'test/test_notification_tracker.h', 'test/test_tab_contents_view.cc', diff --git a/content/test/js_injection_ready_observer.h b/content/test/js_injection_ready_observer.h new file mode 100644 index 0000000..8daf7d8 --- /dev/null +++ b/content/test/js_injection_ready_observer.h @@ -0,0 +1,23 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_JS_INJECTION_READY_OBSERVER_H_ +#define CONTENT_TEST_JS_INJECTION_READY_OBSERVER_H_ +#pragma once + +class RenderViewHost; + +// Interface to notify when JavaScript injection is possible. +class JsInjectionReadyObserver { + public: + // Called to indicate page entry committed and ready for JavaScript + // injection. |render_view_host| may be used to route injection messages to + // the appropriate RenderView. + virtual void OnJsInjectionReady(RenderViewHost* render_view_host) = 0; + + protected: + virtual ~JsInjectionReadyObserver() {} +}; + +#endif // CONTENT_TEST_JS_INJECTION_READY_OBSERVER_H_ diff --git a/content/test/test_navigation_observer.cc b/content/test/test_navigation_observer.cc new file mode 100644 index 0000000..aadff92 --- /dev/null +++ b/content/test/test_navigation_observer.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/test_navigation_observer.h" + +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" +#include "content/public/browser/render_view_host_observer.h" +#include "content/test/js_injection_ready_observer.h" +#include "testing/gtest/include/gtest/gtest.h" + +// This class observes |render_view_host| and calls OnJsInjectionReady() of +// |js_injection_ready_observer| when the time is right to inject JavaScript +// into the page. +class TestNavigationObserver::RVHOSendJS + : public content::RenderViewHostObserver { + public: + RVHOSendJS(RenderViewHost* render_view_host, + JsInjectionReadyObserver* js_injection_ready_observer) + : content::RenderViewHostObserver(render_view_host), + js_injection_ready_observer_(js_injection_ready_observer) { + } + + private: + // content::RenderViewHostObserver implementation. + virtual void RenderViewHostInitialized() OVERRIDE { + if (js_injection_ready_observer_) + js_injection_ready_observer_->OnJsInjectionReady(render_view_host()); + } + + JsInjectionReadyObserver* js_injection_ready_observer_; + + DISALLOW_COPY_AND_ASSIGN(RVHOSendJS); +}; + +TestNavigationObserver::TestNavigationObserver( + const content::NotificationSource& source, + JsInjectionReadyObserver* js_injection_ready_observer, + int number_of_navigations) + : navigation_started_(false), + navigations_completed_(0), + number_of_navigations_(number_of_navigations), + js_injection_ready_observer_(js_injection_ready_observer), + done_(false), + running_(false) { + // When javascript injection is requested, register for RenderViewHost + // creation. + if (js_injection_ready_observer_) { + registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED, + content::NotificationService::AllSources()); + } + RegisterAsObserver(source); +} + +TestNavigationObserver::~TestNavigationObserver() { +} + +void TestNavigationObserver::WaitForObservation( + const base::Closure& wait_loop_callback, + const base::Closure& done_callback) { + if (!done_) { + EXPECT_FALSE(running_); + running_ = true; + done_callback_ = done_callback; + wait_loop_callback.Run(); + } +} + +TestNavigationObserver::TestNavigationObserver( + JsInjectionReadyObserver* js_injection_ready_observer, + int number_of_navigations) + : navigation_started_(false), + navigations_completed_(0), + number_of_navigations_(number_of_navigations), + js_injection_ready_observer_(js_injection_ready_observer), + done_(false), + running_(false) { + // When javascript injection is requested, register for RenderViewHost + // creation. + if (js_injection_ready_observer_) { + registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED, + content::NotificationService::AllSources()); + } +} + +void TestNavigationObserver::RegisterAsObserver( + const content::NotificationSource& source) { + // Register for events to know when we've finished loading the page and are + // ready to quit the current message loop to return control back to the + // waiting test. + registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source); + registrar_.Add(this, content::NOTIFICATION_LOAD_START, source); + registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source); +} + +void TestNavigationObserver::Observe( + int type, const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case content::NOTIFICATION_NAV_ENTRY_COMMITTED: + case content::NOTIFICATION_LOAD_START: + navigation_started_ = true; + break; + case content::NOTIFICATION_LOAD_STOP: + if (navigation_started_ && + ++navigations_completed_ == number_of_navigations_) { + navigation_started_ = false; + done_ = true; + if (running_) + done_callback_.Run(); + } + break; + case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED: + rvho_send_js_.reset(new RVHOSendJS( + content::Source<RenderViewHost>(source).ptr(), + js_injection_ready_observer_)); + break; + default: + NOTREACHED(); + } +} diff --git a/content/test/test_navigation_observer.h b/content/test/test_navigation_observer.h new file mode 100644 index 0000000..5c1f550 --- /dev/null +++ b/content/test/test_navigation_observer.h @@ -0,0 +1,89 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_TEST_NAVIGATION_OBSERVER_H_ +#define CONTENT_TEST_TEST_NAVIGATION_OBSERVER_H_ +#pragma once + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +class JsInjectionReadyObserver; + +// For browser_tests, which run on the UI thread, run a second +// MessageLoop and quit when the navigation completes loading. For +// WebUI tests that need to inject javascript, construct with a +// JsInjectionReadyObserver and this class will call its +// OnJsInjectionReady() at the appropriate time. +class TestNavigationObserver : public content::NotificationObserver { + public: + class RVHOSendJS; + + // Create and register a new TestNavigationObserver against the + // |controller|. When |js_injection_ready_observer| is non-null, notify with + // OnEntryCommitted() after |number_of_navigations| navigations. + // Note: |js_injection_ready_observer| is owned by the caller and should be + // valid until this class is destroyed. + TestNavigationObserver(const content::NotificationSource& source, + JsInjectionReadyObserver* js_injection_ready_observer, + int number_of_navigations); + + virtual ~TestNavigationObserver(); + + // Run |wait_loop_callback| until complete, then run |done_callback|. + void WaitForObservation(const base::Closure& wait_loop_callback, + const base::Closure& done_callback); + + protected: + // Note: |js_injection_ready_observer| is owned by the caller and should be + // valid until this class is destroyed. Subclasses using this constructor MUST + // call RegisterAsObserver when a NavigationController becomes available. + explicit TestNavigationObserver( + JsInjectionReadyObserver* js_injection_ready_observer, + int number_of_navigations); + + // Register this TestNavigationObserver as an observer of the |source|. + void RegisterAsObserver(const content::NotificationSource& source); + + private: + // content::NotificationObserver: + virtual void Observe(int type, const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + content::NotificationRegistrar registrar_; + + // If true the navigation has started. + bool navigation_started_; + + // The number of navigations that have been completed. + int navigations_completed_; + + // The number of navigations to wait for. + int number_of_navigations_; + + // Observer to take some action when the page is ready for JavaScript + // injection. + JsInjectionReadyObserver* js_injection_ready_observer_; + + // |done_| will get set when this object observes a TabStripModel event. + bool done_; + + // |done_callback_| will be set while |running_| is true and will be called + // when navigation completes. + base::Closure done_callback_; + + // |running_| will be true during WaitForObservation until |done_| is true. + bool running_; + + // |rvho_send_js_| will hold a RenderViewHostObserver subclass to allow + // JavaScript injection at the appropriate time. + scoped_ptr<RVHOSendJS> rvho_send_js_; + + DISALLOW_COPY_AND_ASSIGN(TestNavigationObserver); +}; + +#endif // CONTENT_TEST_TEST_NAVIGATION_OBSERVER_H_ |