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 "content/browser/frame_host/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #include "content/public/test/browser_test_utils.h" | 43 #include "content/public/test/browser_test_utils.h" |
44 #include "content/public/test/content_browser_test.h" | 44 #include "content/public/test/content_browser_test.h" |
45 #include "content/public/test/content_browser_test_utils.h" | 45 #include "content/public/test/content_browser_test_utils.h" |
46 #include "content/public/test/test_navigation_observer.h" | 46 #include "content/public/test/test_navigation_observer.h" |
47 #include "content/public/test/test_utils.h" | 47 #include "content/public/test/test_utils.h" |
48 #include "content/shell/browser/shell.h" | 48 #include "content/shell/browser/shell.h" |
49 #include "content/shell/common/shell_switches.h" | 49 #include "content/shell/common/shell_switches.h" |
50 #include "content/test/content_browser_test_utils_internal.h" | 50 #include "content/test/content_browser_test_utils_internal.h" |
51 #include "net/dns/mock_host_resolver.h" | 51 #include "net/dns/mock_host_resolver.h" |
52 #include "net/test/embedded_test_server/embedded_test_server.h" | 52 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 53 #include "net/test/embedded_test_server/embedded_test_server_connection_listener
.h" |
53 #include "net/test/embedded_test_server/http_request.h" | 54 #include "net/test/embedded_test_server/http_request.h" |
54 #include "net/test/url_request/url_request_failed_job.h" | 55 #include "net/test/url_request/url_request_failed_job.h" |
55 #include "testing/gmock/include/gmock/gmock-matchers.h" | 56 #include "testing/gmock/include/gmock/gmock-matchers.h" |
56 | 57 |
57 namespace { | 58 namespace { |
58 | 59 |
59 static std::string kAddNamedFrameScript = | 60 static std::string kAddNamedFrameScript = |
60 "var f = document.createElement('iframe');" | 61 "var f = document.createElement('iframe');" |
61 "f.name = 'foo-frame-name';" | 62 "f.name = 'foo-frame-name';" |
62 "document.body.appendChild(f);"; | 63 "document.body.appendChild(f);"; |
63 static std::string kAddFrameScript = | 64 static std::string kAddFrameScript = |
64 "var f = document.createElement('iframe');" | 65 "var f = document.createElement('iframe');" |
65 "document.body.appendChild(f);"; | 66 "document.body.appendChild(f);"; |
66 static std::string kRemoveFrameScript = | 67 static std::string kRemoveFrameScript = |
67 "var f = document.querySelector('iframe');" | 68 "var f = document.querySelector('iframe');" |
68 "f.parentNode.removeChild(f);"; | 69 "f.parentNode.removeChild(f);"; |
69 | 70 |
70 } // namespace | 71 } // namespace |
71 | 72 |
72 namespace content { | 73 namespace content { |
73 | 74 |
| 75 // Gets notified by the EmbeddedTestServer on incoming requests. |
| 76 class ConnectionListener |
| 77 : public net::test_server::EmbeddedTestServerConnectionListener { |
| 78 public: |
| 79 |
| 80 ConnectionListener() |
| 81 : bytes_read(0) {} |
| 82 ~ConnectionListener() override {} |
| 83 |
| 84 // Get called from the EmbeddedTestServer thread to be notified that |
| 85 // a connection was accepted. |
| 86 void AcceptedSocket(const net::StreamSocket& connection) override {} |
| 87 |
| 88 // Get called from the EmbeddedTestServer thread to be notified that |
| 89 // a connection was read from. |
| 90 void ReadFromSocket(const net::StreamSocket& connection, int bytes) override { |
| 91 base::AutoLock lock(lock_); |
| 92 bytes_read += bytes; |
| 93 } |
| 94 |
| 95 int BytesRead() { |
| 96 base::AutoLock lock(lock_); |
| 97 return bytes_read; |
| 98 } |
| 99 |
| 100 void ResetBytesRead() { |
| 101 base::AutoLock lock(lock_); |
| 102 bytes_read = 0; |
| 103 } |
| 104 |
| 105 private: |
| 106 // This lock protects all the members below, which each are used on both the |
| 107 // IO and UI thread. Members declared after the lock are protected by it. |
| 108 mutable base::Lock lock_; |
| 109 int bytes_read; |
| 110 }; |
| 111 |
74 class NavigationControllerBrowserTest : public ContentBrowserTest { | 112 class NavigationControllerBrowserTest : public ContentBrowserTest { |
75 protected: | 113 protected: |
76 void SetUpOnMainThread() override { | 114 void SetUpOnMainThread() override { |
77 host_resolver()->AddRule("*", "127.0.0.1"); | 115 host_resolver()->AddRule("*", "127.0.0.1"); |
78 content::SetupCrossSiteRedirector(embedded_test_server()); | 116 content::SetupCrossSiteRedirector(embedded_test_server()); |
| 117 connection_listener.reset(new ConnectionListener()); |
| 118 embedded_test_server()->SetConnectionListener(connection_listener.get()); |
79 ASSERT_TRUE(embedded_test_server()->Start()); | 119 ASSERT_TRUE(embedded_test_server()->Start()); |
80 } | 120 } |
| 121 |
| 122 std::unique_ptr<ConnectionListener> connection_listener; |
81 }; | 123 }; |
82 | 124 |
83 // Ensure that tests can navigate subframes cross-site in both default mode and | 125 // Ensure that tests can navigate subframes cross-site in both default mode and |
84 // --site-per-process, but that they only go cross-process in the latter. | 126 // --site-per-process, but that they only go cross-process in the latter. |
85 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadCrossSiteSubframe) { | 127 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadCrossSiteSubframe) { |
86 // Load a main frame with a subframe. | 128 // Load a main frame with a subframe. |
87 GURL main_url(embedded_test_server()->GetURL( | 129 GURL main_url(embedded_test_server()->GetURL( |
88 "/navigation_controller/page_with_iframe.html")); | 130 "/navigation_controller/page_with_iframe.html")); |
89 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | 131 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
90 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | 132 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
(...skipping 6938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7029 // Do a browser-initiated fragment navigation. | 7071 // Do a browser-initiated fragment navigation. |
7030 NavigationHandleCommitObserver handle_observer(shell()->web_contents(), | 7072 NavigationHandleCommitObserver handle_observer(shell()->web_contents(), |
7031 kFragmentURL); | 7073 kFragmentURL); |
7032 EXPECT_TRUE(NavigateToURL(shell(), kFragmentURL)); | 7074 EXPECT_TRUE(NavigateToURL(shell(), kFragmentURL)); |
7033 | 7075 |
7034 EXPECT_TRUE(handle_observer.has_committed()); | 7076 EXPECT_TRUE(handle_observer.has_committed()); |
7035 EXPECT_TRUE(handle_observer.was_same_page()); | 7077 EXPECT_TRUE(handle_observer.was_same_page()); |
7036 EXPECT_FALSE(handle_observer.was_renderer_initiated()); | 7078 EXPECT_FALSE(handle_observer.was_renderer_initiated()); |
7037 } | 7079 } |
7038 | 7080 |
| 7081 // Ensure that browser-initiated same-document navigations are detected and |
| 7082 // don't issue network requests. |
| 7083 // see crbug.com/663777 |
| 7084 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 7085 SamePageBrowserInitiatedNoReload) { |
| 7086 GURL url(embedded_test_server()->GetURL("/title1.html")); |
| 7087 GURL url_fragment_1(embedded_test_server()->GetURL("/title1.html#id_1")); |
| 7088 GURL url_fragment_2(embedded_test_server()->GetURL("/title1.html#id_2")); |
| 7089 |
| 7090 // 1) Perform a new-document navigation. |
| 7091 connection_listener->ResetBytesRead(); |
| 7092 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 7093 EXPECT_TRUE(connection_listener->BytesRead() > 0); |
| 7094 |
| 7095 // 2) Perform a same-document navigation by adding a fragment. |
| 7096 connection_listener->ResetBytesRead(); |
| 7097 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_1)); |
| 7098 EXPECT_TRUE(connection_listener->BytesRead() == 0); |
| 7099 |
| 7100 // 3) Perform a same-document navigation by modifying the fragment. |
| 7101 connection_listener->ResetBytesRead(); |
| 7102 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); |
| 7103 EXPECT_TRUE(connection_listener->BytesRead() == 0); |
| 7104 |
| 7105 // 4) Redo the last navigation, but this time it should trigger a reload. |
| 7106 connection_listener->ResetBytesRead(); |
| 7107 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); |
| 7108 EXPECT_TRUE(connection_listener->BytesRead() > 0); |
| 7109 |
| 7110 // 5) Perform a new-document navigation by removing the fragment. |
| 7111 connection_listener->ResetBytesRead(); |
| 7112 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 7113 EXPECT_TRUE(connection_listener->BytesRead() > 0); |
| 7114 } |
| 7115 |
7039 } // namespace content | 7116 } // namespace content |
OLD | NEW |