1 // Copyright (c) 2012 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.
6 #include "base/strings/string_number_conversions.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/tab_contents/render_view_context_menu.h"
11 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/browser/navigation_controller.h"
18 #include "content/public/browser/navigation_entry.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "net/test/spawned_test_server/spawned_test_server.h"
24 #include "third_party/WebKit/public/web/WebInputEvent.h"
26 // GTK requires a X11-level mouse event to open a context menu correctly.
27 #if defined(TOOLKIT_GTK)
28 #define MAYBE_ContextMenuOrigin DISABLED_ContextMenuOrigin
29 #define MAYBE_HttpsContextMenuOrigin DISABLED_HttpsContextMenuOrigin
30 #define MAYBE_ContextMenuRedirect DISABLED_ContextMenuRedirect
31 #define MAYBE_HttpsContextMenuRedirect DISABLED_HttpsContextMenuRedirect
33 #define MAYBE_ContextMenuOrigin ContextMenuOrigin
34 #define MAYBE_HttpsContextMenuOrigin HttpsContextMenuOrigin
35 #define MAYBE_ContextMenuRedirect ContextMenuRedirect
36 #define MAYBE_HttpsContextMenuRedirect HttpsContextMenuRedirect
41 const base::FilePath::CharType kDocRoot
[] =
42 FILE_PATH_LITERAL("chrome/test/data/referrer_policy");
46 class ReferrerPolicyTest
: public InProcessBrowserTest
{
48 ReferrerPolicyTest() {}
49 virtual ~ReferrerPolicyTest() {}
51 virtual void SetUp() OVERRIDE
{
52 test_server_
.reset(new net::SpawnedTestServer(
53 net::SpawnedTestServer::TYPE_HTTP
,
54 net::SpawnedTestServer::kLocalhost
,
55 base::FilePath(kDocRoot
)));
56 ASSERT_TRUE(test_server_
->Start());
57 ssl_test_server_
.reset(new net::SpawnedTestServer(
58 net::SpawnedTestServer::TYPE_HTTPS
,
59 net::SpawnedTestServer::kLocalhost
,
60 base::FilePath(kDocRoot
)));
61 ASSERT_TRUE(ssl_test_server_
->Start());
63 InProcessBrowserTest::SetUp();
67 enum ExpectedReferrer
{
68 EXPECT_EMPTY_REFERRER
,
70 EXPECT_ORIGIN_AS_REFERRER
73 // Returns the expected title for the tab with the given (full) referrer and
74 // the expected modification of it.
75 base::string16
GetExpectedTitle(const GURL
& url
,
76 ExpectedReferrer expected_referrer
) {
78 switch (expected_referrer
) {
79 case EXPECT_EMPTY_REFERRER
:
80 referrer
= "Referrer is empty";
82 case EXPECT_FULL_REFERRER
:
83 referrer
= "Referrer is " + url
.spec();
85 case EXPECT_ORIGIN_AS_REFERRER
:
86 referrer
= "Referrer is " + url
.GetWithEmptyPath().spec();
89 return base::ASCIIToUTF16(referrer
);
92 // Adds all possible titles to the TitleWatcher, so we don't time out
93 // waiting for the title if the test fails.
94 void AddAllPossibleTitles(const GURL
& url
,
95 content::TitleWatcher
* title_watcher
) {
96 title_watcher
->AlsoWaitForTitle(
97 GetExpectedTitle(url
, EXPECT_EMPTY_REFERRER
));
98 title_watcher
->AlsoWaitForTitle(
99 GetExpectedTitle(url
, EXPECT_FULL_REFERRER
));
100 title_watcher
->AlsoWaitForTitle(
101 GetExpectedTitle(url
, EXPECT_ORIGIN_AS_REFERRER
));
104 // Returns a string representation of a given |referrer_policy|.
105 std::string
ReferrerPolicyToString(blink::WebReferrerPolicy referrer_policy
) {
106 switch (referrer_policy
) {
107 case blink::WebReferrerPolicyDefault
:
109 case blink::WebReferrerPolicyOrigin
:
111 case blink::WebReferrerPolicyAlways
:
113 case blink::WebReferrerPolicyNever
:
121 // Navigates from a page with a given |referrer_policy| and checks that the
122 // reported referrer matches the expectation.
124 // referrer_policy: The referrer policy to test.
125 // start_on_https: True if the test should start on an HTTPS page.
126 // target_blank: True if the link that is generated should have the
127 // attribute target=_blank
128 // redirect: True if the link target should first do a server
129 // redirect before evaluating the passed referrer.
130 // opens_new_tab: True if this test opens a new tab.
131 // button: If not WebMouseEvent::ButtonNone, click on the
132 // link with the specified mouse button.
133 // expected_referrer: The kind of referrer to expect.
136 // The URL of the first page navigated to.
137 GURL
RunReferrerTest(const blink::WebReferrerPolicy referrer_policy
,
142 blink::WebMouseEvent::Button button
,
143 ExpectedReferrer expected_referrer
) {
145 net::SpawnedTestServer
* start_server
=
146 start_on_https
? ssl_test_server_
.get() : test_server_
.get();
147 start_url
= start_server
->GetURL(
148 std::string("files/referrer-policy-start.html?") +
149 "policy=" + ReferrerPolicyToString(referrer_policy
) +
150 "&port=" + base::IntToString(test_server_
->host_port_pair().port()) +
152 base::IntToString(ssl_test_server_
->host_port_pair().port()) +
153 "&redirect=" + (redirect
? "true" : "false") +
155 (button
== blink::WebMouseEvent::ButtonNone
? "false" : "true") +
156 "&target=" + (target_blank
? "_blank" : ""));
158 ui_test_utils::WindowedTabAddedNotificationObserver
tab_added_observer(
159 content::NotificationService::AllSources());
161 base::string16 expected_title
=
162 GetExpectedTitle(start_url
, expected_referrer
);
163 content::WebContents
* tab
=
164 browser()->tab_strip_model()->GetActiveWebContents();
165 content::TitleWatcher
title_watcher(tab
, expected_title
);
167 // Watch for all possible outcomes to avoid timeouts if something breaks.
168 AddAllPossibleTitles(start_url
, &title_watcher
);
170 ui_test_utils::NavigateToURL(browser(), start_url
);
172 if (button
!= blink::WebMouseEvent::ButtonNone
) {
173 blink::WebMouseEvent mouse_event
;
174 mouse_event
.type
= blink::WebInputEvent::MouseDown
;
175 mouse_event
.button
= button
;
178 mouse_event
.clickCount
= 1;
179 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
180 mouse_event
.type
= blink::WebInputEvent::MouseUp
;
181 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
185 tab_added_observer
.Wait();
186 tab
= tab_added_observer
.GetTab();
188 content::WaitForLoadStop(tab
);
189 EXPECT_EQ(expected_title
, tab
->GetTitle());
191 EXPECT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
194 EXPECT_EQ(referrer_policy
,
195 tab
->GetController().GetActiveEntry()->GetReferrer().policy
);
200 scoped_ptr
<net::SpawnedTestServer
> test_server_
;
201 scoped_ptr
<net::SpawnedTestServer
> ssl_test_server_
;
204 // The basic behavior of referrer policies is covered by layout tests in
205 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
206 // code paths chrome uses to navigate. To keep the number of combinations down,
207 // we only test the "origin" policy here.
209 // Some tests are marked as FAILS, see http://crbug.com/124750
211 // Content initiated navigation, from HTTP to HTTP.
212 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, Origin
) {
213 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, false, false,
214 blink::WebMouseEvent::ButtonNone
,
215 EXPECT_ORIGIN_AS_REFERRER
);
218 // Content initiated navigation, from HTTPS to HTTP.
219 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsDefault
) {
220 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, false, false,
221 blink::WebMouseEvent::ButtonNone
,
222 EXPECT_ORIGIN_AS_REFERRER
);
225 // User initiated navigation, from HTTP to HTTP.
226 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, LeftClickOrigin
) {
227 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, false, false,
228 blink::WebMouseEvent::ButtonLeft
,
229 EXPECT_ORIGIN_AS_REFERRER
);
232 // User initiated navigation, from HTTPS to HTTP.
233 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsLeftClickOrigin
) {
234 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, false, false,
235 blink::WebMouseEvent::ButtonLeft
,
236 EXPECT_ORIGIN_AS_REFERRER
);
239 // User initiated navigation, middle click, from HTTP to HTTP.
240 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickOrigin
) {
241 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, false, true,
242 blink::WebMouseEvent::ButtonMiddle
,
243 EXPECT_ORIGIN_AS_REFERRER
);
246 // User initiated navigation, middle click, from HTTPS to HTTP.
247 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickOrigin
) {
248 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, false, true,
249 blink::WebMouseEvent::ButtonMiddle
,
250 EXPECT_ORIGIN_AS_REFERRER
);
253 // User initiated navigation, target blank, from HTTP to HTTP.
254 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, TargetBlankOrigin
) {
255 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, true, false, true,
256 blink::WebMouseEvent::ButtonLeft
,
257 EXPECT_ORIGIN_AS_REFERRER
);
260 // User initiated navigation, target blank, from HTTPS to HTTP.
261 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsTargetBlankOrigin
) {
262 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, true, false, true,
263 blink::WebMouseEvent::ButtonLeft
,
264 EXPECT_ORIGIN_AS_REFERRER
);
267 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
268 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickTargetBlankOrigin
) {
269 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, true, false, true,
270 blink::WebMouseEvent::ButtonMiddle
,
271 EXPECT_ORIGIN_AS_REFERRER
);
274 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
275 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickTargetBlankOrigin
) {
276 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, true, false, true,
277 blink::WebMouseEvent::ButtonMiddle
,
278 EXPECT_ORIGIN_AS_REFERRER
);
281 // Context menu, from HTTP to HTTP.
282 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MAYBE_ContextMenuOrigin
) {
283 ContextMenuNotificationObserver
context_menu_observer(
284 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
285 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, false, true,
286 blink::WebMouseEvent::ButtonRight
,
287 EXPECT_ORIGIN_AS_REFERRER
);
290 // Context menu, from HTTPS to HTTP.
291 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MAYBE_HttpsContextMenuOrigin
) {
292 ContextMenuNotificationObserver
context_menu_observer(
293 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
294 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, false, true,
295 blink::WebMouseEvent::ButtonRight
,
296 EXPECT_ORIGIN_AS_REFERRER
);
299 // Content initiated navigation, from HTTP to HTTP via server redirect.
300 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, Redirect
) {
301 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, true, false,
302 blink::WebMouseEvent::ButtonNone
,
303 EXPECT_ORIGIN_AS_REFERRER
);
306 // Content initiated navigation, from HTTPS to HTTP via server redirect.
307 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsRedirect
) {
308 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, true, false,
309 blink::WebMouseEvent::ButtonNone
,
310 EXPECT_ORIGIN_AS_REFERRER
);
313 // User initiated navigation, from HTTP to HTTP via server redirect.
314 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, LeftClickRedirect
) {
315 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, true, false,
316 blink::WebMouseEvent::ButtonLeft
,
317 EXPECT_ORIGIN_AS_REFERRER
);
320 // User initiated navigation, from HTTPS to HTTP via server redirect.
321 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsLeftClickRedirect
) {
322 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, true, false,
323 blink::WebMouseEvent::ButtonLeft
,
324 EXPECT_ORIGIN_AS_REFERRER
);
327 // User initiated navigation, middle click, from HTTP to HTTP via server
329 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickRedirect
) {
330 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, true, true,
331 blink::WebMouseEvent::ButtonMiddle
,
332 EXPECT_ORIGIN_AS_REFERRER
);
335 // User initiated navigation, middle click, from HTTPS to HTTP via server
337 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsMiddleClickRedirect
) {
338 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, true, true,
339 blink::WebMouseEvent::ButtonMiddle
,
340 EXPECT_ORIGIN_AS_REFERRER
);
343 // User initiated navigation, target blank, from HTTP to HTTP via server
345 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, TargetBlankRedirect
) {
346 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, true, true, true,
347 blink::WebMouseEvent::ButtonLeft
,
348 EXPECT_ORIGIN_AS_REFERRER
);
351 // User initiated navigation, target blank, from HTTPS to HTTP via server
353 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, HttpsTargetBlankRedirect
) {
354 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, true, true, true,
355 blink::WebMouseEvent::ButtonLeft
,
356 EXPECT_ORIGIN_AS_REFERRER
);
359 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
361 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MiddleClickTargetBlankRedirect
) {
362 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, true, true, true,
363 blink::WebMouseEvent::ButtonMiddle
,
364 EXPECT_ORIGIN_AS_REFERRER
);
367 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
368 // via server redirect.
369 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
,
370 HttpsMiddleClickTargetBlankRedirect
) {
371 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, true, true, true,
372 blink::WebMouseEvent::ButtonMiddle
,
373 EXPECT_ORIGIN_AS_REFERRER
);
376 // Context menu, from HTTP to HTTP via server redirect.
377 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MAYBE_ContextMenuRedirect
) {
378 ContextMenuNotificationObserver
context_menu_observer(
379 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
380 RunReferrerTest(blink::WebReferrerPolicyOrigin
, false, false, true, true,
381 blink::WebMouseEvent::ButtonRight
,
382 EXPECT_ORIGIN_AS_REFERRER
);
385 // Context menu, from HTTPS to HTTP via server redirect.
386 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, MAYBE_HttpsContextMenuRedirect
) {
387 ContextMenuNotificationObserver
context_menu_observer(
388 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
389 RunReferrerTest(blink::WebReferrerPolicyOrigin
, true, false, true, true,
390 blink::WebMouseEvent::ButtonRight
,
391 EXPECT_ORIGIN_AS_REFERRER
);
394 // Tests history navigation actions: Navigate from A to B with a referrer
395 // policy, then navigate to C, back to B, and reload.
396 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest
, History
) {
397 // Navigate from A to B.
398 GURL start_url
= RunReferrerTest(blink::WebReferrerPolicyOrigin
,
403 blink::WebMouseEvent::ButtonLeft
,
404 EXPECT_ORIGIN_AS_REFERRER
);
407 ui_test_utils::NavigateToURL(browser(), test_server_
->GetURL(std::string()));
409 base::string16 expected_title
=
410 GetExpectedTitle(start_url
, EXPECT_ORIGIN_AS_REFERRER
);
411 content::WebContents
* tab
=
412 browser()->tab_strip_model()->GetActiveWebContents();
413 scoped_ptr
<content::TitleWatcher
> title_watcher(
414 new content::TitleWatcher(tab
, expected_title
));
416 // Watch for all possible outcomes to avoid timeouts if something breaks.
417 AddAllPossibleTitles(start_url
, title_watcher
.get());
420 chrome::GoBack(browser(), CURRENT_TAB
);
421 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
423 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
424 AddAllPossibleTitles(start_url
, title_watcher
.get());
427 chrome::Reload(browser(), CURRENT_TAB
);
428 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());
430 title_watcher
.reset(new content::TitleWatcher(tab
, expected_title
));
431 AddAllPossibleTitles(start_url
, title_watcher
.get());
433 // Shift-reload to B.
434 chrome::ReloadIgnoringCache(browser(), CURRENT_TAB
);
435 EXPECT_EQ(expected_title
, title_watcher
->WaitAndGetTitle());