Chromium Code Reviews| Index: content/browser/frame_host/navigation_controller_impl_browsertest.cc |
| diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
| index aad2ac3c8a1806280a52513e2cb504e8a066b956..7a89b26c1d1e5a179453f9ccdeabc4965d0ca207 100644 |
| --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
| +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
| @@ -11,6 +11,10 @@ |
| #include "content/browser/frame_host/navigation_entry_impl.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/resource_controller.h" |
| +#include "content/public/browser/resource_dispatcher_host.h" |
| +#include "content/public/browser/resource_dispatcher_host_delegate.h" |
| +#include "content/public/browser/resource_throttle.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "content/public/common/bindings_policy.h" |
| @@ -249,12 +253,17 @@ class FrameNavigateParamsCapturer : public WebContentsObserver { |
| node->current_frame_host()->delegate()->GetAsWebContents()), |
| frame_tree_node_id_(node->frame_tree_node_id()), |
| navigations_remaining_(1), |
| + wait_for_load_(true), |
| message_loop_runner_(new MessageLoopRunner) {} |
| void set_navigations_remaining(int count) { |
| navigations_remaining_ = count; |
| } |
| + void set_wait_for_load(bool ignore) { |
| + wait_for_load_ = ignore; |
| + } |
| + |
| void Wait() { |
| message_loop_runner_->Run(); |
| } |
| @@ -289,7 +298,8 @@ class FrameNavigateParamsCapturer : public WebContentsObserver { |
| --navigations_remaining_; |
| params_.push_back(params); |
| details_.push_back(details); |
| - if (!web_contents()->IsLoading() && !navigations_remaining_) |
| + if (!navigations_remaining_ && |
| + (!web_contents()->IsLoading() || !wait_for_load_)) |
| message_loop_runner_->Quit(); |
| } |
| @@ -304,6 +314,9 @@ class FrameNavigateParamsCapturer : public WebContentsObserver { |
| // How many navigations remain to capture. |
| int navigations_remaining_; |
| + // Whether to also wait for the load to complete. |
| + bool wait_for_load_; |
| + |
| // The params of the navigations. |
| std::vector<FrameNavigateParams> params_; |
| @@ -935,7 +948,6 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| } |
| } |
| - |
| // Verify the tree of FrameNavigationEntries after NAVIGATION_TYPE_AUTO_SUBFRAME |
| // commits. |
| // TODO(creis): Test cross-site and nested iframes. |
| @@ -986,4 +998,76 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| } |
| } |
| +namespace { |
| + |
| +class HttpThrottle : public ResourceThrottle { |
| + public: |
| + // ResourceThrottle |
| + void WillStartRequest(bool* defer) override { |
| + *defer = true; |
| + } |
| + |
| + const char* GetNameForLogging() const override { |
| + return "HttpThrottle"; |
| + } |
| +}; |
| + |
| +class StallDelegate : public ResourceDispatcherHostDelegate { |
|
Charlie Reis
2015/04/15 17:43:08
FYI for Nasko, since he was writing a more general
|
| + // ResourceDispatcherHostDelegate |
| + void RequestBeginning( |
| + net::URLRequest* request, |
| + content::ResourceContext* resource_context, |
| + content::AppCacheService* appcache_service, |
| + ResourceType resource_type, |
| + ScopedVector<content::ResourceThrottle>* throttles) override { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| + throttles->push_back(new HttpThrottle); |
| + } |
| +}; |
| + |
| +} // namespace |
| + |
| +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| + NavigationTypeClassification_InPageWhilePending) { |
| + NavigationControllerImpl& controller = |
| + static_cast<NavigationControllerImpl&>( |
| + shell()->web_contents()->GetController()); |
| + |
| + FrameTreeNode* root = |
| + static_cast<WebContentsImpl*>(shell()->web_contents())-> |
| + GetFrameTree()->root(); |
| + |
| + // Start with a normal page. |
| + GURL url1(embedded_test_server()->GetURL( |
| + "/navigation_controller/simple_page_1.html")); |
| + EXPECT_TRUE(NavigateToURL(shell(), url1)); |
| + |
| + // Have the user decide to go to a different page which is very slow. |
| + StallDelegate stall_delegate; |
| + ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate); |
| + GURL url2(embedded_test_server()->GetURL( |
| + "/navigation_controller/simple_page_2.html")); |
| + controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| + |
| + // That should be the pending entry. |
| + NavigationEntryImpl* entry = controller.GetPendingEntry(); |
| + ASSERT_NE(nullptr, entry); |
| + EXPECT_EQ(url2, entry->GetURL()); |
| + |
| + { |
| + // Now the existing page uses history.replaceState(). |
| + FrameNavigateParamsCapturer capturer(root); |
| + capturer.set_wait_for_load(false); |
| + EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), |
| + "history.replaceState({}, '', 'x')")); |
| + capturer.Wait(); |
| + |
| + // The fact that there was a pending entry shouldn't interfere with the |
| + // classification. |
| + EXPECT_EQ(NAVIGATION_TYPE_IN_PAGE, capturer.details().type); |
| + } |
| + |
| + ResourceDispatcherHost::Get()->SetDelegate(nullptr); |
| +} |
| + |
| } // namespace content |