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:
ash
ash_element_identifiers.ccash_element_identifiers.hash_strings.grd
ash_strings_grd
IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT_V2.png.sha1IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT_V2.png.sha1IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_ACCNAME.png.sha1IDS_ASH_WELCOME_TOUR_FILES_APP_BUBBLE_BODY_TEXT.png.sha1IDS_ASH_WELCOME_TOUR_HOME_BUTTON_BUBBLE_ACCNAME.png.sha1IDS_ASH_WELCOME_TOUR_SEARCH_BOX_BUBBLE_ACCNAME.png.sha1IDS_ASH_WELCOME_TOUR_SETTINGS_APP_BUBBLE_ACCNAME.png.sha1IDS_ASH_WELCOME_TOUR_SHELF_BUBBLE_ACCNAME.png.sha1IDS_ASH_WELCOME_TOUR_STATUS_AREA_BUBBLE_ACCNAME.png.sha1
constants
user_education
chrome/browser/ui/ash/user_education
tools/metrics/histograms/metadata/ash_user_education
@ -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. You’ll 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, you’ll 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, you’ll 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">
|
||||
|
Reference in New Issue
Block a user