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