Skip to navigation

Narrate a recording with annotations

Draw annotations into the page and leave them up across steps and navigation, so they appear in the video. The annotate action narrates a recorded flow. It points at fields, numbers steps, and redacts sensitive information as the recording plays. New to recording? Start with Record video. The annotation types, targets, style, and the annotationDefaults theme are defined once on Annotate screenshots. This guide covers only what changes in motion.

Before you begin

Make sure you have the following:

  • Doc Detective installed.
  • A directory where you can create a .spec.json file.
  • A headed, visible context and a recording span to narrate.
  • A page to draw into. The annotate action can’t draw on native app surfaces.

The steps in this guide work the same in every authoring style. Write them in a standalone .spec.json, inline in a doc source file, or let Doc Detective detect them from prose.

Narrate a recording with annotations

The annotate action draws annotations into the page and leaves them up across steps and navigation, so they appear in the video. This is the difference from screenshot.annotations, which apply to a single still:

screenshot.annotationsannotate
LifetimeOne captureUntil something clears them
Appears in recordingsNoYes
Works on app surfacesYesNo, it needs a page to draw into
Touches the pageNoYes

Give an annotate step at least one of add, update, or clear. add draws annotations, and update changes annotations already on screen, matched by id. For clear, true clears everything and a list of ids clears just those. clear runs before add, so clearing and adding the same id reads as replacing it.

Four fields matter only in motion:

  • id: a handle, so a later step can update or clear the annotation.
  • track: follow the element as the page scrolls or the layout shifts.
  • transition: how the annotation enters and leaves. enter accepts none, fade, pop, or draw; exit accepts none or fade; durationMs sets the length.
  • duration: milliseconds to stay up before clearing itself, with no paired clear step.

This sequence points at one field, moves the annotations to the next, then clears them, all inside a recording span:

{
"tests": [
{
"steps": [
{ "record": "sso-setup.webm" },
{
"description": "Point at the first field.",
"annotate": {
"add": [
{ "id": "step", "badge": "#idp", "label": "1" },
{ "id": "guide", "callout": "#idp", "label": "Pick your provider first", "position": "right", "track": true }
]
}
},
{ "click": "#idp" },
{
"description": "Move the annotations to the next field.",
"annotate": {
"update": [
{ "id": "step", "badge": "#metadata-url", "label": "2" },
{ "id": "guide", "callout": "#metadata-url", "label": "Paste the metadata URL" }
]
}
},
{ "annotate": { "clear": true } },
{ "stopRecord": true }
]
}
]
}

For a redaction that stays up for a whole recording, set three fields. Use all: true with an object target so every match is covered, track: true so the blur follows the element, and transition: { "enter": "none" } so the blur never fades in. A fading blur leaves the content readable during the animation, and every frame of that is in the video:

{
"annotate": {
"add": [
{
"id": "redact",
"blur": { "selector": ".account-id" },
"all": true,
"track": true,
"transition": { "enter": "none" }
}
]
}
}

The step exposes $$annotationCount, the number of annotations on screen after it runs. The annotation objects themselves live in one place, on the screenshot guide. That covers the six types, targets, style, and the annotationDefaults theme. See Annotate screenshots and Annotations. For the annotate fields, see the annotate action reference and the annotate schema.

Verify it works

  • The annotate step exposes $$annotationCount, the number of annotations on screen after it runs.
  • The annotations appear in the recording and stay up across steps and navigation until something clears them.

What’s next