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 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
9 #include "chrome/browser/extensions/browser_action_test_util.h"
10 #include "chrome/browser/extensions/extension_browsertest.h"
11 #include "chrome/browser/extensions/extension_toolbar_model.h"
12 #include "chrome/browser/ui/browser_window.h"
13 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
14 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
15 #include "content/public/test/test_utils.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/common/extension.h"
18 #include "ui/gfx/geometry/point.h"
19 #include "ui/views/view.h"
21 class BrowserActionsContainerTest
: public ExtensionBrowserTest
{
23 BrowserActionsContainerTest() {
25 virtual ~BrowserActionsContainerTest() {}
27 virtual void SetUpOnMainThread() OVERRIDE
{
28 browser_actions_bar_
.reset(new BrowserActionTestUtil(browser()));
31 BrowserActionTestUtil
* browser_actions_bar() {
32 return browser_actions_bar_
.get();
35 // Make sure extension with index |extension_index| has an icon.
36 void EnsureExtensionHasIcon(int extension_index
) {
37 if (!browser_actions_bar_
->HasIcon(extension_index
)) {
38 // The icon is loaded asynchronously and a notification is then sent to
39 // observers. So we wait on it.
40 ExtensionAction
* browser_action
=
41 browser_actions_bar_
->GetExtensionAction(extension_index
);
43 content::WindowedNotificationObserver
observer(
44 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED
,
45 content::Source
<ExtensionAction
>(browser_action
));
48 EXPECT_TRUE(browser_actions_bar()->HasIcon(extension_index
));
52 scoped_ptr
<BrowserActionTestUtil
> browser_actions_bar_
;
55 // Test the basic functionality.
56 // http://crbug.com/120770
58 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest
, DISABLED_Basic
) {
60 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest
, Basic
) {
62 BrowserActionsContainer::disable_animations_during_testing_
= true;
64 // Load an extension with no browser action.
65 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
66 .AppendASCII("browser_action")
67 .AppendASCII("none")));
68 // This extension should not be in the model (has no browser action).
69 EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());
71 // Load an extension with a browser action.
72 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
73 .AppendASCII("browser_action")
74 .AppendASCII("basics")));
75 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
76 EnsureExtensionHasIcon(0);
78 // Unload the extension.
79 std::string id
= browser_actions_bar()->GetExtensionId(0);
81 EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());
84 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest
, Visibility
) {
85 BrowserActionsContainer::disable_animations_during_testing_
= true;
87 // Load extension A (contains browser action).
88 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
89 .AppendASCII("browser_action")
90 .AppendASCII("basics")));
91 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
92 EnsureExtensionHasIcon(0);
93 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
94 std::string idA
= browser_actions_bar()->GetExtensionId(0);
96 // Load extension B (contains browser action).
97 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
98 .AppendASCII("browser_action")
99 .AppendASCII("add_popup")));
100 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
101 EnsureExtensionHasIcon(0);
102 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
103 std::string idB
= browser_actions_bar()->GetExtensionId(1);
107 // Load extension C (contains browser action).
108 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
109 .AppendASCII("browser_action")
110 .AppendASCII("remove_popup")));
111 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
112 EnsureExtensionHasIcon(2);
113 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
114 std::string idC
= browser_actions_bar()->GetExtensionId(2);
116 // Change container to show only one action, rest in overflow: A, [B, C].
117 browser_actions_bar()->SetIconVisibilityCount(1);
118 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
120 // Disable extension A (should disappear). State becomes: B [C].
121 DisableExtension(idA
);
122 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
123 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
124 EXPECT_EQ(idB
, browser_actions_bar()->GetExtensionId(0));
126 // Enable A again. A should get its spot in the same location and the bar
127 // should not grow (chevron is showing). For details: http://crbug.com/35349.
128 // State becomes: A, [B, C].
129 EnableExtension(idA
);
130 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
131 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
132 EXPECT_EQ(idA
, browser_actions_bar()->GetExtensionId(0));
134 // Disable C (in overflow). State becomes: A, [B].
135 DisableExtension(idC
);
136 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
137 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
138 EXPECT_EQ(idA
, browser_actions_bar()->GetExtensionId(0));
140 // Enable C again. State becomes: A, [B, C].
141 EnableExtension(idC
);
142 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
143 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
144 EXPECT_EQ(idA
, browser_actions_bar()->GetExtensionId(0));
146 // Now we have 3 extensions. Make sure they are all visible. State: A, B, C.
147 browser_actions_bar()->SetIconVisibilityCount(3);
148 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
150 // Disable extension A (should disappear). State becomes: B, C.
151 DisableExtension(idA
);
152 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
153 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
154 EXPECT_EQ(idB
, browser_actions_bar()->GetExtensionId(0));
156 // Disable extension B (should disappear). State becomes: C.
157 DisableExtension(idB
);
158 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
159 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
160 EXPECT_EQ(idC
, browser_actions_bar()->GetExtensionId(0));
162 // Enable B. State becomes: B, C.
163 EnableExtension(idB
);
164 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
165 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
166 EXPECT_EQ(idB
, browser_actions_bar()->GetExtensionId(0));
168 // Enable A. State becomes: A, B, C.
169 EnableExtension(idA
);
170 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
171 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
172 EXPECT_EQ(idA
, browser_actions_bar()->GetExtensionId(0));
175 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest
, ForceHide
) {
176 BrowserActionsContainer::disable_animations_during_testing_
= true;
178 // Load extension A (contains browser action).
179 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
180 .AppendASCII("browser_action")
181 .AppendASCII("basics")));
182 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
183 EnsureExtensionHasIcon(0);
184 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
185 std::string idA
= browser_actions_bar()->GetExtensionId(0);
187 // Force hide this browser action.
188 extensions::ExtensionActionAPI::SetBrowserActionVisibility(
189 extensions::ExtensionPrefs::Get(browser()->profile()), idA
, false);
190 EXPECT_EQ(0, browser_actions_bar()->VisibleBrowserActions());
193 // Test that the BrowserActionsContainer responds correctly when the underlying
194 // model enters highlight mode, and that browser actions are undraggable in
195 // highlight mode. (Highlight mode itself it tested more thoroughly in the
196 // ExtensionToolbarModel browsertests).
197 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest
, HighlightMode
) {
198 BrowserActionsContainer::disable_animations_during_testing_
= true;
200 // Load three extensions with browser actions.
201 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
202 .AppendASCII("browser_action")
203 .AppendASCII("basics")));
204 std::string id_a
= browser_actions_bar()->GetExtensionId(0);
205 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
206 .AppendASCII("browser_action")
207 .AppendASCII("add_popup")));
208 std::string id_b
= browser_actions_bar()->GetExtensionId(1);
209 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("api_test")
210 .AppendASCII("browser_action")
211 .AppendASCII("remove_popup")));
213 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
214 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
216 BrowserActionsContainer
* container
= browser()
218 ->GetBrowserWindowTesting()
222 // Currently, dragging should be enabled.
223 BrowserActionView
* action_view
= container
->GetBrowserActionViewAt(0);
224 ASSERT_TRUE(action_view
);
225 gfx::Point
point(action_view
->x(), action_view
->y());
226 EXPECT_TRUE(container
->CanStartDragForView(action_view
, point
, point
));
228 extensions::ExtensionToolbarModel
* model
=
229 extensions::ExtensionToolbarModel::Get(profile());
231 extensions::ExtensionIdList extension_ids
;
232 extension_ids
.push_back(id_a
);
233 extension_ids
.push_back(id_b
);
234 model
->HighlightExtensions(extension_ids
);
236 // Only two browser actions should be visible.
237 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
238 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
240 // We shouldn't be able to drag in highlight mode.
241 action_view
= container
->GetBrowserActionViewAt(0);
242 EXPECT_FALSE(container
->CanStartDragForView(action_view
, point
, point
));
244 // We should go back to normal after leaving highlight mode.
245 model
->StopHighlighting();
246 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
247 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
248 action_view
= container
->GetBrowserActionViewAt(0);
249 EXPECT_TRUE(container
->CanStartDragForView(action_view
, point
, point
));