1 // Copyright 2013 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.
5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu_controller.h"
7 #include "base/files/file_path.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/extensions/browser_action_test_util.h"
11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/extensions/extension_action_manager.h"
13 #include "chrome/browser/extensions/extension_browsertest.h"
14 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
18 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
19 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
20 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "content/public/browser/devtools_agent_host.h"
26 #include "content/public/test/test_utils.h"
27 #include "extensions/common/extension.h"
28 #include "ui/base/l10n/l10n_util_mac.h"
30 using extensions::Extension;
34 NSMenuItem* GetInspectItem(NSMenu* menu) {
35 return [menu itemWithTitle:
36 l10n_util::GetNSStringWithFixup(IDS_EXTENSION_ACTION_INSPECT_POPUP)];
41 class ExtensionActionContextMenuControllerTest : public ExtensionBrowserTest {
43 ExtensionActionContextMenuControllerTest() : extension_(NULL), action_(NULL) {
47 void SetupPageAction() {
48 extension_ = InstallExtension(
49 test_data_dir_.AppendASCII("browsertest")
50 .AppendASCII("page_action_popup"),
52 EXPECT_TRUE(extension_);
53 extensions::ExtensionActionManager* action_manager =
54 extensions::ExtensionActionManager::Get(browser()->profile());
55 action_ = action_manager->GetPageAction(*extension_);
58 content::WebContents* contents =
59 browser()->tab_strip_model()->GetActiveWebContents();
60 action_->SetIsVisible(extensions::ExtensionTabUtil::GetTabId(contents),
63 BrowserWindowCocoa* window =
64 static_cast<BrowserWindowCocoa*>(browser()->window());
65 ToolbarController* toolbarController =
66 [window->cocoa_controller() toolbarController];
67 LocationBarViewMac* locationBarView =
68 [toolbarController locationBarBridge];
69 locationBarView->Update(NULL);
72 const Extension* extension_;
73 ExtensionAction* action_;
76 IN_PROC_BROWSER_TEST_F(ExtensionActionContextMenuControllerTest, BasicTest) {
78 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
79 [[ExtensionActionContextMenuController alloc] initWithExtension:extension_
81 extensionAction:action_]);
84 PrefService* service = browser()->profile()->GetPrefs();
85 bool original = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
87 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
88 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
89 [controller populateMenu:menu];
90 EXPECT_GT([menu numberOfItems], 0);
91 EXPECT_TRUE(GetInspectItem(menu));
93 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
94 [menu removeAllItems];
95 [controller populateMenu:menu];
96 EXPECT_GT([menu numberOfItems], 0);
97 EXPECT_FALSE(GetInspectItem(menu));
99 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, original);
102 // Test that browser action context menus work. Browser actions have their
103 // menus created during browser initialization, when there is no tab. This
104 // test simulates that and checks the menu is operational.
105 IN_PROC_BROWSER_TEST_F(ExtensionActionContextMenuControllerTest,
108 InstallExtension(test_data_dir_.AppendASCII("browsertest").AppendASCII(
109 "browser_action_popup"),
111 EXPECT_TRUE(extension_);
112 extensions::ExtensionActionManager* action_manager =
113 extensions::ExtensionActionManager::Get(browser()->profile());
114 action_ = action_manager->GetBrowserAction(*extension_);
115 EXPECT_TRUE(action_);
117 Browser* empty_browser(
118 new Browser(Browser::CreateParams(browser()->profile(),
119 browser()->host_desktop_type())));
121 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
122 [[ExtensionActionContextMenuController alloc]
123 initWithExtension:extension_
124 browser:empty_browser
125 extensionAction:action_]);
126 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
127 [controller populateMenu:menu];
128 EXPECT_GT([menu numberOfItems], 0);
130 // Close the empty browser. Can't just free it directly because there are
131 // dangling references in the various native controllers that must be
133 NSWindow* window = empty_browser->window()->GetNativeWindow();
134 BrowserWindowController* wc =
135 [BrowserWindowController browserWindowControllerForWindow:window];
136 ASSERT_TRUE(wc != NULL);
142 class DevToolsAttachedObserver {
144 DevToolsAttachedObserver(const base::Closure& callback)
145 : callback_(callback),
146 devtools_callback_(base::Bind(
147 &DevToolsAttachedObserver::OnDevToolsStateChanged,
148 base::Unretained(this))) {
149 content::DevToolsAgentHost::AddAgentStateCallback(devtools_callback_);
152 ~DevToolsAttachedObserver() {
153 content::DevToolsAgentHost::RemoveAgentStateCallback(devtools_callback_);
156 void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached) {
162 base::Closure callback_;
163 base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
165 DISALLOW_COPY_AND_ASSIGN(DevToolsAttachedObserver);
170 IN_PROC_BROWSER_TEST_F(
171 ExtensionActionContextMenuControllerTest, DISABLED_RunInspectPopup) {
173 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
174 [[ExtensionActionContextMenuController alloc] initWithExtension:extension_
176 extensionAction:action_]);
178 PrefService* service = browser()->profile()->GetPrefs();
179 bool original = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
181 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
183 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
184 [controller populateMenu:menu];
185 EXPECT_GT([menu numberOfItems], 0);
186 NSMenuItem* inspectItem = GetInspectItem(menu);
187 EXPECT_TRUE(inspectItem);
189 scoped_refptr<content::MessageLoopRunner> loop_runner(
190 new content::MessageLoopRunner);
191 DevToolsAttachedObserver observer(loop_runner->QuitClosure());
192 [NSApp sendAction:[inspectItem action]
193 to:[inspectItem target]
197 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, original);