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 |