0

welcome_tour: Add new experiment

This cl adds a new experiment arm with changes:
1. Add a new feature flag: WelcomeTourV2.
1. Change the dialog text.
2. Add one step for Files app in the Launcher.

Bug: 329285586
Test: Manually on DUT and added new tests
Change-Id: Ibbd7af6f3ee1220894c02fb7365b125d0d147818
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5491184
Commit-Queue: Tao Wu <wutao@chromium.org>
Reviewed-by: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/main@{#1293239}
This commit is contained in:
Tao Wu
2024-04-26 20:43:49 +00:00
committed by Chromium LUCI CQ
parent fa4edda1ab
commit 2b099e3200
23 changed files with 366 additions and 145 deletions

@ -15,6 +15,7 @@ DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kBluetoothFeatureTileToggleElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kCalendarViewElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kEnterpriseManagedView);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kExploreAppElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kFilesAppElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kHoldingSpaceTrayElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kHomeButtonElementId);
DEFINE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(kLoginUserViewElementId);

@ -33,6 +33,9 @@ DECLARE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(ASH_EXPORT, kEnterpriseManagedView);
// associated element.
DECLARE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(ASH_EXPORT, kExploreAppElementId);
// Uniquely identifies an element corresponding to the Files app.
DECLARE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(ASH_EXPORT, kFilesAppElementId);
// Uniquely identifies the `HoldingSpaceTray`.
DECLARE_EXPORTED_ELEMENT_IDENTIFIER_VALUE(ASH_EXPORT,
kHoldingSpaceTrayElementId);

@ -7627,14 +7627,26 @@ To shut down the device, press and hold the power button on the device again.
<message name="IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT" desc="Text shown in the body of the dialog as part of the System UI Welcome Tour.">
Take a quick tour to learn how to get around your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>. Get up and running in 5 steps.
</message>
<message name="IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT_V2" desc="Text shown in the body of the dialog as part of the System UI Welcome Tour V2.">
Take a quick tour to learn how to get around your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>
</message>
<message name="IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT" desc="Text shown as the Welcome Tour dialog title.">
Hi there. <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> is a little different.
</message>
<message name="IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT_V2" desc="Text shown as the Welcome Tour V2 dialog title.">
6 tips to get started on <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>
</message>
<message name="IDS_ASH_WELCOME_TOUR_EXPLORE_APP_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the Explore app as part of the System UI Welcome Tour.">
Those were the basics! Continue in Explore, our built-in app for tips and help. Youll find tips for getting started, recommended apps, special offers, and the newest <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> features.
</message>
<message name="IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the Files app as part of the System UI Welcome Tour.">
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. You can find the Files app in Launcher. Manage your local files and your Google Drive files, all in the Files app.
</message>
<message name="IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the Files app as part of the System UI Welcome Tour.">
Manage your local files and your Google Drive files, all in the Files app.
</message>
<message name="IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the home button as part of the System UI Welcome Tour.">
Tour step 3 of 5. Use apps to do everything you need on your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>. You can find your apps in the Launcher. Press Alt + Shift + L to focus on the Launcher button.
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. Use apps to do everything you need on your <ph name="PRODUCT_NAME">$3<ex>Chromebook</ex></ph>. You can find your apps in the Launcher. Press Alt + Shift + L to focus on the Launcher button.
</message>
<message name="IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT_CHROMEBOOK" desc="Text shown in the body of a help bubble anchored to the home button as part of the System UI Welcome Tour.">
Use apps to do everything you need on your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>. You can find your apps in the Launcher. You can also press the Launcher key (above the left Shift key) on the keyboard.
@ -7646,25 +7658,25 @@ To shut down the device, press and hold the power button on the device again.
''' '''
</message>
<message name="IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the search box as part of the System UI Welcome Tour.">
Tour step 4 of 5. Once Launcher is activated, youll get an enhanced search bar. You can start typing to search for your files, apps, and more. You can also get answers to questions about your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>.
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. Once Launcher is activated, youll get an enhanced search bar. You can start typing to search for your files, apps, and more. You can also get answers to questions about your <ph name="PRODUCT_NAME">$3<ex>Chromebook</ex></ph>.
</message>
<message name="IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the search box as part of the System UI Welcome Tour.">
Search for your files, apps, and more in the Launcher. You can also get answers to questions about your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph>.
</message>
<message name="IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the Settings app as part of the System UI Welcome Tour">
Tour step 5 of 5. You can find your device Settings in Launcher. Try customizing your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> in Settings like changing your wallpaper or setting a screen saver.
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. You can find your device Settings in Launcher. Try customizing your <ph name="PRODUCT_NAME">$3<ex>Chromebook</ex></ph> in Settings like changing your wallpaper or setting a screen saver.
</message>
<message name="IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the Settings app as part of the System UI Welcome Tour">
Customize and personalize your <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> in Settings. Try changing your wallpaper or setting a screen saver.
</message>
<message name="IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the shelf as part of the System UI Welcome Tour.">
Tour step 1 of 5. Your pinned and open apps are on the shelf located at the bottom of your screen. Press Alt + Shift + L then tab to focus on shelf items.
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. Your pinned and open apps are on the shelf located at the bottom of your screen. Press Alt + Shift + L then tab to focus on shelf items.
</message>
<message name="IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the shelf as part of the System UI Welcome Tour.">
Your pinned and open apps are on the shelf. To pin an app to the shelf, right-click an app or tap your touchpad with two fingers.
</message>
<message name="IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_ACCNAME" desc="The accessible name of a help bubble anchored to the status area as part of the System UI Welcome Tour.">
Tour step 2 of 5. Frequently used controls like Wi-Fi, Bluetooth and volume are in Quick Settings. You can also go here to take screenshots. Press Alt + Shift + S to open Quick Settings.
Tour step <ph name="STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>5</ex></ph>. Frequently used controls like Wi-Fi, Bluetooth and volume are in Quick Settings. You can also go here to take screenshots. Press Alt + Shift + S to open Quick Settings.
</message>
<message name="IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the status area as part of the System UI Welcome Tour.">
Frequently used controls like Wi-Fi, Bluetooth and volume are in Quick Settings. You can also go here to take screenshots.

