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