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 SaveAsImageForCanvas) {
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));
92 // GTK requires a X11-level mouse event to open a context menu correctly.
93 #if defined(TOOLKIT_GTK)
94 #define MAYBE_RealMenu DISABLED_RealMenu
96 #define MAYBE_RealMenu RealMenu
98 // Opens a link in a new tab via a "real" context menu.
99 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
101 ContextMenuNotificationObserver menu_observer(
102 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
103 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
104 content::NotificationService::AllSources());
106 // Go to a page with a link
107 ui_test_utils::NavigateToURL(
108 browser(), GURL("data:text/html,<a href='about:blank'>link</a>"));
110 // Open a context menu.
111 blink::WebMouseEvent mouse_event;
112 mouse_event.type = blink::WebInputEvent::MouseDown;
113 mouse_event.button = blink::WebMouseEvent::ButtonRight;
116 content::WebContents* tab =
117 browser()->tab_strip_model()->GetActiveWebContents();
118 gfx::Rect offset = tab->GetContainerBounds();
119 mouse_event.globalX = 15 + offset.x();
120 mouse_event.globalY = 15 + offset.y();
121 mouse_event.clickCount = 1;
122 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
123 mouse_event.type = blink::WebInputEvent::MouseUp;
124 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
126 // The menu_observer will select "Open in new tab", wait for the new tab to
129 tab = tab_observer.GetTab();
130 content::WaitForLoadStop(tab);
132 // Verify that it's the correct tab.
133 EXPECT_EQ(GURL("about:blank"), tab->GetURL());
136 // Verify that "Open Link in New Tab" doesn't send URL fragment as referrer.
137 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenInNewTabReferrer) {
138 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
139 content::NotificationService::AllSources());
141 ASSERT_TRUE(test_server()->Start());
142 GURL echoheader(test_server()->GetURL("echoheader?Referer"));
144 // Go to a |page| with a link to echoheader URL.
145 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>");
146 ui_test_utils::NavigateToURL(browser(), page);
148 // Set up referrer URL with fragment.
149 const GURL kReferrerWithFragment("http://foo.com/test#fragment");
150 const std::string kCorrectReferrer("http://foo.com/test");
152 // Set up menu with link URL.
153 content::ContextMenuParams context_menu_params;
154 context_menu_params.page_url = kReferrerWithFragment;
155 context_menu_params.link_url = echoheader;
157 // Select "Open Link in New Tab" and wait for the new tab to be added.
158 TestRenderViewContextMenu menu(
159 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
160 context_menu_params);
162 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
165 content::WebContents* tab = tab_observer.GetTab();
166 content::WaitForLoadStop(tab);
168 // Verify that it's the correct tab.
169 ASSERT_EQ(echoheader, tab->GetURL());
170 // Verify that the text on the page matches |kCorrectReferrer|.
171 std::string actual_referrer;
172 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
174 "window.domAutomationController.send(window.document.body.textContent);",
176 ASSERT_EQ(kCorrectReferrer, actual_referrer);
178 // Verify that the referrer on the page matches |kCorrectReferrer|.
179 std::string page_referrer;
180 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
182 "window.domAutomationController.send(window.document.referrer);",
184 ASSERT_EQ(kCorrectReferrer, page_referrer);
187 // Verify that "Open Link in Incognito Window " doesn't send referrer URL.
188 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenIncognitoNoneReferrer) {
189 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
190 content::NotificationService::AllSources());
192 ASSERT_TRUE(test_server()->Start());
193 GURL echoheader(test_server()->GetURL("echoheader?Referer"));
195 // Go to a |page| with a link to echoheader URL.
196 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>");
197 ui_test_utils::NavigateToURL(browser(), page);
199 // Set up referrer URL with fragment.
200 const GURL kReferrerWithFragment("http://foo.com/test#fragment");
201 const std::string kNoneReferrer("None");
202 const std::string kEmptyReferrer("");
204 // Set up menu with link URL.
205 content::ContextMenuParams context_menu_params;
206 context_menu_params.page_url = kReferrerWithFragment;
207 context_menu_params.link_url = echoheader;
209 // Select "Open Link in Incognito Window" and wait for window to be added.
210 TestRenderViewContextMenu menu(
211 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
212 context_menu_params);
214 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
217 content::WebContents* tab = tab_observer.GetTab();
218 content::WaitForLoadStop(tab);
220 // Verify that it's the correct tab.
221 ASSERT_EQ(echoheader, tab->GetURL());
222 // Verify that the text on the page matches |kNoneReferrer|.
223 std::string actual_referrer;
224 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
226 "window.domAutomationController.send(window.document.body.textContent);",
228 ASSERT_EQ(kNoneReferrer, actual_referrer);
230 // Verify that the referrer on the page matches |kEmptyReferrer|.
231 std::string page_referrer;
232 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
234 "window.domAutomationController.send(window.document.referrer);",
236 ASSERT_EQ(kEmptyReferrer, page_referrer);
239 // Ensure that View Page Info won't crash if there is no visible entry.
240 // See http://crbug.com/370863.
241 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, ViewPageInfoWithNoEntry) {
242 // Create a new tab with no committed entry.
243 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
244 content::NotificationService::AllSources());
245 ASSERT_TRUE(content::ExecuteScript(
246 browser()->tab_strip_model()->GetActiveWebContents(), "window.open();"));
248 content::WebContents* tab = tab_observer.GetTab();
249 EXPECT_FALSE(tab->GetController().GetLastCommittedEntry());
250 EXPECT_FALSE(tab->GetController().GetVisibleEntry());
252 // Create a context menu.
253 content::ContextMenuParams context_menu_params;
254 TestRenderViewContextMenu menu(tab->GetMainFrame(), context_menu_params);
257 // The item shouldn't be enabled in the menu.
258 EXPECT_FALSE(menu.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO));
260 // Ensure that viewing page info doesn't crash even if you can get to it.
261 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO, 0);