@ -0,0 +1 @@
51a3652b0cb8ef770f15462f0519ea031f18d413

@ -0,0 +1 @@
51a3652b0cb8ef770f15462f0519ea031f18d413

@ -0,0 +1 @@
93c76dc2f8e75ba245303cd501a3845f50a7c888

@ -0,0 +1 @@
7b0b90b838683dcee5d4ec016866dbdbb28fd877

@ -1 +1 @@
50db39a2b7ba065eccee1cf516f22df2eb6b3fd2
3c8b8fdbc4f4ffb71612416164a2d0e24ffeabda

@ -1 +1 @@
e8894f733d95248c62b26dab3d4105e930c811ea
1edf44ecb7d5585ec7bd12dc48ef008a462054c8

@ -1 +1 @@
5802fb73976b6c11ecc58d80caa101e8bf0fe1ca
e62a986f0e1f3d275800ed50640502c39cc97a1f

@ -1 +1 @@
26f96d0e6ac397230594df7cb2b33be2bd3c0ef1
7191eeb4821f140a1d56960f58e1f11ffc82a93c

@ -1 +1 @@
6ec4e1ca2a23bb080ed7480fc3c1f0f284cd4530
b6d1a374171d4edbb58fb97f5d994e00ea2dfbda

@ -3004,6 +3004,12 @@ BASE_FEATURE(kWelcomeTourForceUserEligibility,
"WelcomeTourForceUserEligibility",
base::FEATURE_DISABLED_BY_DEFAULT);
// Enables the Welcome Tour V2 that has different strings and steps than V1.
// Enabling this flag has no effect unless `kWelcomeTour` is also enabled.
BASE_FEATURE(kWelcomeTourV2,
"WelcomeTourV2",
base::FEATURE_DISABLED_BY_DEFAULT);
// Controls whether to enable MAC Address Randomization on WiFi connection.
BASE_FEATURE(kWifiConnectMacAddressRandomization,
"WifiConnectMacAddressRandomization",
@ -4558,6 +4564,10 @@ bool IsWelcomeTourForceUserEligibilityEnabled() {
base::FeatureList::IsEnabled(kWelcomeTourForceUserEligibility);
}
bool IsWelcomeTourV2Enabled() {
return IsWelcomeTourEnabled() && base::FeatureList::IsEnabled(kWelcomeTourV2);
}
bool IsWifiDirectEnabled() {
return base::FeatureList::IsEnabled(kWifiDirect);
}

@ -913,6 +913,8 @@ BASE_DECLARE_FEATURE(kWelcomeTourChromeVoxSupported);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kWelcomeTourForceUserEligibility);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kWelcomeTourV2);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kWifiConnectMacAddressRandomization);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kWifiDirect);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kWifiSyncAllowDeletes);
@ -1333,6 +1335,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWelcomeTourChromeVoxSupported();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWelcomeTourEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWelcomeTourEnabledCounterfactually();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWelcomeTourForceUserEligibilityEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWelcomeTourV2Enabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWifiDirectEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWifiSyncAndroidEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWindowBoundsTrackerEnabled();

