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