#include <memory>
#include <vector>
#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/feature_engagement/tracker_factory.h"
#include "chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/performance_controls/performance_controls_metrics.h"
#include "chrome/browser/ui/performance_controls/performance_intervention_button_controller.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/performance_controls/performance_intervention_bubble.h"
#include "chrome/browser/ui/views/performance_controls/performance_intervention_button.h"
#include "chrome/browser/ui/views/performance_controls/tab_list_row_view.h"
#include "chrome/browser/ui/views/performance_controls/tab_list_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/interaction/interaction_test_util_browser.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "chrome/test/user_education/interactive_feature_promo_test.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/performance_manager/public/features.h"
#include "components/performance_manager/public/resource_attribution/page_context.h"
#include "components/performance_manager/public/user_tuning/prefs.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "net/dns/mock_host_resolver.h"
#include "ui/base/interaction/interaction_test_util.h"
#include "ui/base/ozone_buildflags.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/animation/animation_test_api.h"
#include "ui/views/bubble/bubble_dialog_model_host.h"
#include "ui/views/interaction/interaction_test_util_views.h"
#include "ui/views/test/button_test_api.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/view.h"
namespace {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(…);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(…);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(…);
constexpr char kSkipPixelTestsReason[] = …;
constexpr char kMessageTriggerResultHistogram[] = …;
class DiscardWaiter : public resource_coordinator::TabLifecycleObserver { … };
}
class PerformanceInterventionInteractiveTest
: public InteractiveFeaturePromoTest { … };
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
ShowAndHideButton) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
BodyTextControlledByFeatureParamSingluarTab) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
BodyTextControlledByFeatureParamPluralTabs) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
LimitShowingButton) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
ActivateActionableTab) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
CloseActionableTab) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
InterventionToolbarButton) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
DialogRespondsToToolbarButtonClick) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
DialogUnaffectedByActionableTabChange) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
ButtonHidesAfterDialogCloses) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
ButtonStaysAfterDismissClicked) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
ButtonHidesAfterDeactivateClicked) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
TakeSuggestedAction) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
RemoveSuggestedTabFromList) { … }
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
UiShowsWhenPrefEnabled) { … }
#if !(BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_OZONE_WAYLAND))
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
UiShowsOnlyOnActiveWindow) {
Browser* const first_browser = browser();
ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 0, GetURL("a.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 1, GetURL("b.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
Browser* const second_browser = CreateBrowser(first_browser->profile());
ASSERT_TRUE(AddTabAtIndexToBrowser(second_browser, 0, GetURL("c.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
BrowserWindow* const first_browser_window = first_browser->window();
BrowserWindow* const second_browser_window = second_browser->window();
second_browser_window->Activate();
ASSERT_TRUE(second_browser_window->IsActive());
ASSERT_FALSE(first_browser_window->IsActive());
ToolbarButton* const first_button =
BrowserView::GetBrowserViewForBrowser(first_browser)
->toolbar()
->performance_intervention_button();
ToolbarButton* const second_button =
BrowserView::GetBrowserViewForBrowser(second_browser)
->toolbar()
->performance_intervention_button();
ASSERT_FALSE(first_button->GetVisible());
ASSERT_FALSE(second_button->GetVisible());
NotifyActionableTabListChange({0, 1}, first_browser);
EXPECT_FALSE(first_button->GetVisible());
EXPECT_TRUE(second_button->GetVisible());
ui_test_utils::BrowserActivationWaiter first_browser_waiter(first_browser);
first_browser_window->Activate();
first_browser_waiter.WaitForActivation();
ASSERT_FALSE(second_browser_window->IsActive());
ASSERT_TRUE(first_browser_window->IsActive());
NotifyActionableTabListChange({0}, first_browser);
EXPECT_FALSE(first_button->GetVisible());
EXPECT_TRUE(second_button->GetVisible());
}
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
NonactiveInterventionButtonHides) {
Browser* const first_browser = browser();
ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 0, GetURL("a.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 1, GetURL("b.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
Browser* const second_browser = CreateBrowser(first_browser->profile());
ASSERT_TRUE(AddTabAtIndexToBrowser(second_browser, 0, GetURL("c.com"),
ui::PageTransition::PAGE_TRANSITION_LINK));
BrowserWindow* const first_browser_window = first_browser->window();
BrowserWindow* const second_browser_window = second_browser->window();
second_browser_window->Activate();
ASSERT_TRUE(second_browser_window->IsActive());
NotifyActionableTabListChange({0, 1}, first_browser);
PerformanceInterventionButton* const intervention_button =
BrowserView::GetBrowserViewForBrowser(second_browser)
->toolbar()
->performance_intervention_button();
EXPECT_TRUE(intervention_button->GetVisible());
EXPECT_TRUE(intervention_button->IsBubbleShowing());
views::test::WidgetDestroyedWaiter widget_waiter(
intervention_button->bubble_dialog_model_host()->GetWidget());
ui::MouseEvent e(ui::EventType::kMousePressed, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
views::test::ButtonTestApi test_api(intervention_button);
test_api.NotifyClick(e);
widget_waiter.Wait();
EXPECT_TRUE(intervention_button->GetVisible());
EXPECT_FALSE(intervention_button->IsBubbleShowing());
ui_test_utils::BrowserActivationWaiter first_browser_waiter(first_browser);
first_browser_window->Activate();
first_browser_waiter.WaitForActivation();
ASSERT_FALSE(second_browser_window->IsActive());
ASSERT_TRUE(first_browser_window->IsActive());
EXPECT_TRUE(intervention_button->GetVisible());
NotifyActionableTabListChange({0}, first_browser);
EXPECT_TRUE(intervention_button->GetVisible());
EXPECT_FALSE(intervention_button->IsBubbleShowing());
NotifyActionableTabListChange({}, first_browser);
EXPECT_FALSE(intervention_button->GetVisible());
}
#endif
#if !BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
SuggestTabsOnlyForLastActiveProfile) { … }
#endif
class PerformanceInterventionNonUiMetricsTest
: public PerformanceInterventionInteractiveTest { … };
IN_PROC_BROWSER_TEST_F(PerformanceInterventionNonUiMetricsTest,
TriggerMetricsRecorded) { … }
class PerformanceInterventionMixedProfileTest
: public PerformanceInterventionInteractiveTest { … };
#if !BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(PerformanceInterventionMixedProfileTest,
SuggestTabsForMultipleProfiles) { … }
#endif