Home | History | Annotate | Download | only in extensions
      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/strings/utf_string_conversions.h"
      6 #include "chrome/browser/extensions/extension_action.h"
      7 #include "chrome/browser/extensions/extension_action_manager.h"
      8 #include "chrome/browser/extensions/extension_action_test_util.h"
      9 #include "chrome/browser/extensions/extension_browsertest.h"
     10 #include "chrome/browser/extensions/extension_service.h"
     11 #include "chrome/browser/extensions/extension_tab_util.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/browser_window.h"
     14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     15 #include "chrome/test/base/ui_test_utils.h"
     16 #include "extensions/browser/extension_system.h"
     17 #include "extensions/common/extension.h"
     18 #include "extensions/common/switches.h"
     19 
     20 namespace extensions {
     21 namespace {
     22 
     23 const std::string kFeedPage = "files/feeds/feed.html";
     24 const std::string kNoFeedPage = "files/feeds/no_feed.html";
     25 const std::string kLocalization =
     26     "files/extensions/browsertest/title_localized_pa/simple.html";
     27 
     28 const std::string kHashPageA =
     29     "files/extensions/api_test/page_action/hash_change/test_page_A.html";
     30 const std::string kHashPageAHash = kHashPageA + "#asdf";
     31 const std::string kHashPageB =
     32     "files/extensions/api_test/page_action/hash_change/test_page_B.html";
     33 
     34 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionCrash25562) {
     35   ASSERT_TRUE(test_server()->Start());
     36 
     37   CommandLine::ForCurrentProcess()->AppendSwitch(
     38       switches::kAllowLegacyExtensionManifests);
     39 
     40   // This page action will not show an icon, since it doesn't specify one but
     41   // is included here to test for a crash (http://crbug.com/25562).
     42   ASSERT_TRUE(LoadExtension(
     43       test_data_dir_.AppendASCII("browsertest")
     44                     .AppendASCII("crash_25562")));
     45 
     46   // Navigate to the feed page.
     47   GURL feed_url = test_server()->GetURL(kFeedPage);
     48   ui_test_utils::NavigateToURL(browser(), feed_url);
     49   // We should now have one page action ready to go in the LocationBar.
     50   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
     51 }
     52 
     53 // Tests that we can load page actions in the Omnibox.
     54 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageAction) {
     55   ASSERT_TRUE(test_server()->Start());
     56 
     57   ASSERT_TRUE(LoadExtension(
     58       test_data_dir_.AppendASCII("subscribe_page_action")));
     59 
     60   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
     61 
     62   // Navigate to the feed page.
     63   GURL feed_url = test_server()->GetURL(kFeedPage);
     64   ui_test_utils::NavigateToURL(browser(), feed_url);
     65   // We should now have one page action ready to go in the LocationBar.
     66   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
     67 
     68   // Navigate to a page with no feed.
     69   GURL no_feed = test_server()->GetURL(kNoFeedPage);
     70   ui_test_utils::NavigateToURL(browser(), no_feed);
     71   // Make sure the page action goes away.
     72   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
     73 }
     74 
     75 // Tests that we don't lose the page action icon on in-page navigations.
     76 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionInPageNavigation) {
     77   ASSERT_TRUE(test_server()->Start());
     78 
     79   base::FilePath extension_path(test_data_dir_.AppendASCII("api_test")
     80                                         .AppendASCII("page_action")
     81                                         .AppendASCII("hash_change"));
     82   ASSERT_TRUE(LoadExtension(extension_path));
     83 
     84   // Page action should become visible when we navigate here.
     85   GURL feed_url = test_server()->GetURL(kHashPageA);
     86   ui_test_utils::NavigateToURL(browser(), feed_url);
     87   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
     88 
     89   // In-page navigation, page action should remain.
     90   feed_url = test_server()->GetURL(kHashPageAHash);
     91   ui_test_utils::NavigateToURL(browser(), feed_url);
     92   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
     93 
     94   // Not an in-page navigation, page action should go away.
     95   feed_url = test_server()->GetURL(kHashPageB);
     96   ui_test_utils::NavigateToURL(browser(), feed_url);
     97   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
     98 }
     99 
    100 // Tests that the location bar forgets about unloaded page actions.
    101 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, UnloadPageAction) {
    102   ASSERT_TRUE(test_server()->Start());
    103 
    104   base::FilePath extension_path(
    105       test_data_dir_.AppendASCII("subscribe_page_action"));
    106   ASSERT_TRUE(LoadExtension(extension_path));
    107 
    108   // Navigation prompts the location bar to load page actions.
    109   GURL feed_url = test_server()->GetURL(kFeedPage);
    110   ui_test_utils::NavigateToURL(browser(), feed_url);
    111   content::WebContents* tab =
    112       browser()->tab_strip_model()->GetActiveWebContents();
    113   EXPECT_EQ(1u, extension_action_test_util::GetTotalPageActionCount(tab));
    114 
    115   UnloadExtension(last_loaded_extension_id());
    116 
    117   // Make sure the page action goes away when it's unloaded.
    118   EXPECT_EQ(0u, extension_action_test_util::GetTotalPageActionCount(tab));
    119 }
    120 
    121 // Tests that we can load page actions in the Omnibox.
    122 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionRefreshCrash) {
    123   base::TimeTicks start_time = base::TimeTicks::Now();
    124 
    125   ExtensionService* service = extensions::ExtensionSystem::Get(
    126       browser()->profile())->extension_service();
    127 
    128   size_t size_before = service->extensions()->size();
    129 
    130   base::FilePath base_path = test_data_dir_.AppendASCII("browsertest")
    131                                      .AppendASCII("crash_44415");
    132   // Load extension A.
    133   const Extension* extensionA = LoadExtension(base_path.AppendASCII("ExtA"));
    134   ASSERT_TRUE(extensionA);
    135   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
    136   ASSERT_EQ(size_before + 1, service->extensions()->size());
    137 
    138   LOG(INFO) << "Load extension A done  : "
    139             << (base::TimeTicks::Now() - start_time).InMilliseconds()
    140             << " ms" << std::flush;
    141 
    142   // Load extension B.
    143   const Extension* extensionB = LoadExtension(base_path.AppendASCII("ExtB"));
    144   ASSERT_TRUE(extensionB);
    145   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(2));
    146   ASSERT_EQ(size_before + 2, service->extensions()->size());
    147 
    148   LOG(INFO) << "Load extension B done  : "
    149             << (base::TimeTicks::Now() - start_time).InMilliseconds()
    150             << " ms" << std::flush;
    151 
    152   std::string idA = extensionA->id();
    153   ReloadExtension(extensionA->id());
    154   // ExtensionA has changed, so refetch it.
    155   ASSERT_EQ(size_before + 2, service->extensions()->size());
    156   extensionA = service->extensions()->GetByID(idA);
    157 
    158   LOG(INFO) << "Reload extension A done: "
    159             << (base::TimeTicks::Now() - start_time).InMilliseconds()
    160             << " ms" << std::flush;
    161 
    162   ReloadExtension(extensionB->id());
    163 
    164   LOG(INFO) << "Reload extension B done: "
    165             << (base::TimeTicks::Now() - start_time).InMilliseconds()
    166             << " ms" << std::flush;
    167 
    168   // This is where it would crash, before http://crbug.com/44415 was fixed.
    169   ReloadExtension(extensionA->id());
    170 
    171   LOG(INFO) << "Test completed         : "
    172             << (base::TimeTicks::Now() - start_time).InMilliseconds()
    173             << " ms" << std::flush;
    174 }
    175 
    176 // Tests that tooltips of a page action icon can be specified using UTF8.
    177 // See http://crbug.com/25349.
    178 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationPageAction) {
    179   ASSERT_TRUE(test_server()->Start());
    180 
    181   ExtensionService* service = extensions::ExtensionSystem::Get(
    182       browser()->profile())->extension_service();
    183   const size_t size_before = service->extensions()->size();
    184 
    185   base::FilePath extension_path(test_data_dir_.AppendASCII("browsertest")
    186                                         .AppendASCII("title_localized_pa"));
    187   const Extension* extension = LoadExtension(extension_path);
    188   ASSERT_TRUE(extension);
    189 
    190   // Any navigation prompts the location bar to load the page action.
    191   GURL url = test_server()->GetURL(kLocalization);
    192   ui_test_utils::NavigateToURL(browser(), url);
    193   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
    194 
    195   ASSERT_EQ(size_before + 1, service->extensions()->size());
    196 
    197   EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur: l10n page action").c_str(),
    198                extension->description().c_str());
    199   EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(),
    200                extension->name().c_str());
    201   int tab_id = ExtensionTabUtil::GetTabId(
    202       browser()->tab_strip_model()->GetActiveWebContents());
    203   EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur").c_str(),
    204                ExtensionActionManager::Get(browser()->profile())->
    205                GetPageAction(*extension)->
    206                GetTitle(tab_id).c_str());
    207 }
    208 
    209 }  // namespace
    210 }  // namespace extensions
    211