Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "content/browser/frame_host/frame_navigation_entry.h" | 8 #include "content/browser/frame_host/frame_navigation_entry.h" |
| 9 #include "content/browser/frame_host/frame_tree.h" | 9 #include "content/browser/frame_host/frame_tree.h" |
| 10 #include "content/browser/frame_host/navigation_controller_impl.h" | 10 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 11 #include "content/browser/frame_host/navigation_entry_impl.h" | 11 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 12 #include "content/browser/web_contents/web_contents_impl.h" | 12 #include "content/browser/web_contents/web_contents_impl.h" |
| 13 #include "content/public/browser/render_view_host.h" | 13 #include "content/public/browser/render_view_host.h" |
| 14 #include "content/public/browser/resource_controller.h" | |
| 15 #include "content/public/browser/resource_dispatcher_host.h" | |
| 16 #include "content/public/browser/resource_dispatcher_host_delegate.h" | |
| 17 #include "content/public/browser/resource_throttle.h" | |
| 14 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
| 15 #include "content/public/browser/web_contents_observer.h" | 19 #include "content/public/browser/web_contents_observer.h" |
| 16 #include "content/public/common/bindings_policy.h" | 20 #include "content/public/common/bindings_policy.h" |
| 17 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
| 18 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
| 19 #include "content/public/test/browser_test_utils.h" | 23 #include "content/public/test/browser_test_utils.h" |
| 20 #include "content/public/test/content_browser_test.h" | 24 #include "content/public/test/content_browser_test.h" |
| 21 #include "content/public/test/content_browser_test_utils.h" | 25 #include "content/public/test/content_browser_test_utils.h" |
| 22 #include "content/public/test/test_navigation_observer.h" | 26 #include "content/public/test/test_navigation_observer.h" |
| 23 #include "content/public/test/test_utils.h" | 27 #include "content/public/test/test_utils.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 namespace { | 246 namespace { |
| 243 | 247 |
| 244 class FrameNavigateParamsCapturer : public WebContentsObserver { | 248 class FrameNavigateParamsCapturer : public WebContentsObserver { |
| 245 public: | 249 public: |
| 246 // Observes navigation for the specified |node|. | 250 // Observes navigation for the specified |node|. |
| 247 explicit FrameNavigateParamsCapturer(FrameTreeNode* node) | 251 explicit FrameNavigateParamsCapturer(FrameTreeNode* node) |
| 248 : WebContentsObserver( | 252 : WebContentsObserver( |
| 249 node->current_frame_host()->delegate()->GetAsWebContents()), | 253 node->current_frame_host()->delegate()->GetAsWebContents()), |
| 250 frame_tree_node_id_(node->frame_tree_node_id()), | 254 frame_tree_node_id_(node->frame_tree_node_id()), |
| 251 navigations_remaining_(1), | 255 navigations_remaining_(1), |
| 256 wait_for_load_(true), | |
| 252 message_loop_runner_(new MessageLoopRunner) {} | 257 message_loop_runner_(new MessageLoopRunner) {} |
| 253 | 258 |
| 254 void set_navigations_remaining(int count) { | 259 void set_navigations_remaining(int count) { |
| 255 navigations_remaining_ = count; | 260 navigations_remaining_ = count; |
| 256 } | 261 } |
| 257 | 262 |
| 263 void set_wait_for_load(bool ignore) { | |
| 264 wait_for_load_ = ignore; | |
| 265 } | |
| 266 | |
| 258 void Wait() { | 267 void Wait() { |
| 259 message_loop_runner_->Run(); | 268 message_loop_runner_->Run(); |
| 260 } | 269 } |
| 261 | 270 |
| 262 const FrameNavigateParams& params() const { | 271 const FrameNavigateParams& params() const { |
| 263 EXPECT_EQ(1U, params_.size()); | 272 EXPECT_EQ(1U, params_.size()); |
| 264 return params_[0]; | 273 return params_[0]; |
| 265 } | 274 } |
| 266 | 275 |
| 267 const std::vector<FrameNavigateParams>& all_params() const { | 276 const std::vector<FrameNavigateParams>& all_params() const { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 282 const LoadCommittedDetails& details, | 291 const LoadCommittedDetails& details, |
| 283 const FrameNavigateParams& params) override { | 292 const FrameNavigateParams& params) override { |
| 284 RenderFrameHostImpl* rfh = | 293 RenderFrameHostImpl* rfh = |
| 285 static_cast<RenderFrameHostImpl*>(render_frame_host); | 294 static_cast<RenderFrameHostImpl*>(render_frame_host); |
| 286 if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_) | 295 if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_) |
| 287 return; | 296 return; |
| 288 | 297 |
| 289 --navigations_remaining_; | 298 --navigations_remaining_; |
| 290 params_.push_back(params); | 299 params_.push_back(params); |
| 291 details_.push_back(details); | 300 details_.push_back(details); |
| 292 if (!web_contents()->IsLoading() && !navigations_remaining_) | 301 if (!navigations_remaining_ && |
| 302 (!web_contents()->IsLoading() || !wait_for_load_)) | |
| 293 message_loop_runner_->Quit(); | 303 message_loop_runner_->Quit(); |
| 294 } | 304 } |
| 295 | 305 |
| 296 void DidStopLoading() override { | 306 void DidStopLoading() override { |
| 297 if (!navigations_remaining_) | 307 if (!navigations_remaining_) |
| 298 message_loop_runner_->Quit(); | 308 message_loop_runner_->Quit(); |
| 299 } | 309 } |
| 300 | 310 |
| 301 // The id of the FrameTreeNode whose navigations to observe. | 311 // The id of the FrameTreeNode whose navigations to observe. |
| 302 int frame_tree_node_id_; | 312 int frame_tree_node_id_; |
| 303 | 313 |
| 304 // How many navigations remain to capture. | 314 // How many navigations remain to capture. |
| 305 int navigations_remaining_; | 315 int navigations_remaining_; |
| 306 | 316 |
| 317 // Whether to also wait for the load to complete. | |
| 318 bool wait_for_load_; | |
| 319 | |
| 307 // The params of the navigations. | 320 // The params of the navigations. |
| 308 std::vector<FrameNavigateParams> params_; | 321 std::vector<FrameNavigateParams> params_; |
| 309 | 322 |
| 310 // The details of the navigations. | 323 // The details of the navigations. |
| 311 std::vector<LoadCommittedDetails> details_; | 324 std::vector<LoadCommittedDetails> details_; |
| 312 | 325 |
| 313 // The MessageLoopRunner used to spin the message loop. | 326 // The MessageLoopRunner used to spin the message loop. |
| 314 scoped_refptr<MessageLoopRunner> message_loop_runner_; | 327 scoped_refptr<MessageLoopRunner> message_loop_runner_; |
| 315 }; | 328 }; |
| 316 | 329 |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 928 ASSERT_EQ(2U, params.size()); | 941 ASSERT_EQ(2U, params.size()); |
| 929 ASSERT_EQ(2U, details.size()); | 942 ASSERT_EQ(2U, details.size()); |
| 930 EXPECT_EQ(ui::PAGE_TRANSITION_LINK, params[0].transition); | 943 EXPECT_EQ(ui::PAGE_TRANSITION_LINK, params[0].transition); |
| 931 EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, details[0].type); | 944 EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, details[0].type); |
| 932 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, | 945 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, |
| 933 params[1].transition); | 946 params[1].transition); |
| 934 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, details[1].type); | 947 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, details[1].type); |
| 935 } | 948 } |
| 936 } | 949 } |
| 937 | 950 |
| 938 | |
| 939 // Verify the tree of FrameNavigationEntries after NAVIGATION_TYPE_AUTO_SUBFRAME | 951 // Verify the tree of FrameNavigationEntries after NAVIGATION_TYPE_AUTO_SUBFRAME |
| 940 // commits. | 952 // commits. |
| 941 // TODO(creis): Test cross-site and nested iframes. | 953 // TODO(creis): Test cross-site and nested iframes. |
| 942 // TODO(creis): Test updating entries for history auto subframe navigations. | 954 // TODO(creis): Test updating entries for history auto subframe navigations. |
| 943 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 955 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 944 FrameNavigationEntry_AutoSubframe) { | 956 FrameNavigationEntry_AutoSubframe) { |
| 945 GURL main_url(embedded_test_server()->GetURL( | 957 GURL main_url(embedded_test_server()->GetURL( |
| 946 "/navigation_controller/simple_page_1.html")); | 958 "/navigation_controller/simple_page_1.html")); |
| 947 NavigateToURL(shell(), main_url); | 959 NavigateToURL(shell(), main_url); |
| 948 const NavigationControllerImpl& controller = | 960 const NavigationControllerImpl& controller = |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 979 ASSERT_EQ(1U, entry->root_node()->children.size()); | 991 ASSERT_EQ(1U, entry->root_node()->children.size()); |
| 980 FrameNavigationEntry* frame_entry = | 992 FrameNavigationEntry* frame_entry = |
| 981 entry->root_node()->children[0]->frame_entry.get(); | 993 entry->root_node()->children[0]->frame_entry.get(); |
| 982 EXPECT_EQ(frame_url, frame_entry->url()); | 994 EXPECT_EQ(frame_url, frame_entry->url()); |
| 983 } else { | 995 } else { |
| 984 // There are no subframe FrameNavigationEntries by default. | 996 // There are no subframe FrameNavigationEntries by default. |
| 985 EXPECT_EQ(0U, entry->root_node()->children.size()); | 997 EXPECT_EQ(0U, entry->root_node()->children.size()); |
| 986 } | 998 } |
| 987 } | 999 } |
| 988 | 1000 |
| 1001 namespace { | |
| 1002 | |
| 1003 class HttpThrottle : public ResourceThrottle { | |
| 1004 public: | |
| 1005 // ResourceThrottle | |
| 1006 void WillStartRequest(bool* defer) override { | |
| 1007 *defer = true; | |
| 1008 } | |
| 1009 | |
| 1010 const char* GetNameForLogging() const override { | |
| 1011 return "HttpThrottle"; | |
| 1012 } | |
| 1013 }; | |
| 1014 | |
| 1015 class StallDelegate : public ResourceDispatcherHostDelegate { | |
|
Charlie Reis
2015/04/15 17:43:08
FYI for Nasko, since he was writing a more general
| |
| 1016 // ResourceDispatcherHostDelegate | |
| 1017 void RequestBeginning( | |
| 1018 net::URLRequest* request, | |
| 1019 content::ResourceContext* resource_context, | |
| 1020 content::AppCacheService* appcache_service, | |
| 1021 ResourceType resource_type, | |
| 1022 ScopedVector<content::ResourceThrottle>* throttles) override { | |
| 1023 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 1024 throttles->push_back(new HttpThrottle); | |
| 1025 } | |
| 1026 }; | |
| 1027 | |
| 1028 } // namespace | |
| 1029 | |
| 1030 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | |
| 1031 NavigationTypeClassification_InPageWhilePending) { | |
| 1032 NavigationControllerImpl& controller = | |
| 1033 static_cast<NavigationControllerImpl&>( | |
| 1034 shell()->web_contents()->GetController()); | |
| 1035 | |
| 1036 FrameTreeNode* root = | |
| 1037 static_cast<WebContentsImpl*>(shell()->web_contents())-> | |
| 1038 GetFrameTree()->root(); | |
| 1039 | |
| 1040 // Start with a normal page. | |
| 1041 GURL url1(embedded_test_server()->GetURL( | |
| 1042 "/navigation_controller/simple_page_1.html")); | |
| 1043 EXPECT_TRUE(NavigateToURL(shell(), url1)); | |
| 1044 | |
| 1045 // Have the user decide to go to a different page which is very slow. | |
| 1046 StallDelegate stall_delegate; | |
| 1047 ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate); | |
| 1048 GURL url2(embedded_test_server()->GetURL( | |
| 1049 "/navigation_controller/simple_page_2.html")); | |
| 1050 controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | |
| 1051 | |
| 1052 // That should be the pending entry. | |
| 1053 NavigationEntryImpl* entry = controller.GetPendingEntry(); | |
| 1054 ASSERT_NE(nullptr, entry); | |
| 1055 EXPECT_EQ(url2, entry->GetURL()); | |
| 1056 | |
| 1057 { | |
| 1058 // Now the existing page uses history.replaceState(). | |
| 1059 FrameNavigateParamsCapturer capturer(root); | |
| 1060 capturer.set_wait_for_load(false); | |
| 1061 EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), | |
| 1062 "history.replaceState({}, '', 'x')")); | |
| 1063 capturer.Wait(); | |
| 1064 | |
| 1065 // The fact that there was a pending entry shouldn't interfere with the | |
| 1066 // classification. | |
| 1067 EXPECT_EQ(NAVIGATION_TYPE_IN_PAGE, capturer.details().type); | |
| 1068 } | |
| 1069 | |
| 1070 ResourceDispatcherHost::Get()->SetDelegate(nullptr); | |
| 1071 } | |
| 1072 | |
| 989 } // namespace content | 1073 } // namespace content |
| OLD | NEW |