[email protected] | 863e647 | 2012-01-24 19:33:58 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 3f58d855 | 2009-08-14 23:59:37 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 5 | #include "chrome/browser/extensions/extension_browsertest.h" |
[email protected] | 81e6378 | 2009-02-27 19:35:09 | [diff] [blame] | 6 | |
[email protected] | 3f58d855 | 2009-08-14 23:59:37 | [diff] [blame] | 7 | #include <vector> |
| 8 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 9 | #include "base/command_line.h" |
| 10 | #include "base/file_path.h" |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 11 | #include "base/file_util.h" |
[email protected] | ea1a3f6 | 2012-11-16 20:34:23 | [diff] [blame] | 12 | #include "base/files/scoped_temp_dir.h" |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 13 | #include "base/path_service.h" |
[email protected] | 528c56d | 2010-07-30 19:28:44 | [diff] [blame] | 14 | #include "base/string_number_conversions.h" |
[email protected] | 3d43eef | 2012-10-09 23:17:56 | [diff] [blame] | 15 | #include "base/stringprintf.h" |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 16 | #include "base/utf_string_conversions.h" |
[email protected] | 178f851 | 2012-02-09 01:49:36 | [diff] [blame] | 17 | #include "chrome/browser/extensions/app_shortcut_manager.h" |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 18 | #include "chrome/browser/extensions/component_loader.h" |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 19 | #include "chrome/browser/extensions/crx_installer.h" |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 20 | #include "chrome/browser/extensions/extension_creator.h" |
[email protected] | 14a000d | 2010-04-29 21:44:24 | [diff] [blame] | 21 | #include "chrome/browser/extensions/extension_error_reporter.h" |
[email protected] | fad7367 | 2012-06-15 23:26:06 | [diff] [blame] | 22 | #include "chrome/browser/extensions/extension_host.h" |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 23 | #include "chrome/browser/extensions/extension_install_prompt.h" |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 24 | #include "chrome/browser/extensions/extension_service.h" |
[email protected] | be93bba0 | 2012-10-24 16:44:03 | [diff] [blame] | 25 | #include "chrome/browser/extensions/extension_system.h" |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 26 | #include "chrome/browser/extensions/unpacked_installer.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 27 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 7b5dc00 | 2010-11-16 23:08:10 | [diff] [blame] | 28 | #include "chrome/browser/ui/browser.h" |
[email protected] | 00070c73 | 2011-04-09 15:31:33 | [diff] [blame] | 29 | #include "chrome/browser/ui/browser_window.h" |
[email protected] | 1b1989f5 | 2012-12-03 08:33:54 | [diff] [blame] | 30 | #include "chrome/browser/ui/extensions/native_app_window.h" |
[email protected] | 99bfb204 | 2012-12-01 07:16:45 | [diff] [blame] | 31 | #include "chrome/browser/ui/extensions/shell_window.h" |
[email protected] | 6a3ec231 | 2010-12-02 19:30:19 | [diff] [blame] | 32 | #include "chrome/browser/ui/omnibox/location_bar.h" |
[email protected] | 91e51d61 | 2012-10-21 23:03:05 | [diff] [blame] | 33 | #include "chrome/browser/ui/tabs/tab_strip_model.h" |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 34 | #include "chrome/common/chrome_notification_types.h" |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 35 | #include "chrome/common/chrome_paths.h" |
[email protected] | 7b5dc00 | 2010-11-16 23:08:10 | [diff] [blame] | 36 | #include "chrome/common/chrome_switches.h" |
[email protected] | d69d7b17 | 2012-08-09 04:17:26 | [diff] [blame] | 37 | #include "chrome/common/chrome_version_info.h" |
[email protected] | af44e7fb | 2011-07-29 18:32:32 | [diff] [blame] | 38 | #include "chrome/test/base/ui_test_utils.h" |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 39 | #include "content/public/browser/navigation_controller.h" |
| 40 | #include "content/public/browser/navigation_entry.h" |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 41 | #include "content/public/browser/notification_registrar.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 42 | #include "content/public/browser/notification_service.h" |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 43 | #include "content/public/browser/render_view_host.h" |
[email protected] | 7d478cb | 2012-07-24 17:19:42 | [diff] [blame] | 44 | #include "content/public/test/browser_test_utils.h" |
[email protected] | 36b64321 | 2012-09-07 12:53:00 | [diff] [blame] | 45 | #include "sync/api/string_ordinal.h" |
[email protected] | 81e6378 | 2009-02-27 19:35:09 | [diff] [blame] | 46 | |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 47 | using extensions::Extension; |
[email protected] | 6d77749 | 2012-07-11 17:33:43 | [diff] [blame] | 48 | using extensions::ExtensionCreator; |
[email protected] | 00b5d0a5 | 2012-10-30 13:13:53 | [diff] [blame] | 49 | using extensions::FeatureSwitch; |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 50 | |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 51 | ExtensionBrowserTest::ExtensionBrowserTest() |
[email protected] | 9931fbfc | 2010-07-23 09:15:51 | [diff] [blame] | 52 | : loaded_(false), |
| 53 | installed_(false), |
| 54 | extension_installs_observed_(0), |
[email protected] | bbcde910 | 2012-03-25 22:40:49 | [diff] [blame] | 55 | extension_load_errors_observed_(0), |
[email protected] | 9931fbfc | 2010-07-23 09:15:51 | [diff] [blame] | 56 | target_page_action_count_(-1), |
[email protected] | 2b5fdc3 | 2012-08-14 03:55:43 | [diff] [blame] | 57 | target_visible_page_action_count_(-1), |
[email protected] | 612a1cb1 | 2012-10-17 13:18:03 | [diff] [blame] | 58 | current_channel_(chrome::VersionInfo::CHANNEL_DEV), |
| 59 | override_prompt_for_external_extensions_( |
[email protected] | 00b5d0a5 | 2012-10-30 13:13:53 | [diff] [blame] | 60 | FeatureSwitch::prompt_for_external_extensions(), false), |
| 61 | override_sideload_wipeout_( |
| 62 | FeatureSwitch::sideload_wipeout(), false) { |
[email protected] | 3a305db | 2011-04-12 13:40:53 | [diff] [blame] | 63 | EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); |
[email protected] | 178f851 | 2012-02-09 01:49:36 | [diff] [blame] | 64 | } |
| 65 | |
[email protected] | e66ba95 | 2012-10-09 09:59:44 | [diff] [blame] | 66 | ExtensionBrowserTest::~ExtensionBrowserTest() {} |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 67 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 68 | void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) { |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 69 | PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); |
| 70 | test_data_dir_ = test_data_dir_.AppendASCII("extensions"); |
[email protected] | 856c8d7 | 2009-11-24 16:33:12 | [diff] [blame] | 71 | |
[email protected] | 1172ba7 | 2010-05-21 22:21:11 | [diff] [blame] | 72 | #if defined(OS_CHROMEOS) |
| 73 | // This makes sure that we create the Default profile first, with no |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 74 | // ExtensionService and then the real profile with one, as we do when |
[email protected] | 1172ba7 | 2010-05-21 22:21:11 | [diff] [blame] | 75 | // running on chromeos. |
[email protected] | 05076ba2 | 2010-07-30 05:59:57 | [diff] [blame] | 76 | command_line->AppendSwitchASCII(switches::kLoginUser, |
| 77 | "[email protected]"); |
| 78 | command_line->AppendSwitchASCII(switches::kLoginProfile, "user"); |
[email protected] | 1172ba7 | 2010-05-21 22:21:11 | [diff] [blame] | 79 | #endif |
[email protected] | 81e6378 | 2009-02-27 19:35:09 | [diff] [blame] | 80 | } |
[email protected] | 653c9ea | 2009-05-06 16:58:56 | [diff] [blame] | 81 | |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 82 | const Extension* ExtensionBrowserTest::LoadExtensionWithFlags( |
| 83 | const FilePath& path, int flags) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 84 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 85 | browser()->profile())->extension_service(); |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 86 | { |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 87 | content::NotificationRegistrar registrar; |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 88 | registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 89 | content::NotificationService::AllSources()); |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 90 | scoped_refptr<extensions::UnpackedInstaller> installer( |
| 91 | extensions::UnpackedInstaller::Create(service)); |
| 92 | installer->set_prompt_for_plugins(false); |
[email protected] | b7462f3 | 2012-09-02 15:18:12 | [diff] [blame] | 93 | installer->set_require_modern_manifest_version( |
| 94 | (flags & kFlagAllowOldManifestVersions) == 0); |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 95 | installer->Load(path); |
[email protected] | 729eb63 | 2012-07-26 04:45:26 | [diff] [blame] | 96 | content::RunMessageLoop(); |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 97 | } |
[email protected] | 19f358e | 2010-10-28 20:22:50 | [diff] [blame] | 98 | |
[email protected] | 84df833 | 2011-12-06 18:22:46 | [diff] [blame] | 99 | // Find the loaded extension by its path. See crbug.com/59531 for why |
| 100 | // we cannot just use last_loaded_extension_id_. |
[email protected] | 19f358e | 2010-10-28 20:22:50 | [diff] [blame] | 101 | FilePath extension_path = path; |
| 102 | file_util::AbsolutePath(&extension_path); |
[email protected] | 9adb969 | 2010-10-29 23:14:02 | [diff] [blame] | 103 | const Extension* extension = NULL; |
[email protected] | 84df833 | 2011-12-06 18:22:46 | [diff] [blame] | 104 | for (ExtensionSet::const_iterator iter = service->extensions()->begin(); |
| 105 | iter != service->extensions()->end(); ++iter) { |
[email protected] | 19f358e | 2010-10-28 20:22:50 | [diff] [blame] | 106 | if ((*iter)->path() == extension_path) { |
| 107 | extension = *iter; |
| 108 | break; |
| 109 | } |
| 110 | } |
| 111 | if (!extension) |
[email protected] | a964e11 | 2011-04-14 21:52:51 | [diff] [blame] | 112 | return NULL; |
[email protected] | 653c9ea | 2009-05-06 16:58:56 | [diff] [blame] | 113 | |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 114 | if (!(flags & kFlagIgnoreManifestWarnings)) { |
| 115 | const Extension::InstallWarningVector& install_warnings = |
| 116 | extension->install_warnings(); |
| 117 | if (!install_warnings.empty()) { |
| 118 | std::string install_warnings_message = StringPrintf( |
| 119 | "Unexpected warnings when loading test extension %s:\n", |
| 120 | path.AsUTF8Unsafe().c_str()); |
| 121 | |
| 122 | for (Extension::InstallWarningVector::const_iterator it = |
| 123 | install_warnings.begin(); it != install_warnings.end(); ++it) { |
| 124 | install_warnings_message += " " + it->message + "\n"; |
| 125 | } |
| 126 | |
| 127 | EXPECT_TRUE(extension->install_warnings().empty()) << |
| 128 | install_warnings_message; |
| 129 | return NULL; |
| 130 | } |
| 131 | } |
| 132 | |
[email protected] | d10f460 | 2011-06-16 15:44:50 | [diff] [blame] | 133 | const std::string extension_id = extension->id(); |
| 134 | |
[email protected] | c7c401d | 2011-03-16 10:20:01 | [diff] [blame] | 135 | // The call to OnExtensionInstalled ensures the other extension prefs |
| 136 | // are set up with the defaults. |
| 137 | service->extension_prefs()->OnExtensionInstalled( |
[email protected] | 26367b6 | 2012-10-04 23:03:32 | [diff] [blame] | 138 | extension, Extension::ENABLED, |
[email protected] | 36b64321 | 2012-09-07 12:53:00 | [diff] [blame] | 139 | syncer::StringOrdinal::CreateInitialOrdinal()); |
[email protected] | d10f460 | 2011-06-16 15:44:50 | [diff] [blame] | 140 | |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 141 | // Toggling incognito or file access will reload the extension, so wait for |
| 142 | // the reload and grab the new extension instance. The default state is |
| 143 | // incognito disabled and file access enabled, so we don't wait in those |
| 144 | // cases. |
| 145 | { |
[email protected] | a7fe911 | 2012-07-20 02:34:45 | [diff] [blame] | 146 | content::WindowedNotificationObserver load_signal( |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 147 | chrome::NOTIFICATION_EXTENSION_LOADED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 148 | content::Source<Profile>(browser()->profile())); |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 149 | CHECK(!service->IsIncognitoEnabled(extension_id)); |
[email protected] | db7331a | 2010-02-25 22:10:50 | [diff] [blame] | 150 | |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 151 | if (flags & kFlagEnableIncognito) { |
| 152 | service->SetIsIncognitoEnabled(extension_id, true); |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 153 | load_signal.Wait(); |
| 154 | extension = service->GetExtensionById(extension_id, false); |
| 155 | CHECK(extension) << extension_id << " not found after reloading."; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | { |
[email protected] | a7fe911 | 2012-07-20 02:34:45 | [diff] [blame] | 160 | content::WindowedNotificationObserver load_signal( |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 161 | chrome::NOTIFICATION_EXTENSION_LOADED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 162 | content::Source<Profile>(browser()->profile())); |
[email protected] | cdfca970 | 2011-08-08 16:07:01 | [diff] [blame] | 163 | CHECK(service->AllowFileAccess(extension)); |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 164 | if (!(flags & kFlagEnableFileAccess)) { |
| 165 | service->SetAllowFileAccess(extension, false); |
[email protected] | c1bf62c7 | 2011-07-15 22:18:42 | [diff] [blame] | 166 | load_signal.Wait(); |
| 167 | extension = service->GetExtensionById(extension_id, false); |
| 168 | CHECK(extension) << extension_id << " not found after reloading."; |
| 169 | } |
[email protected] | d10f460 | 2011-06-16 15:44:50 | [diff] [blame] | 170 | } |
| 171 | |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 172 | if (!WaitForExtensionViewsToLoad()) |
[email protected] | a964e11 | 2011-04-14 21:52:51 | [diff] [blame] | 173 | return NULL; |
| 174 | |
| 175 | return extension; |
[email protected] | 653c9ea | 2009-05-06 16:58:56 | [diff] [blame] | 176 | } |
[email protected] | 1bd5413 | 2009-06-11 00:05:34 | [diff] [blame] | 177 | |
[email protected] | a964e11 | 2011-04-14 21:52:51 | [diff] [blame] | 178 | const Extension* ExtensionBrowserTest::LoadExtension(const FilePath& path) { |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 179 | return LoadExtensionWithFlags(path, kFlagEnableFileAccess); |
[email protected] | db7331a | 2010-02-25 22:10:50 | [diff] [blame] | 180 | } |
| 181 | |
[email protected] | a964e11 | 2011-04-14 21:52:51 | [diff] [blame] | 182 | const Extension* ExtensionBrowserTest::LoadExtensionIncognito( |
| 183 | const FilePath& path) { |
[email protected] | 24e0429 | 2012-08-10 21:08:08 | [diff] [blame] | 184 | return LoadExtensionWithFlags(path, |
| 185 | kFlagEnableFileAccess | kFlagEnableIncognito); |
[email protected] | db7331a | 2010-02-25 22:10:50 | [diff] [blame] | 186 | } |
| 187 | |
[email protected] | 863e647 | 2012-01-24 19:33:58 | [diff] [blame] | 188 | const Extension* ExtensionBrowserTest::LoadExtensionAsComponent( |
| 189 | const FilePath& path) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 190 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 191 | browser()->profile())->extension_service(); |
[email protected] | 61b55b6 | 2011-03-24 09:03:10 | [diff] [blame] | 192 | |
| 193 | std::string manifest; |
| 194 | if (!file_util::ReadFileToString(path.Append(Extension::kManifestFilename), |
| 195 | &manifest)) |
[email protected] | 863e647 | 2012-01-24 19:33:58 | [diff] [blame] | 196 | return NULL; |
[email protected] | 61b55b6 | 2011-03-24 09:03:10 | [diff] [blame] | 197 | |
[email protected] | ee837d3 | 2012-10-02 22:25:49 | [diff] [blame] | 198 | std::string extension_id = service->component_loader()->Add(manifest, path); |
| 199 | const Extension* extension = service->extensions()->GetByID(extension_id); |
[email protected] | 863e647 | 2012-01-24 19:33:58 | [diff] [blame] | 200 | if (!extension) |
| 201 | return NULL; |
| 202 | last_loaded_extension_id_ = extension->id(); |
| 203 | return extension; |
[email protected] | 61b55b6 | 2011-03-24 09:03:10 | [diff] [blame] | 204 | } |
| 205 | |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 206 | FilePath ExtensionBrowserTest::PackExtension(const FilePath& dir_path) { |
[email protected] | 3a305db | 2011-04-12 13:40:53 | [diff] [blame] | 207 | FilePath crx_path = temp_dir_.path().AppendASCII("temp.crx"); |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 208 | if (!file_util::Delete(crx_path, false)) { |
| 209 | ADD_FAILURE() << "Failed to delete crx: " << crx_path.value(); |
| 210 | return FilePath(); |
| 211 | } |
| 212 | |
[email protected] | 21a5ad6 | 2012-04-03 04:48:45 | [diff] [blame] | 213 | // Look for PEM files with the same name as the directory. |
| 214 | FilePath pem_path = dir_path.ReplaceExtension(FILE_PATH_LITERAL(".pem")); |
| 215 | FilePath pem_path_out; |
| 216 | |
| 217 | if (!file_util::PathExists(pem_path)) { |
| 218 | pem_path = FilePath(); |
| 219 | pem_path_out = crx_path.DirName().AppendASCII("temp.pem"); |
| 220 | if (!file_util::Delete(pem_path_out, false)) { |
| 221 | ADD_FAILURE() << "Failed to delete pem: " << pem_path_out.value(); |
| 222 | return FilePath(); |
| 223 | } |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 224 | } |
| 225 | |
[email protected] | 21a5ad6 | 2012-04-03 04:48:45 | [diff] [blame] | 226 | return PackExtensionWithOptions(dir_path, crx_path, pem_path, pem_path_out); |
[email protected] | f66a50a | 2011-11-02 23:53:46 | [diff] [blame] | 227 | } |
| 228 | |
| 229 | FilePath ExtensionBrowserTest::PackExtensionWithOptions( |
| 230 | const FilePath& dir_path, |
| 231 | const FilePath& crx_path, |
| 232 | const FilePath& pem_path, |
| 233 | const FilePath& pem_out_path) { |
[email protected] | 19a906b | 2011-02-07 20:56:37 | [diff] [blame] | 234 | if (!file_util::PathExists(dir_path)) { |
| 235 | ADD_FAILURE() << "Extension dir not found: " << dir_path.value(); |
| 236 | return FilePath(); |
| 237 | } |
| 238 | |
[email protected] | f66a50a | 2011-11-02 23:53:46 | [diff] [blame] | 239 | if (!file_util::PathExists(pem_path) && pem_out_path.empty()) { |
| 240 | ADD_FAILURE() << "Must specify a PEM file or PEM output path"; |
| 241 | return FilePath(); |
| 242 | } |
| 243 | |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 244 | scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); |
| 245 | if (!creator->Run(dir_path, |
| 246 | crx_path, |
[email protected] | f66a50a | 2011-11-02 23:53:46 | [diff] [blame] | 247 | pem_path, |
[email protected] | 93d973a | 2012-01-08 07:38:26 | [diff] [blame] | 248 | pem_out_path, |
| 249 | ExtensionCreator::kOverwriteCRX)) { |
[email protected] | fc38935a | 2011-10-31 23:53:28 | [diff] [blame] | 250 | ADD_FAILURE() << "ExtensionCreator::Run() failed: " |
| 251 | << creator->error_message(); |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 252 | return FilePath(); |
| 253 | } |
| 254 | |
| 255 | if (!file_util::PathExists(crx_path)) { |
| 256 | ADD_FAILURE() << crx_path.value() << " was not created."; |
| 257 | return FilePath(); |
| 258 | } |
| 259 | return crx_path; |
| 260 | } |
| 261 | |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 262 | // This class is used to simulate an installation abort by the user. |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 263 | class MockAbortExtensionInstallPrompt : public ExtensionInstallPrompt { |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 264 | public: |
[email protected] | 91e51d61 | 2012-10-21 23:03:05 | [diff] [blame] | 265 | MockAbortExtensionInstallPrompt() : ExtensionInstallPrompt(NULL) { |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 266 | } |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 267 | |
| 268 | // Simulate a user abort on an extension installation. |
[email protected] | af6efb2 | 2012-10-12 02:23:05 | [diff] [blame] | 269 | virtual void ConfirmInstall(Delegate* delegate, |
| 270 | const Extension* extension, |
| 271 | const ShowDialogCallback& show_dialog_callback) { |
[email protected] | d828fac | 2011-06-28 05:43:04 | [diff] [blame] | 272 | delegate->InstallUIAbort(true); |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 273 | MessageLoopForUI::current()->Quit(); |
| 274 | } |
| 275 | |
[email protected] | c8f0043 | 2011-02-22 01:30:26 | [diff] [blame] | 276 | virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 277 | |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 278 | virtual void OnInstallFailure(const extensions::CrxInstallerError& error) {} |
[email protected] | c70013bd | 2010-01-20 21:50:03 | [diff] [blame] | 279 | }; |
| 280 | |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 281 | class MockAutoConfirmExtensionInstallPrompt : public ExtensionInstallPrompt { |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 282 | public: |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 283 | explicit MockAutoConfirmExtensionInstallPrompt( |
[email protected] | 91e51d61 | 2012-10-21 23:03:05 | [diff] [blame] | 284 | content::WebContents* web_contents) |
| 285 | : ExtensionInstallPrompt(web_contents) {} |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 286 | |
| 287 | // Proceed without confirmation prompt. |
[email protected] | af6efb2 | 2012-10-12 02:23:05 | [diff] [blame] | 288 | virtual void ConfirmInstall(Delegate* delegate, |
| 289 | const Extension* extension, |
| 290 | const ShowDialogCallback& show_dialog_callback) { |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 291 | delegate->InstallUIProceed(); |
| 292 | } |
| 293 | }; |
| 294 | |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 295 | const Extension* ExtensionBrowserTest::InstallExtensionFromWebstore( |
| 296 | const FilePath& path, |
| 297 | int expected_change) { |
[email protected] | cefa749d | 2011-08-11 22:21:48 | [diff] [blame] | 298 | return InstallOrUpdateExtension("", path, INSTALL_UI_TYPE_NONE, |
[email protected] | 7e7b782e | 2012-08-03 01:13:57 | [diff] [blame] | 299 | expected_change, Extension::INTERNAL, |
| 300 | browser(), true); |
[email protected] | cefa749d | 2011-08-11 22:21:48 | [diff] [blame] | 301 | } |
| 302 | |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 303 | const Extension* ExtensionBrowserTest::InstallOrUpdateExtension( |
| 304 | const std::string& id, |
| 305 | const FilePath& path, |
| 306 | InstallUIType ui_type, |
| 307 | int expected_change) { |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 308 | return InstallOrUpdateExtension(id, path, ui_type, expected_change, |
[email protected] | 7e7b782e | 2012-08-03 01:13:57 | [diff] [blame] | 309 | Extension::INTERNAL, browser(), false); |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 310 | } |
| 311 | |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 312 | const Extension* ExtensionBrowserTest::InstallOrUpdateExtension( |
| 313 | const std::string& id, |
| 314 | const FilePath& path, |
| 315 | InstallUIType ui_type, |
| 316 | int expected_change, |
[email protected] | 32fc4ff7 | 2012-06-15 21:50:01 | [diff] [blame] | 317 | Browser* browser, |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 318 | bool from_webstore) { |
[email protected] | 7e7b782e | 2012-08-03 01:13:57 | [diff] [blame] | 319 | return InstallOrUpdateExtension(id, path, ui_type, expected_change, |
| 320 | Extension::INTERNAL, browser, from_webstore); |
| 321 | } |
| 322 | |
| 323 | const Extension* ExtensionBrowserTest::InstallOrUpdateExtension( |
| 324 | const std::string& id, |
| 325 | const FilePath& path, |
| 326 | InstallUIType ui_type, |
| 327 | int expected_change, |
| 328 | Extension::Location install_source) { |
| 329 | return InstallOrUpdateExtension(id, path, ui_type, expected_change, |
| 330 | install_source, browser(), false); |
| 331 | } |
| 332 | |
| 333 | const Extension* ExtensionBrowserTest::InstallOrUpdateExtension( |
| 334 | const std::string& id, |
| 335 | const FilePath& path, |
| 336 | InstallUIType ui_type, |
| 337 | int expected_change, |
| 338 | Extension::Location install_source, |
| 339 | Browser* browser, |
| 340 | bool from_webstore) { |
[email protected] | 32fc4ff7 | 2012-06-15 21:50:01 | [diff] [blame] | 341 | ExtensionService* service = browser->profile()->GetExtensionService(); |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 342 | service->set_show_extensions_prompts(false); |
| 343 | size_t num_before = service->extensions()->size(); |
[email protected] | 1bd5413 | 2009-06-11 00:05:34 | [diff] [blame] | 344 | |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 345 | { |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 346 | ExtensionInstallPrompt* install_ui = NULL; |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 347 | if (ui_type == INSTALL_UI_TYPE_CANCEL) { |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 348 | install_ui = new MockAbortExtensionInstallPrompt(); |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 349 | } else if (ui_type == INSTALL_UI_TYPE_NORMAL) { |
[email protected] | 91e51d61 | 2012-10-21 23:03:05 | [diff] [blame] | 350 | install_ui = new ExtensionInstallPrompt( |
| 351 | browser->tab_strip_model()->GetActiveWebContents()); |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 352 | } else if (ui_type == INSTALL_UI_TYPE_AUTO_CONFIRM) { |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 353 | install_ui = new MockAutoConfirmExtensionInstallPrompt( |
[email protected] | 91e51d61 | 2012-10-21 23:03:05 | [diff] [blame] | 354 | browser->tab_strip_model()->GetActiveWebContents()); |
[email protected] | 619f8618 | 2012-07-03 21:30:18 | [diff] [blame] | 355 | } |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 356 | |
| 357 | // TODO(tessamac): Update callers to always pass an unpacked extension |
| 358 | // and then always pack the extension here. |
| 359 | FilePath crx_path = path; |
| 360 | if (crx_path.Extension() != FILE_PATH_LITERAL(".crx")) { |
| 361 | crx_path = PackExtension(path); |
| 362 | } |
| 363 | if (crx_path.empty()) |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 364 | return NULL; |
[email protected] | 8fd16f50 | 2010-04-22 18:23:18 | [diff] [blame] | 365 | |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 366 | scoped_refptr<extensions::CrxInstaller> installer( |
| 367 | extensions::CrxInstaller::Create(service, install_ui)); |
[email protected] | 6dfbbf8 | 2010-03-12 23:09:16 | [diff] [blame] | 368 | installer->set_expected_id(id); |
[email protected] | cefa749d | 2011-08-11 22:21:48 | [diff] [blame] | 369 | installer->set_is_gallery_install(from_webstore); |
[email protected] | 7e7b782e | 2012-08-03 01:13:57 | [diff] [blame] | 370 | installer->set_install_source(install_source); |
[email protected] | d903981 | 2012-06-09 06:05:48 | [diff] [blame] | 371 | if (!from_webstore) { |
| 372 | installer->set_off_store_install_allow_reason( |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 373 | extensions::CrxInstaller::OffStoreInstallAllowedInTest); |
[email protected] | d903981 | 2012-06-09 06:05:48 | [diff] [blame] | 374 | } |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 375 | |
| 376 | content::NotificationRegistrar registrar; |
| 377 | registrar.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 378 | content::Source<extensions::CrxInstaller>(installer.get())); |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 379 | |
[email protected] | 59e0336 | 2011-01-21 21:24:08 | [diff] [blame] | 380 | installer->InstallCrx(crx_path); |
[email protected] | 2a40953 | 2009-08-28 19:39:44 | [diff] [blame] | 381 | |
[email protected] | 729eb63 | 2012-07-26 04:45:26 | [diff] [blame] | 382 | content::RunMessageLoop(); |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 383 | } |
| 384 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 385 | size_t num_after = service->extensions()->size(); |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 386 | EXPECT_EQ(num_before + expected_change, num_after); |
| 387 | if (num_before + expected_change != num_after) { |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 388 | VLOG(1) << "Num extensions before: " << base::IntToString(num_before) |
| 389 | << " num after: " << base::IntToString(num_after) |
| 390 | << " Installed extensions follow:"; |
[email protected] | 7d11cee | 2009-07-08 02:40:42 | [diff] [blame] | 391 | |
[email protected] | 84df833 | 2011-12-06 18:22:46 | [diff] [blame] | 392 | for (ExtensionSet::const_iterator it = service->extensions()->begin(); |
| 393 | it != service->extensions()->end(); ++it) |
| 394 | VLOG(1) << " " << (*it)->id(); |
[email protected] | 7d11cee | 2009-07-08 02:40:42 | [diff] [blame] | 395 | |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 396 | VLOG(1) << "Errors follow:"; |
[email protected] | fc67082 | 2011-12-17 09:33:49 | [diff] [blame] | 397 | const std::vector<string16>* errors = |
[email protected] | 7d11cee | 2009-07-08 02:40:42 | [diff] [blame] | 398 | ExtensionErrorReporter::GetInstance()->GetErrors(); |
[email protected] | fc67082 | 2011-12-17 09:33:49 | [diff] [blame] | 399 | for (std::vector<string16>::const_iterator iter = errors->begin(); |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 400 | iter != errors->end(); ++iter) |
| 401 | VLOG(1) << *iter; |
[email protected] | 7d11cee | 2009-07-08 02:40:42 | [diff] [blame] | 402 | |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 403 | return NULL; |
[email protected] | 9c73efa | 2009-07-08 00:18:36 | [diff] [blame] | 404 | } |
[email protected] | 1bd5413 | 2009-06-11 00:05:34 | [diff] [blame] | 405 | |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 406 | if (!WaitForExtensionViewsToLoad()) |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 407 | return NULL; |
| 408 | return service->GetExtensionById(last_loaded_extension_id_, false); |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 409 | } |
[email protected] | 1bd5413 | 2009-06-11 00:05:34 | [diff] [blame] | 410 | |
[email protected] | e172584 | 2009-10-20 06:40:15 | [diff] [blame] | 411 | void ExtensionBrowserTest::ReloadExtension(const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 412 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 413 | browser()->profile())->extension_service(); |
[email protected] | e172584 | 2009-10-20 06:40:15 | [diff] [blame] | 414 | service->ReloadExtension(extension_id); |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 415 | ui_test_utils::RegisterAndWait(this, |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 416 | chrome::NOTIFICATION_EXTENSION_LOADED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 417 | content::NotificationService::AllSources()); |
[email protected] | e172584 | 2009-10-20 06:40:15 | [diff] [blame] | 418 | } |
| 419 | |
[email protected] | 57f71b9 | 2009-09-11 19:31:38 | [diff] [blame] | 420 | void ExtensionBrowserTest::UnloadExtension(const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 421 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 422 | browser()->profile())->extension_service(); |
[email protected] | 814a7bf0f | 2011-08-13 05:30:59 | [diff] [blame] | 423 | service->UnloadExtension(extension_id, extension_misc::UNLOAD_REASON_DISABLE); |
[email protected] | 57f71b9 | 2009-09-11 19:31:38 | [diff] [blame] | 424 | } |
| 425 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 426 | void ExtensionBrowserTest::UninstallExtension(const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 427 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 428 | browser()->profile())->extension_service(); |
[email protected] | d6ebc979 | 2011-04-07 18:18:33 | [diff] [blame] | 429 | service->UninstallExtension(extension_id, false, NULL); |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 430 | } |
| 431 | |
[email protected] | 7d9ad0b3 | 2010-02-12 21:44:45 | [diff] [blame] | 432 | void ExtensionBrowserTest::DisableExtension(const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 433 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 434 | browser()->profile())->extension_service(); |
[email protected] | 44d62b6 | 2012-04-11 00:06:03 | [diff] [blame] | 435 | service->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION); |
[email protected] | 7d9ad0b3 | 2010-02-12 21:44:45 | [diff] [blame] | 436 | } |
| 437 | |
| 438 | void ExtensionBrowserTest::EnableExtension(const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 439 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 440 | browser()->profile())->extension_service(); |
[email protected] | 7d9ad0b3 | 2010-02-12 21:44:45 | [diff] [blame] | 441 | service->EnableExtension(extension_id); |
| 442 | } |
| 443 | |
[email protected] | 57f71b9 | 2009-09-11 19:31:38 | [diff] [blame] | 444 | bool ExtensionBrowserTest::WaitForPageActionCountChangeTo(int count) { |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 445 | LocationBarTesting* location_bar = |
| 446 | browser()->window()->GetLocationBar()->GetLocationBarForTesting(); |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 447 | if (location_bar->PageActionCount() != count) { |
| 448 | target_page_action_count_ = count; |
| 449 | ui_test_utils::RegisterAndWait(this, |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 450 | chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 451 | content::NotificationService::AllSources()); |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 452 | } |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 453 | return location_bar->PageActionCount() == count; |
[email protected] | 57f71b9 | 2009-09-11 19:31:38 | [diff] [blame] | 454 | } |
| 455 | |
| 456 | bool ExtensionBrowserTest::WaitForPageActionVisibilityChangeTo(int count) { |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 457 | LocationBarTesting* location_bar = |
| 458 | browser()->window()->GetLocationBar()->GetLocationBarForTesting(); |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 459 | if (location_bar->PageActionVisibleCount() != count) { |
| 460 | target_visible_page_action_count_ = count; |
| 461 | ui_test_utils::RegisterAndWait(this, |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 462 | chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 463 | content::NotificationService::AllSources()); |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 464 | } |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 465 | return location_bar->PageActionVisibleCount() == count; |
[email protected] | 361b28a | 2009-07-09 21:30:53 | [diff] [blame] | 466 | } |
| 467 | |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 468 | bool ExtensionBrowserTest::WaitForExtensionViewsToLoad() { |
| 469 | // Wait for all the extension render view hosts that exist to finish loading. |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 470 | content::NotificationRegistrar registrar; |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 471 | registrar.Add(this, content::NOTIFICATION_LOAD_STOP, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 472 | content::NotificationService::AllSources()); |
[email protected] | 86c008e8 | 2009-08-28 20:26:05 | [diff] [blame] | 473 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 474 | ExtensionProcessManager* manager = |
[email protected] | be93bba0 | 2012-10-24 16:44:03 | [diff] [blame] | 475 | extensions::ExtensionSystem::Get(browser()->profile())->process_manager(); |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 476 | ExtensionProcessManager::ViewSet all_views = manager->GetAllViews(); |
| 477 | for (ExtensionProcessManager::ViewSet::const_iterator iter = |
| 478 | all_views.begin(); |
| 479 | iter != all_views.end();) { |
| 480 | if (!(*iter)->IsLoading()) { |
[email protected] | c290a623 | 2009-09-25 17:45:16 | [diff] [blame] | 481 | ++iter; |
[email protected] | bd618b4c | 2009-11-04 19:49:51 | [diff] [blame] | 482 | } else { |
[email protected] | 729eb63 | 2012-07-26 04:45:26 | [diff] [blame] | 483 | content::RunMessageLoop(); |
[email protected] | bd618b4c | 2009-11-04 19:49:51 | [diff] [blame] | 484 | |
| 485 | // Test activity may have modified the set of extension processes during |
| 486 | // message processing, so re-start the iteration to catch added/removed |
| 487 | // processes. |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 488 | all_views = manager->GetAllViews(); |
| 489 | iter = all_views.begin(); |
[email protected] | bd618b4c | 2009-11-04 19:49:51 | [diff] [blame] | 490 | } |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 491 | } |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 492 | return true; |
| 493 | } |
| 494 | |
[email protected] | f4ea1128 | 2009-10-14 00:19:31 | [diff] [blame] | 495 | bool ExtensionBrowserTest::WaitForExtensionInstall() { |
| 496 | int before = extension_installs_observed_; |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 497 | ui_test_utils::RegisterAndWait(this, |
| 498 | chrome::NOTIFICATION_EXTENSION_INSTALLED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 499 | content::NotificationService::AllSources()); |
[email protected] | f4ea1128 | 2009-10-14 00:19:31 | [diff] [blame] | 500 | return extension_installs_observed_ == (before + 1); |
| 501 | } |
| 502 | |
| 503 | bool ExtensionBrowserTest::WaitForExtensionInstallError() { |
| 504 | int before = extension_installs_observed_; |
[email protected] | 3e59bac | 2010-04-08 16:16:55 | [diff] [blame] | 505 | ui_test_utils::RegisterAndWait(this, |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 506 | chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 507 | content::NotificationService::AllSources()); |
[email protected] | f4ea1128 | 2009-10-14 00:19:31 | [diff] [blame] | 508 | return extension_installs_observed_ == before; |
| 509 | } |
| 510 | |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 511 | void ExtensionBrowserTest::WaitForExtensionLoad() { |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 512 | ui_test_utils::RegisterAndWait(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 513 | content::NotificationService::AllSources()); |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 514 | WaitForExtensionViewsToLoad(); |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 515 | } |
| 516 | |
[email protected] | bbcde910 | 2012-03-25 22:40:49 | [diff] [blame] | 517 | bool ExtensionBrowserTest::WaitForExtensionLoadError() { |
| 518 | int before = extension_load_errors_observed_; |
| 519 | ui_test_utils::RegisterAndWait(this, |
| 520 | chrome::NOTIFICATION_EXTENSION_LOAD_ERROR, |
| 521 | content::NotificationService::AllSources()); |
| 522 | return extension_load_errors_observed_ != before; |
| 523 | } |
| 524 | |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 525 | bool ExtensionBrowserTest::WaitForExtensionCrash( |
| 526 | const std::string& extension_id) { |
[email protected] | 06bdd2b | 2012-11-30 18:47:13 | [diff] [blame] | 527 | ExtensionService* service = extensions::ExtensionSystem::Get( |
| 528 | browser()->profile())->extension_service(); |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 529 | |
| 530 | if (!service->GetExtensionById(extension_id, true)) { |
| 531 | // The extension is already unloaded, presumably due to a crash. |
| 532 | return true; |
| 533 | } |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 534 | ui_test_utils::RegisterAndWait( |
| 535 | this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 536 | content::NotificationService::AllSources()); |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 537 | return (service->GetExtensionById(extension_id, true) == NULL); |
| 538 | } |
| 539 | |
[email protected] | 8c6af5b | 2012-06-15 20:10:26 | [diff] [blame] | 540 | bool ExtensionBrowserTest::WaitForCrxInstallerDone() { |
| 541 | int before = crx_installers_done_observed_; |
| 542 | ui_test_utils::RegisterAndWait(this, |
| 543 | chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
| 544 | content::NotificationService::AllSources()); |
| 545 | return crx_installers_done_observed_ == (before + 1); |
| 546 | } |
| 547 | |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 548 | void ExtensionBrowserTest::OpenWindow(content::WebContents* contents, |
| 549 | const GURL& url, |
| 550 | bool newtab_process_should_equal_opener, |
| 551 | content::WebContents** newtab_result) { |
[email protected] | a7fe911 | 2012-07-20 02:34:45 | [diff] [blame] | 552 | content::WindowedNotificationObserver observer( |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 553 | content::NOTIFICATION_LOAD_STOP, |
| 554 | content::NotificationService::AllSources()); |
[email protected] | 7d478cb | 2012-07-24 17:19:42 | [diff] [blame] | 555 | ASSERT_TRUE(content::ExecuteJavaScript( |
[email protected] | 06bc5d9 | 2013-01-02 22:44:13 | [diff] [blame^] | 556 | contents->GetRenderViewHost(), |
| 557 | "", |
| 558 | "window.open('" + url.spec() + "');")); |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 559 | |
| 560 | // The above window.open call is not user-initiated, so it will create |
| 561 | // a popup window instead of a new tab in current window. |
| 562 | // The stop notification will come from the new tab. |
| 563 | observer.Wait(); |
| 564 | content::NavigationController* controller = |
| 565 | content::Source<content::NavigationController>(observer.source()).ptr(); |
| 566 | content::WebContents* newtab = controller->GetWebContents(); |
| 567 | ASSERT_TRUE(newtab); |
| 568 | EXPECT_EQ(url, controller->GetLastCommittedEntry()->GetURL()); |
| 569 | if (newtab_process_should_equal_opener) |
| 570 | EXPECT_EQ(contents->GetRenderProcessHost(), newtab->GetRenderProcessHost()); |
| 571 | else |
| 572 | EXPECT_NE(contents->GetRenderProcessHost(), newtab->GetRenderProcessHost()); |
| 573 | |
| 574 | if (newtab_result) |
| 575 | *newtab_result = newtab; |
| 576 | } |
| 577 | |
| 578 | void ExtensionBrowserTest::NavigateInRenderer(content::WebContents* contents, |
| 579 | const GURL& url) { |
| 580 | bool result = false; |
[email protected] | a7fe911 | 2012-07-20 02:34:45 | [diff] [blame] | 581 | content::WindowedNotificationObserver observer( |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 582 | content::NOTIFICATION_LOAD_STOP, |
| 583 | content::NotificationService::AllSources()); |
[email protected] | 7d478cb | 2012-07-24 17:19:42 | [diff] [blame] | 584 | ASSERT_TRUE(content::ExecuteJavaScriptAndExtractBool( |
[email protected] | 06bc5d9 | 2013-01-02 22:44:13 | [diff] [blame^] | 585 | contents->GetRenderViewHost(), |
| 586 | "", |
| 587 | "window.addEventListener('unload', function() {" |
| 588 | " window.domAutomationController.send(true);" |
| 589 | "}, false);" |
| 590 | "window.location = '" + url.spec() + "';", |
[email protected] | 19da16a9 | 2012-05-23 17:11:29 | [diff] [blame] | 591 | &result)); |
| 592 | ASSERT_TRUE(result); |
| 593 | observer.Wait(); |
| 594 | EXPECT_EQ(url, contents->GetController().GetLastCommittedEntry()->GetURL()); |
| 595 | } |
| 596 | |
[email protected] | 3a1dc57 | 2012-07-31 22:25:13 | [diff] [blame] | 597 | extensions::ExtensionHost* ExtensionBrowserTest::FindHostWithPath( |
[email protected] | fad7367 | 2012-06-15 23:26:06 | [diff] [blame] | 598 | ExtensionProcessManager* manager, |
| 599 | const std::string& path, |
| 600 | int expected_hosts) { |
[email protected] | 3a1dc57 | 2012-07-31 22:25:13 | [diff] [blame] | 601 | extensions::ExtensionHost* host = NULL; |
[email protected] | fad7367 | 2012-06-15 23:26:06 | [diff] [blame] | 602 | int num_hosts = 0; |
| 603 | ExtensionProcessManager::ExtensionHostSet background_hosts = |
| 604 | manager->background_hosts(); |
| 605 | for (ExtensionProcessManager::const_iterator iter = background_hosts.begin(); |
| 606 | iter != background_hosts.end(); ++iter) { |
| 607 | if ((*iter)->GetURL().path() == path) { |
| 608 | EXPECT_FALSE(host); |
| 609 | host = *iter; |
| 610 | } |
| 611 | num_hosts++; |
| 612 | } |
| 613 | EXPECT_EQ(expected_hosts, num_hosts); |
| 614 | return host; |
| 615 | } |
| 616 | |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 617 | void ExtensionBrowserTest::Observe( |
| 618 | int type, |
| 619 | const content::NotificationSource& source, |
| 620 | const content::NotificationDetails& details) { |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 621 | switch (type) { |
| 622 | case chrome::NOTIFICATION_EXTENSION_LOADED: |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 623 | last_loaded_extension_id_ = |
| 624 | content::Details<const Extension>(details).ptr()->id(); |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 625 | VLOG(1) << "Got EXTENSION_LOADED notification."; |
[email protected] | 7d11cee | 2009-07-08 02:40:42 | [diff] [blame] | 626 | MessageLoopForUI::current()->Quit(); |
| 627 | break; |
| 628 | |
[email protected] | 84f4dc0 | 2011-11-29 21:58:26 | [diff] [blame] | 629 | case chrome::NOTIFICATION_CRX_INSTALLER_DONE: |
| 630 | VLOG(1) << "Got CRX_INSTALLER_DONE notification."; |
| 631 | { |
| 632 | const Extension* extension = |
| 633 | content::Details<const Extension>(details).ptr(); |
| 634 | if (extension) |
| 635 | last_loaded_extension_id_ = extension->id(); |
| 636 | else |
| 637 | last_loaded_extension_id_ = ""; |
| 638 | } |
[email protected] | 8c6af5b | 2012-06-15 20:10:26 | [diff] [blame] | 639 | ++crx_installers_done_observed_; |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 640 | MessageLoopForUI::current()->Quit(); |
| 641 | break; |
| 642 | |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 643 | case chrome::NOTIFICATION_EXTENSION_INSTALLED: |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 644 | VLOG(1) << "Got EXTENSION_INSTALLED notification."; |
[email protected] | f4ea1128 | 2009-10-14 00:19:31 | [diff] [blame] | 645 | ++extension_installs_observed_; |
| 646 | MessageLoopForUI::current()->Quit(); |
| 647 | break; |
| 648 | |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 649 | case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 650 | VLOG(1) << "Got EXTENSION_INSTALL_ERROR notification."; |
[email protected] | f4ea1128 | 2009-10-14 00:19:31 | [diff] [blame] | 651 | MessageLoopForUI::current()->Quit(); |
| 652 | break; |
| 653 | |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 654 | case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 655 | VLOG(1) << "Got EXTENSION_PROCESS_TERMINATED notification."; |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 656 | MessageLoopForUI::current()->Quit(); |
| 657 | break; |
| 658 | |
[email protected] | bbcde910 | 2012-03-25 22:40:49 | [diff] [blame] | 659 | case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: |
| 660 | VLOG(1) << "Got EXTENSION_LOAD_ERROR notification."; |
| 661 | ++extension_load_errors_observed_; |
| 662 | MessageLoopForUI::current()->Quit(); |
| 663 | break; |
| 664 | |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 665 | case chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED: { |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 666 | LocationBarTesting* location_bar = |
| 667 | browser()->window()->GetLocationBar()->GetLocationBarForTesting(); |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 668 | VLOG(1) << "Got EXTENSION_PAGE_ACTION_COUNT_CHANGED notification. Number " |
| 669 | "of page actions: " << location_bar->PageActionCount(); |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 670 | if (location_bar->PageActionCount() == |
| 671 | target_page_action_count_) { |
| 672 | target_page_action_count_ = -1; |
| 673 | MessageLoopForUI::current()->Quit(); |
| 674 | } |
| 675 | break; |
| 676 | } |
| 677 | |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 678 | case chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED: { |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 679 | LocationBarTesting* location_bar = |
| 680 | browser()->window()->GetLocationBar()->GetLocationBarForTesting(); |
[email protected] | e99a88e9 | 2010-10-22 18:08:03 | [diff] [blame] | 681 | VLOG(1) << "Got EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED notification. " |
| 682 | "Number of visible page actions: " |
| 683 | << location_bar->PageActionVisibleCount(); |
[email protected] | d818e07f | 2010-02-10 13:10:03 | [diff] [blame] | 684 | if (location_bar->PageActionVisibleCount() == |
| 685 | target_visible_page_action_count_) { |
| 686 | target_visible_page_action_count_ = -1; |
| 687 | MessageLoopForUI::current()->Quit(); |
| 688 | } |
| 689 | break; |
| 690 | } |
| 691 | |
[email protected] | d1fe135 | 2012-04-26 00:47:32 | [diff] [blame] | 692 | case content::NOTIFICATION_LOAD_STOP: |
| 693 | VLOG(1) << "Got LOAD_STOP notification."; |
| 694 | MessageLoopForUI::current()->Quit(); |
| 695 | break; |
| 696 | |
[email protected] | 17c4f3c | 2009-07-04 16:36:25 | [diff] [blame] | 697 | default: |
| 698 | NOTREACHED(); |
| 699 | break; |
| 700 | } |
[email protected] | 1bd5413 | 2009-06-11 00:05:34 | [diff] [blame] | 701 | } |