Index: chrome/browser/apps/web_view_browsertest.cc |
diff --git a/chrome/browser/apps/web_view_browsertest.cc b/chrome/browser/apps/web_view_browsertest.cc |
index 0444c25858e4ca7fe59b952974eaad83cb6e6d61..99be9b0a9bea2c0c952c0d57dc829b8c89056bc9 100644 |
--- a/chrome/browser/apps/web_view_browsertest.cc |
+++ b/chrome/browser/apps/web_view_browsertest.cc |
@@ -6,6 +6,7 @@ |
#include "base/path_service.h" |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "chrome/app/chrome_command_ids.h" |
#include "chrome/browser/apps/app_browsertest_util.h" |
#include "chrome/browser/automation/automation_util.h" |
#include "chrome/browser/chrome_content_browser_client.h" |
@@ -13,6 +14,7 @@ |
#include "chrome/browser/prerender/prerender_link_manager.h" |
#include "chrome/browser/prerender/prerender_link_manager_factory.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/renderer_context_menu/render_view_context_menu.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
#include "chrome/test/base/ui_test_utils.h" |
@@ -42,8 +44,10 @@ |
#include "base/win/windows_version.h" |
#endif |
+using extensions::MenuItem; |
using prerender::PrerenderLinkManager; |
using prerender::PrerenderLinkManagerFactory; |
+using ui::MenuModel; |
namespace { |
const char kEmptyResponsePath[] = "/close-socket"; |
@@ -132,6 +136,60 @@ class InterstitialObserver : public content::WebContentsObserver { |
DISALLOW_COPY_AND_ASSIGN(InterstitialObserver); |
}; |
+// This test class helps us sidestep platform-specific issues with popping up a |
+// real context menu, while still running through the actual code in |
+// RenderViewContextMenu where extension items get added and executed. |
+class TestRenderViewContextMenu : public RenderViewContextMenu { |
Yoyo Zhou
2014/03/07 02:40:30
This looks duplicated from ExtensionContextMenuBro
lazyboy
2014/03/07 06:38:03
I've made WebViewTest (this) and ExtensionContextM
|
+ public: |
+ TestRenderViewContextMenu(content::RenderFrameHost* render_frame_host, |
+ const content::ContextMenuParams& params) |
+ : RenderViewContextMenu(render_frame_host, params) {} |
+ |
+ virtual ~TestRenderViewContextMenu() {} |
+ |
+ // Searches for an menu item with |command_id|. If it's found, the return |
+ // value is true and the model and index where it appears in that model are |
+ // returned in |found_model| and |found_index|. Otherwise returns false. |
+ bool GetMenuModelAndItemIndex(int command_id, |
+ MenuModel** found_model, |
+ int *found_index) { |
+ std::vector<MenuModel*> models_to_search; |
+ models_to_search.push_back(&menu_model_); |
+ |
+ while (!models_to_search.empty()) { |
+ MenuModel* model = models_to_search.back(); |
+ models_to_search.pop_back(); |
+ for (int i = 0; i < model->GetItemCount(); i++) { |
+ if (model->GetCommandIdAt(i) == command_id) { |
+ *found_model = model; |
+ *found_index = i; |
+ return true; |
+ } else if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) { |
+ models_to_search.push_back(model->GetSubmenuModelAt(i)); |
+ } |
+ } |
+ } |
+ |
+ return false; |
+ } |
+ |
+ extensions::ContextMenuMatcher& extension_items() { |
+ return extension_items_; |
+ } |
+ |
+ protected: |
+ // These two functions implement pure virtual methods of |
+ // RenderViewContextMenu. |
+ virtual bool GetAcceleratorForCommandId( |
+ int command_id, |
+ ui::Accelerator* accelerator) OVERRIDE { |
+ // None of our commands have accelerators, so always return false. |
+ return false; |
+ } |
+ virtual void PlatformInit() OVERRIDE {} |
+ virtual void PlatformCancel() OVERRIDE {} |
+}; |
+ |
} // namespace |
// This class intercepts media access request from the embedder. The request |
@@ -486,6 +544,39 @@ class WebViewTest : public extensions::PlatformAppBrowserTest { |
return scoped_ptr<net::test_server::HttpResponse>(); |
} |
+ TestRenderViewContextMenu* CreateMenu(Browser* browser, |
+ const GURL& page_url, |
+ content::WebContents* web_contents) { |
+ content::ContextMenuParams params; |
+ params.page_url = page_url; |
+ params.link_url = GURL(); |
+ params.frame_url = GURL(); |
+ TestRenderViewContextMenu* menu = |
+ new TestRenderViewContextMenu(web_contents->GetMainFrame(), params); |
+ printf("menu->Init()\n"); |
+ menu->Init(); |
+ return menu; |
+ } |
+ |
+ // Shortcut to return the current MenuManager. |
+ extensions::MenuManager* menu_manager() { |
+ return extensions::MenuManager::Get(browser()->profile()); |
+ } |
+ |
+ // This gets all the items that any extension has registered for possible |
+ // inclusion in context menus. |
+ MenuItem::List GetItems() { |
+ MenuItem::List result; |
+ std::set<MenuItem::ExtensionKey> extension_ids = |
+ menu_manager()->ExtensionIds(); |
+ std::set<MenuItem::ExtensionKey>::iterator i; |
+ for (i = extension_ids.begin(); i != extension_ids.end(); ++i) { |
+ const MenuItem::List* list = menu_manager()->MenuItems(*i); |
+ result.insert(result.end(), list->begin(), list->end()); |
+ } |
+ return result; |
+ } |
+ |
enum TestServer { |
NEEDS_TEST_SERVER, |
NO_TEST_SERVER |
@@ -1510,6 +1601,68 @@ void WebViewTest::MediaAccessAPIAllowTestHelper(const std::string& test_name) { |
mock->WaitForSetMediaPermission(); |
} |
+IN_PROC_BROWSER_TEST_F(WebViewTest, ContextMenusAPI_Basic) { |
+ GuestContentBrowserClient new_client; |
+ content::ContentBrowserClient* old_client = |
+ SetBrowserClientForTesting(&new_client); |
+ |
+ ExtensionTestMessageListener launched_listener("Launched", false); |
+ launched_listener.AlsoListenForFailureMessage("TEST_FAILED"); |
+ LoadAndLaunchPlatformApp("web_view/context_menus/basic"); |
+ ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); |
+ |
+ content::WebContents* guest_web_contents = new_client.WaitForGuestCreated(); |
+ ASSERT_TRUE(guest_web_contents); |
+ SetBrowserClientForTesting(old_client); |
+ |
+ content::WebContents* embedder = GetFirstAppWindowWebContents(); |
+ ASSERT_TRUE(embedder); |
+ |
+ // 1. Basic property test. |
+ ExecuteScriptWaitForTitle(embedder, "checkProperties()", "ITEM_CHECKED"); |
+ |
+ // 2. Create a menu item and wait for created callback to be called. |
+ ExecuteScriptWaitForTitle(embedder, "createMenuItem()", "ITEM_CREATED"); |
+ |
+ // 3. Click the created item, wait for the click handlers to fire from JS. |
+ ExtensionTestMessageListener click_listener("ITEM_CLICKED", false); |
+ GURL page_url("http://www.google.com"); |
+ // Create and build our test context menu. |
+ scoped_ptr<TestRenderViewContextMenu> menu( |
+ CreateMenu(browser(), page_url, guest_web_contents)); |
+ // Look for the extension item in the menu, and execute it. |
+ int command_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST; |
+ ASSERT_TRUE(menu->IsCommandIdEnabled(command_id)); |
+ menu->ExecuteCommand(command_id, 0); |
+ |
+ // Wait for embedder's script to tell us its onclick fired, it does |
+ // chrome.test.sendMessage('ITEM_CLICKED') |
+ ASSERT_TRUE(click_listener.WaitUntilSatisfied()); |
+ |
+ // 4. Update the item's title and verify. |
+ ExecuteScriptWaitForTitle(embedder, "updateMenuItem()", "ITEM_UPDATED"); |
+ MenuItem::List items = GetItems(); |
+ ASSERT_EQ(1u, items.size()); |
+ MenuItem* item = items.at(0); |
+ EXPECT_EQ("new_title", item->title()); |
+ |
+ // 5. Remove the item. |
+ ExecuteScriptWaitForTitle(embedder, "removeItem()", "ITEM_REMOVED"); |
+ MenuItem::List items_after_removal = GetItems(); |
+ ASSERT_EQ(0u, items_after_removal.size()); |
+ |
+ // 6. Add some more items. |
+ ExecuteScriptWaitForTitle(embedder, "createThreeMenuItems()", |
+ "ITEM_MULTIPLE_CREATED"); |
+ MenuItem::List items_after_insertion = GetItems(); |
+ ASSERT_EQ(3u, items_after_insertion.size()); |
+ |
+ // 7. Test removeAll(). |
+ ExecuteScriptWaitForTitle(embedder, "removeAllItems()", "ITEM_ALL_REMOVED"); |
+ MenuItem::List items_after_all_removal = GetItems(); |
+ ASSERT_EQ(0u, items_after_all_removal.size()); |
+} |
+ |
IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllow) { |
MediaAccessAPIAllowTestHelper("testAllow"); |
} |
@@ -1892,6 +2045,11 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAPI_findupdate) { |
TestHelper("testFindAPI_findupdate", "web_view/shim", NO_TEST_SERVER); |
} |
+IN_PROC_BROWSER_TEST_F(WebViewTest, ContextMenusClick) { |
+ ASSERT_TRUE(RunPlatformAppTestWithArg( |
+ "platform_apps/web_view/common", "context_menus_click")) << message_; |
+} |
+ |
// <webview> screenshot capture fails with ubercomp. |
// See http://crbug.com/327035. |
IN_PROC_BROWSER_TEST_P(WebViewCaptureTest, |
@@ -1899,6 +2057,7 @@ IN_PROC_BROWSER_TEST_P(WebViewCaptureTest, |
TestHelper("testScreenshotCapture", "web_view/shim", NO_TEST_SERVER); |
} |
+ |
Yoyo Zhou
2014/03/07 02:40:30
nit: stray newline
lazyboy
2014/03/07 06:38:03
Done.
|
// Threaded compositing is always enabled on Aura and Mac. |
#if !defined(USE_AURA) && !defined(OS_MACOSX) |
INSTANTIATE_TEST_CASE_P(WithoutThreadedCompositor, |