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/path_service.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/extensions/browser_action_test_util.h"
12 #include "chrome/browser/extensions/extension_action.h"
13 #include "chrome/browser/extensions/extension_action_manager.h"
14 #include "chrome/browser/extensions/extension_browsertest.h"
15 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
19 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
20 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
21 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/pref_names.h"
25 #include "content/public/browser/devtools_manager.h"
26 #include "content/public/test/test_utils.h"
27 #include "extensions/common/extension.h"
28 #include "grit/generated_resources.h"
29 #include "ui/base/l10n/l10n_util_mac.h"
31 using extensions::Extension;
35 NSMenuItem* GetInspectItem(NSMenu* menu) {
36 return [menu itemWithTitle:
37 l10n_util::GetNSStringWithFixup(IDS_EXTENSION_ACTION_INSPECT_POPUP)];
42 class ExtensionActionContextMenuControllerTest : public ExtensionBrowserTest {
44 ExtensionActionContextMenuControllerTest() : extension_(NULL), action_(NULL) {
48 void SetupPageAction() {
49 extension_ = InstallExtension(
50 test_data_dir_.AppendASCII("browsertest")
51 .AppendASCII("page_action_popup"),
53 EXPECT_TRUE(extension_);
54 extensions::ExtensionActionManager* action_manager =
55 extensions::ExtensionActionManager::Get(browser()->profile());
56 action_ = action_manager->GetPageAction(*extension_);
59 content::WebContents* contents =
60 browser()->tab_strip_model()->GetActiveWebContents();
61 action_->SetAppearance(extensions::ExtensionTabUtil::GetTabId(contents),
62 ExtensionAction::ACTIVE);
64 BrowserWindowCocoa* window =
65 static_cast<BrowserWindowCocoa*>(browser()->window());
66 ToolbarController* toolbarController =
67 [window->cocoa_controller() toolbarController];
68 LocationBarViewMac* locationBarView =
69 [toolbarController locationBarBridge];
70 locationBarView->Update(NULL);
73 const Extension* extension_;
74 ExtensionAction* action_;
77 IN_PROC_BROWSER_TEST_F(ExtensionActionContextMenuControllerTest, BasicTest) {
79 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
80 [[ExtensionActionContextMenuController alloc] initWithExtension:extension_
82 extensionAction:action_]);
85 PrefService* service = browser()->profile()->GetPrefs();
86 bool original = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
88 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
89 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
90 [controller populateMenu:menu];
91 EXPECT_GT([menu numberOfItems], 0);
92 EXPECT_TRUE(GetInspectItem(menu));
94 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
95 [menu removeAllItems];
96 [controller populateMenu:menu];
97 EXPECT_GT([menu numberOfItems], 0);
98 EXPECT_FALSE(GetInspectItem(menu));
100 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, original);
103 // Test that browser action context menus work. Browser actions have their
104 // menus created during browser initialization, when there is no tab. This
105 // test simulates that and checks the menu is operational.
106 IN_PROC_BROWSER_TEST_F(ExtensionActionContextMenuControllerTest,
109 InstallExtension(test_data_dir_.AppendASCII("browsertest").AppendASCII(
110 "browser_action_popup"),
112 EXPECT_TRUE(extension_);
113 extensions::ExtensionActionManager* action_manager =
114 extensions::ExtensionActionManager::Get(browser()->profile());
115 action_ = action_manager->GetBrowserAction(*extension_);
116 EXPECT_TRUE(action_);
118 Browser* empty_browser(
119 new Browser(Browser::CreateParams(browser()->profile(),
120 browser()->host_desktop_type())));
122 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
123 [[ExtensionActionContextMenuController alloc]
124 initWithExtension:extension_
125 browser:empty_browser
126 extensionAction:action_]);
127 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
128 [controller populateMenu:menu];
129 EXPECT_GT([menu numberOfItems], 0);
131 // Close the empty browser. Can't just free it directly because there are
132 // dangling references in the various native controllers that must be
134 NSWindow* window = empty_browser->window()->GetNativeWindow();
135 BrowserWindowController* wc =
136 [BrowserWindowController browserWindowControllerForWindow:window];
137 ASSERT_TRUE(wc != NULL);
143 class DevToolsAttachedObserver {
145 DevToolsAttachedObserver(const base::Closure& callback)
146 : callback_(callback),
147 devtools_callback_(base::Bind(
148 &DevToolsAttachedObserver::OnDevToolsStateChanged,
149 base::Unretained(this))) {
150 content::DevToolsManager::GetInstance()->AddAgentStateCallback(
154 ~DevToolsAttachedObserver() {
155 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback(
159 void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached) {
165 base::Closure callback_;
166 base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
168 DISALLOW_COPY_AND_ASSIGN(DevToolsAttachedObserver);
173 IN_PROC_BROWSER_TEST_F(
174 ExtensionActionContextMenuControllerTest, DISABLED_RunInspectPopup) {
176 base::scoped_nsobject<ExtensionActionContextMenuController> controller(
177 [[ExtensionActionContextMenuController alloc] initWithExtension:extension_
179 extensionAction:action_]);
181 PrefService* service = browser()->profile()->GetPrefs();
182 bool original = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
184 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
186 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
187 [controller populateMenu:menu];
188 EXPECT_GT([menu numberOfItems], 0);
189 NSMenuItem* inspectItem = GetInspectItem(menu);
190 EXPECT_TRUE(inspectItem);
192 scoped_refptr<content::MessageLoopRunner> loop_runner(
193 new content::MessageLoopRunner);
194 DevToolsAttachedObserver observer(loop_runner->QuitClosure());
195 [NSApp sendAction:[inspectItem action]
196 to:[inspectItem target]
200 service->SetBoolean(prefs::kExtensionsUIDeveloperMode, original);