Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_startup_installer_browsertest.cc
blobe833c602fd9f387da7c39bc793bfd4ba5b11babc
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 #include "base/command_line.h"
6 #include "base/scoped_observer.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/extension_install_prompt.h"
9 #include "chrome/browser/extensions/extension_install_ui.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/startup_helper.h"
12 #include "chrome/browser/extensions/webstore_installer_test.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/test_switches.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_types.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/test/browser_test_utils.h"
27 #include "extensions/browser/extension_host.h"
28 #include "extensions/browser/extension_registry.h"
29 #include "extensions/browser/extension_registry_observer.h"
30 #include "extensions/browser/extension_system.h"
31 #include "extensions/common/extension_builder.h"
32 #include "extensions/common/value_builder.h"
33 #include "net/dns/mock_host_resolver.h"
34 #include "url/gurl.h"
36 using content::WebContents;
37 using extensions::DictionaryBuilder;
38 using extensions::Extension;
39 using extensions::ExtensionBuilder;
40 using extensions::ListBuilder;
42 const char kWebstoreDomain[] = "cws.com";
43 const char kAppDomain[] = "app.com";
44 const char kNonAppDomain[] = "nonapp.com";
45 const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje";
46 const char kTestDataPath[] = "extensions/api_test/webstore_inline_install";
47 const char kCrxFilename[] = "extension.crx";
49 class WebstoreStartupInstallerTest : public WebstoreInstallerTest {
50 public:
51 WebstoreStartupInstallerTest()
52 : WebstoreInstallerTest(
53 kWebstoreDomain,
54 kTestDataPath,
55 kCrxFilename,
56 kAppDomain,
57 kNonAppDomain) {}
60 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, Install) {
61 ExtensionInstallPrompt::g_auto_confirm_for_tests =
62 ExtensionInstallPrompt::ACCEPT;
64 ui_test_utils::NavigateToURL(
65 browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
67 RunTest("runTest");
69 const extensions::Extension* extension =
70 extensions::ExtensionRegistry::Get(
71 browser()->profile())->enabled_extensions().GetByID(kTestExtensionId);
72 EXPECT_TRUE(extension);
75 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest,
76 InstallNotAllowedFromNonVerifiedDomains) {
77 ExtensionInstallPrompt::g_auto_confirm_for_tests =
78 ExtensionInstallPrompt::CANCEL;
79 ui_test_utils::NavigateToURL(
80 browser(),
81 GenerateTestServerUrl(kNonAppDomain, "install_non_verified_domain.html"));
83 RunTest("runTest1");
84 RunTest("runTest2");
87 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, FindLink) {
88 ui_test_utils::NavigateToURL(
89 browser(), GenerateTestServerUrl(kAppDomain, "find_link.html"));
91 RunTest("runTest");
94 // Flakes on all platforms: http://crbug.com/95713, http://crbug.com/229947
95 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest,
96 DISABLED_ArgumentValidation) {
97 ExtensionInstallPrompt::g_auto_confirm_for_tests =
98 ExtensionInstallPrompt::CANCEL;
100 // Each of these tests has to run separately, since one page/tab can
101 // only have one in-progress install request. These tests don't all pass
102 // callbacks to install, so they have no way to wait for the installation
103 // to complete before starting the next test.
104 bool is_finished = false;
105 for (int i = 0; !is_finished; ++i) {
106 ui_test_utils::NavigateToURL(
107 browser(),
108 GenerateTestServerUrl(kAppDomain, "argument_validation.html"));
109 is_finished = !RunIndexedTest("runTest", i);
113 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, MultipleInstallCalls) {
114 ExtensionInstallPrompt::g_auto_confirm_for_tests =
115 ExtensionInstallPrompt::CANCEL;
117 ui_test_utils::NavigateToURL(
118 browser(),
119 GenerateTestServerUrl(kAppDomain, "multiple_install_calls.html"));
120 RunTest("runTest");
123 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, InstallNotSupported) {
124 ExtensionInstallPrompt::g_auto_confirm_for_tests =
125 ExtensionInstallPrompt::CANCEL;
126 ui_test_utils::NavigateToURL(
127 browser(),
128 GenerateTestServerUrl(kAppDomain, "install_not_supported.html"));
130 ui_test_utils::WindowedTabAddedNotificationObserver observer(
131 content::NotificationService::AllSources());
132 RunTest("runTest");
133 observer.Wait();
135 // The inline install should fail, and a store-provided URL should be opened
136 // in a new tab.
137 WebContents* web_contents =
138 browser()->tab_strip_model()->GetActiveWebContents();
139 EXPECT_EQ(GURL("http://cws.com/show-me-the-money"), web_contents->GetURL());
142 // Regression test for http://crbug.com/144991.
143 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, InstallFromHostedApp) {
144 ExtensionInstallPrompt::g_auto_confirm_for_tests =
145 ExtensionInstallPrompt::ACCEPT;
147 const GURL kInstallUrl = GenerateTestServerUrl(kAppDomain, "install.html");
149 // We're forced to construct a hosted app dynamically because we need the
150 // app to run on a declared URL, but we don't know the port ahead of time.
151 scoped_refptr<const Extension> hosted_app = ExtensionBuilder()
152 .SetManifest(DictionaryBuilder()
153 .Set("name", "hosted app")
154 .Set("version", "1")
155 .Set("app", DictionaryBuilder()
156 .Set("urls", ListBuilder().Append(kInstallUrl.spec()))
157 .Set("launch", DictionaryBuilder()
158 .Set("web_url", kInstallUrl.spec())))
159 .Set("manifest_version", 2))
160 .Build();
161 ASSERT_TRUE(hosted_app.get());
163 ExtensionService* extension_service =
164 extensions::ExtensionSystem::Get(browser()->profile())->
165 extension_service();
167 extension_service->AddExtension(hosted_app.get());
168 EXPECT_TRUE(extension_service->extensions()->Contains(hosted_app->id()));
170 ui_test_utils::NavigateToURL(browser(), kInstallUrl);
172 EXPECT_FALSE(extension_service->extensions()->Contains(kTestExtensionId));
173 RunTest("runTest");
174 EXPECT_TRUE(extension_service->extensions()->Contains(kTestExtensionId));
177 class WebstoreStartupInstallerSupervisedUsersTest
178 : public WebstoreStartupInstallerTest {
179 public:
180 // InProcessBrowserTest overrides:
181 virtual void SetUpCommandLine(base::CommandLine* command_line) override {
182 WebstoreStartupInstallerTest::SetUpCommandLine(command_line);
183 command_line->AppendSwitchASCII(switches::kSupervisedUserId, "asdf");
187 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerSupervisedUsersTest,
188 InstallProhibited) {
189 #if defined(OS_WIN) && defined(USE_ASH)
190 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
191 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
192 switches::kAshBrowserTests))
193 return;
194 #endif
196 ExtensionInstallPrompt::g_auto_confirm_for_tests =
197 ExtensionInstallPrompt::ACCEPT;
199 ui_test_utils::NavigateToURL(
200 browser(), GenerateTestServerUrl(kAppDomain, "install_prohibited.html"));
202 RunTest("runTest");
204 // No error infobar should show up.
205 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
206 InfoBarService* infobar_service = InfoBarService::FromWebContents(contents);
207 EXPECT_EQ(0u, infobar_service->infobar_count());
210 // The unpack failure test needs to use a different install .crx, which is
211 // specified via a command-line flag, so it needs its own test subclass.
212 class WebstoreStartupInstallUnpackFailureTest
213 : public WebstoreStartupInstallerTest {
214 public:
215 virtual void SetUpCommandLine(base::CommandLine* command_line) override {
216 WebstoreStartupInstallerTest::SetUpCommandLine(command_line);
218 GURL crx_url = GenerateTestServerUrl(
219 kWebstoreDomain, "malformed_extension.crx");
220 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
221 switches::kAppsGalleryUpdateURL, crx_url.spec());
224 virtual void SetUpInProcessBrowserTestFixture() override {
225 WebstoreStartupInstallerTest::SetUpInProcessBrowserTestFixture();
226 ExtensionInstallUI::set_disable_failure_ui_for_tests();
230 IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallUnpackFailureTest,
231 WebstoreStartupInstallUnpackFailureTest) {
232 ExtensionInstallPrompt::g_auto_confirm_for_tests =
233 ExtensionInstallPrompt::ACCEPT;
235 ui_test_utils::NavigateToURL(browser(),
236 GenerateTestServerUrl(kAppDomain, "install_unpack_failure.html"));
238 RunTest("runTest");
241 class CommandLineWebstoreInstall
242 : public WebstoreStartupInstallerTest,
243 public content::NotificationObserver,
244 public extensions::ExtensionRegistryObserver {
245 public:
246 CommandLineWebstoreInstall() : saw_install_(false), browser_open_count_(0) {}
247 virtual ~CommandLineWebstoreInstall() {}
249 virtual void SetUpOnMainThread() override {
250 WebstoreStartupInstallerTest::SetUpOnMainThread();
251 extensions::ExtensionRegistry::Get(browser()->profile())->AddObserver(this);
252 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
253 content::NotificationService::AllSources());
256 virtual void TearDownOnMainThread() override {
257 extensions::ExtensionRegistry::Get(browser()->profile())
258 ->RemoveObserver(this);
259 WebstoreStartupInstallerTest::TearDownOnMainThread();
262 bool saw_install() { return saw_install_; }
264 int browser_open_count() { return browser_open_count_; }
266 // NotificationObserver interface.
267 virtual void Observe(int type,
268 const content::NotificationSource& source,
269 const content::NotificationDetails& details) override {
270 DCHECK_EQ(type, chrome::NOTIFICATION_BROWSER_OPENED);
271 ++browser_open_count_;
274 virtual void OnExtensionWillBeInstalled(
275 content::BrowserContext* browser_context,
276 const extensions::Extension* extension,
277 bool is_update,
278 bool from_ephemeral,
279 const std::string& old_name) override {
280 EXPECT_EQ(extension->id(), kTestExtensionId);
281 saw_install_ = true;
284 content::NotificationRegistrar registrar_;
286 // Have we seen an installation notification for kTestExtensionId ?
287 bool saw_install_;
289 // How many NOTIFICATION_BROWSER_OPENED notifications have we seen?
290 int browser_open_count_;
293 IN_PROC_BROWSER_TEST_F(CommandLineWebstoreInstall, CannotInstallNonEphemeral) {
294 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
295 command_line->AppendSwitchASCII(
296 switches::kInstallEphemeralAppFromWebstore, kTestExtensionId);
297 ExtensionInstallPrompt::g_auto_confirm_for_tests =
298 ExtensionInstallPrompt::ACCEPT;
299 extensions::StartupHelper helper;
300 EXPECT_FALSE(helper.InstallEphemeralApp(*command_line, browser()->profile()));
301 EXPECT_FALSE(saw_install());
302 EXPECT_EQ(0, browser_open_count());