@ -33,7 +33,8 @@ enum class HelpBubbleId {
kWelcomeTourSettingsApp,
kWelcomeTourShelf,
kWelcomeTourStatusArea,
kMaxValue = kWelcomeTourStatusArea,
kWelcomeTourFilesApp,
kMaxValue = kWelcomeTourFilesApp,
};
// Each value uniquely identifies a style of help bubble. Help bubbles of

@ -4,6 +4,7 @@
#include "ash/user_education/welcome_tour/welcome_tour_controller.h"
#include <string>
#include <string_view>
#include "ash/accessibility/accessibility_controller.h"
@ -34,6 +35,7 @@
#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/timer/elapsed_timer.h"
#include "chromeos/constants/devicetype.h"
@ -61,6 +63,10 @@ namespace {
// The singleton instance owned by the `UserEducationController`.
WelcomeTourController* g_instance = nullptr;
// Strings.
constexpr char16_t kTotalStepsV1[] = u"5";
constexpr char16_t kTotalStepsV2[] = u"6";
// Helpers ---------------------------------------------------------------------
user_education::HelpBubbleParams::ExtendedProperties
@ -177,6 +183,9 @@ ui::ElementContext WelcomeTourController::GetInitialElementContext() const {
user_education::TutorialDescription
WelcomeTourController::GetTutorialDescription() const {
const std::u16string product_name = ui::GetChromeOSDeviceName();
const std::u16string total_steps =
features::IsWelcomeTourV2Enabled() ? kTotalStepsV2 : kTotalStepsV1;
int current_step = 1;
user_education::TutorialDescription tutorial_description;
tutorial_description.complete_button_text_id =
@ -200,10 +209,16 @@ WelcomeTourController::GetTutorialDescription() const {
tutorial_description.steps.emplace_back(
user_education::TutorialDescription::BubbleStep(kShelfViewElementId)
.SetBubbleArrow(user_education::HelpBubbleArrow::kBottomCenter)
.SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT)
.SetBubbleScreenreaderText(IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_ACCNAME)
.SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT)
.SetExtendedProperties(CreateHelpBubbleExtendedProperties(
HelpBubbleId::kWelcomeTourShelf))
HelpBubbleId::kWelcomeTourShelf,
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
/*body_text=*/
l10n_util::GetStringUTF8(
IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT)))
.AddCustomNextButton(DefaultNextButtonCallback().Then(
base::BindRepeating(&WelcomeTourController::SetCurrentStep,
weak_ptr_factory_.GetMutableWeakPtr(),
@ -225,11 +240,16 @@ WelcomeTourController::GetTutorialDescription() const {
user_education::TutorialDescription::BubbleStep(
kUnifiedSystemTrayElementName)
.SetBubbleArrow(user_education::HelpBubbleArrow::kBottomRight)
.SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_BODY_TEXT)
.SetBubbleScreenreaderText(
IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_ACCNAME)
.SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT)
.SetExtendedProperties(CreateHelpBubbleExtendedProperties(
HelpBubbleId::kWelcomeTourStatusArea))
HelpBubbleId::kWelcomeTourStatusArea,
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
/*body_text=*/
l10n_util::GetStringUTF8(
IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_BODY_TEXT)))
.AddCustomNextButton(DefaultNextButtonCallback().Then(
base::BindRepeating(&WelcomeTourController::SetCurrentStep,
weak_ptr_factory_.GetMutableWeakPtr(),
@ -257,6 +277,7 @@ WelcomeTourController::GetTutorialDescription() const {
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps,
product_name),
/*body_text=*/
l10n_util::GetStringFUTF8(
@ -287,15 +308,20 @@ WelcomeTourController::GetTutorialDescription() const {
HelpBubbleId::kWelcomeTourSearchBox,
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME, product_name),
IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps,
product_name),
/*body_text=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT,
product_name)))
.AddCustomNextButton(DefaultNextButtonCallback().Then(
base::BindRepeating(&WelcomeTourController::SetCurrentStep,
weak_ptr_factory_.GetMutableWeakPtr(),
welcome_tour_metrics::Step::kSettingsApp)))
.AddCustomNextButton(
DefaultNextButtonCallback().Then(base::BindRepeating(
&WelcomeTourController::SetCurrentStep,
weak_ptr_factory_.GetMutableWeakPtr(),
features::IsWelcomeTourV2Enabled()
? welcome_tour_metrics::Step::kFilesApp
: welcome_tour_metrics::Step::kSettingsApp)))
.InAnyContext());
// Wait for "Next" button click before proceeding to the next bubble step.
@ -305,7 +331,36 @@ WelcomeTourController::GetTutorialDescription() const {
kSearchBoxViewElementId)
.InSameContext());
// Step 5: Settings app.
if (features::IsWelcomeTourV2Enabled()) {
// Step 5 in V2: Files app.
tutorial_description.steps.emplace_back(
user_education::TutorialDescription::BubbleStep(kFilesAppElementId)
.SetBubbleArrow(user_education::HelpBubbleArrow::kBottomLeft)
.SetBubbleBodyText(IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT)
.SetExtendedProperties(CreateHelpBubbleExtendedProperties(
HelpBubbleId::kWelcomeTourFilesApp,
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
/*body_text=*/
l10n_util::GetStringUTF8(
IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_BODY_TEXT)))
.AddCustomNextButton(DefaultNextButtonCallback().Then(
base::BindRepeating(&WelcomeTourController::SetCurrentStep,
weak_ptr_factory_.GetMutableWeakPtr(),
welcome_tour_metrics::Step::kSettingsApp)))
.InSameContext());
// Wait for "Next" button click before proceeding to the next bubble step.
tutorial_description.steps.emplace_back(
user_education::TutorialDescription::EventStep(
user_education::kHelpBubbleNextButtonClickedEvent,
kFilesAppElementId)
.InSameContext());
}
// Step 5 in V1 and step 6 in V2: Settings app.
tutorial_description.steps.emplace_back(
user_education::TutorialDescription::BubbleStep(kSettingsAppElementId)
.SetBubbleArrow(user_education::HelpBubbleArrow::kBottomLeft)
@ -315,6 +370,7 @@ WelcomeTourController::GetTutorialDescription() const {
/*accessible_name=*/
l10n_util::GetStringFUTF8(
IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps,
product_name),
/*body_text=*/
l10n_util::GetStringFUTF8(
@ -333,7 +389,7 @@ WelcomeTourController::GetTutorialDescription() const {
kSettingsAppElementId)
.InSameContext());
// Step 6: Explore app.
// Step 6 in V1 and step 7 in V2: Explore app.
// NOTE: The accessible name is the same as the body text.
tutorial_description.steps.emplace_back(
user_education::TutorialDescription::BubbleStep(kExploreAppElementId)
@ -346,7 +402,7 @@ WelcomeTourController::GetTutorialDescription() const {
product_name)))
.InSameContext());
// Step 7: Explore app window.
// Step 7 in V1 and step 8 in V2: Explore app window.
// Implemented in `WelcomeTourController::OnWelcomeTourEnded()`.
return tutorial_description;

