Home | History | Annotate | Download | only in renderer_context_menu
      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 
     28 using content::WebContents;
     29 
     30 namespace {
     31 
     32 class 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 
     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 IN_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.
     93 IN_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.
    130 IN_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.
    181 IN_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.
    234 IN_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