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 "base/command_line.h" 6 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 7 #include "chrome/browser/extensions/browser_action_test_util.h" 8 #include "chrome/browser/extensions/extension_action.h" 9 #include "chrome/browser/extensions/extension_action_icon_factory.h" 10 #include "chrome/browser/extensions/extension_action_manager.h" 11 #include "chrome/browser/extensions/extension_apitest.h" 12 #include "chrome/browser/extensions/extension_prefs.h" 13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_system.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/browser_window.h" 19 #include "chrome/browser/ui/omnibox/location_bar.h" 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" 21 #include "chrome/common/chrome_switches.h" 22 #include "chrome/common/extensions/extension.h" 23 #include "chrome/test/base/ui_test_utils.h" 24 #include "content/public/browser/web_contents.h" 25 26 // These are a mash-up of the tests from from page_actions_apitest.cc and 27 // browser_actions_apitest.cc. 28 29 namespace extensions { 30 namespace { 31 32 class PageAsBrowserActionApiTest : public ExtensionApiTest { 33 public: 34 PageAsBrowserActionApiTest() {} 35 virtual ~PageAsBrowserActionApiTest() {} 36 37 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 38 ExtensionApiTest::SetUpCommandLine(command_line); 39 command_line->AppendSwitchASCII(switches::kScriptBadges, "1"); 40 } 41 42 protected: 43 BrowserActionTestUtil GetBrowserActionsBar() { 44 return BrowserActionTestUtil(browser()); 45 } 46 47 ExtensionActionManager* extension_action_manager() { 48 return ExtensionActionManager::Get(browser()->profile()); 49 } 50 }; 51 52 IN_PROC_BROWSER_TEST_F(PageAsBrowserActionApiTest, Basic) { 53 ASSERT_TRUE(test_server()->Start()); 54 ASSERT_TRUE(RunExtensionTest("page_action/basics")) << message_; 55 const Extension* extension = GetSingleLoadedExtension(); 56 ASSERT_TRUE(extension) << message_; 57 58 // The extension declares a page action, but it should have gotten a browser 59 // action instead. 60 ASSERT_TRUE(extension_action_manager()->GetBrowserAction(*extension)); 61 ASSERT_FALSE(extension_action_manager()->GetPageAction(*extension)); 62 63 // With the "action box" there won't be browser actions unless they're pinned. 64 ExtensionActionAPI::SetBrowserActionVisibility( 65 extensions::ExtensionSystem::Get(browser()->profile())-> 66 extension_service()->extension_prefs(), 67 extension->id(), 68 true); 69 70 // Test that there is a browser action in the toolbar. 71 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions()); 72 73 { 74 // Tell the extension to update the page action state. 75 ResultCatcher catcher; 76 ui_test_utils::NavigateToURL(browser(), 77 GURL(extension->GetResourceURL("update.html"))); 78 ASSERT_TRUE(catcher.GetNextResult()); 79 } 80 81 // Test that we received the changes. 82 int tab_id = ExtensionTabUtil::GetTabId( 83 browser()->tab_strip_model()->GetActiveWebContents()); 84 ExtensionAction* action = 85 extension_action_manager()->GetBrowserAction(*extension); 86 ASSERT_TRUE(action); 87 EXPECT_EQ("Modified", action->GetTitle(tab_id)); 88 89 { 90 // Simulate the page action being clicked. 91 ResultCatcher catcher; 92 ExtensionService* service = extensions::ExtensionSystem::Get( 93 browser()->profile())->extension_service(); 94 service->toolbar_model()->ExecuteBrowserAction(extension, browser(), NULL); 95 EXPECT_TRUE(catcher.GetNextResult()); 96 } 97 98 { 99 // Tell the extension to update the page action state again. 100 ResultCatcher catcher; 101 ui_test_utils::NavigateToURL(browser(), 102 GURL(extension->GetResourceURL("update2.html"))); 103 ASSERT_TRUE(catcher.GetNextResult()); 104 } 105 106 // We should not be creating icons asynchronously, so we don't need an 107 // observer. 108 ExtensionActionIconFactory icon_factory( 109 profile(), extension, action, NULL); 110 111 // Test that we received the changes. 112 EXPECT_FALSE(icon_factory.GetIcon(tab_id).IsEmpty()); 113 } 114 115 // Test that calling chrome.pageAction.setPopup() can enable a popup. 116 IN_PROC_BROWSER_TEST_F(PageAsBrowserActionApiTest, AddPopup) { 117 // Load the extension, which has no default popup. 118 ASSERT_TRUE(RunExtensionTest("page_action/add_popup")) << message_; 119 const Extension* extension = GetSingleLoadedExtension(); 120 ASSERT_TRUE(extension) << message_; 121 122 int tab_id = ExtensionTabUtil::GetTabId( 123 browser()->tab_strip_model()->GetActiveWebContents()); 124 125 ExtensionAction* page_action = 126 extension_action_manager()->GetBrowserAction(*extension); 127 ASSERT_TRUE(page_action) 128 << "Page action test extension should have a page action."; 129 130 ASSERT_FALSE(page_action->HasPopup(tab_id)); 131 132 // Simulate the page action being clicked. The resulting event should 133 // install a page action popup. 134 { 135 ResultCatcher catcher; 136 ExtensionService* service = extensions::ExtensionSystem::Get( 137 browser()->profile())->extension_service(); 138 service->toolbar_model()->ExecuteBrowserAction(extension, browser(), NULL); 139 ASSERT_TRUE(catcher.GetNextResult()); 140 } 141 142 ASSERT_TRUE(page_action->HasPopup(tab_id)) 143 << "Clicking on the page action should have caused a popup to be added."; 144 145 ASSERT_STREQ("/a_popup.html", 146 page_action->GetPopupUrl(tab_id).path().c_str()); 147 148 // Now change the popup from a_popup.html to a_second_popup.html . 149 // Load a page which removes the popup using chrome.pageAction.setPopup(). 150 { 151 ResultCatcher catcher; 152 ui_test_utils::NavigateToURL( 153 browser(), 154 GURL(extension->GetResourceURL("change_popup.html"))); 155 ASSERT_TRUE(catcher.GetNextResult()); 156 } 157 158 ASSERT_TRUE(page_action->HasPopup(tab_id)); 159 ASSERT_STREQ("/another_popup.html", 160 page_action->GetPopupUrl(tab_id).path().c_str()); 161 } 162 163 // Test that calling chrome.pageAction.setPopup() can remove a popup. 164 IN_PROC_BROWSER_TEST_F(PageAsBrowserActionApiTest, RemovePopup) { 165 // Load the extension, which has a page action with a default popup. 166 ASSERT_TRUE(RunExtensionTest("page_action/remove_popup")) << message_; 167 const Extension* extension = GetSingleLoadedExtension(); 168 ASSERT_TRUE(extension) << message_; 169 170 int tab_id = ExtensionTabUtil::GetTabId( 171 browser()->tab_strip_model()->GetActiveWebContents()); 172 173 ExtensionAction* page_action = 174 extension_action_manager()->GetBrowserAction(*extension); 175 ASSERT_TRUE(page_action) 176 << "Page action test extension should have a page action."; 177 178 ASSERT_TRUE(page_action->HasPopup(tab_id)) 179 << "Expect a page action popup before the test removes it."; 180 181 // Load a page which removes the popup using chrome.pageAction.setPopup(). 182 { 183 ResultCatcher catcher; 184 ui_test_utils::NavigateToURL( 185 browser(), 186 GURL(extension->GetResourceURL("remove_popup.html"))); 187 ASSERT_TRUE(catcher.GetNextResult()); 188 } 189 190 ASSERT_FALSE(page_action->HasPopup(tab_id)) 191 << "Page action popup should have been removed."; 192 } 193 194 IN_PROC_BROWSER_TEST_F(PageAsBrowserActionApiTest, Getters) { 195 ASSERT_TRUE(RunExtensionTest("page_action/getters")) << message_; 196 const Extension* extension = GetSingleLoadedExtension(); 197 ASSERT_TRUE(extension) << message_; 198 199 ResultCatcher catcher; 200 ui_test_utils::NavigateToURL(browser(), 201 GURL(extension->GetResourceURL("update.html"))); 202 ASSERT_TRUE(catcher.GetNextResult()); 203 } 204 205 } 206 } // namespace extensions 207