User Education Tutorials

Once you have the PRD spec for your tutorial, here are the steps you will follow to create the promo:

  1. Create your tutorial identifier and metrics.
  2. Register and describe your tutorial.
  3. Add an entry point for your tutorial.
  4. Manually test (and optionally, a write regression test) for your tutorial.

Create your Tutorial Identifier and Metrics

A TutorialIdentifier is a unique string. Create a new ID for your tutorial and add it to tutorial_identifiers.h and .cc.

In the same file, you should also create your “metrics prefix”, which will be used for recording histograms. Unlike the tutorial ID, the histogram prefix should be CamelCase with no special characters or spaces.

Finally, add the metrics prefix you defined above to the “TutorialID” variants block in /tools/metrics/histograms/metadata/user_education/histograms.xml. Be sure to use the histogram prefix and not the full tutorial name/ID.

Register and describe your Tutorial

In browser_user_education_service.cc, in MaybeRegisterChromeTutorials(), you should create your TutorialDescription and register it with the provided TutorialRegistry.

The basic pattern is as follows:

  // Create the tutorial with histograms and steps:
  auto my_tutorial_description =
      TutorialDescription::Create<kMyTutorialMetricPrefix>(
          // Tutorial steps go here...
      );
  
  // Add metadata. Note that this could be assigning an entire metadata object
  // or setting individual fields of the existing `metadata` member.
  // The minimum recommended fields are "additional_description", "milestone",
  // and "owners"; in the future these will become required.
  my_tutorial_description.metadata = ...

  // Actually register the tutorial:
  tutorial_registry.AddTutorial(
      kMyTutorialId,
      std::move(my_tutorial_description));

All of this should be fairly straightforward except the steps, and there are plenty of examples in the existing code.

Defining Tutorial steps

There are four general kinds of steps, all defined in tutorial_descriptions.h, and all of which target a UI element by ElementIdentifier:

  • BubbleStep - shows a help bubble anchored to the specified element.
  • EventStep - waits for the code to fire a custom event via ElementTracker on the specified element.
  • HiddenStep - waits for the element to be shown or hidden, or the user to click on a button or menu item, without showing a bubble.
  • If (or the convenience class IfView) - checks to see if the element (or View) is present and fulfils some predicate you define; if it does, then the steps in .Then(...) are executed; else the steps in .Else(...) (optional) are executed.

Each step can be further modified by member functions on either the step class or the base Step class. These are things like specifying what context to look for the target element in, whether the element must be present at the start or end of the step, etc.

See Help Bubbles for more information on UI elements, identifiers, contexts, etc.

When to use conditionals

If you have multiple variations on a Tutorial based on UI state or some easily- checkable condition, then using If or IfView is preferable to creating multiple versions of the Tutorial. This is especially true if the Tutorial is repeatable and running through it once changes the state in such a way that the other variation would need to be shown. (Example: Tab Groups tutorial created a tab group, so some of the bubbles need to change to reference the fact that there is already a tab group).

Note that the “progress bar” shown in each tutorial bubble is based on the longest possible journey through the Tutorial, so if a conditional step skips steps or shows an abridged version of the tutorial, the progress may jump from e.g. 1/6 to 3/6.

Steps: notes and suggestions

When creating Tutorials, the flow should be:

  1. Show a bubble describing the next action the user should take
  2. Observe some change that is the result (EventStep or HiddenStep)
  3. Show the next bubble with further instructions

If (3) involves anchoring the next bubble to an element that will appear as a result of the action prompted in (1), you can omit (2). This is because there is an implied “wait for the target element to become visible” in all BubbleSteps.

On the other hand, if (1) and (3) both reference UI elements that are already visible when the Tutorial starts, the first bubble will show, immediately be hidden, and then the second bubble will show; the user will never actually see the first bubble. In this case (2) is mandatory and should watch for either the user input or a resulting event or UI change.

The final Tutorial step must be a bubble step, and will mark the “success” state. It may be given additional buttons or icons reflecting this state. This bubble will persist until the user dismisses it, or it is forced to be hidden for other reasons (such as the UI it is anchored to disappearing).

Just generally, think about how your UI works. Think about the things the user might do and how the UI might react. For example, if there‘s a chance the user is likely to dismiss an element you want to show a bubble on in a way that won’t allow the tutorial to continue, consider anchoring the bubble elsewhere.

Similarly, are there any circumstances in which a particular step might fail to happen, even if the user performs the action you tell them to? If so, then you probably need to rethink how your steps work.

Add an entry point for your Tutorial

Typically this is done through a Tutorial Feature Promo (IPH) or through the “What's New” Page. For more information on these entry points, check out the Getting Started guide.

Test your Tutorial

If your tutorial launches from an IPH, you can test it any of the ways you could test an IPH, suggestions are in the documentation.

You can also launch your Tutorial directly from the tester page (chrome://user-education-internals). Note that unlike IPH, you do not need to have the starting point of the tutorial present when you click the “Launch” button; you merely need to be able to bring it up in 20-30 seconds. The tutorial will start as soon as the anchor view for the first bubble of the tutorial becomes visible.

For automated testing, you can:

  • Launch the tutorial directly in an interactive_ui_tests test.
  • Launch your IPH (again, see the IPH documentation).

In the second case, press the promo's action button to start the Tutorial.

Automated regression testing

To launch a Tutorial directly in an interactive_ui_tests test, invoke the instance of TutorialService you get from the current profile's UserEducationService via UserEducationServiceFactory::GetForBrowserContext().

We recommend using an InteractiveBrowserTest (i.e. Kombucha) rather than a vanilla InProcessBrowserTest because of the ability to simulate user input. As you perform the inputs that trigger the different tutorial steps, you can check for the expected help bubbles and their contents using the element identifiers defined in HelpBubbleView (if they‘re Views) or InstrumentWebContents() and WaitForStateChange() to find the bubble if it’s in a WebUI in a tab.

We also recommend using PressButton(), SelectMenuItem(), etc. instead of MoveMouse() and PressMouse() wherever possible; you should have separate tests for the responsiveness of your feature's UI; for testing Tutorials the goal is merely to ensure that each bubble appears as expected.

Any additional questions?

Please reach out to Frizzle Team for more information.