1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSERTEST_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSERTEST_H_
10 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/test/scoped_path_override.h"
15 #include "chrome/browser/extensions/extension_test_notification_observer.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/common/extensions/features/feature_channel.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/browser/extension_host.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/feature_switch.h"
25 #include "extensions/common/manifest.h"
27 class ExtensionService
;
30 namespace extensions
{
31 class ExtensionCacheFake
;
36 // Base class for extension browser tests. Provides utilities for loading,
37 // unloading, and installing extensions.
38 class ExtensionBrowserTest
: virtual public InProcessBrowserTest
{
40 // Flags used to configure how the tests are run.
44 // Allow the extension to run in incognito mode.
45 kFlagEnableIncognito
= 1 << 0,
47 // Allow file access for the extension.
48 kFlagEnableFileAccess
= 1 << 1,
50 // Don't fail when the loaded manifest has warnings (should only be used
51 // when testing deprecated features).
52 kFlagIgnoreManifestWarnings
= 1 << 2,
54 // Allow older manifest versions (typically these can't be loaded - we allow
56 kFlagAllowOldManifestVersions
= 1 << 3,
59 ExtensionBrowserTest();
60 ~ExtensionBrowserTest() override
;
63 ExtensionService
* extension_service() {
64 return extensions::ExtensionSystem::Get(profile())->extension_service();
67 const std::string
& last_loaded_extension_id() {
68 return observer_
->last_loaded_extension_id();
71 // Get the profile to use.
72 virtual Profile
* profile();
74 static const extensions::Extension
* GetExtensionByPath(
75 const extensions::ExtensionSet
& extensions
,
76 const base::FilePath
& path
);
78 // InProcessBrowserTest
79 void SetUp() override
;
80 void SetUpCommandLine(base::CommandLine
* command_line
) override
;
81 void SetUpOnMainThread() override
;
82 void TearDownOnMainThread() override
;
84 const extensions::Extension
* LoadExtension(const base::FilePath
& path
);
86 // Load extension and enable it in incognito mode.
87 const extensions::Extension
* LoadExtensionIncognito(
88 const base::FilePath
& path
);
90 // Load extension from the |path| folder. |flags| is bit mask of values from
92 const extensions::Extension
* LoadExtensionWithFlags(
93 const base::FilePath
& path
, int flags
);
95 // Same as above, but sets the installation parameter to the extension
97 const extensions::Extension
* LoadExtensionWithInstallParam(
98 const base::FilePath
& path
,
100 const std::string
& install_param
);
102 // Loads unpacked extension from |path| with manifest |manifest_relative_path|
103 // and imitates that it is a component extension.
104 // |manifest_relative_path| is relative to |path|.
105 const extensions::Extension
* LoadExtensionAsComponentWithManifest(
106 const base::FilePath
& path
,
107 const base::FilePath::CharType
* manifest_relative_path
);
109 // Loads unpacked extension from |path| and imitates that it is a component
110 // extension. Equivalent to
111 // LoadExtensionAsComponentWithManifest(path, extensions::kManifestFilename).
112 const extensions::Extension
* LoadExtensionAsComponent(
113 const base::FilePath
& path
);
115 // Loads and launches the app from |path|, and returns it.
116 const extensions::Extension
* LoadAndLaunchApp(const base::FilePath
& path
);
118 // Pack the extension in |dir_path| into a crx file and return its path.
119 // Return an empty FilePath if there were errors.
120 base::FilePath
PackExtension(const base::FilePath
& dir_path
);
122 // Pack the extension in |dir_path| into a crx file at |crx_path|, using the
123 // key |pem_path|. If |pem_path| does not exist, create a new key at
125 // Return the path to the crx file, or an empty FilePath if there were errors.
126 base::FilePath
PackExtensionWithOptions(const base::FilePath
& dir_path
,
127 const base::FilePath
& crx_path
,
128 const base::FilePath
& pem_path
,
129 const base::FilePath
& pem_out_path
);
131 // |expected_change| indicates how many extensions should be installed (or
132 // disabled, if negative).
133 // 1 means you expect a new install, 0 means you expect an upgrade, -1 means
134 // you expect a failed upgrade.
135 const extensions::Extension
* InstallExtension(const base::FilePath
& path
,
136 int expected_change
) {
137 return InstallOrUpdateExtension(
138 std::string(), path
, INSTALL_UI_TYPE_NONE
, expected_change
);
141 // Same as above, but an install source other than Manifest::INTERNAL can be
143 const extensions::Extension
* InstallExtension(
144 const base::FilePath
& path
,
146 extensions::Manifest::Location install_source
) {
147 return InstallOrUpdateExtension(std::string(),
149 INSTALL_UI_TYPE_NONE
,
154 // Installs extension as if it came from the Chrome Webstore.
155 const extensions::Extension
* InstallExtensionFromWebstore(
156 const base::FilePath
& path
, int expected_change
);
158 // Same as above but passes an id to CrxInstaller and does not allow a
159 // privilege increase.
160 const extensions::Extension
* UpdateExtension(const std::string
& id
,
161 const base::FilePath
& path
,
162 int expected_change
) {
163 return InstallOrUpdateExtension(id
, path
, INSTALL_UI_TYPE_NONE
,
167 // Same as UpdateExtension but waits for the extension to be idle first.
168 const extensions::Extension
* UpdateExtensionWaitForIdle(
169 const std::string
& id
, const base::FilePath
& path
, int expected_change
);
171 // Same as |InstallExtension| but with the normal extension UI showing up
172 // (for e.g. info bar on success).
173 const extensions::Extension
* InstallExtensionWithUI(
174 const base::FilePath
& path
,
175 int expected_change
) {
176 return InstallOrUpdateExtension(
177 std::string(), path
, INSTALL_UI_TYPE_NORMAL
, expected_change
);
180 const extensions::Extension
* InstallExtensionWithUIAutoConfirm(
181 const base::FilePath
& path
,
184 return InstallOrUpdateExtension(std::string(),
186 INSTALL_UI_TYPE_AUTO_CONFIRM
,
189 extensions::Extension::NO_FLAGS
);
192 const extensions::Extension
* InstallExtensionWithSourceAndFlags(
193 const base::FilePath
& path
,
195 extensions::Manifest::Location install_source
,
196 extensions::Extension::InitFromValueFlags creation_flags
) {
197 return InstallOrUpdateExtension(std::string(),
199 INSTALL_UI_TYPE_NONE
,
208 const extensions::Extension
* InstallEphemeralAppWithSourceAndFlags(
209 const base::FilePath
& path
,
211 extensions::Manifest::Location install_source
,
212 extensions::Extension::InitFromValueFlags creation_flags
) {
213 return InstallOrUpdateExtension(std::string(),
215 INSTALL_UI_TYPE_NONE
,
224 // Begins install process but simulates a user cancel.
225 const extensions::Extension
* StartInstallButCancel(
226 const base::FilePath
& path
) {
227 return InstallOrUpdateExtension(
228 std::string(), path
, INSTALL_UI_TYPE_CANCEL
, 0);
231 void ReloadExtension(const std::string extension_id
);
233 void UnloadExtension(const std::string
& extension_id
);
235 void UninstallExtension(const std::string
& extension_id
);
237 void DisableExtension(const std::string
& extension_id
);
239 void EnableExtension(const std::string
& extension_id
);
241 // Wait for the number of visible page actions to change to |count|.
242 bool WaitForPageActionVisibilityChangeTo(int count
) {
243 return observer_
->WaitForPageActionVisibilityChangeTo(count
);
246 // Waits until an extension is installed and loaded. Returns true if an
247 // install happened before timeout.
248 bool WaitForExtensionInstall() {
249 return observer_
->WaitForExtensionInstall();
252 // Wait for an extension install error to be raised. Returns true if an
254 bool WaitForExtensionInstallError() {
255 return observer_
->WaitForExtensionInstallError();
258 // Waits until an extension is loaded and all view have loaded.
259 void WaitForExtensionAndViewLoad() {
260 return observer_
->WaitForExtensionAndViewLoad();
263 // Waits until an extension is loaded.
264 void WaitForExtensionLoad() {
265 return observer_
->WaitForExtensionLoad();
268 // Waits for an extension load error. Returns true if the error really
270 bool WaitForExtensionLoadError() {
271 return observer_
->WaitForExtensionLoadError();
274 // Wait for the specified extension to crash. Returns true if it really
276 bool WaitForExtensionCrash(const std::string
& extension_id
) {
277 return observer_
->WaitForExtensionCrash(extension_id
);
280 // Wait for the crx installer to be done. Returns true if it really is done.
281 bool WaitForCrxInstallerDone() {
282 return observer_
->WaitForCrxInstallerDone();
285 // Wait for all extension views to load.
286 bool WaitForExtensionViewsToLoad() {
287 return observer_
->WaitForExtensionViewsToLoad();
290 // Wait for the extension to be idle.
291 bool WaitForExtensionIdle(const std::string
& extension_id
) {
292 return observer_
->WaitForExtensionIdle(extension_id
);
295 // Wait for the extension to not be idle.
296 bool WaitForExtensionNotIdle(const std::string
& extension_id
) {
297 return observer_
->WaitForExtensionNotIdle(extension_id
);
300 // Simulates a page calling window.open on an URL and waits for the
302 void OpenWindow(content::WebContents
* contents
,
304 bool newtab_process_should_equal_opener
,
305 content::WebContents
** newtab_result
);
307 // Simulates a page navigating itself to an URL and waits for the
309 void NavigateInRenderer(content::WebContents
* contents
, const GURL
& url
);
311 // Looks for an ExtensionHost whose URL has the given path component
312 // (including leading slash). Also verifies that the expected number of hosts
314 extensions::ExtensionHost
* FindHostWithPath(
315 extensions::ProcessManager
* manager
,
316 const std::string
& path
,
320 // extensions::browsertest_util::ExecuteScriptInBackgroundPage(profile(),
321 // extension_id, script).
322 std::string
ExecuteScriptInBackgroundPage(const std::string
& extension_id
,
323 const std::string
& script
);
326 // extensions::browsertest_util::ExecuteScriptInBackgroundPageNoWait(
327 // profile(), extension_id, script).
328 bool ExecuteScriptInBackgroundPageNoWait(const std::string
& extension_id
,
329 const std::string
& script
);
334 #if defined(OS_CHROMEOS)
335 // True if the command line should be tweaked as if ChromeOS user is
336 // already logged in.
337 bool set_chromeos_user_
;
340 // test_data/extensions.
341 base::FilePath test_data_dir_
;
343 scoped_ptr
<ExtensionTestNotificationObserver
> observer_
;
346 // Temporary directory for testing.
347 base::ScopedTempDir temp_dir_
;
349 // Specifies the type of UI (if any) to show during installation and what
350 // user action to simulate.
352 INSTALL_UI_TYPE_NONE
,
353 INSTALL_UI_TYPE_CANCEL
,
354 INSTALL_UI_TYPE_NORMAL
,
355 INSTALL_UI_TYPE_AUTO_CONFIRM
,
358 const extensions::Extension
* InstallOrUpdateExtension(
359 const std::string
& id
,
360 const base::FilePath
& path
,
361 InstallUIType ui_type
,
362 int expected_change
);
363 const extensions::Extension
* InstallOrUpdateExtension(
364 const std::string
& id
,
365 const base::FilePath
& path
,
366 InstallUIType ui_type
,
369 extensions::Extension::InitFromValueFlags creation_flags
);
370 const extensions::Extension
* InstallOrUpdateExtension(
371 const std::string
& id
,
372 const base::FilePath
& path
,
373 InstallUIType ui_type
,
375 extensions::Manifest::Location install_source
);
376 const extensions::Extension
* InstallOrUpdateExtension(
377 const std::string
& id
,
378 const base::FilePath
& path
,
379 InstallUIType ui_type
,
381 extensions::Manifest::Location install_source
,
383 extensions::Extension::InitFromValueFlags creation_flags
,
387 // Make the current channel "dev" for the duration of the test.
388 extensions::ScopedCurrentChannel current_channel_
;
390 // Disable external install UI.
391 extensions::FeatureSwitch::ScopedOverride
392 override_prompt_for_external_extensions_
;
395 // Use mock shortcut directories to ensure app shortcuts are cleaned up.
396 base::ScopedPathOverride user_desktop_override_
;
397 base::ScopedPathOverride common_desktop_override_
;
398 base::ScopedPathOverride user_quick_launch_override_
;
399 base::ScopedPathOverride start_menu_override_
;
400 base::ScopedPathOverride common_start_menu_override_
;
403 // The default profile to be used.
406 // Cache cache implementation.
407 scoped_ptr
<extensions::ExtensionCacheFake
> test_extension_cache_
;
410 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSERTEST_H_