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
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/command_line.h"
7 #include "base/strings/stringprintf.h"
8 #include "content/browser/web_contents/web_contents_impl.h"
9 #include "content/public/browser/web_contents.h"
10 #include "content/public/common/content_switches.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/public/test/test_navigation_observer.h"
15 #include "content/shell/browser/shell.h"
16 #include "net/dns/mock_host_resolver.h"
17 #include "net/test/embedded_test_server/embedded_test_server.h"
18 #include "net/test/url_request/url_request_failed_job.h"
23 class BrowserSideNavigationBrowserTest
: public ContentBrowserTest
{
25 BrowserSideNavigationBrowserTest() {}
28 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
29 command_line
->AppendSwitch(switches::kEnableBrowserSideNavigation
);
32 void SetUpOnMainThread() override
{
33 host_resolver()->AddRule("*", "127.0.0.1");
34 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
38 // Ensure that browser initiated basic navigations work with browser side
40 IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest
,
41 BrowserInitiatedNavigations
) {
42 // Perform a navigation with no live renderer.
44 TestNavigationObserver
observer(shell()->web_contents());
45 GURL
url(embedded_test_server()->GetURL("/title1.html"));
46 NavigateToURL(shell(), url
);
47 EXPECT_EQ(url
, observer
.last_navigation_url());
48 EXPECT_TRUE(observer
.last_navigation_succeeded());
51 RenderFrameHost
* initial_rfh
=
52 static_cast<WebContentsImpl
*>(shell()->web_contents())
53 ->GetFrameTree()->root()->current_frame_host();
55 // Perform a same site navigation.
57 TestNavigationObserver
observer(shell()->web_contents());
58 GURL
url(embedded_test_server()->GetURL("/title2.html"));
59 NavigateToURL(shell(), url
);
60 EXPECT_EQ(url
, observer
.last_navigation_url());
61 EXPECT_TRUE(observer
.last_navigation_succeeded());
64 // The RenderFrameHost should not have changed.
65 EXPECT_EQ(initial_rfh
, static_cast<WebContentsImpl
*>(shell()->web_contents())
66 ->GetFrameTree()->root()->current_frame_host());
68 // Perform a cross-site navigation.
70 TestNavigationObserver
observer(shell()->web_contents());
71 GURL url
= embedded_test_server()->GetURL("foo.com", "/title3.html");
72 NavigateToURL(shell(), url
);
73 EXPECT_EQ(url
, observer
.last_navigation_url());
74 EXPECT_TRUE(observer
.last_navigation_succeeded());
77 // The RenderFrameHost should have changed.
78 EXPECT_NE(initial_rfh
, static_cast<WebContentsImpl
*>(shell()->web_contents())
79 ->GetFrameTree()->root()->current_frame_host());
82 // Ensure that renderer initiated same-site navigations work with browser side
84 IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest
,
85 RendererInitiatedSameSiteNavigation
) {
86 // Perform a navigation with no live renderer.
88 TestNavigationObserver
observer(shell()->web_contents());
89 GURL
url(embedded_test_server()->GetURL("/simple_links.html"));
90 NavigateToURL(shell(), url
);
91 EXPECT_EQ(url
, observer
.last_navigation_url());
92 EXPECT_TRUE(observer
.last_navigation_succeeded());
95 RenderFrameHost
* initial_rfh
=
96 static_cast<WebContentsImpl
*>(shell()->web_contents())
97 ->GetFrameTree()->root()->current_frame_host();
99 // Simulate clicking on a same-site link.
101 TestNavigationObserver
observer(shell()->web_contents());
102 GURL
url(embedded_test_server()->GetURL("/title2.html"));
103 bool success
= false;
104 EXPECT_TRUE(ExecuteScriptAndExtractBool(
105 shell()->web_contents(),
106 "window.domAutomationController.send(clickSameSiteLink());", &success
));
107 EXPECT_TRUE(success
);
108 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
109 EXPECT_EQ(url
, observer
.last_navigation_url());
110 EXPECT_TRUE(observer
.last_navigation_succeeded());
113 // The RenderFrameHost should not have changed.
114 EXPECT_EQ(initial_rfh
, static_cast<WebContentsImpl
*>(shell()->web_contents())
115 ->GetFrameTree()->root()->current_frame_host());
118 // Ensure that renderer initiated cross-site navigations work with browser side
120 IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest
,
121 RendererInitiatedCrossSiteNavigation
) {
122 // Perform a navigation with no live renderer.
124 TestNavigationObserver
observer(shell()->web_contents());
125 GURL
url(embedded_test_server()->GetURL("/simple_links.html"));
126 NavigateToURL(shell(), url
);
127 EXPECT_EQ(url
, observer
.last_navigation_url());
128 EXPECT_TRUE(observer
.last_navigation_succeeded());
131 RenderFrameHost
* initial_rfh
=
132 static_cast<WebContentsImpl
*>(shell()->web_contents())
133 ->GetFrameTree()->root()->current_frame_host();
135 // Simulate clicking on a cross-site link.
137 TestNavigationObserver
observer(shell()->web_contents());
138 const char kReplacePortNumber
[] =
139 "window.domAutomationController.send(setPortNumber(%d));";
140 uint16 port_number
= embedded_test_server()->port();
141 GURL url
= embedded_test_server()->GetURL("foo.com", "/title2.html");
142 bool success
= false;
143 EXPECT_TRUE(ExecuteScriptAndExtractBool(
144 shell()->web_contents(),
145 base::StringPrintf(kReplacePortNumber
, port_number
),
148 EXPECT_TRUE(ExecuteScriptAndExtractBool(
149 shell()->web_contents(),
150 "window.domAutomationController.send(clickCrossSiteLink());",
152 EXPECT_TRUE(success
);
153 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
154 EXPECT_EQ(url
, observer
.last_navigation_url());
155 EXPECT_TRUE(observer
.last_navigation_succeeded());
158 // The RenderFrameHost should not have changed.
159 EXPECT_EQ(initial_rfh
, static_cast<WebContentsImpl
*>(shell()->web_contents())
160 ->GetFrameTree()->root()->current_frame_host());
163 // Ensure that browser side navigation handles navigation failures.
164 IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest
, FailedNavigation
) {
165 // Perform a navigation with no live renderer.
167 TestNavigationObserver
observer(shell()->web_contents());
168 GURL
url(embedded_test_server()->GetURL("/title1.html"));
169 NavigateToURL(shell(), url
);
170 EXPECT_EQ(url
, observer
.last_navigation_url());
171 EXPECT_TRUE(observer
.last_navigation_succeeded());
174 // Now navigate to an unreachable url.
176 TestNavigationObserver
observer(shell()->web_contents());
178 net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_RESET
));
179 BrowserThread::PostTask(
180 BrowserThread::IO
, FROM_HERE
,
181 base::Bind(&net::URLRequestFailedJob::AddUrlHandler
));
182 NavigateToURL(shell(), error_url
);
183 EXPECT_EQ(error_url
, observer
.last_navigation_url());
184 NavigationEntry
* entry
=
185 shell()->web_contents()->GetController().GetLastCommittedEntry();
186 EXPECT_EQ(PAGE_TYPE_ERROR
, entry
->GetPageType());
190 } // namespace content