#include "base/functional/callback.h"
#include "base/scoped_observation.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/background/glic/glic_background_mode_manager.h"
#include "chrome/browser/background/glic/glic_status_icon.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/glic/glic_pref_names.h"
#include "chrome/browser/glic/glic_profile_manager.h"
#include "chrome/browser/glic/public/glic_keyed_service.h"
#include "chrome/browser/glic/public/glic_keyed_service_factory.h"
#include "chrome/browser/glic/test_support/glic_test_util.h"
#include "chrome/browser/glic/test_support/interactive_glic_test.h"
#include "chrome/browser/glic/widget/glic_window_controller.h"
#include "chrome/browser/global_features.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/status_icons/status_tray.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/views/frame/tab_strip_view_interface.h"
#include "chrome/browser/ui/views/interaction/browser_elements_views.h"
#include "chrome/browser/ui/views/tabs/glic_button.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_test.h"
namespace glic {
class GlicStatusIconUiTest : public test::InteractiveGlicTest,
public testing::WithParamInterface<bool> {
public:
GlicStatusIconUiTest() {
feature_list_.InitAndDisableFeature(features::kGlicWarming);
}
~GlicStatusIconUiTest() override = default;
void TearDownOnMainThread() override {
g_browser_process->local_state()->SetBoolean(prefs::kGlicLauncherEnabled,
false);
test::InteractiveGlicTest::TearDownOnMainThread();
}
bool IsContextMenuItemVisible(int id) {
return GetContextMenu()->IsCommandIdVisible(id);
}
auto EnableGlicLauncher() {
return Do([]() {
g_browser_process->local_state()->SetBoolean(prefs::kGlicLauncherEnabled,
true);
});
}
auto VerifyStatusIconVisibility(bool visible) {
return Do([visible]() {
EXPECT_EQ(visible,
g_browser_process->status_tray()->HasStatusIconOfTypeForTesting(
StatusTray::StatusIconType::GLIC_ICON));
});
}
auto VerifyStatusIconContextMenuItemVisibilty(bool show_item_is_visible) {
return Do([this, show_item_is_visible]() {
EXPECT_EQ(show_item_is_visible,
this->IsContextMenuItemVisible(IDC_GLIC_STATUS_ICON_MENU_SHOW));
EXPECT_NE(show_item_is_visible, this->IsContextMenuItemVisible(
IDC_GLIC_STATUS_ICON_MENU_CLOSE));
});
}
auto SimulateContextMenuItemClick(int id) {
return Do([this, id]() { this->GetContextMenu()->ExecuteCommand(id, 0); });
}
bool ShouldForceEmptyButtonBounds() const { return GetParam(); }
auto CreateAndActivateGlicForProfile(Profile* profile) {
return Do([profile] {
auto* service = GlicKeyedServiceFactory::GetGlicKeyedService(profile);
GlicProfileManager::GetInstance()->SetActiveGlic(service);
GlicProfileManager::ForceProfileForLaunchForTesting(profile);
});
}
auto ForceEmptyButtonBounds(Browser* browser) {
return Do([browser] {
auto* glic_button =
BrowserElementsViews::From(browser)->GetViewAs<glic::GlicButton>(
kGlicButtonElementId);
glic_button->SetSize(gfx::Size(0, 0));
});
}
Profile* CreateSecondProfile() {
auto* profile_manager = g_browser_process->profile_manager();
auto new_path = profile_manager->GenerateNextProfileDirectoryPath();
profiles::testing::CreateProfileSync(profile_manager, new_path);
auto* profile = profile_manager->GetProfile(new_path);
return profile;
}
GlicWindowController& GetWindowControllerForProfile(Profile* profile) {
auto* service = GlicKeyedServiceFactory::GetGlicKeyedService(profile);
return service->window_controller();
}
private:
StatusIconMenuModel* GetContextMenu() {
GlicBackgroundModeManager* const manager =
g_browser_process->GetFeatures()->glic_background_mode_manager();
GlicStatusIcon* status_icon = manager->GetStatusIconForTesting();
return status_icon->GetContextMenuForTesting();
}
base::test::ScopedFeatureList feature_list_;
};
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_ShowClose DISABLED_ShowClose
#else
#define MAYBE_ShowClose ShowClose
#endif
IN_PROC_BROWSER_TEST_P(GlicStatusIconUiTest, MAYBE_ShowClose) {
if (base::FeatureList::IsEnabled(features::kGlicMultiInstance)) {
GTEST_SKIP() << "Skipping for kGlicMultiInstance";
}
Profile* other_profile = CreateSecondProfile();
RunTestSequence(
VerifyStatusIconVisibility(false), EnableGlicLauncher(),
VerifyStatusIconVisibility(true),
VerifyStatusIconContextMenuItemVisibilty(true),
WaitForShow(kGlicButtonElementId),
If([this]() { return this->ShouldForceEmptyButtonBounds(); },
Then(ForceEmptyButtonBounds(browser()))),
SimulateContextMenuItemClick(IDC_GLIC_STATUS_ICON_MENU_SHOW),
WaitForAndInstrumentGlic(kHostAndContents),
VerifyStatusIconContextMenuItemVisibilty(false),
SimulateContextMenuItemClick(IDC_GLIC_STATUS_ICON_MENU_CLOSE),
WaitForHide(kGlicViewElementId),
VerifyStatusIconContextMenuItemVisibilty(true),
CreateAndActivateGlicForProfile(other_profile),
VerifyStatusIconContextMenuItemVisibilty(true),
SimulateContextMenuItemClick(IDC_GLIC_STATUS_ICON_MENU_SHOW),
WaitForAndInstrumentGlic(kHostAndContents,
GetWindowControllerForProfile(other_profile)),
VerifyStatusIconContextMenuItemVisibilty(false));
}
INSTANTIATE_TEST_SUITE_P(All,
GlicStatusIconUiTest,
testing::Bool(),
[](const testing::TestParamInfo<bool>& info) {
return info.param ? "empty_button_bounds"
: "non_empty_button_bounds";
});
}