[Mahi] Magic boost integration test
Test the basic functions:
showing the opt in card,
clicking on the accept button on the card,
clicking on the decline button on the card.
Bug: b/349852159
Change-Id: I79453c338e71dd21c131680f22292a8ee5ca2459
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5691106
Reviewed-by: Andre Le <leandre@chromium.org>
Commit-Queue: Jiaming Cheng <jiamingc@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1326412}
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index da5cda5..deeea01 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -3230,6 +3230,7 @@
"//chrome/browser/ash/kerberos:browser_tests",
"//chrome/browser/ash/lock_screen_apps:browser_tests",
"//chrome/browser/ash/login:browser_tests",
+ "//chrome/browser/ash/magic_boost:browser_tests",
"//chrome/browser/ash/mahi:browser_tests",
"//chrome/browser/ash/net:browser_tests",
"//chrome/browser/ash/os_feedback:browser_tests",
diff --git a/chrome/browser/ash/magic_boost/BUILD.gn b/chrome/browser/ash/magic_boost/BUILD.gn
index d537c82..3976220 100644
--- a/chrome/browser/ash/magic_boost/BUILD.gn
+++ b/chrome/browser/ash/magic_boost/BUILD.gn
@@ -71,3 +71,30 @@
"//ui/lottie",
]
}
+
+source_set("browser_tests") {
+ testonly = true
+
+ defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+
+ sources = [ "magic_boost_browsertest.cc" ]
+
+ deps = [
+ ":magic_boost",
+ "//ash",
+ "//ash/constants",
+ "//base",
+ "//base/test:test_support",
+ "//chrome/browser/ui/chromeos/magic_boost:magic_boost",
+ "//chrome/browser/ui/chromeos/magic_boost:magic_boost_constants",
+ "//chrome/test:test_support",
+ "//chromeos/constants",
+ "//content/public/browser",
+ "//content/test:test_support",
+ "//testing/gtest",
+ "//ui/base",
+ "//ui/compositor",
+ "//ui/events:test_support",
+ "//ui/views",
+ ]
+}
diff --git a/chrome/browser/ash/magic_boost/DEPS b/chrome/browser/ash/magic_boost/DEPS
index 8564c96..bd7bf05e 100644
--- a/chrome/browser/ash/magic_boost/DEPS
+++ b/chrome/browser/ash/magic_boost/DEPS
@@ -23,3 +23,10 @@
"+chrome/browser/profiles",
]
+
+specific_include_rules = {
+ "magic_boost_browsertest.cc": [
+ "+chrome/browser/ui/chromeos/magic_boost",
+ "+chrome/test/base",
+ ],
+}
diff --git a/chrome/browser/ash/magic_boost/magic_boost_browsertest.cc b/chrome/browser/ash/magic_boost/magic_boost_browsertest.cc
new file mode 100644
index 0000000..850b61b
--- /dev/null
+++ b/chrome/browser/ash/magic_boost/magic_boost_browsertest.cc
@@ -0,0 +1,162 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "ash/constants/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/system/magic_boost/magic_boost_disclaimer_view.h"
+#include "ash/test/ash_test_util.h"
+#include "base/command_line.h"
+#include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/chromeos/magic_boost/magic_boost_constants.h"
+#include "chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/components/mahi/public/cpp/mahi_switches.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "ui/events/test/event_generator.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+namespace {
+
+// Runs a specific callback when the observed view is deleted.
+class ViewDeletionObserver : public ::views::ViewObserver {
+ public:
+ ViewDeletionObserver(views::View* view,
+ base::RepeatingClosure on_delete_callback)
+ : on_delete_callback_(on_delete_callback) {
+ observation_.Observe(view);
+ }
+
+ private:
+ // ViewObserver:
+ void OnViewIsDeleting(views::View* observed_view) override {
+ observation_.Reset();
+ on_delete_callback_.Run();
+ }
+
+ base::RepeatingClosure on_delete_callback_;
+ base::ScopedObservation<views::View, views::ViewObserver> observation_{this};
+};
+
+// Waits until the content view specified by `widget` is closed.
+void WaitUntilViewClosed(views::Widget* widget) {
+ ASSERT_TRUE(widget);
+
+ base::RunLoop run_loop;
+ ViewDeletionObserver view_observer(
+ widget->GetContentsView(),
+ base::BindLambdaForTesting([&run_loop]() { run_loop.Quit(); }));
+ run_loop.Run();
+}
+
+} // namespace
+
+class MagicBoostBrowserTest : public InProcessBrowserTest {
+ public:
+ void SetUp() override {
+ feature_list_.InitWithFeatures(
+ /*enabled_features=*/{chromeos::features::kMahi,
+ chromeos::features::kMagicBoost,
+ chromeos::features::kOrca,
+ chromeos::features::kFeatureManagementOrca},
+ /*disabled_features=*/{});
+
+ InProcessBrowserTest::SetUp();
+ }
+
+ protected:
+ ui::test::EventGenerator& event_generator() { return *event_generator_; }
+
+ private:
+ // InProcessBrowserTest:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(chromeos::switches::kUseFakeMahiManager);
+ }
+
+ void SetUpOnMainThread() override {
+ InProcessBrowserTest::SetUpOnMainThread();
+
+ event_generator_ = std::make_unique<ui::test::EventGenerator>(
+ Shell::GetPrimaryRootWindow());
+ }
+
+ base::test::ScopedFeatureList feature_list_;
+ base::AutoReset<bool> ignore_mahi_secret_key_ =
+ switches::SetIgnoreMahiSecretKeyForTest();
+ std::unique_ptr<ui::test::EventGenerator> event_generator_;
+};
+
+IN_PROC_BROWSER_TEST_F(MagicBoostBrowserTest, ShowDisclaimerView) {
+ EXPECT_FALSE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+ EXPECT_FALSE(FindWidgetWithName(
+ chromeos::MagicBoostOptInCard::GetWidgetNameForTest()));
+
+ // Right click on the web content to show the opt in card.
+ event_generator().MoveMouseTo(chrome_test_utils::GetActiveWebContents(this)
+ ->GetViewBounds()
+ .CenterPoint());
+ event_generator().ClickRightButton();
+
+ // Finds the opt in card and still cannot find the disclaimer view.
+ views::Widget* opt_in_card_widget = FindWidgetWithNameAndWaitIfNeeded(
+ chromeos::MagicBoostOptInCard::GetWidgetNameForTest());
+ EXPECT_FALSE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+ ASSERT_TRUE(opt_in_card_widget);
+
+ // Left click on the accept button in the opt in card.
+ const views::View* const accept_button =
+ opt_in_card_widget->GetContentsView()->GetViewByID(
+ chromeos::magic_boost::ViewId::OptInCardPrimaryButton);
+ ASSERT_TRUE(accept_button);
+ event_generator().MoveMouseTo(
+ accept_button->GetBoundsInScreen().CenterPoint());
+ event_generator().ClickLeftButton();
+
+ // Closes the opt in card and shows the disclaimer view.
+ WaitUntilViewClosed(opt_in_card_widget);
+ EXPECT_TRUE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+}
+
+IN_PROC_BROWSER_TEST_F(MagicBoostBrowserTest, DeclineOptIn) {
+ EXPECT_FALSE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+ EXPECT_FALSE(FindWidgetWithName(
+ chromeos::MagicBoostOptInCard::GetWidgetNameForTest()));
+
+ // Right click on the web content to show the opt in card.
+ event_generator().MoveMouseTo(chrome_test_utils::GetActiveWebContents(this)
+ ->GetViewBounds()
+ .CenterPoint());
+ event_generator().ClickRightButton();
+
+ // Finds the opt in card and still cannot find the disclaimer view.
+ views::Widget* opt_in_card_widget = FindWidgetWithNameAndWaitIfNeeded(
+ chromeos::MagicBoostOptInCard::GetWidgetNameForTest());
+ EXPECT_FALSE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+ ASSERT_TRUE(opt_in_card_widget);
+
+ // Left click on the decline button in the opt in card.
+ const views::View* const decline_button =
+ opt_in_card_widget->GetContentsView()->GetViewByID(
+ chromeos::magic_boost::ViewId::OptInCardSecondaryButton);
+ ASSERT_TRUE(decline_button);
+ event_generator().MoveMouseTo(
+ decline_button->GetBoundsInScreen().CenterPoint());
+ event_generator().ClickLeftButton();
+
+ // Closes the opt in card. Not showing the disclaimer view.
+ WaitUntilViewClosed(opt_in_card_widget);
+ EXPECT_FALSE(FindWidgetWithName(MagicBoostDisclaimerView::GetWidgetName()));
+
+ // TODO(b/349852159): Check the pref value after clicking the decline button
+ // with both Orca included or not.
+}
+
+} // namespace ash
diff --git a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.cc b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.cc
index d7b217f4..9e1819a 100644
--- a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.cc
+++ b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.cc
@@ -260,6 +260,11 @@
secondary_button_->RequestFocus();
}
+// static
+const char* MagicBoostOptInCard::GetWidgetNameForTest() {
+ return kWidgetName;
+}
+
void MagicBoostOptInCard::OnPrimaryButtonPressed() {
magic_boost::RecordOptInCardActionMetrics(
controller_->GetOptInFeatures(),
diff --git a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.h b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.h
index 50900a36..8b57293 100644
--- a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.h
+++ b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card.h
@@ -46,6 +46,9 @@
// views::View:
void RequestFocus() override;
+ // Returns the host widget's name.
+ static const char* GetWidgetNameForTest();
+
private:
// Button callbacks.
void OnPrimaryButtonPressed();