blob: eefd88dd3c63f259eb8f1521ae8f97cd17adc5b5 [file] [log] [blame]
// Copyright 2022 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/views/commerce/price_tracking_icon_view.h"
#include "base/test/metrics/user_action_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/timer/mock_timer.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/commerce/shopping_service_factory.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/commerce/price_tracking/mock_shopping_list_ui_tab_helper.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/commerce/price_tracking_bubble_dialog_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/star_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/bookmarks/test/bookmark_test_helpers.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/mock_shopping_service.h"
#include "components/commerce/core/test_utils.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/feature_engagement/test/scoped_iph_feature_list.h"
#include "components/omnibox/browser/vector_icons.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/user_education/test/feature_promo_test_util.h"
#include "content/public/test/browser_test.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/base_event_utils.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/interaction/element_tracker_views.h"
#include "ui/views/test/button_test_api.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/any_widget_observer.h"
namespace {
const char kNonTrackableUrl[] = "http://google.com";
const char kTrackableUrl[] = "about:blank";
const char kNonBookmarkedUrl[] = "about:blank?bookmarked=false";
} // namespace
// TODO(crbug.com/1401515): Do the tests below still make sense after the
// features::kUnifiedSidePanel flag removal, or should these be removed as well?
class PriceTrackingIconViewInteractiveTest : public InProcessBrowserTest {
public:
PriceTrackingIconViewInteractiveTest() {
test_features_.InitAndEnableFeatures(
{commerce::kShoppingList,
feature_engagement::kIPHPriceTrackingInSidePanelFeature},
{});
}
PriceTrackingIconViewInteractiveTest(
const PriceTrackingIconViewInteractiveTest&) = delete;
PriceTrackingIconViewInteractiveTest& operator=(
const PriceTrackingIconViewInteractiveTest&) = delete;
~PriceTrackingIconViewInteractiveTest() override = default;
void SetUpOnMainThread() override {
bookmarks::BookmarkModel* bookmark_model =
BookmarkModelFactory::GetForBrowserContext(browser()->profile());
bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
bookmarks::AddIfNotBookmarked(bookmark_model, GURL(kTrackableUrl),
std::u16string());
mock_shopping_service_ = static_cast<commerce::MockShoppingService*>(
commerce::ShoppingServiceFactory::GetInstance()
->SetTestingFactoryAndUse(
browser()->profile(),
base::BindRepeating([](content::BrowserContext* context) {
return commerce::MockShoppingService::Build();
})));
MockShoppingListUiTabHelper::CreateForWebContents(
browser()->tab_strip_model()->GetActiveWebContents());
mock_tab_helper_ = static_cast<MockShoppingListUiTabHelper*>(
MockShoppingListUiTabHelper::FromWebContents(
browser()->tab_strip_model()->GetActiveWebContents()));
const gfx::Image image = mock_tab_helper_->GetValidProductImage();
ON_CALL(*mock_tab_helper_, GetProductImage)
.WillByDefault(
testing::ReturnRef(mock_tab_helper_->GetValidProductImage()));
}
PriceTrackingIconView* GetChip() {
auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
auto* location_bar_view = browser_view->toolbar()->location_bar();
const ui::ElementContext context =
views::ElementTrackerViews::GetContextForView(location_bar_view);
views::View* matched_view =
views::ElementTrackerViews::GetInstance()->GetFirstMatchingView(
kPriceTrackingChipElementId, context);
return matched_view
? views::AsViewClass<PriceTrackingIconView>(matched_view)
: nullptr;
}
void ClickPriceTrackingIconView() {
// TODO(meiliang@): Investigte why calling
// ui_test_utils::ClickOnView(GetChip()) does not work.
views::test::ButtonTestApi(GetChip()).NotifyClick(
ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0));
base::RunLoop().RunUntilIdle();
}
void SimulateServerPriceTrackStateUpdated(bool is_price_tracked) {
// Ensure the tab helper has the correct value from the "server" before the
// meta event is triggered.
ON_CALL(*mock_tab_helper_, IsPriceTracking)
.WillByDefault(testing::Return(is_price_tracked));
bookmarks::BookmarkModel* bookmark_model =
BookmarkModelFactory::GetForBrowserContext(browser()->profile());
commerce::AddProductBookmark(bookmark_model, u"title", GURL(kTrackableUrl),
0, is_price_tracked);
}
StarView* GetBookmarkStar() {
auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
auto* location_bar_view = browser_view->toolbar()->location_bar();
const ui::ElementContext context =
views::ElementTrackerViews::GetContextForView(location_bar_view);
views::View* matched_view =
views::ElementTrackerViews::GetInstance()->GetFirstMatchingView(
kBookmarkStarViewElementId, context);
return matched_view ? views::AsViewClass<StarView>(matched_view) : nullptr;
}
protected:
base::UserActionTester user_action_tester_;
raw_ptr<commerce::MockShoppingService> mock_shopping_service_;
raw_ptr<MockShoppingListUiTabHelper, DanglingUntriaged> mock_tab_helper_;
private:
feature_engagement::test::ScopedIphFeatureList test_features_;
};
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
FUEBubbleShownOnPress) {
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_FIRST_USE_EXPERIENCE);
}
IN_PROC_BROWSER_TEST_F(
PriceTrackingIconViewInteractiveTest,
PriceTrackingBubbleShownOnPress_BeforeFUEOnTrackedProduct) {
EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
prefs::kShouldShowPriceTrackFUEBubble));
bookmarks::BookmarkModel* bookmark_model =
BookmarkModelFactory::GetForBrowserContext(browser()->profile());
commerce::AddProductBookmark(bookmark_model, u"title", GURL(kTrackableUrl), 0,
true);
ON_CALL(*mock_tab_helper_, IsPriceTracking)
.WillByDefault(testing::Return(true));
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/true);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
PriceTrackingBubbleShownOnPress_AfterFUE) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
BubbleCanBeReshowOnPress) {
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
auto* widget = GetChip()->GetBubble()->GetWidget();
views::test::WidgetDestroyedWaiter destroyed_waiter(widget);
widget->CloseWithReason(views::Widget::ClosedReason::kEscKeyPressed);
destroyed_waiter.Wait();
EXPECT_FALSE(icon_view->GetBubble());
// Click the icon again to reshow the bubble.
EXPECT_CALL(*mock_tab_helper_, GetProductImage);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
EnablePriceTrackOnPress) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingDisabledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetBubble());
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingEnabledFilledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
RecordOmniboxChipClicked) {
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChipClicked"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChipClicked"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
RecordOmniboxChipTracked) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
NoRecordOmniboxChipTracked_ForTrackedProduct) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
0);
auto* icon_view = GetChip();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/true);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
0);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
NoRecordOmniboxChipTracked_ForFUEFlow) {
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.OmniboxChip.Tracked"),
0);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewInteractiveTest,
TrackedProductIsDifferentBookmark) {
bookmarks::BookmarkModel* bookmark_model =
BookmarkModelFactory::GetForBrowserContext(browser()->profile());
const uint64_t cluster_id = 12345L;
commerce::AddProductBookmark(bookmark_model, u"title",
GURL("https://example.com"), cluster_id, true);
ON_CALL(*mock_tab_helper_, ShouldShowPriceTrackingIconView)
.WillByDefault(testing::Return(true));
ON_CALL(*mock_tab_helper_, IsPriceTracking)
.WillByDefault(testing::Return(true));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kNonBookmarkedUrl)));
EXPECT_STREQ(GetChip()->GetVectorIcon().name,
omnibox::kPriceTrackingEnabledFilledIcon.name);
EXPECT_FALSE(GetBookmarkStar()->GetActive());
}
class PriceTrackingIconViewErrorHandelingTest
: public PriceTrackingIconViewInteractiveTest {
public:
PriceTrackingIconViewErrorHandelingTest() {
test_features_.InitWithFeaturesAndParameters(
{{commerce::kShoppingList,
{{commerce::kRevertIconOnFailureParam, "true"}}}},
{});
}
private:
base::test::ScopedFeatureList test_features_;
};
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewErrorHandelingTest,
IconRevertedOnFailure) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/false);
ON_CALL(*mock_tab_helper_, ShouldShowPriceTrackingIconView)
.WillByDefault(testing::Return(true));
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingDisabledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
// Simulate the failure.
mock_shopping_service_->SetSubscribeCallbackValue(false);
ClickPriceTrackingIconView();
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingDisabledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_FALSE(icon_view->GetBubble());
}
class PriceTrackingIconViewEngagementTest
: public PriceTrackingIconViewInteractiveTest {
public:
PriceTrackingIconViewEngagementTest() {
test_features_.InitAndEnableFeatures(
{commerce::kShoppingList,
feature_engagement::kIPHPriceTrackingPageActionIconLabelFeature});
}
void SetUpOnMainThread() override {
PriceTrackingIconViewInteractiveTest::SetUpOnMainThread();
BrowserFeaturePromoController* const promo_controller =
BrowserView::GetBrowserViewForBrowser(browser())
->GetFeaturePromoController();
EXPECT_TRUE(
user_education::test::WaitForFeatureEngagementReady(promo_controller));
SetUpChip();
}
void SetUpChip() {
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/false);
ON_CALL(*mock_tab_helper_, ShouldShowPriceTrackingIconView)
.WillByDefault(testing::Return(true));
}
void WaitForIconFinishAnimating(PriceTrackingIconView* icon_view) {
while (icon_view->is_animating_label()) {
base::RunLoop().RunUntilIdle();
}
}
private:
feature_engagement::test::ScopedIphFeatureList test_features_;
};
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewEngagementTest, ShowExpandedIcon) {
auto* icon_view = GetChip();
EXPECT_FALSE(icon_view->GetVisible());
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_TRUE(icon_view->ShouldShowLabel());
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewEngagementTest,
ExpandedIconShownOnceOnly) {
auto* icon_view = GetChip();
EXPECT_FALSE(icon_view->GetVisible());
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_TRUE(icon_view->ShouldShowLabel());
ON_CALL(*mock_tab_helper_, ShouldShowPriceTrackingIconView)
.WillByDefault(testing::Return(false));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kNonTrackableUrl)));
EXPECT_FALSE(icon_view->GetVisible());
EXPECT_FALSE(icon_view->ShouldShowLabel());
ON_CALL(*mock_tab_helper_, ShouldShowPriceTrackingIconView)
.WillByDefault(testing::Return(true));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_FALSE(icon_view->ShouldShowLabel());
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewEngagementTest, AutoCollapseIcon) {
auto* icon_view = GetChip();
EXPECT_FALSE(icon_view->GetVisible());
base::MockOneShotTimer timer;
icon_view->SetOneShotTimerForTesting(&timer);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
WaitForIconFinishAnimating(icon_view);
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_TRUE(icon_view->ShouldShowLabel());
// Simulate ready to collapse the icon.
timer.Fire();
WaitForIconFinishAnimating(icon_view);
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_FALSE(icon_view->ShouldShowLabel());
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewEngagementTest,
StopCollapseTimerWhenClickingIcon) {
auto* icon_view = GetChip();
EXPECT_FALSE(icon_view->GetVisible());
base::MockOneShotTimer timer;
icon_view->SetOneShotTimerForTesting(&timer);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
WaitForIconFinishAnimating(icon_view);
EXPECT_TRUE(icon_view->GetVisible());
ClickPriceTrackingIconView();
EXPECT_FALSE(timer.IsRunning());
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_TRUE(icon_view->ShouldShowLabel());
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewEngagementTest,
CollapseIconUponBubbleClosing) {
auto* icon_view = GetChip();
EXPECT_FALSE(icon_view->GetVisible());
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kTrackableUrl)));
WaitForIconFinishAnimating(icon_view);
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_TRUE(icon_view->ShouldShowLabel());
ClickPriceTrackingIconView();
views::test::WidgetVisibleWaiter(icon_view->GetBubble()->GetWidget()).Wait();
EXPECT_TRUE(icon_view->GetBubble());
// Close bubble and verify the label is hiding.
auto* widget = icon_view->GetBubble()->GetWidget();
views::test::WidgetDestroyedWaiter destroyed_waiter(widget);
widget->CloseWithReason(views::Widget::ClosedReason::kEscKeyPressed);
destroyed_waiter.Wait();
EXPECT_FALSE(icon_view->GetBubble());
WaitForIconFinishAnimating(icon_view);
EXPECT_TRUE(icon_view->GetVisible());
EXPECT_FALSE(icon_view->ShouldShowLabel());
}
class PriceTrackingBubbleInteractiveTest
: public PriceTrackingIconViewInteractiveTest {
public:
PriceTrackingBubbleInteractiveTest() = default;
PriceTrackingBubbleInteractiveTest(
const PriceTrackingBubbleInteractiveTest&) = delete;
PriceTrackingBubbleInteractiveTest& operator=(
const PriceTrackingBubbleInteractiveTest&) = delete;
~PriceTrackingBubbleInteractiveTest() override = default;
};
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
TrackPriceOnFUEBubble) {
// Show PriceTackingIconView.
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
// Verify the PriceTackingIconView original state.
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingDisabledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
// Click PriceTackingIconView and show the PriceTrackingBubble.
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_FIRST_USE_EXPERIENCE);
// Click the Accept(Track price) bubble.
bubble->Accept();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
// Verify the PriceTackingIconView updates its state.
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingEnabledFilledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
EXPECT_TRUE(GetBookmarkStar()->GetActive());
}
// TODO(crbug.com/1401515): Does the tests below still make sense after the
// features::kUnifiedSidePanel flag removal, or should it be removed as well?
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
NotTriggerSidePanelIPH) {
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_FALSE(prefs->GetBoolean(prefs::kShouldShowSidePanelBookmarkTab));
auto* promo_controller = BrowserView::GetBrowserViewForBrowser(browser())
->GetFeaturePromoController();
EXPECT_TRUE(
user_education::test::WaitForFeatureEngagementReady(promo_controller));
// Trigger IPH now so it won't be triggred later.
EXPECT_TRUE(
promo_controller->feature_engagement_tracker()->ShouldTriggerHelpUI(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
EXPECT_FALSE(
promo_controller->feature_engagement_tracker()->WouldTriggerHelpUI(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
// Show PriceTackingIconView.
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
// Click PriceTackingIconView and show the PriceTrackingBubble.
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
// Click the Accept(Track price) bubble.
bubble->Accept();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
// Verify IPH is not showing and pref is not set up to force show bookmark tab
// in side panel.
EXPECT_FALSE(promo_controller->IsPromoActive(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
EXPECT_FALSE(prefs->GetBoolean(prefs::kShouldShowSidePanelBookmarkTab));
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
UnrackPriceOnNormalBubble) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
// Show PriceTackingIconView.
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
// Click PriceTackingIconView and show the PriceTrackingBubble.
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
// Verify the PriceTackingIconView state before cancel.
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingEnabledFilledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACKING_PRICE));
// Click the Cancel(Untrack) button.
bubble->Cancel();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/false);
// Verify the PriceTackingIconView updates its state.
EXPECT_EQ(icon_view->GetIconLabelForTesting(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
EXPECT_STREQ(icon_view->GetVectorIcon().name,
omnibox::kPriceTrackingDisabledIcon.name);
EXPECT_EQ(icon_view->GetTextForTooltipAndAccessibleName(),
l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE));
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordFirstRunBubbleShown) {
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleShown"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleShown"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordFirstRunBubblTrackedPrice) {
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleTrackedPrice"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
bubble->Accept();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleTrackedPrice"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordFirstRunBubbleDismissed) {
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleDismissed"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
bubble->Cancel();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.FirstRunBubbleDismissed"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordConfirmationShown) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.ConfirmationShown"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.ConfirmationShown"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordConfirmationUntracked) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.Confirmation.Untrack"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
bubble->Cancel();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.Confirmation.Untrack"),
1);
}
IN_PROC_BROWSER_TEST_F(PriceTrackingBubbleInteractiveTest,
RecordEditedBookmarkFolderFromOmniboxBubble) {
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kShouldShowPriceTrackFUEBubble, false);
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.EditedBookmarkFolderFromOmniboxBubble"),
0);
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
bubble->GetBodyLabelForTesting()->ClickFirstLinkForTesting();
EXPECT_EQ(user_action_tester_.GetActionCount(
"Commerce.PriceTracking.EditedBookmarkFolderFromOmniboxBubble"),
1);
}
class PriceTrackingIconViewUnifiedSidePanelInteractiveTest
: public PriceTrackingBubbleInteractiveTest {
public:
PriceTrackingIconViewUnifiedSidePanelInteractiveTest() {
test_features_.InitAndEnableFeatures(
{commerce::kShoppingList,
feature_engagement::kIPHPriceTrackingInSidePanelFeature});
}
private:
feature_engagement::test::ScopedIphFeatureList test_features_;
};
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewUnifiedSidePanelInteractiveTest,
TriggerSidePanelIPH) {
SidePanelCoordinator* coordinator =
BrowserView::GetBrowserViewForBrowser(browser())
->side_panel_coordinator();
DCHECK(coordinator);
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(prefs::kShouldShowPriceTrackFUEBubble, false);
auto* promo_controller = BrowserView::GetBrowserViewForBrowser(browser())
->GetFeaturePromoController();
EXPECT_TRUE(
user_education::test::WaitForFeatureEngagementReady(promo_controller));
// Show PriceTackingIconView.
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
// Click PriceTackingIconView and show the PriceTrackingBubble.
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
// Click the Accept(Track price) bubble.
bubble->Accept();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
// Verify IPH is showing and side panel registry is properly set up to force
// show bookmark tab in side panel.
EXPECT_TRUE(promo_controller->IsPromoActive(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
SidePanelRegistry* registry =
SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
EXPECT_TRUE(registry->active_entry().has_value());
EXPECT_EQ(registry->active_entry().value()->key().id(),
SidePanelEntry::Id::kBookmarks);
EXPECT_FALSE(prefs->GetBoolean(prefs::kShouldShowSidePanelBookmarkTab));
}
IN_PROC_BROWSER_TEST_F(PriceTrackingIconViewUnifiedSidePanelInteractiveTest,
NotTriggerSidePanelIPH) {
SidePanelCoordinator* coordinator =
BrowserView::GetBrowserViewForBrowser(browser())
->side_panel_coordinator();
DCHECK(coordinator);
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(prefs::kShouldShowPriceTrackFUEBubble, false);
auto* promo_controller = BrowserView::GetBrowserViewForBrowser(browser())
->GetFeaturePromoController();
EXPECT_TRUE(
user_education::test::WaitForFeatureEngagementReady(promo_controller));
// Trigger IPH now so it won't be triggred later.
EXPECT_TRUE(
promo_controller->feature_engagement_tracker()->ShouldTriggerHelpUI(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
EXPECT_FALSE(
promo_controller->feature_engagement_tracker()->WouldTriggerHelpUI(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
// Show PriceTackingIconView.
auto* icon_view = GetChip();
icon_view->ForceVisibleForTesting(/*is_tracking_price=*/false);
// Click PriceTackingIconView and show the PriceTrackingBubble.
ClickPriceTrackingIconView();
auto* bubble =
static_cast<PriceTrackingBubbleDialogView*>(icon_view->GetBubble());
EXPECT_TRUE(bubble);
EXPECT_EQ(bubble->GetTypeForTesting(),
PriceTrackingBubbleDialogView::Type::TYPE_NORMAL);
// Click the Accept(Track price) bubble.
bubble->Accept();
SimulateServerPriceTrackStateUpdated(/*is_price_tracked=*/true);
// Verify IPH is not showing and side panel registry is not set up to force
// show bookmark tab in side panel.
EXPECT_FALSE(promo_controller->IsPromoActive(
feature_engagement::kIPHPriceTrackingInSidePanelFeature));
SidePanelRegistry* registry =
SidePanelCoordinator::GetGlobalSidePanelRegistry(browser());
EXPECT_FALSE(registry->active_entry().has_value());
EXPECT_FALSE(prefs->GetBoolean(prefs::kShouldShowSidePanelBookmarkTab));
}