blob: da13018592028ea7d35e498e6bc301a379044536 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/accelerator_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "chrome/test/interaction/tracked_element_webcontents.h"
#include "chrome/test/interaction/webcontents_interaction_test_util.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/performance_manager/public/features.h"
#include "content/public/test/browser_test.h"
#include "extensions/common/extension_urls.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/expect_call_in_scope.h"
#include "ui/base/interaction/interaction_sequence.h"
#include "url/gurl.h"
namespace {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPrimaryTabPageElementId);
} // namespace
class AppMenuModelInteractiveTest : public InteractiveBrowserTest {
public:
AppMenuModelInteractiveTest() = default;
~AppMenuModelInteractiveTest() override = default;
AppMenuModelInteractiveTest(const AppMenuModelInteractiveTest&) = delete;
void operator=(const AppMenuModelInteractiveTest&) = delete;
void SetUp() override {
set_open_about_blank_on_browser_launch(true);
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
InteractiveBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
InteractiveBrowserTest::SetUpOnMainThread();
embedded_test_server()->StartAcceptingConnections();
}
void TearDownOnMainThread() override {
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
InteractiveBrowserTest::TearDownOnMainThread();
}
protected:
auto CheckInconitoWindowOpened() {
return Check(base::BindLambdaForTesting([]() {
Browser* new_browser;
if (BrowserList::GetIncognitoBrowserCount() == 1) {
new_browser = BrowserList::GetInstance()->GetLastActive();
} else {
new_browser = ui_test_utils::WaitForBrowserToOpen();
}
return new_browser->profile()->IsIncognitoProfile();
}));
}
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(AppMenuModelInteractiveTest, PerformanceNavigation) {
RunTestSequence(InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kMoreToolsMenuItem),
SelectMenuItem(ToolsMenuModel::kPerformanceMenuItem),
WaitForWebContentsNavigation(
kPrimaryTabPageElementId,
GURL(chrome::kChromeUIPerformanceSettingsURL)));
}
IN_PROC_BROWSER_TEST_F(AppMenuModelInteractiveTest, IncognitoMenuItem) {
RunTestSequence(PressButton(kAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kIncognitoMenuItem),
CheckInconitoWindowOpened());
}
IN_PROC_BROWSER_TEST_F(AppMenuModelInteractiveTest, IncognitoAccelerator) {
ui::Accelerator incognito_accelerator;
chrome::AcceleratorProviderForBrowser(browser())->GetAcceleratorForCommandId(
IDC_NEW_INCOGNITO_WINDOW, &incognito_accelerator);
RunTestSequence(
SendAccelerator(kAppMenuButtonElementId, incognito_accelerator),
CheckInconitoWindowOpened());
}
class ExtensionsMenuModelInteractiveTest : public AppMenuModelInteractiveTest {
public:
explicit ExtensionsMenuModelInteractiveTest(bool enable_feature = true) {
scoped_feature_list_.InitWithFeatureState(
features::kExtensionsMenuInAppMenu, enable_feature);
}
~ExtensionsMenuModelInteractiveTest() override = default;
ExtensionsMenuModelInteractiveTest(
const ExtensionsMenuModelInteractiveTest&) = delete;
void operator=(const ExtensionsMenuModelInteractiveTest&) = delete;
void SetUp() override {
set_open_about_blank_on_browser_launch(true);
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
InteractiveBrowserTest::SetUp();
}
protected:
base::HistogramTester histograms;
};
class ExtensionsMenuModelPresenceTest
: public ExtensionsMenuModelInteractiveTest,
public testing::WithParamInterface<bool> {
public:
ExtensionsMenuModelPresenceTest()
: ExtensionsMenuModelInteractiveTest(/*enable_feature=*/GetParam()) {}
~ExtensionsMenuModelPresenceTest() override = default;
ExtensionsMenuModelPresenceTest(const ExtensionsMenuModelPresenceTest&) =
delete;
void operator=(const ExtensionsMenuModelPresenceTest&) = delete;
};
INSTANTIATE_TEST_SUITE_P(
All,
ExtensionsMenuModelPresenceTest,
/* features::kNewExtensionsTopLevelMenu status */ testing::Bool());
// Test to confirm that the structure of the Extensions menu is present but that
// no histograms are logged since it isn't interacted with.
IN_PROC_BROWSER_TEST_P(ExtensionsMenuModelPresenceTest, MenuPresence) {
if (GetParam()) { // Menu enabled
RunTestSequence(
InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
EnsurePresent(AppMenuModel::kExtensionsMenuItem),
SelectMenuItem(AppMenuModel::kExtensionsMenuItem),
EnsurePresent(ExtensionsMenuModel::kManageExtensionsMenuItem),
EnsurePresent(ExtensionsMenuModel::kVisitChromeWebStoreMenuItem));
} else {
RunTestSequence(InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
EnsureNotPresent(AppMenuModel::kExtensionsMenuItem));
}
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.VisitChromeWebStore", 0);
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.ManageExtensions", 0);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_MANAGE_EXTENSIONS, 0);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_VISIT_CHROME_WEB_STORE, 0);
}
// Test to confirm that the manage extensions menu item navigates when selected
// and emite histograms that it did so.
IN_PROC_BROWSER_TEST_F(ExtensionsMenuModelInteractiveTest, ManageExtensions) {
RunTestSequence(
InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kExtensionsMenuItem),
SelectMenuItem(ExtensionsMenuModel::kManageExtensionsMenuItem),
WaitForWebContentsNavigation(kPrimaryTabPageElementId,
GURL(chrome::kChromeUIExtensionsURL)));
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.ManageExtensions", 1);
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.VisitChromeWebStore", 0);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_MANAGE_EXTENSIONS, 1);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_VISIT_CHROME_WEB_STORE, 0);
}
// Test to confirm that the visit Chome Web Store menu item navigates when
// selected and emits histograms that it did so.
IN_PROC_BROWSER_TEST_F(ExtensionsMenuModelInteractiveTest,
VisitChromeWebStore) {
RunTestSequence(
InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kExtensionsMenuItem),
SelectMenuItem(ExtensionsMenuModel::kVisitChromeWebStoreMenuItem),
WaitForWebContentsNavigation(kPrimaryTabPageElementId,
extension_urls::AppendUtmSource(
extension_urls::GetWebstoreLaunchURL(),
extension_urls::kAppMenuUtmSource)));
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.VisitChromeWebStore", 1);
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.ManageExtensions", 0);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_VISIT_CHROME_WEB_STORE, 1);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_MANAGE_EXTENSIONS, 0);
}
class PasswordManagerMenuItemInteractiveTest
: public AppMenuModelInteractiveTest,
public testing::WithParamInterface<bool> {
public:
PasswordManagerMenuItemInteractiveTest() {
scoped_feature_list_.InitWithFeatureState(
password_manager::features::kPasswordManagerRedesign, GetParam());
}
PasswordManagerMenuItemInteractiveTest(
const PasswordManagerMenuItemInteractiveTest&) = delete;
void operator=(const PasswordManagerMenuItemInteractiveTest&) = delete;
~PasswordManagerMenuItemInteractiveTest() override = default;
};
INSTANTIATE_TEST_SUITE_P(
All,
PasswordManagerMenuItemInteractiveTest,
/* features::kPasswordManagerRedesign status */ testing::Bool());
IN_PROC_BROWSER_TEST_P(PasswordManagerMenuItemInteractiveTest,
PasswordManagerMenuItem) {
base::HistogramTester histograms;
if (base::FeatureList::IsEnabled(
password_manager::features::kPasswordManagerRedesign)) {
RunTestSequence(InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
SelectMenuItem(AppMenuModel::kPasswordManagerMenuItem),
WaitForWebContentsNavigation(
kPrimaryTabPageElementId,
GURL("chrome://password-manager/passwords")));
histograms.ExpectTotalCount("WrenchMenu.TimeToAction.PasswordManager", 1);
histograms.ExpectBucketCount("WrenchMenu.MenuAction",
MENU_ACTION_PASSWORD_MANAGER, 1);
} else {
RunTestSequence(InstrumentTab(kPrimaryTabPageElementId),
PressButton(kAppMenuButtonElementId),
EnsureNotPresent(AppMenuModel::kPasswordManagerMenuItem));
}
}
IN_PROC_BROWSER_TEST_P(PasswordManagerMenuItemInteractiveTest,
NoMenuItemOnPasswordManagerPage) {
RunTestSequence(
AddInstrumentedTab(kPrimaryTabPageElementId,
GURL("chrome://password-manager/passwords")),
PressButton(kAppMenuButtonElementId),
EnsureNotPresent(AppMenuModel::kPasswordManagerMenuItem));
}