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 { |
| 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 |