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. 4 5 #include <string> 6 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/tab_contents/render_view_context_menu.h" 13 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h" 14 #include "chrome/browser/tab_contents/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/browser/web_contents_view.h" 25 #include "content/public/test/browser_test_utils.h" 26 #include "third_party/WebKit/public/web/WebContextMenuData.h" 27 #include "third_party/WebKit/public/web/WebInputEvent.h" 28 29 using content::WebContents; 30 31 namespace { 32 33 class ContextMenuBrowserTest : public InProcessBrowserTest { 34 public: 35 ContextMenuBrowserTest() { } 36 37 TestRenderViewContextMenu* CreateContextMenu(GURL unfiltered_url, GURL url) { 38 content::ContextMenuParams params; 39 params.media_type = WebKit::WebContextMenuData::MediaTypeNone; 40 params.unfiltered_link_url = unfiltered_url; 41 params.link_url = url; 42 WebContents* web_contents = 43 browser()->tab_strip_model()->GetActiveWebContents(); 44 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); 45 #if defined(OS_MACOSX) 46 params.writing_direction_default = 0; 47 params.writing_direction_left_to_right = 0; 48 params.writing_direction_right_to_left = 0; 49 #endif // OS_MACOSX 50 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( 51 browser()->tab_strip_model()->GetActiveWebContents(), params); 52 menu->Init(); 53 return menu; 54 } 55 }; 56 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/"))); 62 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)); 66 } 67 68 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, 69 OpenEntryAbsentForFilteredURLs) { 70 scoped_ptr<TestRenderViewContextMenu> menu( 71 CreateContextMenu(GURL("chrome://history"), 72 GURL())); 73 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)); 77 } 78 79 // GTK requires a X11-level mouse event to open a context menu correctly. 80 #if defined(TOOLKIT_GTK) 81 #define MAYBE_RealMenu DISABLED_RealMenu 82 #else 83 #define MAYBE_RealMenu RealMenu 84 #endif 85 // Opens a link in a new tab via a "real" context menu. 86 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, 87 MAYBE_RealMenu) { 88 ContextMenuNotificationObserver menu_observer( 89 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB); 90 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 91 content::NotificationService::AllSources()); 92 93 // Go to a page with a link 94 ui_test_utils::NavigateToURL( 95 browser(), GURL("data:text/html,<a href='about:blank'>link</a>")); 96 97 // Open a context menu. 98 WebKit::WebMouseEvent mouse_event; 99 mouse_event.type = WebKit::WebInputEvent::MouseDown; 100 mouse_event.button = WebKit::WebMouseEvent::ButtonRight; 101 mouse_event.x = 15; 102 mouse_event.y = 15; 103 gfx::Rect offset; 104 content::WebContents* tab = 105 browser()->tab_strip_model()->GetActiveWebContents(); 106 tab->GetView()->GetContainerBounds(&offset); 107 mouse_event.globalX = 15 + offset.x(); 108 mouse_event.globalY = 15 + offset.y(); 109 mouse_event.clickCount = 1; 110 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 111 mouse_event.type = WebKit::WebInputEvent::MouseUp; 112 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 113 114 // The menu_observer will select "Open in new tab", wait for the new tab to 115 // be added. 116 tab_observer.Wait(); 117 tab = tab_observer.GetTab(); 118 content::WaitForLoadStop(tab); 119 120 // Verify that it's the correct tab. 121 EXPECT_EQ(GURL("about:blank"), tab->GetURL()); 122 } 123 124 // Verify that "Open Link in New Tab" doesn't send URL fragment as referrer. 125 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenInNewTabReferrer) { 126 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 127 content::NotificationService::AllSources()); 128 129 ASSERT_TRUE(test_server()->Start()); 130 GURL echoheader(test_server()->GetURL("echoheader?Referer")); 131 132 // Go to a |page| with a link to echoheader URL. 133 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>"); 134 ui_test_utils::NavigateToURL(browser(), page); 135 136 // Set up referrer URL with fragment. 137 const GURL kReferrerWithFragment("http://foo.com/test#fragment"); 138 const std::string kCorrectReferrer("http://foo.com/test"); 139 140 // Set up menu with link URL. 141 content::ContextMenuParams context_menu_params; 142 context_menu_params.page_url = kReferrerWithFragment; 143 context_menu_params.link_url = echoheader; 144 145 // Select "Open Link in New Tab" and wait for the new tab to be added. 146 TestRenderViewContextMenu menu( 147 browser()->tab_strip_model()->GetActiveWebContents(), 148 context_menu_params); 149 menu.Init(); 150 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0); 151 152 tab_observer.Wait(); 153 content::WebContents* tab = tab_observer.GetTab(); 154 content::WaitForLoadStop(tab); 155 156 // Verify that it's the correct tab. 157 ASSERT_EQ(echoheader, tab->GetURL()); 158 // Verify that the text on the page matches |kCorrectReferrer|. 159 std::string actual_referrer; 160 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 161 tab, 162 "window.domAutomationController.send(window.document.body.textContent);", 163 &actual_referrer)); 164 ASSERT_EQ(kCorrectReferrer, actual_referrer); 165 166 // Verify that the referrer on the page matches |kCorrectReferrer|. 167 std::string page_referrer; 168 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 169 tab, 170 "window.domAutomationController.send(window.document.referrer);", 171 &page_referrer)); 172 ASSERT_EQ(kCorrectReferrer, page_referrer); 173 } 174 175 // Verify that "Open Link in Incognito Window " doesn't send referrer URL. 176 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenIncognitoNoneReferrer) { 177 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 178 content::NotificationService::AllSources()); 179 180 ASSERT_TRUE(test_server()->Start()); 181 GURL echoheader(test_server()->GetURL("echoheader?Referer")); 182 183 // Go to a |page| with a link to echoheader URL. 184 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>"); 185 ui_test_utils::NavigateToURL(browser(), page); 186 187 // Set up referrer URL with fragment. 188 const GURL kReferrerWithFragment("http://foo.com/test#fragment"); 189 const std::string kNoneReferrer("None"); 190 const std::string kEmptyReferrer(""); 191 192 // Set up menu with link URL. 193 content::ContextMenuParams context_menu_params; 194 context_menu_params.page_url = kReferrerWithFragment; 195 context_menu_params.link_url = echoheader; 196 197 // Select "Open Link in Incognito Window" and wait for window to be added. 198 TestRenderViewContextMenu menu( 199 browser()->tab_strip_model()->GetActiveWebContents(), 200 context_menu_params); 201 menu.Init(); 202 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0); 203 204 tab_observer.Wait(); 205 content::WebContents* tab = tab_observer.GetTab(); 206 content::WaitForLoadStop(tab); 207 208 // Verify that it's the correct tab. 209 ASSERT_EQ(echoheader, tab->GetURL()); 210 // Verify that the text on the page matches |kNoneReferrer|. 211 std::string actual_referrer; 212 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 213 tab, 214 "window.domAutomationController.send(window.document.body.textContent);", 215 &actual_referrer)); 216 ASSERT_EQ(kNoneReferrer, actual_referrer); 217 218 // Verify that the referrer on the page matches |kEmptyReferrer|. 219 std::string page_referrer; 220 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 221 tab, 222 "window.domAutomationController.send(window.document.referrer);", 223 &page_referrer)); 224 ASSERT_EQ(kEmptyReferrer, page_referrer); 225 } 226 227 } // namespace 228