1 // Copyright (c) 2012 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/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_service.h" 12 #include "content/public/test/test_utils.h" 13 14 using extensions::Extension; 15 16 class BrowserActionsContainerTest : public ExtensionBrowserTest { 17 public: 18 BrowserActionsContainerTest() { 19 } 20 virtual ~BrowserActionsContainerTest() {} 21 22 virtual void SetUpOnMainThread() OVERRIDE { 23 browser_actions_bar_.reset(new BrowserActionTestUtil(browser())); 24 } 25 26 BrowserActionTestUtil* browser_actions_bar() { 27 return browser_actions_bar_.get(); 28 } 29 30 // Make sure extension with index |extension_index| has an icon. 31 void EnsureExtensionHasIcon(int extension_index) { 32 if (!browser_actions_bar_->HasIcon(extension_index)) { 33 // The icon is loaded asynchronously and a notification is then sent to 34 // observers. So we wait on it. 35 ExtensionAction* browser_action = 36 browser_actions_bar_->GetExtensionAction(extension_index); 37 38 content::WindowedNotificationObserver observer( 39 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, 40 content::Source<ExtensionAction>(browser_action)); 41 observer.Wait(); 42 } 43 EXPECT_TRUE(browser_actions_bar()->HasIcon(extension_index)); 44 } 45 46 private: 47 scoped_ptr<BrowserActionTestUtil> browser_actions_bar_; 48 }; 49 50 // Test the basic functionality. 51 // http://crbug.com/120770 52 #if defined(OS_WIN) 53 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, DISABLED_Basic) { 54 #else 55 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Basic) { 56 #endif 57 BrowserActionsContainer::disable_animations_during_testing_ = true; 58 59 // Load an extension with no browser action. 60 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 61 .AppendASCII("browser_action") 62 .AppendASCII("none"))); 63 // This extension should not be in the model (has no browser action). 64 EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions()); 65 66 // Load an extension with a browser action. 67 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 68 .AppendASCII("browser_action") 69 .AppendASCII("basics"))); 70 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); 71 EnsureExtensionHasIcon(0); 72 73 // Unload the extension. 74 std::string id = browser_actions_bar()->GetExtensionId(0); 75 UnloadExtension(id); 76 EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions()); 77 } 78 79 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Visibility) { 80 BrowserActionsContainer::disable_animations_during_testing_ = true; 81 82 // Load extension A (contains browser action). 83 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 84 .AppendASCII("browser_action") 85 .AppendASCII("basics"))); 86 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); 87 EnsureExtensionHasIcon(0); 88 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 89 std::string idA = browser_actions_bar()->GetExtensionId(0); 90 91 // Load extension B (contains browser action). 92 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 93 .AppendASCII("browser_action") 94 .AppendASCII("add_popup"))); 95 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); 96 EnsureExtensionHasIcon(0); 97 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); 98 std::string idB = browser_actions_bar()->GetExtensionId(1); 99 100 EXPECT_NE(idA, idB); 101 102 // Load extension C (contains browser action). 103 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 104 .AppendASCII("browser_action") 105 .AppendASCII("remove_popup"))); 106 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); 107 EnsureExtensionHasIcon(2); 108 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); 109 std::string idC = browser_actions_bar()->GetExtensionId(2); 110 111 // Change container to show only one action, rest in overflow: A, [B, C]. 112 browser_actions_bar()->SetIconVisibilityCount(1); 113 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 114 115 // Disable extension A (should disappear). State becomes: B [C]. 116 DisableExtension(idA); 117 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); 118 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 119 EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); 120 121 // Enable A again. A should get its spot in the same location and the bar 122 // should not grow (chevron is showing). For details: http://crbug.com/35349. 123 // State becomes: A, [B, C]. 124 EnableExtension(idA); 125 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); 126 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 127 EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); 128 129 // Disable C (in overflow). State becomes: A, [B]. 130 DisableExtension(idC); 131 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); 132 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 133 EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); 134 135 // Enable C again. State becomes: A, [B, C]. 136 EnableExtension(idC); 137 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); 138 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 139 EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); 140 141 // Now we have 3 extensions. Make sure they are all visible. State: A, B, C. 142 browser_actions_bar()->SetIconVisibilityCount(3); 143 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); 144 145 // Disable extension A (should disappear). State becomes: B, C. 146 DisableExtension(idA); 147 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); 148 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); 149 EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); 150 151 // Disable extension B (should disappear). State becomes: C. 152 DisableExtension(idB); 153 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); 154 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 155 EXPECT_EQ(idC, browser_actions_bar()->GetExtensionId(0)); 156 157 // Enable B. State becomes: B, C. 158 EnableExtension(idB); 159 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); 160 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions()); 161 EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0)); 162 163 // Enable A. State becomes: A, B, C. 164 EnableExtension(idA); 165 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); 166 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); 167 EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0)); 168 } 169 170 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, ForceHide) { 171 BrowserActionsContainer::disable_animations_during_testing_ = true; 172 173 // Load extension A (contains browser action). 174 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test") 175 .AppendASCII("browser_action") 176 .AppendASCII("basics"))); 177 EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions()); 178 EnsureExtensionHasIcon(0); 179 EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions()); 180 std::string idA = browser_actions_bar()->GetExtensionId(0); 181 182 // Force hide this browser action. 183 extensions::ExtensionActionAPI::SetBrowserActionVisibility( 184 extensions::ExtensionSystem::Get(browser()->profile())-> 185 extension_service()->extension_prefs(), 186 idA, 187 false); 188 EXPECT_EQ(0, browser_actions_bar()->VisibleBrowserActions()); 189 } 190