blob: a730cbd50c104bebc9ddb78f28cafac8bc41b0fa [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <optional>
#include <sstream>
#include "base/feature_list.h"
#include "base/functional/overloaded.h"
#include "base/test/metrics/user_action_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h"
#include "chrome/browser/ui/toolbar_controller_util.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_util.h"
#include "chrome/browser/ui/views/toolbar/chrome_labs/chrome_labs_button.h"
#include "chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h"
#include "chrome/browser/ui/views/toolbar/toolbar_controller.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/interaction/feature_engagement_initialized_observer.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/feature_engagement/test/scoped_iph_feature_list.h"
#include "components/user_education/common/feature_promo_result.h"
#include "components/user_education/views/help_bubble_view.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/test/test_extension_dir.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/test/views_test_utils.h"
#include "ui/views/view_class_properties.h"
namespace {
constexpr int kBrowserContentAllowedMinimumWidth =
BrowserViewLayout::kMainBrowserContentsMinimumWidth;
} // namespace
class ToolbarControllerUiTest : public InteractiveFeaturePromoTest {
public:
ToolbarControllerUiTest()
: InteractiveFeaturePromoTest(UseDefaultTrackerAllowingPromos(
{feature_engagement::kIPHTabSearchFeature})) {
ToolbarControllerUtil::SetPreventOverflowForTesting(false);
scoped_feature_list_.InitWithFeatures(
{features::kResponsiveToolbar, features::kSidePanelPinning,
features::kChromeRefresh2023},
{});
}
void SetUpOnMainThread() override {
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
embedded_test_server()->StartAcceptingConnections();
InteractiveFeaturePromoTest::SetUpOnMainThread();
browser_view_ = BrowserView::GetBrowserViewForBrowser(browser());
toolbar_controller_ = const_cast<ToolbarController*>(
browser_view_->toolbar()->toolbar_controller());
toolbar_container_view_ = const_cast<views::View*>(
toolbar_controller_->toolbar_container_view_.get());
overflow_button_ = toolbar_controller_->overflow_button_;
dummy_button_size_ = overflow_button_->GetPreferredSize();
responsive_elements_ = toolbar_controller_->responsive_elements_;
element_flex_order_start_ = toolbar_controller_->element_flex_order_start_;
MaybeAddDummyButtonsToToolbarView();
overflow_threshold_width_ = GetOverflowThresholdWidthInToolbarContainer();
}
void TearDownOnMainThread() override {
toolbar_container_view_ = nullptr;
overflow_button_ = nullptr;
toolbar_controller_ = nullptr;
browser_view_ = nullptr;
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
InteractiveFeaturePromoTest::TearDownOnMainThread();
}
// Returns the minimum width the toolbar view can be without any ToolbarButton
// dropped out in ToolbarContainer. This function calculates the
// browser width where elements with flex order > kOrderOffset defined in
// ToolbarView should have minimum size. Since elements with flex order <=
// kOrderOffset happens to have minimum width == preferred width it has no
// effect on diff_sum.
int GetOverflowThresholdWidthInToolbarContainer() {
int diff_sum = 0;
for (views::View* element : toolbar_container_view_->children()) {
diff_sum += element->GetPreferredSize().width() -
element->GetMinimumSize().width();
}
return toolbar_container_view_->GetPreferredSize().width() - diff_sum;
}
// Returns the minimum width the toolbar view can be without any elements
// dropped out in PinnedSidePanelContainer. This function calculates the
// browser width where elements with flex order > kToolbarActionsFlexOrder
// defined in ToolbarView should have minimum size
int GetOverflowThresholdWidthInPinnedSidePanelContainer() {
auto* extensions_container =
browser_view_->toolbar()->extensions_container();
int diff = extensions_container->GetPreferredSize().width() -
extensions_container->GetMinimumSize().width();
return toolbar_container_view_->GetPreferredSize().width() - diff;
}
// Because actual_browser_minimum_width == Max(toolbar_width,
// kBrowserContentAllowedMinimumWidth) So if `overflow_threshold_width_` <
// kBrowserContentAllowedMinimumWidth, then actual_browser_minimum_width ==
// kBrowserContentAllowedMinimumWidth In this case we will never see any
// overflow so stuff toolbar with some fixed dummy buttons till it's
// guaranteed we can observe overflow with browser resized to its minimum
// width.
void MaybeAddDummyButtonsToToolbarView() {
while (GetOverflowThresholdWidthInToolbarContainer() <=
kBrowserContentAllowedMinimumWidth) {
toolbar_container_view_->AddChildView(CreateADummyButton());
}
}
std::unique_ptr<ToolbarButton> CreateADummyButton() {
auto button = std::make_unique<ToolbarButton>();
button->SetPreferredSize(dummy_button_size_);
button->SetMinSize(dummy_button_size_);
button->SetAccessibleName(u"dummybutton");
button->SetVisible(true);
return button;
}
// Forces `id` to overflow by filling toolbar with dummy buttons.
void AddDummyButtonsToToolbarTillElementOverflows(
absl::variant<ui::ElementIdentifier, actions::ActionId> id) {
// This element must have been managed by controller.
EXPECT_TRUE(
std::find_if(
responsive_elements_.begin(), responsive_elements_.end(),
[id](const ToolbarController::ResponsiveElementInfo& element) {
return absl::visit(
base::Overloaded(
[&](ToolbarController::ElementIdInfo overflow_id) {
return absl::holds_alternative<ui::ElementIdentifier>(
id) &&
overflow_id.overflow_identifier ==
absl::get<ui::ElementIdentifier>(id);
},
[&](actions::ActionId overflow_id) {
return absl::holds_alternative<actions::ActionId>(id) &&
overflow_id == absl::get<actions::ActionId>(id);
}),
element.overflow_id);
}) != responsive_elements_.end());
SetBrowserWidth(kBrowserContentAllowedMinimumWidth);
absl::visit(
base::Overloaded{
[this](ui::ElementIdentifier id) {
const auto* element =
toolbar_controller_->FindToolbarElementWithId(
toolbar_container_view_, id);
ASSERT_NE(element, nullptr);
while (element->GetVisible()) {
toolbar_container_view_->AddChildView(CreateADummyButton());
views::test::RunScheduledLayout(browser_view_);
}
},
[this](actions::ActionId id) {
while (!delegate()->IsOverflowed(id)) {
toolbar_container_view_->AddChildView(CreateADummyButton());
views::test::RunScheduledLayout(browser_view_);
}
}},
id);
}
// This checks menu model, not the actual menu that pops up.
// TODO(pengchaocai): Explore a way to check the actual menu appearing.
auto CheckMenuMatchesOverflowedElements() {
return Steps(Check([this]() {
const ui::SimpleMenuModel* menu = GetOverflowMenu();
EXPECT_NE(menu, nullptr);
EXPECT_GT(menu->GetItemCount(), size_t(0));
const auto& responsive_elements =
toolbar_controller_->responsive_elements_;
for (size_t i = 0; i < responsive_elements.size(); ++i) {
if (toolbar_controller_->IsOverflowed(responsive_elements[i])) {
if (toolbar_controller_->GetMenuText(responsive_elements[i]) !=
menu->GetLabelAt(menu->GetIndexOfCommandId(i).value())) {
return false;
}
}
}
return true;
}));
}
auto ActivateMenuItemWithElementId(
absl::variant<ui::ElementIdentifier, actions::ActionId> id) {
return Do([=]() {
int command_id = -1;
for (size_t i = 0; i < responsive_elements_.size(); ++i) {
const auto& overflow_id = responsive_elements_[i].overflow_id;
absl::visit(
base::Overloaded(
[&](ToolbarController::ElementIdInfo overflow_id) {
if (absl::holds_alternative<ui::ElementIdentifier>(id) &&
overflow_id.overflow_identifier ==
absl::get<ui::ElementIdentifier>(id)) {
command_id = i;
return;
}
},
[&](actions::ActionId overflow_id) {
if (absl::holds_alternative<actions::ActionId>(id) &&
overflow_id == absl::get<actions::ActionId>(id)) {
command_id = i;
return;
}
}),
overflow_id);
if (command_id != -1) {
break;
}
}
auto* menu = const_cast<ui::SimpleMenuModel*>(GetOverflowMenu());
auto index = menu->GetIndexOfCommandId(command_id);
EXPECT_TRUE(index.has_value());
menu->ActivatedAt(index.value());
});
}
auto ForceForwardButtonOverflow() {
return Steps(Do([this]() {
AddDummyButtonsToToolbarTillElementOverflows(
kToolbarForwardButtonElementId);
}),
WaitForHide(kToolbarForwardButtonElementId),
WaitForShow(kToolbarOverflowButtonElementId));
}
auto CheckActionItemOverflowed(actions::ActionId id, bool overflowed) {
return CheckResult([=]() { return delegate()->IsOverflowed(id); },
overflowed);
}
auto PinBookmarkToToolbar() {
return Steps(Do([=]() {
chrome::ExecuteCommand(browser(),
IDC_SHOW_BOOKMARK_SIDE_PANEL);
}),
WaitForShow(kSidePanelElementId), FlushEvents(),
PressButton(kSidePanelPinButtonElementId),
PressButton(kSidePanelCloseButtonElementId));
}
auto PinReadingModeToToolbar() {
return Steps(Do([=]() {
chrome::ExecuteCommand(browser(),
IDC_SHOW_READING_MODE_SIDE_PANEL);
}),
WaitForShow(kSidePanelElementId), FlushEvents(),
PressButton(kSidePanelPinButtonElementId),
PressButton(kSidePanelCloseButtonElementId),
WaitForHide(kSidePanelElementId), FlushEvents());
}
auto SetBrowserSuperWide() {
return Steps(Do([this]() { SetBrowserWidth(3000); }),
WaitForHide(kToolbarOverflowButtonElementId));
}
auto LoadAndPinExtensionButton() {
return Steps(Do([this]() {
extensions::TestExtensionDir extension_directory;
constexpr char kManifest[] = R"({
"name": "Test Extension",
"version": "1",
"manifest_version": 3,
"host_permissions": [
"<all_urls>"
]
})";
extension_directory.WriteManifest(kManifest);
extensions::ChromeTestExtensionLoader loader(browser()->profile());
scoped_refptr<const extensions::Extension> extension =
loader.LoadExtension(extension_directory.UnpackedPath());
// Pin extension.
auto* toolbar_model = ToolbarActionsModel::Get(browser()->profile());
ASSERT_TRUE(toolbar_model);
toolbar_model->SetActionVisibility(extension->id(), true);
views::test::RunScheduledLayout(browser_view_);
}));
}
auto ResizeRelativeToOverflow(int diff) {
return Do(
[this, diff]() { SetBrowserWidth(overflow_threshold_width() + diff); });
}
void SetBrowserWidth(int width) {
int widget_width = browser_view_->GetWidget()->GetSize().width();
int browser_width = browser_view_->size().width();
browser_view_->GetWidget()->SetSize(
{width + widget_width - browser_width,
browser_view_->GetWidget()->GetSize().height()});
views::test::RunScheduledLayout(browser_view_);
}
const views::View* FindToolbarElementWithId(ui::ElementIdentifier id) const {
return toolbar_controller_->FindToolbarElementWithId(
toolbar_container_view_, id);
}
gfx::Size dummy_button_size() { return dummy_button_size_; }
ToolbarController::PinnedActionsDelegate* delegate() {
return toolbar_controller_->pinned_actions_delegate_;
}
const views::View* overflow_button() const { return overflow_button_; }
int element_flex_order_start() const { return element_flex_order_start_; }
const std::vector<ToolbarController::ResponsiveElementInfo>&
responsive_elements() const {
return responsive_elements_;
}
int overflow_threshold_width() const { return overflow_threshold_width_; }
std::vector<const ToolbarController::ResponsiveElementInfo*>
GetOverflowedElements() {
return toolbar_controller_->GetOverflowedElements();
}
const ui::SimpleMenuModel* GetOverflowMenu() {
return static_cast<OverflowButton*>(overflow_button_)
->menu_model_for_testing();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
raw_ptr<BrowserView> browser_view_;
raw_ptr<ToolbarController> toolbar_controller_;
raw_ptr<views::View> toolbar_container_view_;
raw_ptr<views::View> overflow_button_;
std::vector<ToolbarController::ResponsiveElementInfo> responsive_elements_;
int element_flex_order_start_;
gfx::Size dummy_button_size_;
// The minimum width the toolbar view can be without any elements dropped out.
int overflow_threshold_width_;
};
// TODO(crbug.com/41495158): Flaky on Windows.
#if BUILDFLAG(IS_WIN)
#define MAYBE_StartBrowserWithThresholdWidth \
DISABLED_StartBrowserWithThresholdWidth
#else
#define MAYBE_StartBrowserWithThresholdWidth StartBrowserWithThresholdWidth
#endif
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
MAYBE_StartBrowserWithThresholdWidth) {
// Start browser with threshold width. Should not see overflow.
SetBrowserWidth(overflow_threshold_width());
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser a bit wider. Should not see overflow.
SetBrowserWidth(overflow_threshold_width() + 1);
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser back to threshold width. Should not see overflow.
SetBrowserWidth(overflow_threshold_width());
EXPECT_FALSE(overflow_button()->GetVisible());
base::UserActionTester user_action_tester;
EXPECT_EQ(0, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonShown"));
// Resize browser a bit narrower. Should see overflow.
SetBrowserWidth(overflow_threshold_width() - 1);
EXPECT_TRUE(overflow_button()->GetVisible());
EXPECT_EQ(1, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonShown"));
EXPECT_EQ(0, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonHidden"));
// Resize browser back to threshold width. Should not see overflow.
SetBrowserWidth(overflow_threshold_width());
EXPECT_FALSE(overflow_button()->GetVisible());
EXPECT_EQ(1, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonHidden"));
}
// TODO(crbug.com/41495158): Flaky on Windows.
#if BUILDFLAG(IS_WIN)
#define MAYBE_StartBrowserWithWidthSmallerThanThreshold \
DISABLED_StartBrowserWithWidthSmallerThanThreshold
#else
#define MAYBE_StartBrowserWithWidthSmallerThanThreshold \
StartBrowserWithWidthSmallerThanThreshold
#endif
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
MAYBE_StartBrowserWithWidthSmallerThanThreshold) {
// Start browser with a smaller width than threshold. Should see overflow.
SetBrowserWidth(overflow_threshold_width() - 1);
EXPECT_TRUE(overflow_button()->GetVisible());
// Resize browser wider to threshold width. Should not see overflow.
SetBrowserWidth(overflow_threshold_width());
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser a bit narrower. Should see overflow.
SetBrowserWidth(overflow_threshold_width() - 1);
EXPECT_TRUE(overflow_button()->GetVisible());
// Keep resizing browser narrower. Should see overflow.
SetBrowserWidth(overflow_threshold_width() - 2);
EXPECT_TRUE(overflow_button()->GetVisible());
// Resize browser a bit wider. Should still see overflow.
SetBrowserWidth(overflow_threshold_width() - 1);
EXPECT_TRUE(overflow_button()->GetVisible());
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
StartBrowserWithWidthLargerThanThreshold) {
// Start browser with a larger width than threshold. Should not see overflow.
SetBrowserWidth(overflow_threshold_width() + 1);
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser wider. Should not see overflow.
SetBrowserWidth(overflow_threshold_width() + 2);
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser a bit narrower. Should not see overflow.
SetBrowserWidth(overflow_threshold_width() + 1);
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser back to threshold width. Should not see overflow.
SetBrowserWidth(overflow_threshold_width());
EXPECT_FALSE(overflow_button()->GetVisible());
// Resize browser a bit wider. Should not see overflow.
SetBrowserWidth(overflow_threshold_width() + 1);
EXPECT_FALSE(overflow_button()->GetVisible());
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest, MenuMatchesOverflowedElements) {
RunTestSequence(
Do([this]() { SetBrowserWidth(overflow_threshold_width() - 1); }),
WaitForShow(kToolbarOverflowButtonElementId),
PressButton(kToolbarOverflowButtonElementId),
WaitForActivate(kToolbarOverflowButtonElementId),
CheckMenuMatchesOverflowedElements());
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest, ActivateActionElementFromMenu) {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPrimaryTabPageElementId);
const auto back_url = embedded_test_server()->GetURL("/back");
const auto forward_url = embedded_test_server()->GetURL("/forward");
base::UserActionTester user_action_tester;
EXPECT_EQ(0, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonActivated"));
EXPECT_EQ(0, user_action_tester.GetActionCount(
"ResponsiveToolbar.MenuItemActivated.ForwardButton"));
RunTestSequence(
InstrumentTab(kPrimaryTabPageElementId),
NavigateWebContents(kPrimaryTabPageElementId, back_url),
NavigateWebContents(kPrimaryTabPageElementId, forward_url),
PressButton(kToolbarBackButtonElementId),
WaitForWebContentsNavigation(kPrimaryTabPageElementId, back_url),
ForceForwardButtonOverflow(),
PressButton(kToolbarOverflowButtonElementId),
ActivateMenuItemWithElementId(kToolbarForwardButtonElementId),
// Forward navigation is triggered after activating menu item.
WaitForWebContentsNavigation(kPrimaryTabPageElementId, forward_url));
EXPECT_EQ(1, user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowButtonActivated"));
EXPECT_EQ(1,
user_action_tester.GetActionCount(
"ResponsiveToolbar.OverflowMenuItemActivated.ForwardButton"));
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
ActionItemsOverflowAndReappear) {
RunTestSequence(PinBookmarkToToolbar(), SetBrowserSuperWide(),
// Pinned bookmark button is visible.
CheckActionItemOverflowed(
ChromeActionIds::kActionSidePanelShowBookmarks, false),
Do([this]() {
AddDummyButtonsToToolbarTillElementOverflows(
ChromeActionIds::kActionSidePanelShowBookmarks);
}),
CheckActionItemOverflowed(
ChromeActionIds::kActionSidePanelShowBookmarks, true),
WaitForShow(kToolbarOverflowButtonElementId),
// Set browser super wide action item reappears.
SetBrowserSuperWide(),
CheckActionItemOverflowed(
ChromeActionIds::kActionSidePanelShowBookmarks, false),
WaitForHide(kToolbarOverflowButtonElementId));
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
ActionItemsShowInMenuAndActivateFromMenu) {
RunTestSequence(
PinBookmarkToToolbar(), SetBrowserSuperWide(), Do([this]() {
AddDummyButtonsToToolbarTillElementOverflows(
ChromeActionIds::kActionSidePanelShowBookmarks);
}),
CheckActionItemOverflowed(ChromeActionIds::kActionSidePanelShowBookmarks,
true),
WaitForShow(kToolbarOverflowButtonElementId),
PressButton(kToolbarOverflowButtonElementId),
CheckMenuMatchesOverflowedElements(),
// Check bookmark menu item is activated correctly.
ActivateMenuItemWithElementId(
ChromeActionIds::kActionSidePanelShowBookmarks),
WaitForShow(kSidePanelElementId), FlushEvents(), Check([this]() {
auto* coordinator =
SidePanelUtil::GetSidePanelCoordinatorForBrowser(browser());
return coordinator->IsSidePanelEntryShowing(
SidePanelEntry::Key(SidePanelEntry::Id::kBookmarks));
}));
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
ActivatedActionItemsDoNotOverflow) {
RunTestSequence(
PinBookmarkToToolbar(), SetBrowserSuperWide(),
CheckActionItemOverflowed(ChromeActionIds::kActionSidePanelShowBookmarks,
false),
EnsureNotPresent(kSidePanelElementId),
// Open bookmark side panel.
Do([=]() {
chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_SIDE_PANEL);
}),
WaitForShow(kSidePanelElementId), FlushEvents(),
ForceForwardButtonOverflow(),
// Activated bookmark button is still visible because side panel is open
// even though it should overflow earlier than forward button.
CheckActionItemOverflowed(ChromeActionIds::kActionSidePanelShowBookmarks,
false),
// Set browser wide still no overflow.
SetBrowserSuperWide(),
CheckActionItemOverflowed(ChromeActionIds::kActionSidePanelShowBookmarks,
false));
}
// TODO(crbug.com/1522194): Flaky on multiple platforms.
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
DISABLED_DeactivatedActionItemsOverflow) {
RunTestSequence(PinBookmarkToToolbar(), SetBrowserSuperWide(), Do([this]() {
AddDummyButtonsToToolbarTillElementOverflows(
ChromeActionIds::kActionSidePanelShowBookmarks);
}),
CheckActionItemOverflowed(
ChromeActionIds::kActionSidePanelShowBookmarks, true),
WaitForShow(kToolbarOverflowButtonElementId),
PressButton(kToolbarOverflowButtonElementId),
ActivateMenuItemWithElementId(
ChromeActionIds::kActionSidePanelShowBookmarks),
WaitForShow(kSidePanelElementId), FlushEvents(),
// Close bookmark side panel.
PressButton(kSidePanelCloseButtonElementId),
WaitForHide(kSidePanelElementId), FlushEvents(),
// Pinned button overflows after side panel is closed.
CheckActionItemOverflowed(
ChromeActionIds::kActionSidePanelShowBookmarks, true));
}
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
EveryElementHasActionMetricName) {
for (auto& it : ToolbarController::GetDefaultResponsiveElements(browser())) {
absl::visit(
base::Overloaded(
[](actions::ActionId id) {
EXPECT_NE(
ToolbarController::GetActionNameFromElementIdentifier(id), "")
<< "Missing metric name for ActionId: " << id;
},
[&](ToolbarController::ElementIdInfo id) {
EXPECT_NE(ToolbarController::GetActionNameFromElementIdentifier(
id.activate_identifier),
"")
<< "Missing metric name for ElementIdentifier: "
<< id.activate_identifier;
}),
it.overflow_id);
}
}
// Verify fixing animation loop bug (crbug.com/).
// Steps to reproduce:
// 1 Set browser with to a big value that nothing should overflow.
// 2. Have 1 pinned extension button in extensions container.
// 3. Have 2 pinned buttons in pinned toolbar container.
// 4. Set browser width to when PinnedToolbarContainer starts to overflow. In
// this case both pinned buttons in PinnedToolbarContainer should overflow,
// overflow button should show. Verify: The pinned extension button should still
// be visible because there's enough space for it. Extensions container should
// not have animation because its visibility didn't change.
// TODO(crbug.com/41495158): Flaky on Windows.
#if BUILDFLAG(IS_WIN)
#define MAYBE_ExtensionHasNoAnimationLoop DISABLED_ExtensionHasNoAnimationLoop
#else
#define MAYBE_ExtensionHasNoAnimationLoop ExtensionHasNoAnimationLoop
#endif
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
MAYBE_ExtensionHasNoAnimationLoop) {
RunTestSequence(
LoadAndPinExtensionButton(), PinBookmarkToToolbar(),
PinReadingModeToToolbar(), Do([this]() {
SetBrowserWidth(GetOverflowThresholdWidthInPinnedSidePanelContainer() -
1);
}),
WaitForShow(kToolbarOverflowButtonElementId));
EXPECT_FALSE(BrowserView::GetBrowserViewForBrowser(browser())
->toolbar()
->extensions_container()
->GetAnimatingLayoutManager()
->is_animating());
}
// TODO(crbug.com/41495158): Flaky on Windows.
#if BUILDFLAG(IS_WIN)
#define MAYBE_DoNotShowIphWhenOverflowed DISABLED_DoNotShowIphWhenOverflowed
#else
#define MAYBE_DoNotShowIphWhenOverflowed DoNotShowIphWhenOverflowed
#endif
IN_PROC_BROWSER_TEST_F(ToolbarControllerUiTest,
MAYBE_DoNotShowIphWhenOverflowed) {
RunTestSequence(
ResizeRelativeToOverflow(-1),
MaybeShowPromo(feature_engagement::kIPHTabSearchFeature,
user_education::FeaturePromoResult::kBlockedByUi),
ResizeRelativeToOverflow(1),
MaybeShowPromo(feature_engagement::kIPHTabSearchFeature),
PressClosePromoButton());
}