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 20namespace extensions { 21namespace { 22 23const std::string kFeedPage = "files/feeds/feed.html"; 24const std::string kNoFeedPage = "files/feeds/no_feed.html"; 25const std::string kLocalization = 26 "files/extensions/browsertest/title_localized_pa/simple.html"; 27 28const std::string kHashPageA = 29 "files/extensions/api_test/page_action/hash_change/test_page_A.html"; 30const std::string kHashPageAHash = kHashPageA + "#asdf"; 31const std::string kHashPageB = 32 "files/extensions/api_test/page_action/hash_change/test_page_B.html"; 33 34IN_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. 54IN_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. 76IN_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. 101IN_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. 122IN_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. 178IN_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