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. 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/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" 27 28using content::WebContents; 29 30namespace { 31 32class ContextMenuBrowserTest : public InProcessBrowserTest { 33 public: 34 ContextMenuBrowserTest() { } 35 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; 48#endif // OS_MACOSX 49 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( 50 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 51 params); 52 menu->Init(); 53 return menu; 54 } 55}; 56 57IN_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 68IN_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 79IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, 80 SaveAsImageForCanvas) { 81 content::ContextMenuParams params; 82 params.media_type = blink::WebContextMenuData::MediaTypeCanvas; 83 84 TestRenderViewContextMenu menu( 85 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 86 params); 87 menu.Init(); 88 89 ASSERT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_SAVEIMAGEAS)); 90} 91 92// Opens a link in a new tab via a "real" context menu. 93IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, RealMenu) { 94 ContextMenuNotificationObserver menu_observer( 95 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB); 96 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 97 content::NotificationService::AllSources()); 98 99 // Go to a page with a link 100 ui_test_utils::NavigateToURL( 101 browser(), GURL("data:text/html,<a href='about:blank'>link</a>")); 102 103 // Open a context menu. 104 blink::WebMouseEvent mouse_event; 105 mouse_event.type = blink::WebInputEvent::MouseDown; 106 mouse_event.button = blink::WebMouseEvent::ButtonRight; 107 mouse_event.x = 15; 108 mouse_event.y = 15; 109 content::WebContents* tab = 110 browser()->tab_strip_model()->GetActiveWebContents(); 111 gfx::Rect offset = tab->GetContainerBounds(); 112 mouse_event.globalX = 15 + offset.x(); 113 mouse_event.globalY = 15 + offset.y(); 114 mouse_event.clickCount = 1; 115 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 116 mouse_event.type = blink::WebInputEvent::MouseUp; 117 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 118 119 // The menu_observer will select "Open in new tab", wait for the new tab to 120 // be added. 121 tab_observer.Wait(); 122 tab = tab_observer.GetTab(); 123 content::WaitForLoadStop(tab); 124 125 // Verify that it's the correct tab. 126 EXPECT_EQ(GURL("about:blank"), tab->GetURL()); 127} 128 129// Verify that "Open Link in New Tab" doesn't send URL fragment as referrer. 130IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenInNewTabReferrer) { 131 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 132 content::NotificationService::AllSources()); 133 134 ASSERT_TRUE(test_server()->Start()); 135 GURL echoheader(test_server()->GetURL("echoheader?Referer")); 136 137 // Go to a |page| with a link to echoheader URL. 138 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>"); 139 ui_test_utils::NavigateToURL(browser(), page); 140 141 // Set up referrer URL with fragment. 142 const GURL kReferrerWithFragment("http://foo.com/test#fragment"); 143 const std::string kCorrectReferrer("http://foo.com/test"); 144 145 // Set up menu with link URL. 146 content::ContextMenuParams context_menu_params; 147 context_menu_params.page_url = kReferrerWithFragment; 148 context_menu_params.link_url = echoheader; 149 150 // Select "Open Link in New Tab" and wait for the new tab to be added. 151 TestRenderViewContextMenu menu( 152 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 153 context_menu_params); 154 menu.Init(); 155 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0); 156 157 tab_observer.Wait(); 158 content::WebContents* tab = tab_observer.GetTab(); 159 content::WaitForLoadStop(tab); 160 161 // Verify that it's the correct tab. 162 ASSERT_EQ(echoheader, tab->GetURL()); 163 // Verify that the text on the page matches |kCorrectReferrer|. 164 std::string actual_referrer; 165 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 166 tab, 167 "window.domAutomationController.send(window.document.body.textContent);", 168 &actual_referrer)); 169 ASSERT_EQ(kCorrectReferrer, actual_referrer); 170 171 // Verify that the referrer on the page matches |kCorrectReferrer|. 172 std::string page_referrer; 173 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 174 tab, 175 "window.domAutomationController.send(window.document.referrer);", 176 &page_referrer)); 177 ASSERT_EQ(kCorrectReferrer, page_referrer); 178} 179 180// Verify that "Open Link in Incognito Window " doesn't send referrer URL. 181IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenIncognitoNoneReferrer) { 182 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 183 content::NotificationService::AllSources()); 184 185 ASSERT_TRUE(test_server()->Start()); 186 GURL echoheader(test_server()->GetURL("echoheader?Referer")); 187 188 // Go to a |page| with a link to echoheader URL. 189 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>"); 190 ui_test_utils::NavigateToURL(browser(), page); 191 192 // Set up referrer URL with fragment. 193 const GURL kReferrerWithFragment("http://foo.com/test#fragment"); 194 const std::string kNoneReferrer("None"); 195 const std::string kEmptyReferrer(""); 196 197 // Set up menu with link URL. 198 content::ContextMenuParams context_menu_params; 199 context_menu_params.page_url = kReferrerWithFragment; 200 context_menu_params.link_url = echoheader; 201 202 // Select "Open Link in Incognito Window" and wait for window to be added. 203 TestRenderViewContextMenu menu( 204 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 205 context_menu_params); 206 menu.Init(); 207 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0); 208 209 tab_observer.Wait(); 210 content::WebContents* tab = tab_observer.GetTab(); 211 content::WaitForLoadStop(tab); 212 213 // Verify that it's the correct tab. 214 ASSERT_EQ(echoheader, tab->GetURL()); 215 // Verify that the text on the page matches |kNoneReferrer|. 216 std::string actual_referrer; 217 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 218 tab, 219 "window.domAutomationController.send(window.document.body.textContent);", 220 &actual_referrer)); 221 ASSERT_EQ(kNoneReferrer, actual_referrer); 222 223 // Verify that the referrer on the page matches |kEmptyReferrer|. 224 std::string page_referrer; 225 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 226 tab, 227 "window.domAutomationController.send(window.document.referrer);", 228 &page_referrer)); 229 ASSERT_EQ(kEmptyReferrer, page_referrer); 230} 231 232// Ensure that View Page Info won't crash if there is no visible entry. 233// See http://crbug.com/370863. 234IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, ViewPageInfoWithNoEntry) { 235 // Create a new tab with no committed entry. 236 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( 237 content::NotificationService::AllSources()); 238 ASSERT_TRUE(content::ExecuteScript( 239 browser()->tab_strip_model()->GetActiveWebContents(), "window.open();")); 240 tab_observer.Wait(); 241 content::WebContents* tab = tab_observer.GetTab(); 242 EXPECT_FALSE(tab->GetController().GetLastCommittedEntry()); 243 EXPECT_FALSE(tab->GetController().GetVisibleEntry()); 244 245 // Create a context menu. 246 content::ContextMenuParams context_menu_params; 247 TestRenderViewContextMenu menu(tab->GetMainFrame(), context_menu_params); 248 menu.Init(); 249 250 // The item shouldn't be enabled in the menu. 251 EXPECT_FALSE(menu.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO)); 252 253 // Ensure that viewing page info doesn't crash even if you can get to it. 254 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO, 0); 255} 256 257} // namespace 258