PLG OS

Implementation worksheet · 7 min read

A product tour focus restoration test plan

Every way out of a product tour is a focus decision: Escape, the close button, Skip, Done on the last step, a click outside, a route change and the target element disappearing. For each exit, name the element focus must land on, then check it with a keyboard and a screen reader. For modal steps, the WAI-ARIA Authoring Practices dialog pattern gives the default: return focus to the element that opened the dialog, and pick another element that fits the workflow if that element no longer exists. A tour that starts itself has no opener, so the plan must declare a fallback in advance. Focus ending up on the document body fails the plan.

The keyboard acceptance test for tours checks that a tour can be operated without a mouse. This plan narrows to the moment the tour lets go. That moment is easy to get wrong, because the tour layer knows it closed but not what the user was doing before it opened. The actor is a keyboard or screen reader user partway through a task. The system boundary is the tour layer plus the host element it attaches to.

Put it into practice

1. Classify every step as modal or non-modal

A modal step, with the page inert behind it, keeps Tab and Shift+Tab inside while open and has to hand focus back on close. A non-modal hint beside a field shouldn't take focus from the field at all: the APG tooltip pattern, which W3C still marks as work in progress, keeps focus on the triggering element, and a hint containing buttons behaves more like a non-modal dialog. Decide per step, because the restoration rule differs.

2. Record the opener when the tour starts

Store the element that had focus when the tour opened. On close, check that it is still in the document (Node.isConnected) before focusing it. If the tour was started from a menu item inside a menu that has since closed, record the menu's button as the fallback, because the item itself is no longer reachable.

3. Declare a fallback for self-starting tours

A tour fired by page load or an event has no opener. Choose a landing point that suits the task the tour introduced: the main heading, the first field of the feature just explained, or the control the last step pointed at. A heading can take programmatic focus with tabindex="-1" without joining the Tab order.

4. Give every exit path its own row

Escape, close button, Skip, Done, click outside (if allowed), browser Back, in-app route change, target removed and session timeout. Each exit gets an expected landing element. 'Same as close' is a valid entry once you have tested it, not when you have assumed it.

5. Check the landing element can be seen

2.4.11 Focus Not Obscured (Minimum) (Level AA) requires a focused component not to be entirely hidden by author-created content; tour backdrops, sticky headers and the next queued prompt are the usual suspects. 2.4.7 Focus Visible (Level AA) requires a visible focus indicator, so confirm the host's focus ring survives: a tour stylesheet that resets outlines globally will remove it.

6. Remove the target in the middle of the tour

Advance to a step anchored inside a collapsible panel, then close the panel with the keyboard. The tour should skip, end or wait according to its rule, and focus must follow a declared path. Test this case hardest, since the target and the tour's anchor vanish together.

7. Run it with a screen reader and log the announcement

After each exit, note which element was announced and whether the user's place in the page still makes sense. Record browser and screen reader versions. Re-run after any change to the tour library, the host's routing or the host's focus styles.

Exit path test plan

Copy this structure into your review document and record your observed result for each row.

Exit path test plan
Exit pathExpected landingIllustrative resultVerdict
Escape on a modal stepThe Help menu button that started the tourLanded on the Help buttonPass
Close buttonThe Help menu buttonLanded on the Help buttonPass
Skip tourThe Help menu buttonLanded on the document bodyFail: no fallback wired to Skip
Done on the final stepThe Export control the last step describedLanded on ExportPass: workflow choice documented
Self-started tour closedMain heading with tabindex="-1"Landed on the headingPass
Target panel closed mid-tourThe panel's toggle buttonLanded on the togglePass
In-app route changeHeading of the new route; tour torn downTour stayed open over the new pageFail: teardown missing
Opener removed before closeDeclared fallback: the section headingLanded on the section headingPass
Landing element under a sticky headerThe same landing element, scrolled into viewFocused control entirely hiddenFail: 2.4.11, Level AA

A failure worth checking

The auto-started welcome tour. It opens on first load, so there is no opener to return to, and its close handler simply removes the layer. When a focused element is removed, document.activeElement becomes the body. A screen reader may announce nothing useful, and where the next Tab press goes depends on the browser. The user was halfway through reading the dashboard and is now somewhere unknown. The fix is a declared, tested fallback for each self-starting tour, not a cleverer default.

Common questions

Must focus go back to the opener after the Done step?

Not necessarily. The APG dialog pattern allows focus to move to a different element when the task completed in the dialog leads directly into a next step. If the last step pointed at Export, landing there is defensible. Write the choice into the plan so testers know which result counts as correct.

Does WCAG require focus restoration?

No success criterion names it. The ones usually at stake are 2.4.3 Focus Order (Level A), 2.1.2 No Keyboard Trap (Level A), 2.4.7 Focus Visible (Level AA) and 2.4.11 Focus Not Obscured (Minimum) (Level AA). The APG patterns are guidance, not normative requirements. This plan tests behavior against those; it doesn't certify conformance.

Basis and scope

This is a proposed implementation method using illustrative examples, not a measured benchmark or a customer case study. Prepared with AI assistance. Validate product-specific behavior against current documentation and your own test environment.

Continue with PLG OS

Explore onboarding →