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