| Index: content/public/test/browser_test_utils.cc
|
| diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
|
| index 2c1907b24c52f5d5b83402dd3566ec84d2803aef..0ba575af209376d9c6dddba210948f30b0391a77 100644
|
| --- a/content/public/test/browser_test_utils.cc
|
| +++ b/content/public/test/browser_test_utils.cc
|
| @@ -44,6 +44,8 @@
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/histogram_fetcher.h"
|
| #include "content/public/browser/navigation_entry.h"
|
| +#include "content/public/browser/navigation_handle.h"
|
| +#include "content/public/browser/navigation_throttle.h"
|
| #include "content/public/browser/notification_service.h"
|
| #include "content/public/browser/notification_types.h"
|
| #include "content/public/browser/render_frame_host.h"
|
| @@ -350,6 +352,29 @@ CrossSiteRedirectResponseHandler(const GURL& server_base_url,
|
| return std::move(http_response);
|
| }
|
|
|
| +// Helper class used by the TestNavigationManager to pause navigations.
|
| +// Note: the throttle should be added to the *end* of the list of throttles,
|
| +// so all NavigationThrottles that should be attached observe the
|
| +// WillStartRequest callback. RegisterThrottleForTesting has this behavior.
|
| +class TestNavigationManagerThrottle : public NavigationThrottle {
|
| + public:
|
| + TestNavigationManagerThrottle(NavigationHandle* handle,
|
| + base::Closure on_will_start_request_closure)
|
| + : NavigationThrottle(handle),
|
| + on_will_start_request_closure_(on_will_start_request_closure) {}
|
| + ~TestNavigationManagerThrottle() override {}
|
| +
|
| + private:
|
| + // NavigationThrottle:
|
| + NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + on_will_start_request_closure_);
|
| + return NavigationThrottle::DEFER;
|
| + }
|
| +
|
| + base::Closure on_will_start_request_closure_;
|
| +};
|
| +
|
| } // namespace
|
|
|
| bool NavigateIframeToURL(WebContents* web_contents,
|
| @@ -1538,4 +1563,98 @@ void FrameFocusedObserver::Wait() {
|
| impl_->Run();
|
| }
|
|
|
| +TestNavigationManager::TestNavigationManager(WebContents* web_contents,
|
| + const GURL& url)
|
| + : WebContentsObserver(web_contents),
|
| + url_(url),
|
| + navigation_paused_(false),
|
| + handle_(nullptr),
|
| + handled_navigation_(false),
|
| + weak_factory_(this) {}
|
| +
|
| +TestNavigationManager::~TestNavigationManager() {
|
| + ResumeNavigation();
|
| +}
|
| +
|
| +bool TestNavigationManager::WaitForWillStartRequest() {
|
| + DCHECK(!did_finish_loop_runner_);
|
| + if (!handle_ && handled_navigation_)
|
| + return true;
|
| + if (navigation_paused_)
|
| + return true;
|
| + will_start_loop_runner_ = new MessageLoopRunner();
|
| + will_start_loop_runner_->Run();
|
| + will_start_loop_runner_ = nullptr;
|
| +
|
| + // This will only be false if DidFinishNavigation is called before
|
| + // OnWillStartRequest, which could occur if a throttle cancels the navigation
|
| + // before the TestNavigationManagerThrottle's method is called.
|
| + return !handled_navigation_;
|
| +}
|
| +
|
| +void TestNavigationManager::WaitForNavigationFinished() {
|
| + DCHECK(!will_start_loop_runner_);
|
| + if (!handle_ && handled_navigation_)
|
| + return;
|
| + // Ensure the navigation is resumed if the manager paused it previously.
|
| + if (navigation_paused_)
|
| + ResumeNavigation();
|
| + did_finish_loop_runner_ = new MessageLoopRunner();
|
| + did_finish_loop_runner_->Run();
|
| + did_finish_loop_runner_ = nullptr;
|
| +}
|
| +
|
| +void TestNavigationManager::DidStartNavigation(NavigationHandle* handle) {
|
| + if (!ShouldMonitorNavigation(handle))
|
| + return;
|
| +
|
| + handle_ = handle;
|
| + std::unique_ptr<NavigationThrottle> throttle(
|
| + new TestNavigationManagerThrottle(
|
| + handle_, base::Bind(&TestNavigationManager::OnWillStartRequest,
|
| + weak_factory_.GetWeakPtr())));
|
| + handle_->RegisterThrottleForTesting(std::move(throttle));
|
| +}
|
| +
|
| +void TestNavigationManager::DidFinishNavigation(NavigationHandle* handle) {
|
| + if (handle != handle_)
|
| + return;
|
| + handle_ = nullptr;
|
| + handled_navigation_ = true;
|
| + navigation_paused_ = false;
|
| +
|
| + // Resume any clients that are waiting for the end of the navigation. Note
|
| + // that |will_start_loop_runner_| can be running if the navigation was
|
| + // cancelled while it was deferred.
|
| + if (did_finish_loop_runner_)
|
| + did_finish_loop_runner_->Quit();
|
| + if (will_start_loop_runner_)
|
| + will_start_loop_runner_->Quit();
|
| +}
|
| +
|
| +void TestNavigationManager::OnWillStartRequest() {
|
| + navigation_paused_ = true;
|
| + if (will_start_loop_runner_)
|
| + will_start_loop_runner_->Quit();
|
| +
|
| + // If waiting for the navigation to finish, resume the navigation.
|
| + if (did_finish_loop_runner_)
|
| + ResumeNavigation();
|
| +}
|
| +
|
| +void TestNavigationManager::ResumeNavigation() {
|
| + if (!navigation_paused_ || !handle_)
|
| + return;
|
| + navigation_paused_ = false;
|
| + handle_->Resume();
|
| +}
|
| +
|
| +bool TestNavigationManager::ShouldMonitorNavigation(NavigationHandle* handle) {
|
| + if (handle_ || handle->GetURL() != url_)
|
| + return false;
|
| + if (handled_navigation_)
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| } // namespace content
|
|
|