app_list_service_interactive_uitest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 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 "chrome/browser/ui/app_list/app_list_service.h"
6
7#include "base/command_line.h"
8#include "base/json/json_file_value_serializer.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/message_loop/message_loop.h"
11#include "base/path_service.h"
12#include "base/strings/utf_string_conversions.h"
13#include "chrome/browser/browser_process.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/profiles/profile_manager.h"
16#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
17#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
18#include "chrome/browser/ui/browser.h"
19#include "chrome/browser/ui/host_desktop.h"
20#include "chrome/common/chrome_constants.h"
21#include "chrome/common/chrome_paths.h"
22#include "chrome/common/chrome_switches.h"
23#include "chrome/common/pref_names.h"
24#include "chrome/test/base/in_process_browser_test.h"
25#include "chrome/test/base/ui_test_utils.h"
26#include "ui/app_list/app_list_model.h"
27#include "ui/app_list/search_box_model.h"
28
29// Interactive UI Test for AppListService that runs on all platforms supporting
30// app_list. Interactive because the app list uses focus changes to dismiss
31// itself, which will cause tests that check the visibility to fail flakily.
32class AppListServiceInteractiveTest : public InProcessBrowserTest {
33 public:
34  AppListServiceInteractiveTest()
35    : profile2_(NULL) {}
36
37  void InitSecondProfile() {
38    ProfileManager* profile_manager = g_browser_process->profile_manager();
39    base::FilePath temp_profile_dir =
40        profile_manager->user_data_dir().AppendASCII("Profile 1");
41    profile_manager->CreateProfileAsync(
42        temp_profile_dir,
43        base::Bind(&AppListServiceInteractiveTest::OnProfileCreated,
44                   this),
45        base::string16(), base::string16(), std::string());
46    content::RunMessageLoop();  // Will stop in OnProfileCreated().
47  }
48
49  void OnProfileCreated(Profile* profile, Profile::CreateStatus status) {
50    if (status == Profile::CREATE_STATUS_INITIALIZED) {
51      profile2_ = profile;
52      base::MessageLoop::current()->Quit();
53    }
54  }
55
56 protected:
57  Profile* profile2_;
58
59 private:
60  DISALLOW_COPY_AND_ASSIGN(AppListServiceInteractiveTest);
61};
62
63// ChromeOS does not support ShowForProfile(), or profile switching within the
64// app list. Profile switching on CrOS goes through a different code path.
65#if defined(OS_CHROMEOS)
66#define MAYBE_ShowAndDismiss DISABLED_ShowAndDismiss
67#define MAYBE_SwitchAppListProfiles DISABLED_SwitchAppListProfiles
68#define MAYBE_SwitchAppListProfilesDuringSearch \
69    DISABLED_SwitchAppListProfilesDuringSearch
70#define MAYBE_ShowAppListNonDefaultProfile \
71    DISABLED_ShowAppListNonDefaultProfile
72#else
73#define MAYBE_ShowAndDismiss ShowAndDismiss
74#define MAYBE_SwitchAppListProfiles SwitchAppListProfiles
75#define MAYBE_SwitchAppListProfilesDuringSearch \
76    SwitchAppListProfilesDuringSearch
77#define MAYBE_ShowAppListNonDefaultProfile ShowAppListNonDefaultProfile
78#endif
79
80// Show the app list, then dismiss it.
81IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest, MAYBE_ShowAndDismiss) {
82  AppListService* service = test::GetAppListService();
83  ASSERT_FALSE(service->IsAppListVisible());
84  service->ShowForProfile(browser()->profile());
85  ASSERT_TRUE(service->IsAppListVisible());
86  service->DismissAppList();
87  ASSERT_FALSE(service->IsAppListVisible());
88}
89
90// Switch profiles on the app list while it is showing.
91IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest,
92                       MAYBE_SwitchAppListProfiles) {
93  InitSecondProfile();
94  test::SigninProfile(browser()->profile());
95  test::SigninProfile(profile2_);
96
97  AppListService* service = test::GetAppListService();
98  ASSERT_TRUE(service);
99
100  AppListControllerDelegate* controller(service->GetControllerDelegate());
101  ASSERT_TRUE(controller);
102
103  // Open the app list with the browser's profile.
104  ASSERT_FALSE(service->IsAppListVisible());
105  controller->ShowForProfileByPath(browser()->profile()->GetPath());
106  app_list::AppListModel* model = test::GetAppListModel(service);
107  ASSERT_TRUE(model);
108
109  base::RunLoop().RunUntilIdle();
110
111  ASSERT_TRUE(service->IsAppListVisible());
112  ASSERT_EQ(browser()->profile(), service->GetCurrentAppListProfile());
113
114  // Open the app list with the second profile.
115  controller->ShowForProfileByPath(profile2_->GetPath());
116  model = test::GetAppListModel(service);
117  ASSERT_TRUE(model);
118  base::RunLoop().RunUntilIdle();
119
120  ASSERT_TRUE(service->IsAppListVisible());
121  ASSERT_EQ(profile2_, service->GetCurrentAppListProfile());
122
123  controller->DismissView();
124}
125
126// Test switching app list profiles while search results are visibile.
127IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest,
128                       MAYBE_SwitchAppListProfilesDuringSearch) {
129  InitSecondProfile();
130  test::SigninProfile(browser()->profile());
131  test::SigninProfile(profile2_);
132
133  AppListService* service = test::GetAppListService();
134  ASSERT_TRUE(service);
135
136  AppListControllerDelegate* controller(service->GetControllerDelegate());
137  ASSERT_TRUE(controller);
138
139  // Set a search with original profile.
140  controller->ShowForProfileByPath(browser()->profile()->GetPath());
141  app_list::AppListModel* model = test::GetAppListModel(service);
142  ASSERT_TRUE(model);
143
144  model->search_box()->SetText(base::ASCIIToUTF16("minimal"));
145  base::RunLoop().RunUntilIdle();
146
147  // Switch to the second profile.
148  controller->ShowForProfileByPath(profile2_->GetPath());
149  model = test::GetAppListModel(service);
150  ASSERT_TRUE(model);
151  base::RunLoop().RunUntilIdle();
152
153  // Ensure the search box is empty.
154  ASSERT_TRUE(model->search_box()->text().empty());
155  ASSERT_EQ(profile2_, service->GetCurrentAppListProfile());
156
157  controller->DismissView();
158  ASSERT_FALSE(service->IsAppListVisible());
159}
160
161// Interactive UI test that adds the --show-app-list command line switch.
162class ShowAppListInteractiveTest : public InProcessBrowserTest {
163 public:
164  ShowAppListInteractiveTest() {}
165
166  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
167    command_line->AppendSwitch(switches::kShowAppList);
168  }
169
170 private:
171  DISALLOW_COPY_AND_ASSIGN(ShowAppListInteractiveTest);
172};
173
174// Test showing the app list using the command line switch.
175IN_PROC_BROWSER_TEST_F(ShowAppListInteractiveTest, ShowAppListFlag) {
176  AppListService* service = test::GetAppListService();
177  // The app list should already be shown because we passed
178  // switches::kShowAppList.
179  ASSERT_TRUE(service->IsAppListVisible());
180
181  // Create a browser to prevent shutdown when we dismiss the app list.  We
182  // need to do this because switches::kShowAppList suppresses the creation of
183  // any browsers.
184  CreateBrowser(service->GetCurrentAppListProfile());
185  service->DismissAppList();
186}
187
188// Interactive UI test that creates a non-default profile and configures it for
189// the --show-app-list flag.
190class ShowAppListNonDefaultInteractiveTest : public ShowAppListInteractiveTest {
191 public:
192  ShowAppListNonDefaultInteractiveTest()
193      : second_profile_name_(FILE_PATH_LITERAL("Profile 1")) {
194  }
195
196  virtual bool SetUpUserDataDirectory() OVERRIDE {
197    // Create a temp dir for "Profile 1" and seed the user data dir with a Local
198    // State file configuring the app list to use it.
199    base::FilePath user_data_dir;
200    CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
201    base::FilePath profile_path = user_data_dir.Append(second_profile_name_);
202    CHECK(second_profile_temp_dir_.Set(profile_path));
203
204    base::FilePath local_pref_path =
205        user_data_dir.Append(chrome::kLocalStateFilename);
206    base::DictionaryValue dict;
207    dict.SetString(prefs::kAppListProfile,
208                   second_profile_name_.MaybeAsASCII());
209    CHECK(JSONFileValueSerializer(local_pref_path).Serialize(dict));
210
211    return InProcessBrowserTest::SetUpUserDataDirectory();
212  }
213
214 protected:
215  const base::FilePath second_profile_name_;
216  base::ScopedTempDir second_profile_temp_dir_;
217
218 private:
219  DISALLOW_COPY_AND_ASSIGN(ShowAppListNonDefaultInteractiveTest);
220};
221
222// Test showing the app list for a profile that doesn't match the browser
223// profile.
224IN_PROC_BROWSER_TEST_F(ShowAppListNonDefaultInteractiveTest,
225                       MAYBE_ShowAppListNonDefaultProfile) {
226  AppListService* service = test::GetAppListService();
227  EXPECT_TRUE(service->IsAppListVisible());
228  EXPECT_EQ(second_profile_name_.value(),
229            service->GetCurrentAppListProfile()->GetPath().BaseName().value());
230
231  // Check that the default profile hasn't been loaded.
232  ProfileManager* profile_manager = g_browser_process->profile_manager();
233  EXPECT_EQ(1u, profile_manager->GetNumberOfProfiles());
234
235  // Create a browser for the Default profile. This stops MaybeTeminate being
236  // called when the app list window is dismissed. Use the last used browser
237  // profile to verify that it is different and causes ProfileManager to load a
238  // new profile.
239  CreateBrowser(profile_manager->GetLastUsedProfile());
240  EXPECT_EQ(2u, profile_manager->GetNumberOfProfiles());
241
242  service->DismissAppList();
243}
244