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.
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/app/chrome_command_ids.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
13 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
14 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "third_party/WebKit/public/web/WebContextMenuData.h"
26 #include "third_party/WebKit/public/web/WebInputEvent.h"
28 using content::WebContents
;
32 class ContextMenuBrowserTest
: public InProcessBrowserTest
{
34 ContextMenuBrowserTest() { }
36 TestRenderViewContextMenu
* CreateContextMenu(GURL unfiltered_url
, GURL url
) {
37 content::ContextMenuParams params
;
38 params
.media_type
= blink::WebContextMenuData::MediaTypeNone
;
39 params
.unfiltered_link_url
= unfiltered_url
;
40 params
.link_url
= url
;
41 WebContents
* web_contents
=
42 browser()->tab_strip_model()->GetActiveWebContents();
43 params
.page_url
= web_contents
->GetController().GetActiveEntry()->GetURL();
44 #if defined(OS_MACOSX)
45 params
.writing_direction_default
= 0;
46 params
.writing_direction_left_to_right
= 0;
47 params
.writing_direction_right_to_left
= 0;
49 TestRenderViewContextMenu
* menu
= new TestRenderViewContextMenu(
50 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
57 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
,
58 OpenEntryPresentForNormalURLs
) {
59 scoped_ptr
<TestRenderViewContextMenu
> menu(
60 CreateContextMenu(GURL("http://www.google.com/"),
61 GURL("http://www.google.com/")));
63 ASSERT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
));
64 ASSERT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW
));
65 ASSERT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION
));
68 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
,
69 OpenEntryAbsentForFilteredURLs
) {
70 scoped_ptr
<TestRenderViewContextMenu
> menu(
71 CreateContextMenu(GURL("chrome://history"),
74 ASSERT_FALSE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
));
75 ASSERT_FALSE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW
));
76 ASSERT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION
));
79 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
,
80 ContextMenuForCanvas
) {
81 content::ContextMenuParams params
;
82 params
.media_type
= blink::WebContextMenuData::MediaTypeCanvas
;
84 TestRenderViewContextMenu
menu(
85 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
89 ASSERT_TRUE(menu
.IsItemPresent(IDC_CONTENT_CONTEXT_SAVEIMAGEAS
));
90 ASSERT_TRUE(menu
.IsItemPresent(IDC_CONTENT_CONTEXT_COPYIMAGE
));
93 // Opens a link in a new tab via a "real" context menu.
94 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
, RealMenu
) {
95 ContextMenuNotificationObserver
menu_observer(
96 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
);
97 ui_test_utils::WindowedTabAddedNotificationObserver
tab_observer(
98 content::NotificationService::AllSources());
100 // Go to a page with a link
101 ui_test_utils::NavigateToURL(
102 browser(), GURL("data:text/html,<a href='about:blank'>link</a>"));
104 // Open a context menu.
105 blink::WebMouseEvent mouse_event
;
106 mouse_event
.type
= blink::WebInputEvent::MouseDown
;
107 mouse_event
.button
= blink::WebMouseEvent::ButtonRight
;
110 content::WebContents
* tab
=
111 browser()->tab_strip_model()->GetActiveWebContents();
112 gfx::Rect offset
= tab
->GetContainerBounds();
113 mouse_event
.globalX
= 15 + offset
.x();
114 mouse_event
.globalY
= 15 + offset
.y();
115 mouse_event
.clickCount
= 1;
116 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
117 mouse_event
.type
= blink::WebInputEvent::MouseUp
;
118 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
120 // The menu_observer will select "Open in new tab", wait for the new tab to
123 tab
= tab_observer
.GetTab();
124 content::WaitForLoadStop(tab
);
126 // Verify that it's the correct tab.
127 EXPECT_EQ(GURL("about:blank"), tab
->GetURL());
130 // Verify that "Open Link in New Tab" doesn't send URL fragment as referrer.
131 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
, OpenInNewTabReferrer
) {
132 ui_test_utils::WindowedTabAddedNotificationObserver
tab_observer(
133 content::NotificationService::AllSources());
135 ASSERT_TRUE(test_server()->Start());
136 GURL
echoheader(test_server()->GetURL("echoheader?Referer"));
138 // Go to a |page| with a link to echoheader URL.
139 GURL
page("data:text/html,<a href='" + echoheader
.spec() + "'>link</a>");
140 ui_test_utils::NavigateToURL(browser(), page
);
142 // Set up referrer URL with fragment.
143 const GURL
kReferrerWithFragment("http://foo.com/test#fragment");
144 const std::string
kCorrectReferrer("http://foo.com/test");
146 // Set up menu with link URL.
147 content::ContextMenuParams context_menu_params
;
148 context_menu_params
.page_url
= kReferrerWithFragment
;
149 context_menu_params
.link_url
= echoheader
;
151 // Select "Open Link in New Tab" and wait for the new tab to be added.
152 TestRenderViewContextMenu
menu(
153 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
154 context_menu_params
);
156 menu
.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB
, 0);
159 content::WebContents
* tab
= tab_observer
.GetTab();
160 content::WaitForLoadStop(tab
);
162 // Verify that it's the correct tab.
163 ASSERT_EQ(echoheader
, tab
->GetURL());
164 // Verify that the text on the page matches |kCorrectReferrer|.
165 std::string actual_referrer
;
166 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
168 "window.domAutomationController.send(window.document.body.textContent);",
170 ASSERT_EQ(kCorrectReferrer
, actual_referrer
);
172 // Verify that the referrer on the page matches |kCorrectReferrer|.
173 std::string page_referrer
;
174 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
176 "window.domAutomationController.send(window.document.referrer);",
178 ASSERT_EQ(kCorrectReferrer
, page_referrer
);
181 // Verify that "Open Link in Incognito Window " doesn't send referrer URL.
182 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
, OpenIncognitoNoneReferrer
) {
183 ui_test_utils::WindowedTabAddedNotificationObserver
tab_observer(
184 content::NotificationService::AllSources());
186 ASSERT_TRUE(test_server()->Start());
187 GURL
echoheader(test_server()->GetURL("echoheader?Referer"));
189 // Go to a |page| with a link to echoheader URL.
190 GURL
page("data:text/html,<a href='" + echoheader
.spec() + "'>link</a>");
191 ui_test_utils::NavigateToURL(browser(), page
);
193 // Set up referrer URL with fragment.
194 const GURL
kReferrerWithFragment("http://foo.com/test#fragment");
195 const std::string
kNoneReferrer("None");
196 const std::string
kEmptyReferrer("");
198 // Set up menu with link URL.
199 content::ContextMenuParams context_menu_params
;
200 context_menu_params
.page_url
= kReferrerWithFragment
;
201 context_menu_params
.link_url
= echoheader
;
203 // Select "Open Link in Incognito Window" and wait for window to be added.
204 TestRenderViewContextMenu
menu(
205 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
206 context_menu_params
);
208 menu
.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD
, 0);
211 content::WebContents
* tab
= tab_observer
.GetTab();
212 content::WaitForLoadStop(tab
);
214 // Verify that it's the correct tab.
215 ASSERT_EQ(echoheader
, tab
->GetURL());
216 // Verify that the text on the page matches |kNoneReferrer|.
217 std::string actual_referrer
;
218 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
220 "window.domAutomationController.send(window.document.body.textContent);",
222 ASSERT_EQ(kNoneReferrer
, actual_referrer
);
224 // Verify that the referrer on the page matches |kEmptyReferrer|.
225 std::string page_referrer
;
226 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
228 "window.domAutomationController.send(window.document.referrer);",
230 ASSERT_EQ(kEmptyReferrer
, page_referrer
);
233 // Check filename on clicking "Save Link As" via a "real" context menu.
234 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
, SuggestedFileName
) {
235 // Register observer.
236 SaveLinkAsContextMenuObserver
menu_observer(
237 content::NotificationService::AllSources());
239 // Go to a page with a link having download attribute.
240 const std::string
kSuggestedFilename("test_filename.png");
241 ui_test_utils::NavigateToURL(
243 GURL("data:text/html,<a href='about:blank' download='" +
244 kSuggestedFilename
+ "'>link</a>"));
246 // Open a context menu.
247 blink::WebMouseEvent mouse_event
;
248 mouse_event
.type
= blink::WebInputEvent::MouseDown
;
249 mouse_event
.button
= blink::WebMouseEvent::ButtonRight
;
252 content::WebContents
* tab
=
253 browser()->tab_strip_model()->GetActiveWebContents();
254 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
255 mouse_event
.type
= blink::WebInputEvent::MouseUp
;
256 tab
->GetRenderViewHost()->ForwardMouseEvent(mouse_event
);
258 // Wait for context menu to be visible.
259 menu_observer
.WaitForMenu();
262 base::string16 suggested_filename
= menu_observer
.GetSuggestedFilename();
263 ASSERT_EQ(kSuggestedFilename
, base::UTF16ToUTF8(suggested_filename
).c_str());
266 // Ensure that View Page Info won't crash if there is no visible entry.
267 // See http://crbug.com/370863.
268 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest
, ViewPageInfoWithNoEntry
) {
269 // Create a new tab with no committed entry.
270 ui_test_utils::WindowedTabAddedNotificationObserver
tab_observer(
271 content::NotificationService::AllSources());
272 ASSERT_TRUE(content::ExecuteScript(
273 browser()->tab_strip_model()->GetActiveWebContents(), "window.open();"));
275 content::WebContents
* tab
= tab_observer
.GetTab();
276 EXPECT_FALSE(tab
->GetController().GetLastCommittedEntry());
277 EXPECT_FALSE(tab
->GetController().GetVisibleEntry());
279 // Create a context menu.
280 content::ContextMenuParams context_menu_params
;
281 TestRenderViewContextMenu
menu(tab
->GetMainFrame(), context_menu_params
);
284 // The item shouldn't be enabled in the menu.
285 EXPECT_FALSE(menu
.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO
));
287 // Ensure that viewing page info doesn't crash even if you can get to it.
288 menu
.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO
, 0);