blob: 2dc50e06ac853f076a6f6b9c9dd85101c85e1137 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/app_list/app_list_service.h"
#include "base/command_line.h"
#include "base/json/json_file_value_serializer.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/test_utils.h"
#include "ui/app_list/app_list_model.h"
#include "ui/app_list/search_box_model.h"
// Interactive UI Test for AppListService that runs on all platforms supporting
// app_list. Interactive because the app list uses focus changes to dismiss
// itself, which will cause tests that check the visibility to fail flakily.
class AppListServiceInteractiveTest : public InProcessBrowserTest {
public:
AppListServiceInteractiveTest()
: profile2_(NULL) {}
void InitSecondProfile() { profile2_ = test::CreateSecondProfileAsync(); }
protected:
Profile* profile2_;
private:
DISALLOW_COPY_AND_ASSIGN(AppListServiceInteractiveTest);
};
// ChromeOS does not support ShowForProfile(), or profile switching within the
// app list. Profile switching on CrOS goes through a different code path.
#if defined(OS_CHROMEOS)
#define MAYBE_ShowAndDismiss DISABLED_ShowAndDismiss
#define MAYBE_SwitchAppListProfiles DISABLED_SwitchAppListProfiles
#define MAYBE_SwitchAppListProfilesDuringSearch \
DISABLED_SwitchAppListProfilesDuringSearch
#define MAYBE_ShowAppListNonDefaultProfile \
DISABLED_ShowAppListNonDefaultProfile
#define MAYBE_DeleteShowingAppList DISABLED_DeleteShowingAppList
#else
#define MAYBE_ShowAndDismiss ShowAndDismiss
#define MAYBE_SwitchAppListProfiles SwitchAppListProfiles
#define MAYBE_SwitchAppListProfilesDuringSearch \
SwitchAppListProfilesDuringSearch
#define MAYBE_ShowAppListNonDefaultProfile ShowAppListNonDefaultProfile
#define MAYBE_DeleteShowingAppList DeleteShowingAppList
#endif
// Show the app list, then dismiss it.
IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest, MAYBE_ShowAndDismiss) {
AppListService* service = test::GetAppListService();
ASSERT_FALSE(service->IsAppListVisible());
service->ShowForProfile(browser()->profile());
ASSERT_TRUE(service->IsAppListVisible());
service->DismissAppList();
ASSERT_FALSE(service->IsAppListVisible());
}
// Switch profiles on the app list while it is showing.
IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest,
MAYBE_SwitchAppListProfiles) {
InitSecondProfile();
AppListService* service = test::GetAppListService();
ASSERT_TRUE(service);
AppListControllerDelegate* controller(service->GetControllerDelegate());
ASSERT_TRUE(controller);
// Open the app list with the browser's profile.
ASSERT_FALSE(service->IsAppListVisible());
controller->ShowForProfileByPath(browser()->profile()->GetPath());
app_list::AppListModel* model = test::GetAppListModel(service);
ASSERT_TRUE(model);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(service->IsAppListVisible());
ASSERT_EQ(browser()->profile(), service->GetCurrentAppListProfile());
// Open the app list with the second profile.
controller->ShowForProfileByPath(profile2_->GetPath());
model = test::GetAppListModel(service);
ASSERT_TRUE(model);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(service->IsAppListVisible());
ASSERT_EQ(profile2_, service->GetCurrentAppListProfile());
controller->DismissView();
}
// Test switching app list profiles while search results are visibile.
IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest,
MAYBE_SwitchAppListProfilesDuringSearch) {
InitSecondProfile();
AppListService* service = test::GetAppListService();
ASSERT_TRUE(service);
AppListControllerDelegate* controller(service->GetControllerDelegate());
ASSERT_TRUE(controller);
// Set a search with original profile.
controller->ShowForProfileByPath(browser()->profile()->GetPath());
app_list::AppListModel* model = test::GetAppListModel(service);
ASSERT_TRUE(model);
model->search_box()->SetText(base::ASCIIToUTF16("minimal"));
base::RunLoop().RunUntilIdle();
// Switch to the second profile.
controller->ShowForProfileByPath(profile2_->GetPath());
model = test::GetAppListModel(service);
ASSERT_TRUE(model);
base::RunLoop().RunUntilIdle();
// Ensure the search box is empty.
ASSERT_TRUE(model->search_box()->text().empty());
ASSERT_EQ(profile2_, service->GetCurrentAppListProfile());
controller->DismissView();
ASSERT_FALSE(service->IsAppListVisible());
}
// Interactive UI test that adds the --show-app-list command line switch.
class ShowAppListInteractiveTest : public InProcessBrowserTest {
public:
ShowAppListInteractiveTest() {}
void SetUpCommandLine(CommandLine* command_line) override {
command_line->AppendSwitch(switches::kShowAppList);
}
private:
DISALLOW_COPY_AND_ASSIGN(ShowAppListInteractiveTest);
};
// Test showing the app list using the command line switch.
#if defined(OS_CHROMEOS)
// http://crbug.com/396499
#define MAYBE_ShowAppListFlag DISABLED_ShowAppListFlag
#else
#define MAYBE_ShowAppListFlag ShowAppListFlag
#endif
IN_PROC_BROWSER_TEST_F(ShowAppListInteractiveTest, MAYBE_ShowAppListFlag) {
AppListService* service = test::GetAppListService();
// The app list should already be shown because we passed
// switches::kShowAppList.
EXPECT_TRUE(service->IsAppListVisible());
// Create a browser to prevent shutdown when we dismiss the app list. We
// need to do this because switches::kShowAppList suppresses the creation of
// any browsers.
Profile* profile = service->GetCurrentAppListProfile();
CreateBrowser(profile);
service->DismissAppList();
EXPECT_FALSE(service->IsAppListVisible());
// With Chrome still running, test receiving a second --show-app-list request
// via the process singleton. ChromeOS has no process singleton so exclude it.
#if !defined(OS_CHROMEOS)
CommandLine command_line(CommandLine::NO_PROGRAM);
command_line.AppendSwitch(switches::kShowAppList);
StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
command_line, base::FilePath(), profile->GetPath());
EXPECT_TRUE(service->IsAppListVisible());
service->DismissAppList();
EXPECT_FALSE(service->IsAppListVisible());
#endif
}
// Interactive UI test that creates a non-default profile and configures it for
// the --show-app-list flag.
class ShowAppListNonDefaultInteractiveTest : public ShowAppListInteractiveTest {
public:
ShowAppListNonDefaultInteractiveTest()
: second_profile_name_(FILE_PATH_LITERAL("Profile 1")) {
}
bool SetUpUserDataDirectory() override {
// Create a temp dir for "Profile 1" and seed the user data dir with a Local
// State file configuring the app list to use it.
base::FilePath user_data_dir;
CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
base::FilePath profile_path = user_data_dir.Append(second_profile_name_);
CHECK(second_profile_temp_dir_.Set(profile_path));
base::FilePath local_pref_path =
user_data_dir.Append(chrome::kLocalStateFilename);
base::DictionaryValue dict;
dict.SetString(prefs::kAppListProfile,
second_profile_name_.MaybeAsASCII());
CHECK(JSONFileValueSerializer(local_pref_path).Serialize(dict));
return InProcessBrowserTest::SetUpUserDataDirectory();
}
protected:
const base::FilePath second_profile_name_;
base::ScopedTempDir second_profile_temp_dir_;
private:
DISALLOW_COPY_AND_ASSIGN(ShowAppListNonDefaultInteractiveTest);
};
// Test showing the app list for a profile that doesn't match the browser
// profile.
IN_PROC_BROWSER_TEST_F(ShowAppListNonDefaultInteractiveTest,
MAYBE_ShowAppListNonDefaultProfile) {
AppListService* service = test::GetAppListService();
EXPECT_TRUE(service->IsAppListVisible());
EXPECT_EQ(second_profile_name_.value(),
service->GetCurrentAppListProfile()->GetPath().BaseName().value());
// Check that the default profile hasn't been loaded.
ProfileManager* profile_manager = g_browser_process->profile_manager();
EXPECT_EQ(1u, profile_manager->GetNumberOfProfiles());
// Create a browser for the Default profile. This stops MaybeTeminate being
// called when the app list window is dismissed. Use the last used browser
// profile to verify that it is different and causes ProfileManager to load a
// new profile.
CreateBrowser(profile_manager->GetLastUsedProfile());
EXPECT_EQ(2u, profile_manager->GetNumberOfProfiles());
service->DismissAppList();
}
// Test showing the app list for a profile then deleting that profile while the
// app list is visible.
IN_PROC_BROWSER_TEST_F(ShowAppListNonDefaultInteractiveTest,
MAYBE_DeleteShowingAppList) {
AppListService* service = test::GetAppListService();
EXPECT_TRUE(service->IsAppListVisible());
EXPECT_EQ(second_profile_name_.value(),
service->GetCurrentAppListProfile()->GetPath().BaseName().value());
ProfileManager* profile_manager = g_browser_process->profile_manager();
// Create a browser for the Default profile.
CreateBrowser(profile_manager->GetLastUsedProfile());
// Delete the profile being used by the app list.
profile_manager->ScheduleProfileForDeletion(
service->GetCurrentAppListProfile()->GetPath(),
ProfileManager::CreateCallback());
// App Launcher should get closed immediately and nothing should explode.
EXPECT_FALSE(service->IsAppListVisible());
}