extension_install_ui_browsertest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/command_line.h"
6#include "base/strings/string_util.h"
7#include "chrome/app/chrome_command_ids.h"
8#include "chrome/browser/chrome_notification_types.h"
9#include "chrome/browser/extensions/extension_browsertest.h"
10#include "chrome/browser/extensions/extension_service.h"
11#include "chrome/browser/infobars/confirm_infobar_delegate.h"
12#include "chrome/browser/infobars/infobar.h"
13#include "chrome/browser/infobars/infobar_service.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/themes/theme_service.h"
16#include "chrome/browser/themes/theme_service_factory.h"
17#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/browser_commands.h"
19#include "chrome/browser/ui/browser_finder.h"
20#include "chrome/browser/ui/tabs/tab_strip_model.h"
21#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
22#include "chrome/common/url_constants.h"
23#include "chrome/test/base/test_switches.h"
24#include "chrome/test/base/ui_test_utils.h"
25#include "content/public/browser/web_contents.h"
26#include "content/public/test/browser_test_utils.h"
27#include "extensions/browser/app_sorting.h"
28#include "extensions/common/id_util.h"
29
30using content::WebContents;
31using extensions::AppSorting;
32using extensions::Extension;
33
34class ExtensionInstallUIBrowserTest : public ExtensionBrowserTest {
35 public:
36  // Checks that a theme info bar is currently visible and issues an undo to
37  // revert to the previous theme.
38  void VerifyThemeInfoBarAndUndoInstall() {
39    WebContents* web_contents =
40        browser()->tab_strip_model()->GetActiveWebContents();
41    ASSERT_TRUE(web_contents);
42    InfoBarService* infobar_service =
43        InfoBarService::FromWebContents(web_contents);
44    ASSERT_EQ(1U, infobar_service->infobar_count());
45    ConfirmInfoBarDelegate* delegate =
46        infobar_service->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
47    ASSERT_TRUE(delegate);
48    delegate->Cancel();
49    ASSERT_EQ(0U, infobar_service->infobar_count());
50  }
51
52  // Install the given theme from the data dir and verify expected name.
53  void InstallThemeAndVerify(const char* theme_name,
54                             const std::string& expected_name) {
55    // If there is already a theme installed, the current theme should be
56    // disabled and the new one installed + enabled.
57    int expected_change = GetTheme() ? 0 : 1;
58    const base::FilePath theme_path = test_data_dir_.AppendASCII(theme_name);
59    ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_path, expected_change,
60        browser()));
61    const Extension* theme = GetTheme();
62    ASSERT_TRUE(theme);
63    ASSERT_EQ(theme->name(), expected_name);
64  }
65
66  const Extension* GetTheme() const {
67    return ThemeServiceFactory::GetThemeForProfile(browser()->profile());
68  }
69};
70
71#if defined(OS_LINUX)
72// Fails consistently on bot chromium.chromiumos \ Linux.
73// See: http://crbug.com/120647.
74#define MAYBE_TestThemeInstallUndoResetsToDefault DISABLED_TestThemeInstallUndoResetsToDefault
75#else
76#define MAYBE_TestThemeInstallUndoResetsToDefault TestThemeInstallUndoResetsToDefault
77#endif
78
79IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
80                       MAYBE_TestThemeInstallUndoResetsToDefault) {
81#if defined(OS_WIN) && defined(USE_ASH)
82  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
83  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
84    return;
85#endif
86
87  // Install theme once and undo to verify we go back to default theme.
88  base::FilePath theme_crx = PackExtension(test_data_dir_.AppendASCII("theme"));
89  ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 1, browser()));
90  const Extension* theme = GetTheme();
91  ASSERT_TRUE(theme);
92  std::string theme_id = theme->id();
93  VerifyThemeInfoBarAndUndoInstall();
94  ASSERT_EQ(NULL, GetTheme());
95
96  // Set the same theme twice and undo to verify we go back to default theme.
97  ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 0, browser()));
98  theme = GetTheme();
99  ASSERT_TRUE(theme);
100  ASSERT_EQ(theme_id, theme->id());
101  ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 0, browser()));
102  theme = GetTheme();
103  ASSERT_TRUE(theme);
104  ASSERT_EQ(theme_id, theme->id());
105  VerifyThemeInfoBarAndUndoInstall();
106  ASSERT_EQ(NULL, GetTheme());
107}
108
109IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
110                       TestThemeInstallUndoResetsToPreviousTheme) {
111#if defined(OS_WIN) && defined(USE_ASH)
112  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
113  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
114    return;
115#endif
116
117  // Install first theme.
118  InstallThemeAndVerify("theme", "camo theme");
119  const Extension* theme = GetTheme();
120  std::string theme_id = theme->id();
121
122  // Then install second theme.
123  InstallThemeAndVerify("theme2", "snowflake theme");
124  const Extension* theme2 = GetTheme();
125  EXPECT_FALSE(theme_id == theme2->id());
126
127  // Undo second theme will revert to first theme.
128  VerifyThemeInfoBarAndUndoInstall();
129  EXPECT_EQ(theme, GetTheme());
130}
131
132IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
133                       TestThemeReset) {
134  InstallThemeAndVerify("theme", "camo theme");
135
136  // Reset to default theme.
137  ThemeServiceFactory::GetForProfile(browser()->profile())->UseDefaultTheme();
138  ASSERT_FALSE(GetTheme());
139}
140
141IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
142                       TestInstallThemeInFullScreen) {
143  EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_FULLSCREEN));
144  InstallThemeAndVerify("theme", "camo theme");
145}
146
147// TODO(samarth): remove along with NTP4 code.
148IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
149                       DISABLED_AppInstallConfirmation) {
150  int num_tabs = browser()->tab_strip_model()->count();
151
152  base::FilePath app_dir = test_data_dir_.AppendASCII("app");
153  ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(app_dir, 1, browser()));
154
155  if (NewTabUI::ShouldShowApps()) {
156    EXPECT_EQ(num_tabs + 1, browser()->tab_strip_model()->count());
157    WebContents* web_contents =
158        browser()->tab_strip_model()->GetActiveWebContents();
159    ASSERT_TRUE(web_contents);
160    EXPECT_TRUE(StartsWithASCII(web_contents->GetURL().spec(),
161                                "chrome://newtab/", false));
162  } else {
163    // TODO(xiyuan): Figure out how to test extension installed bubble?
164  }
165}
166
167// TODO(samarth): remove along with NTP4 code.
168IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
169                       DISABLED_AppInstallConfirmation_Incognito) {
170  Browser* incognito_browser = CreateIncognitoBrowser();
171
172  int num_incognito_tabs = incognito_browser->tab_strip_model()->count();
173  int num_normal_tabs = browser()->tab_strip_model()->count();
174
175  base::FilePath app_dir = test_data_dir_.AppendASCII("app");
176  ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(app_dir, 1,
177                                                incognito_browser));
178
179  EXPECT_EQ(num_incognito_tabs,
180            incognito_browser->tab_strip_model()->count());
181  if (NewTabUI::ShouldShowApps()) {
182    EXPECT_EQ(num_normal_tabs + 1, browser()->tab_strip_model()->count());
183    WebContents* web_contents =
184        browser()->tab_strip_model()->GetActiveWebContents();
185    ASSERT_TRUE(web_contents);
186    EXPECT_TRUE(StartsWithASCII(web_contents->GetURL().spec(),
187                                "chrome://newtab/", false));
188  } else {
189    // TODO(xiyuan): Figure out how to test extension installed bubble?
190  }
191}
192
193class NewTabUISortingBrowserTest : public ExtensionInstallUIBrowserTest,
194                                   public content::NotificationObserver {
195 public:
196  NewTabUISortingBrowserTest() {}
197
198  virtual void Observe(int type,
199                       const content::NotificationSource& source,
200                       const content::NotificationDetails& details) OVERRIDE {
201    if (type != chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED) {
202      observer_->Observe(type, source, details);
203      return;
204    }
205    const std::string* id = content::Details<const std::string>(details).ptr();
206    EXPECT_TRUE(id);
207    last_reordered_extension_id_ = *id;
208  }
209
210 protected:
211  std::string last_reordered_extension_id_;
212  content::NotificationRegistrar registrar_;
213
214 private:
215  DISALLOW_COPY_AND_ASSIGN(NewTabUISortingBrowserTest);
216};
217
218// TODO(samarth): remove along with NTP4 code.
219IN_PROC_BROWSER_TEST_F(NewTabUISortingBrowserTest,
220                       DISABLED_ReorderDuringInstall) {
221  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
222  ExtensionService* service = extensions::ExtensionSystem::Get(
223      browser()->profile())->extension_service();
224  base::FilePath app_dir = test_data_dir_.AppendASCII("app");
225  const std::string app_id = extensions::id_util::GenerateIdForPath(app_dir);
226
227  const extensions::Extension* webstore_extension =
228      service->GetInstalledExtension(extension_misc::kWebStoreAppId);
229  EXPECT_TRUE(webstore_extension);
230  AppSorting* sorting = service->extension_prefs()->app_sorting();
231
232  // Register for notifications in the same way as AppLauncherHandler.
233  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
234      content::Source<AppSorting>(sorting));
235  // ExtensionAppItem calls this when an app install starts.
236  sorting->EnsureValidOrdinals(app_id, syncer::StringOrdinal());
237  // Vefify the app is not actually installed yet.
238  EXPECT_FALSE(service->GetInstalledExtension(app_id));
239  // Move the test app from the end to be before the web store.
240  service->OnExtensionMoved(app_id,
241                            std::string(),
242                            extension_misc::kWebStoreAppId);
243  EXPECT_EQ(app_id, last_reordered_extension_id_);
244
245  // Now install the app.
246  const extensions::Extension* test_app = LoadExtension(app_dir);
247  ASSERT_TRUE(test_app);
248  EXPECT_TRUE(service->GetInstalledExtension(app_id));
249  EXPECT_EQ(app_id, test_app->id());
250}
251