Home | History | Annotate | Download | only in extension_action
      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/extensions/api/extension_action/extension_action_api.h"
      6 #include "chrome/browser/extensions/extension_action.h"
      7 #include "chrome/browser/extensions/extension_action_icon_factory.h"
      8 #include "chrome/browser/extensions/extension_action_manager.h"
      9 #include "chrome/browser/extensions/extension_apitest.h"
     10 #include "chrome/browser/extensions/extension_service.h"
     11 #include "chrome/browser/extensions/extension_tab_util.h"
     12 #include "chrome/browser/profiles/profile.h"
     13 #include "chrome/browser/sessions/session_tab_helper.h"
     14 #include "chrome/browser/ui/browser.h"
     15 #include "chrome/browser/ui/browser_commands.h"
     16 #include "chrome/browser/ui/browser_window.h"
     17 #include "chrome/browser/ui/omnibox/location_bar.h"
     18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     19 #include "chrome/test/base/ui_test_utils.h"
     20 #include "content/public/browser/web_contents.h"
     21 #include "content/public/test/browser_test_utils.h"
     22 #include "extensions/browser/extension_system.h"
     23 #include "extensions/common/extension.h"
     24 
     25 using content::WebContents;
     26 
     27 namespace extensions {
     28 namespace {
     29 
     30 class PageActionApiTest : public ExtensionApiTest {
     31  protected:
     32   ExtensionAction* GetPageAction(const Extension& extension) {
     33     return ExtensionActionManager::Get(browser()->profile())->
     34         GetPageAction(extension);
     35   }
     36 };
     37 
     38 IN_PROC_BROWSER_TEST_F(PageActionApiTest, Basic) {
     39   ASSERT_TRUE(test_server()->Start());
     40   ASSERT_TRUE(RunExtensionTest("page_action/basics")) << message_;
     41   const Extension* extension = GetSingleLoadedExtension();
     42   ASSERT_TRUE(extension) << message_;
     43   {
     44     // Tell the extension to update the page action state.
     45     ResultCatcher catcher;
     46     ui_test_utils::NavigateToURL(browser(),
     47         GURL(extension->GetResourceURL("update.html")));
     48     ASSERT_TRUE(catcher.GetNextResult());
     49   }
     50 
     51   // Test that we received the changes.
     52   int tab_id = SessionTabHelper::FromWebContents(
     53       browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
     54   ExtensionAction* action = GetPageAction(*extension);
     55   ASSERT_TRUE(action);
     56   EXPECT_EQ("Modified", action->GetTitle(tab_id));
     57 
     58   {
     59     // Simulate the page action being clicked.
     60     ResultCatcher catcher;
     61     int tab_id = ExtensionTabUtil::GetTabId(
     62         browser()->tab_strip_model()->GetActiveWebContents());
     63     ExtensionActionAPI::PageActionExecuted(
     64         browser()->profile(), *action, tab_id, std::string(), 0);
     65     EXPECT_TRUE(catcher.GetNextResult());
     66   }
     67 
     68   {
     69     // Tell the extension to update the page action state again.
     70     ResultCatcher catcher;
     71     ui_test_utils::NavigateToURL(browser(),
     72         GURL(extension->GetResourceURL("update2.html")));
     73     ASSERT_TRUE(catcher.GetNextResult());
     74   }
     75 
     76   // We should not be creating icons asynchronously, so we don't need an
     77   // observer.
     78   ExtensionActionIconFactory icon_factory(profile(), extension, action, NULL);
     79 
     80   // Test that we received the changes.
     81   tab_id = SessionTabHelper::FromWebContents(
     82       browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
     83   EXPECT_FALSE(icon_factory.GetIcon(tab_id).IsEmpty());
     84 }
     85 
     86 // Test that calling chrome.pageAction.setPopup() can enable a popup.
     87 IN_PROC_BROWSER_TEST_F(PageActionApiTest, AddPopup) {
     88   // Load the extension, which has no default popup.
     89   ASSERT_TRUE(RunExtensionTest("page_action/add_popup")) << message_;
     90   const Extension* extension = GetSingleLoadedExtension();
     91   ASSERT_TRUE(extension) << message_;
     92 
     93   int tab_id = ExtensionTabUtil::GetTabId(
     94       browser()->tab_strip_model()->GetActiveWebContents());
     95 
     96   ExtensionAction* page_action = GetPageAction(*extension);
     97   ASSERT_TRUE(page_action)
     98       << "Page action test extension should have a page action.";
     99 
    100   ASSERT_FALSE(page_action->HasPopup(tab_id));
    101 
    102   // Simulate the page action being clicked.  The resulting event should
    103   // install a page action popup.
    104   {
    105     ResultCatcher catcher;
    106     ExtensionActionAPI::PageActionExecuted(
    107         browser()->profile(), *page_action, tab_id, std::string(), 1);
    108     ASSERT_TRUE(catcher.GetNextResult());
    109   }
    110 
    111   ASSERT_TRUE(page_action->HasPopup(tab_id))
    112       << "Clicking on the page action should have caused a popup to be added.";
    113 
    114   ASSERT_STREQ("/a_popup.html",
    115                page_action->GetPopupUrl(tab_id).path().c_str());
    116 
    117   // Now change the popup from a_popup.html to a_second_popup.html .
    118   // Load a page which removes the popup using chrome.pageAction.setPopup().
    119   {
    120     ResultCatcher catcher;
    121     ui_test_utils::NavigateToURL(
    122         browser(),
    123         GURL(extension->GetResourceURL("change_popup.html")));
    124     ASSERT_TRUE(catcher.GetNextResult());
    125   }
    126 
    127   ASSERT_TRUE(page_action->HasPopup(tab_id));
    128   ASSERT_STREQ("/another_popup.html",
    129                page_action->GetPopupUrl(tab_id).path().c_str());
    130 }
    131 
    132 // Test that calling chrome.pageAction.setPopup() can remove a popup.
    133 IN_PROC_BROWSER_TEST_F(PageActionApiTest, RemovePopup) {
    134   // Load the extension, which has a page action with a default popup.
    135   ASSERT_TRUE(RunExtensionTest("page_action/remove_popup")) << message_;
    136   const Extension* extension = GetSingleLoadedExtension();
    137   ASSERT_TRUE(extension) << message_;
    138 
    139   int tab_id = ExtensionTabUtil::GetTabId(
    140       browser()->tab_strip_model()->GetActiveWebContents());
    141 
    142   ExtensionAction* page_action = GetPageAction(*extension);
    143   ASSERT_TRUE(page_action)
    144       << "Page action test extension should have a page action.";
    145 
    146   ASSERT_TRUE(page_action->HasPopup(tab_id))
    147       << "Expect a page action popup before the test removes it.";
    148 
    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("remove_popup.html")));
    155     ASSERT_TRUE(catcher.GetNextResult());
    156   }
    157 
    158   ASSERT_FALSE(page_action->HasPopup(tab_id))
    159       << "Page action popup should have been removed.";
    160 }
    161 
    162 // Tests old-style pageActions API that is deprecated but we don't want to
    163 // break.
    164 IN_PROC_BROWSER_TEST_F(PageActionApiTest, OldPageActions) {
    165   ASSERT_TRUE(RunExtensionTestAllowOldManifestVersion("page_action/old_api")) <<
    166       message_;
    167   const Extension* extension = GetSingleLoadedExtension();
    168   ASSERT_TRUE(extension) << message_;
    169 
    170   // Have the extension enable the page action.
    171   {
    172     ResultCatcher catcher;
    173     ui_test_utils::NavigateToURL(browser(),
    174         GURL(extension->GetResourceURL("page.html")));
    175     ASSERT_TRUE(catcher.GetNextResult());
    176   }
    177 
    178   // Simulate the page action being clicked.
    179   {
    180     ResultCatcher catcher;
    181     int tab_id = ExtensionTabUtil::GetTabId(
    182         browser()->tab_strip_model()->GetActiveWebContents());
    183     ExtensionAction* page_action = GetPageAction(*extension);
    184     ExtensionActionAPI::PageActionExecuted(
    185         browser()->profile(), *page_action, tab_id, std::string(), 1);
    186     EXPECT_TRUE(catcher.GetNextResult());
    187   }
    188 }
    189 
    190 // Tests popups in page actions.
    191 // Flaky on the trybots. See http://crbug.com/96725.
    192 IN_PROC_BROWSER_TEST_F(PageActionApiTest, DISABLED_ShowPageActionPopup) {
    193   ASSERT_TRUE(RunExtensionTest("page_action/popup")) << message_;
    194   const Extension* extension = GetSingleLoadedExtension();
    195   ASSERT_TRUE(extension) << message_;
    196 
    197   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
    198 
    199   {
    200     ResultCatcher catcher;
    201     LocationBarTesting* location_bar =
    202         browser()->window()->GetLocationBar()->GetLocationBarForTesting();
    203     location_bar->TestPageActionPressed(0);
    204     ASSERT_TRUE(catcher.GetNextResult());
    205   }
    206 }
    207 
    208 // Test http://crbug.com/57333: that two page action extensions using the same
    209 // icon for the page action icon and the extension icon do not crash.
    210 IN_PROC_BROWSER_TEST_F(PageActionApiTest, TestCrash57333) {
    211   // Load extension A.
    212   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("page_action")
    213                                           .AppendASCII("crash_57333")
    214                                           .AppendASCII("Extension1")));
    215   // Load extension B.
    216   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("page_action")
    217                                           .AppendASCII("crash_57333")
    218                                           .AppendASCII("Extension2")));
    219 }
    220 
    221 IN_PROC_BROWSER_TEST_F(PageActionApiTest, Getters) {
    222   ASSERT_TRUE(RunExtensionTest("page_action/getters")) << message_;
    223   const Extension* extension = GetSingleLoadedExtension();
    224   ASSERT_TRUE(extension) << message_;
    225 
    226   ResultCatcher catcher;
    227   ui_test_utils::NavigateToURL(browser(),
    228       GURL(extension->GetResourceURL("update.html")));
    229   ASSERT_TRUE(catcher.GetNextResult());
    230 }
    231 
    232 // Verify triggering page action.
    233 IN_PROC_BROWSER_TEST_F(PageActionApiTest, TestTriggerPageAction) {
    234   ASSERT_TRUE(test_server()->Start());
    235 
    236   ASSERT_TRUE(RunExtensionTest("trigger_actions/page_action")) << message_;
    237   const Extension* extension = GetSingleLoadedExtension();
    238   ASSERT_TRUE(extension) << message_;
    239 
    240   // Page action icon is displayed when a tab is created.
    241   ui_test_utils::NavigateToURL(browser(),
    242                                test_server()->GetURL("files/simple.html"));
    243   chrome::NewTab(browser());
    244   browser()->tab_strip_model()->ActivateTabAt(0, true);
    245 
    246   ExtensionAction* page_action = GetPageAction(*extension);
    247   ASSERT_TRUE(page_action);
    248 
    249   {
    250     // Simulate the page action being clicked.
    251     ResultCatcher catcher;
    252     int tab_id = ExtensionTabUtil::GetTabId(
    253         browser()->tab_strip_model()->GetActiveWebContents());
    254     ExtensionActionAPI::PageActionExecuted(
    255         browser()->profile(), *page_action, tab_id, std::string(), 0);
    256     EXPECT_TRUE(catcher.GetNextResult());
    257   }
    258 
    259   WebContents* tab =
    260       browser()->tab_strip_model()->GetActiveWebContents();
    261   EXPECT_TRUE(tab != NULL);
    262 
    263   // Verify that the browser action turned the background color red.
    264   const std::string script =
    265       "window.domAutomationController.send(document.body.style."
    266       "backgroundColor);";
    267   std::string result;
    268   EXPECT_TRUE(content::ExecuteScriptAndExtractString(tab, script, &result));
    269   EXPECT_EQ(result, "red");
    270 }
    271 
    272 }  // namespace
    273 }  // namespace extensions
    274