@ -100,6 +100,10 @@ using AcceleratorDetails = AcceleratorLookup::AcceleratorDetails;
using ContextMode = TutorialDescription::ContextMode;
using ElementSpecifier = TutorialDescription::ElementSpecifier;
// Strings.
constexpr char16_t kTotalStepsV1[] = u"5";
constexpr char16_t kTotalStepsV2[] = u"6";
// Actions ---------------------------------------------------------------------
// TODO(http://b/277094923): Try to promote to //base/test/gmock_move_support.h.
@ -116,10 +120,22 @@ auto MoveArgs(T*... out) {
// Matchers --------------------------------------------------------------------
MATCHER_P2(StringFUT8Eq, message_id, sub, "") {
MATCHER_P(StringUTF8Eq, message_id, "") {
return Matches(l10n_util::GetStringUTF8(message_id))(arg);
}
MATCHER_P2(StringFUTF8Eq, message_id, sub, "") {
return Matches(l10n_util::GetStringFUTF8(message_id, sub))(arg);
}
MATCHER_P3(StringFUTF8Eq, message_id, sub1, sub2, "") {
return Matches(l10n_util::GetStringFUTF8(message_id, sub1, sub2))(arg);
}
MATCHER_P4(StringFUTF8Eq, message_id, sub1, sub2, sub3, "") {
return Matches(l10n_util::GetStringFUTF8(message_id, sub1, sub2, sub3))(arg);
}
MATCHER_P(ElementSpecifierEq, element_specifier, "") {
return std::visit(base::Overloaded{
[&](const ui::ElementIdentifier& element_id) {
@ -355,101 +371,6 @@ class WelcomeTourControllerTest : public UserEducationAshTestBase {
// Tests -----------------------------------------------------------------------
// Verifies that `GetTutorialDescription()` returns expected values.
TEST_F(WelcomeTourControllerTest, GetTutorialDescription) {
auto* welcome_tour_controller = WelcomeTourController::Get();
ASSERT_TRUE(welcome_tour_controller);
const std::u16string product_name = ui::GetChromeOSDeviceName();
EXPECT_THAT(
welcome_tour_controller->GetTutorialDescription(),
AllOf(
Field(&TutorialDescription::complete_button_text_id,
Eq(IDS_ASH_WELCOME_TOUR_COMPLETE_BUTTON_TEXT)),
Field(
&TutorialDescription::steps,
ElementsAre(
ShownStep(ElementSpecifier(kWelcomeTourDialogElementId),
ContextMode::kAny),
HiddenStep(ElementSpecifier(kWelcomeTourDialogElementId),
ContextMode::kFromPreviousStep),
BubbleStep(ElementSpecifier(kShelfViewElementId),
ContextMode::kInitial,
HelpBubbleId::kWelcomeTourShelf,
IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT,
HelpBubbleArrow::kBottomCenter,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kShelfViewElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/true),
BubbleStep(ElementSpecifier(kUnifiedSystemTrayElementName),
ContextMode::kAny,
HelpBubbleId::kWelcomeTourStatusArea,
IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_BODY_TEXT,
HelpBubbleArrow::kBottomRight,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kUnifiedSystemTrayElementName),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/true),
BubbleStep(
ElementSpecifier(kHomeButtonElementName),
ContextMode::kAny, HelpBubbleId::kWelcomeTourHomeButton,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_ACCNAME,
product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUT8Eq(
(chromeos::GetDeviceType() ==
chromeos::DeviceType::kChromebook)
? IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT_CHROMEBOOK
: IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT_OTHER_DEVICE_TYPES,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/true),
BubbleStep(
ElementSpecifier(kSearchBoxViewElementId),
ContextMode::kAny, HelpBubbleId::kWelcomeTourSearchBox,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME,
product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kTopCenter,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kSearchBoxViewElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/false),
BubbleStep(
ElementSpecifier(kSettingsAppElementId),
ContextMode::kFromPreviousStep,
HelpBubbleId::kWelcomeTourSettingsApp,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_ACCNAME,
product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kSettingsAppElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/false),
BubbleStep(
ElementSpecifier(kExploreAppElementId),
ContextMode::kFromPreviousStep,
HelpBubbleId::kWelcomeTourExploreApp,
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUT8Eq(
IDS_ASH_WELCOME_TOUR_EXPLORE_APP_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/false)))));
}
// Verifies that the Welcome Tour is started when the primary user session is
// first activated and then never again, as well as that start/end events are
// propagated to observers appropriately.
@ -600,7 +521,154 @@ TEST_F(WelcomeTourControllerTest, AbortsTourAndPropagatesEvents) {
EXPECT_TRUE(ended_future.Wait());
}
// WelcomeTourControllerChromeVoxTest -------------------------------------
// WelcomeTourControllerV2Test -------------------------------------------------
// Base class for tests of the `WelcomeTourController` which are concerned with
// the behavior of WelcomeTourV2 experiment arms, parameterized by whether the
// Welcome Tour V2 feature is enabled.
class WelcomeTourControllerV2Test : public WelcomeTourControllerTest,
public ::testing::WithParamInterface<
/*is_welcome_tour_v2_enabled=*/bool> {
public:
WelcomeTourControllerV2Test() {
scoped_feature_list_.InitWithFeatureState(features::kWelcomeTourV2,
IsWelcomeTourV2Enabled());
}
protected:
// Returns whether the WelcomeTourV2 feature is enabled given test
// parameterization.
bool IsWelcomeTourV2Enabled() const { return GetParam(); }
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(All,
WelcomeTourControllerV2Test,
/*is_welcome_tour_v2_enabled=*/testing::Bool());
// Verifies that `GetTutorialDescription()` returns expected values.
TEST_P(WelcomeTourControllerV2Test, GetTutorialDescription) {
auto* welcome_tour_controller = WelcomeTourController::Get();
ASSERT_TRUE(welcome_tour_controller);
const std::u16string product_name = ui::GetChromeOSDeviceName();
const std::u16string total_steps =
IsWelcomeTourV2Enabled() ? kTotalStepsV2 : kTotalStepsV1;
int current_step = 1;
using ::testing::Matcher;
using Description = user_education::TutorialDescription;
std::vector<Matcher<Description::Step>> expected_steps = {
ShownStep(ElementSpecifier(kWelcomeTourDialogElementId),
ContextMode::kAny),
HiddenStep(ElementSpecifier(kWelcomeTourDialogElementId),
ContextMode::kFromPreviousStep),
BubbleStep(
ElementSpecifier(kShelfViewElementId), ContextMode::kInitial,
HelpBubbleId::kWelcomeTourShelf,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringUTF8Eq(IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_BODY_TEXT),
HelpBubbleArrow::kBottomCenter,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kShelfViewElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/true),
BubbleStep(
ElementSpecifier(kUnifiedSystemTrayElementName), ContextMode::kAny,
HelpBubbleId::kWelcomeTourStatusArea,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringUTF8Eq(IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_BODY_TEXT),
HelpBubbleArrow::kBottomRight,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kUnifiedSystemTrayElementName),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/true),
BubbleStep(
ElementSpecifier(kHomeButtonElementName), ContextMode::kAny,
HelpBubbleId::kWelcomeTourHomeButton,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps,
product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUTF8Eq(
(chromeos::GetDeviceType() == chromeos::DeviceType::kChromebook)
? IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT_CHROMEBOOK
: IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_BODY_TEXT_OTHER_DEVICE_TYPES,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/true),
BubbleStep(ElementSpecifier(kSearchBoxViewElementId), ContextMode::kAny,
HelpBubbleId::kWelcomeTourSearchBox,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME,
base::NumberToString16(current_step++),
total_steps, product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kTopCenter,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kSearchBoxViewElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/false)};
if (features::IsWelcomeTourV2Enabled()) {
expected_steps.insert(
expected_steps.end(),
{// Files app step for V2.
BubbleStep(
ElementSpecifier(kFilesAppElementId),
ContextMode::kFromPreviousStep, HelpBubbleId::kWelcomeTourFilesApp,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringUTF8Eq(IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_BODY_TEXT),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kFilesAppElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/false)});
}
expected_steps.insert(
expected_steps.end(),
{BubbleStep(
ElementSpecifier(kSettingsAppElementId),
ContextMode::kFromPreviousStep,
HelpBubbleId::kWelcomeTourSettingsApp,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_ACCNAME,
base::NumberToString16(current_step++), total_steps,
product_name),
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/true),
EventStep(ElementSpecifier(kSettingsAppElementId),
ContextMode::kFromPreviousStep,
/*has_name_elements_callback=*/false),
BubbleStep(
ElementSpecifier(kExploreAppElementId),
ContextMode::kFromPreviousStep, HelpBubbleId::kWelcomeTourExploreApp,
IDS_ASH_WELCOME_TOUR_OVERRIDDEN_BUBBLE_BODY_TEXT,
StringFUTF8Eq(IDS_ASH_WELCOME_TOUR_EXPLORE_APP_BUBBLE_BODY_TEXT,
product_name),
HelpBubbleArrow::kBottomLeft,
/*has_next_button=*/false)});
EXPECT_THAT(welcome_tour_controller->GetTutorialDescription(),
AllOf(Field(&TutorialDescription::complete_button_text_id,
Eq(IDS_ASH_WELCOME_TOUR_COMPLETE_BUTTON_TEXT)),
Field(&TutorialDescription::steps,
ElementsAreArray(expected_steps))));
}
// WelcomeTourControllerChromeVoxTest ------------------------------------------
// Base class for tests of the `WelcomeTourController` which are concerned with
// the behaviors when ChromeVox is supported in the Welcome Tour, parameterized

@ -69,6 +69,7 @@ WelcomeTourDialog::WelcomeTourDialog(base::OnceClosure accept_callback,
g_instance = this;
const std::u16string product_name = ui::GetChromeOSDeviceName();
bool is_welcome_tour_v2_enabled = features::IsWelcomeTourV2Enabled();
views::Builder<SystemDialogDelegateView>(this)
.SetAcceptButtonText(l10n_util::GetStringUTF16(
@ -79,11 +80,16 @@ WelcomeTourDialog::WelcomeTourDialog(base::OnceClosure accept_callback,
.SetCancelCallback(std::move(cancel_callback))
.SetCloseCallback(std::move(close_callback))
.SetDescription(l10n_util::GetStringFUTF16(
IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT, product_name))
is_welcome_tour_v2_enabled
? IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT_V2
: IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT,
product_name))
.SetModalType(ui::ModalType::MODAL_TYPE_SYSTEM)
.SetProperty(views::kElementIdentifierKey, kWelcomeTourDialogElementId)
.SetTitleText(l10n_util::GetStringFUTF16(
IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT, product_name))
is_welcome_tour_v2_enabled ? IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT_V2
: IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT,
product_name))
.SetTopContentView(views::Builder<views::ImageView>()
.SetImage(ui::ResourceBundle::GetSharedInstance()
.GetThemedLottieImageNamed(

@ -169,6 +169,8 @@ std::string ToString(Step step) {
return "ExploreApp";
case Step::kExploreAppWindow:
return "ExploreAppWindow";
case Step::kFilesApp:
return "FilesApp";
case Step::kHomeButton:
return "HomeButton";
case Step::kSearch:

@ -86,7 +86,8 @@ enum class Step {
kSettingsApp = 5,
kShelf = 6,
kStatusArea = 7,
kMaxValue = kStatusArea,
kFilesApp = 8,
kMaxValue = kFilesApp,
};
// Enumeration of interactions users may engage in after the Welcome Tour. These

@ -13,6 +13,7 @@
#include "base/values.h"
#include "chrome/browser/ash/app_list/app_list_syncable_service.h"
#include "chrome/browser/ash/app_list/app_list_syncable_service_factory.h"
#include "chrome/browser/ash/file_manager/app_id.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
@ -107,6 +108,9 @@ ChromeUserEducationDelegate::CreateHelpBubble(
std::optional<ui::ElementIdentifier>
ChromeUserEducationDelegate::GetElementIdentifierForAppId(
const std::string& app_id) const {
if (!strcmp(file_manager::kFileManagerSwaAppId, app_id.c_str())) {
return ash::kFilesAppElementId;
}
if (!strcmp(web_app::kHelpAppId, app_id.c_str())) {
return ash::kExploreAppElementId;
}

@ -45,6 +45,10 @@ using ::testing::Eq;
using ::testing::Matches;
using ::testing::Property;
using TestVariantsParam = std::tuple<
/*is_apps_collections_enabled=*/bool,
/*is_welcome_tour_v2_enabled=*/bool>;
// Matchers --------------------------------------------------------------------
MATCHER_P(ElementIdentifier, matcher, "") {
@ -55,14 +59,32 @@ MATCHER_P(RootWindow, matcher, "") {
return Matches(matcher)(arg->GetWidget()->GetNativeWindow()->GetRootWindow());
}
// Helpers ---------------------------------------------------------------------
bool IsAppsCollectionsEnabled(TestVariantsParam param) {
return std::get<0>(param);
}
bool IsWelcomeTourV2Enabled(TestVariantsParam param) {
return std::get<1>(param);
}
std::string GenerateTestSuffix(
const testing::TestParamInfo<TestVariantsParam>& info) {
return base::StrCat({IsWelcomeTourV2Enabled(info.param) ? "V2" : "V1", "_",
IsAppsCollectionsEnabled(info.param)
? "AppsCollectionsEnabled"
: "AppsCollectionsDisabled"});
}
} // namespace
// WelcomeTourInteractiveUiTest ------------------------------------------------
// Base class for interactive UI tests of the Welcome Tour in Ash.
class WelcomeTourInteractiveUiTest : public InteractiveBrowserTest,
public ::testing::WithParamInterface<
/*is_apps_collections_enabled=*/bool> {
class WelcomeTourInteractiveUiTest
: public InteractiveBrowserTest,
public testing::WithParamInterface<TestVariantsParam> {
public:
WelcomeTourInteractiveUiTest() {
// NOTE: These tests are not concerned with user eligibility, so explicitly
@ -70,6 +92,7 @@ class WelcomeTourInteractiveUiTest : public InteractiveBrowserTest,
scoped_feature_list_.InitWithFeatureStates(
{{ash::features::kWelcomeTour, true},
{ash::features::kWelcomeTourForceUserEligibility, true},
{ash::features::kWelcomeTourV2, IsWelcomeTourV2Enabled()},
{app_list_features::kAppsCollections, IsAppsCollectionsEnabled()},
{app_list_features::kForceShowAppsCollections,
IsAppsCollectionsEnabled()}});
@ -103,7 +126,15 @@ class WelcomeTourInteractiveUiTest : public InteractiveBrowserTest,
// Returns whether the AppsCollections feature is enabled in the Welcome Tour
// given test parameterization.
bool IsAppsCollectionsEnabled() const { return GetParam(); }
bool IsAppsCollectionsEnabled() const {
return ::IsAppsCollectionsEnabled(GetParam());
}
// Returns whether the WelcomeTourV2 feature is enabled given test
// parameterization.
bool IsWelcomeTourV2Enabled() const {
return ::IsWelcomeTourV2Enabled(GetParam());
}
// Returns a builder for an interaction step that waits for the app list
// bubble to hide.
@ -181,23 +212,21 @@ class WelcomeTourInteractiveUiTest : public InteractiveBrowserTest,
// Returns a builder for an interaction step that checks the dialog
// description.
[[nodiscard]] static auto CheckDialogDescription() {
[[nodiscard]] static auto CheckDialogDescription(int message_id) {
const std::u16string product_name = ui::GetChromeOSDeviceName();
return CheckViewProperty(
ash::SystemDialogDelegateView::kDescriptionTextIdForTesting,
&views::Label::GetText,
l10n_util::GetStringFUTF16(IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT,
product_name));
l10n_util::GetStringFUTF16(message_id, product_name));
}
// Returns a builder for an interaction step that checks the dialog title.
[[nodiscard]] static auto CheckDialogTitle() {
[[nodiscard]] static auto CheckDialogTitle(int message_id) {
const std::u16string product_name = ui::GetChromeOSDeviceName();
return CheckViewProperty(
ash::SystemDialogDelegateView::kTitleTextIdForTesting,
&views::Label::GetText,
l10n_util::GetStringFUTF16(IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT,
product_name));
l10n_util::GetStringFUTF16(message_id, product_name));
}
// Returns a builder for an interaction step that checks that the anchor of a
@ -254,8 +283,10 @@ class WelcomeTourInteractiveUiTest : public InteractiveBrowserTest,
INSTANTIATE_TEST_SUITE_P(All,
WelcomeTourInteractiveUiTest,
/*is_apps_collections_enabled=*/
::testing::Bool());
testing::Combine(
/*is_apps_collections_enabled=*/testing::Bool(),
/*is_welcome_tour_v2_enabled=*/testing::Bool()),
&GenerateTestSuffix);
// Tests -----------------------------------------------------------------------
@ -266,10 +297,17 @@ IN_PROC_BROWSER_TEST_P(WelcomeTourInteractiveUiTest, WelcomeTour) {
RunTestSequence(
// Step 0: Dialog.
InAnyContext(WaitForDialogVisibility(true)),
InSameContext(Steps(
CheckDialogAcceptButtonFocus(true), CheckDialogAcceptButtonText(),
CheckDialogCancelButtonText(), CheckDialogDescription(),
CheckDialogTitle(), PressDialogAcceptButton(), FlushEvents())),
InSameContext(
Steps(CheckDialogAcceptButtonFocus(true),
CheckDialogAcceptButtonText(), CheckDialogCancelButtonText(),
CheckDialogDescription(
IsWelcomeTourV2Enabled()
? IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT_V2
: IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT),
CheckDialogTitle(IsWelcomeTourV2Enabled()
? IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT_V2
: IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT),
PressDialogAcceptButton(), FlushEvents())),
// Step 1: Shelf.
InAnyContext(WaitForHelpBubble()),
@ -315,7 +353,18 @@ IN_PROC_BROWSER_TEST_P(WelcomeTourInteractiveUiTest, WelcomeTour) {
CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
PressHelpBubbleDefaultButton(), FlushEvents())),
// Step 5: Settings app.
// Step 5 in V2: Files app.
If([&] { return IsWelcomeTourV2Enabled(); },
InAnyContext(
Steps(WaitForHelpBubble(), CheckAppListBubbleVisibility(true),
CheckHelpBubbleAnchor(ash::kFilesAppElementId),
CheckHelpBubbleBodyText(l10n_util::GetStringUTF16(
IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_BODY_TEXT)),
CheckHelpBubbleDefaultButtonFocus(true),
CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
PressHelpBubbleDefaultButton(), FlushEvents()))),
// Step 5 in V1 and step 6 in V2: Settings app.
InAnyContext(WaitForHelpBubble()),
InSameContext(
Steps(CheckAppListBubbleVisibility(true),
@ -327,7 +376,7 @@ IN_PROC_BROWSER_TEST_P(WelcomeTourInteractiveUiTest, WelcomeTour) {
CheckHelpBubbleDefaultButtonText(IDS_TUTORIAL_NEXT_BUTTON),
PressHelpBubbleDefaultButton(), FlushEvents())),
// Step 6: Explore app.
// Step 6 in V1 and step 7 in V2: Explore app.
InAnyContext(WaitForHelpBubble()),
InSameContext(Steps(
CheckAppListBubbleVisibility(true),
@ -339,7 +388,7 @@ IN_PROC_BROWSER_TEST_P(WelcomeTourInteractiveUiTest, WelcomeTour) {
IDS_ASH_WELCOME_TOUR_COMPLETE_BUTTON_TEXT),
PressHelpBubbleDefaultButton(), FlushEvents())),
// Step 7: Explore app window.
// Step 7 in V1 and step 8 in V2: Explore app window.
InAnyContext(WaitForBrowser()),
InSameContext(Steps(WaitForAppListBubbleToHide(),
CheckBrowserIsForWebApp(web_app::kHelpAppId))));

@ -111,6 +111,7 @@ chromium-metrics-reviews@google.com.
<int value="5" label="kSettingsApp"/>
<int value="6" label="kShelf"/>
<int value="7" label="kStatusArea"/>
<int value="8" label="kFilesApp"/>
</enum>
<enum name="WelcomeTourTimeBucket">