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