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