How do I capture screenshots for a manual chapter?
Table of Contents
Follows How do I document an entity?, which leaves a chapter with every
screenshot as a [SCREENSHOT NEEDED] placeholder carrying a # Capture:
instruction. This recipe turns each placeholder into a real, cropped,
correctly-named image, driven by the QA Validation Runner. The
Capture screenshots for the Currency Pairs manual chapter scenario is the
worked exemplar this recipe generalises from.
Question
How do I turn a manual chapter's [SCREENSHOT NEEDED] placeholders into
real, correctly-named, correctly-cropped screenshots?
Answer
Prerequisites
Run these three steps, in order, before touching the chapter's placeholders — every time. Capturing screenshots against a stale build or an unprovisioned tenant produces screenshots that don't match what ships.
Ask the user whether a new build is necessary before doing anything else. If nothing has changed since the last build, skip straight to step 2:
./compass.sh build --preset <preset>
- Ready the environment — confirm the database is recent (recreate only if it's not) and the Acme Corporation tenant is provisioned, per How do I ready up an environment? steps 1-5 (skip that recipe's step 6, client start — the scenario in step 2 below starts its own client with the scenario preloaded).
Confirm the chapter itself already builds before capturing anything, so a broken link or missing include isn't mistaken for a capture problem later:
./compass.sh build --direct manual
Create a test scenario, one step per placeholder
Count the placeholders and scaffold a test_scenario doc under the
entity's story directory:
grep -c "SCREENSHOT NEEDED" doc/manual/user_guide/chapter_<plural>.org ./compass.sh add test_scenario \ --slug <plural>-manual-screenshots \ --parent-dir doc/agile/versions/v0/<sprint>/<story-slug> \ --parent-id <task-uuid> \ --parent-title "<the manual-chapter task's title>" \ --title "Capture screenshots for the <Plural> manual chapter" \ --description "Set up UI state and capture the N screenshot placeholders in chapter_<plural>.org."
Fill in the * Scenario Info table before writing steps. Clients
must be genuinely empty (no placeholder text at all, not even
"single client") for the common single-client case — this field is
not just documentation: the QA Validation Runner treats any
non-empty value here as "multi-client" and then only looks for steps
nested one level deeper, under a per-client ** heading. A stray
placeholder with flat ** steps silently loads zero steps, no
error shown. Then add one ** Capture <target_filename>.png
step per placeholder, in the chapter's top-to-bottom order, each body
copying that placeholder's # Capture: instruction verbatim (adjust only
if the concrete data on file differs from the instruction's example,
e.g. a different pair code than the one the instruction names — note the
substitution in the step body). Do not invent extra steps among the
capture steps — the count of capture steps should equal the placeholder
count exactly — but the scenario is not complete without the two closing
review steps below, which are mandatory and not counted against the
placeholder count:
** Read the manual in the Qt client— after the chapter is wired in and the images are captured (steps 3-5 below), rebuild the Qt-embedded HTML help and open the chapter inside the running client's own manual viewer (Help → User Manual, or wherever the entity's window links to it), reading it top to bottom exactly as an end user would: does the prose read correctly, do the segues work, does every screenshot appear where expected and actually show what its caption claims?** Check the built PDF— open the rebuiltuser_manual.pdf(e.g. viazathuraorevince) at the new chapter's pages and confirm layout, figure numbering, and captions look correct in the PDF's own rendering, which can differ from the HTML view (page breaks, figure placement, the List of Figures entries).
Both steps exist because the HTML/Qt-help and LaTeX/PDF renderers are independent pipelines from the same org source, and either can surface a problem the other doesn't (a caption that overflows a PDF column, an image path that resolves for LaTeX but not for the Qt help export, etc.). Do not mark the scenario PASSED without having actually looked at both.
Run the scenario in the client
Start (or restart) the client with the scenario preloaded so the QA
Validation Runner panel opens with it already loaded. --open-scenario
requires an absolute path — a relative one silently fails to load
the scenario, so resolve it explicitly rather than typing a
doc/agile/...-style relative path by hand:
./compass.sh client start --colour <colour> \ --open-scenario "$(realpath doc/agile/versions/v0/<sprint>/<story-slug>/scenario_<plural>-manual-screenshots.org)"
Log in, then work each step: set up the described UI state and click the
runner's Screenshot button, which saves a full-desktop PNG next to the
scenario file (named <scenario-slug>_step<N>_<timestamp>.png) and links
it into that step's *** Result as Notes | [[file:...]], then click
Pass.
A step can fail to auto-capture. If the UI state to capture is a
modal dialog (e.g. a validation-rejection warning), the runner's own
panel cannot receive the Screenshot/Pass click while that dialog holds
focus — the step has to be captured with the desktop's own screenshot
tool instead (e.g. a Screenshot from <timestamp>.png landing wherever
the desktop environment saves them, often a tmp/ or Screenshots/
directory) and then processed by hand through steps 3-4 below like any
other capture. Do not treat this as a scenario-authoring mistake — file
it as the known message-box modality gap rather than trying to route
around it in the scenario itself.
Locate and identify each capture
find doc/agile/versions/v0/<sprint>/<story-slug> \ -iname "<scenario-slug>_step*" -o -iname "<scenario-slug>_2026*"
Open each one (or the scenario doc's per-step Notes links) and match it
against the placeholder it was meant to satisfy — the step title already
names the target filename, so this is a direct lookup, not a guess.
Crop to just the dialog or window, following the naming convention
Every published manual screenshot is cropped tightly to the window or dialog of interest — never the full desktop, and never with the QA Validation Runner panel or other chrome in frame. Use the raw capture's pixel bounds for the window in question (read them off the image; a quick Python/Pillow one-liner is enough, no dedicated tool):
python3 -c "
from PIL import Image
im = Image.open('<raw_capture>.png')
im.crop((left, top, right, bottom)).save('/tmp/<crop_name>.png')
"
View the crop before finalising it — check no other window's edge, no
scenario-runner overlay, and no cut-off button bleeds into frame; widen
the box and re-crop if anything does. Name the final file per
How do I document an entity?§"Name screenshots to the standard" (the
plural/singular rule) — the target name is already fixed by the
placeholder's TODO_<name>.png, so cropping just drops the TODO_
prefix:
cp /tmp/<crop_name>.png assets/images/<final_name>.png
Wire the real images into the chapter and rebuild
Replace each placeholder's link and caption:
#+caption: [SCREENSHOT NEEDED] <what to show>. # Capture: <instruction>. [[proj:assets/images/TODO_<name>.png]]
becomes
#+caption[<Short caption>]: <Long caption describing what the reader sees, naming the concrete record shown if relevant>. [[proj:assets/images/<name>.png]]
Then rebuild the PDF and confirm every new figure appears in the List of Figures:
./compass.sh build --direct manual
pdftotext -layout doc/manual/user_guide/user_manual.pdf - | grep -A20 "List of Figures"
Also rebuild the Qt-embedded HTML help so the client's own in-app manual
viewer reflects the change — this is a separate pipeline from the PDF
and does not update just because deploy_manual ran:
# Exports the self-contained HTML (build/output/help/) … ./compass.sh build --direct help # … then recompiles the .qch resource the Qt client actually ships and # reads (projects/ores.qt/application/resources/help/user_manual.qch). # This step needs the full cmake build, not --direct: it isn't an emacs # script, and the recompiled resource has to be picked up by rebuilding # and restarting ores.qt before the "Read the manual in the Qt client" # step below will show anything new. ./compass.sh build deploy_help_qch --preset <preset>
Both builds are prerequisites for the two review steps in step 1 above — do them before working those steps, not after.
Close out
Update the screenshot task's Status/Result and the scenario's Test
Scenarios table entry, commit the chapter, the PDF, and the new images
together, and note in the task's * Notes if any concrete data (pair
codes, currency codes, dates) differs from what the chapter's
# Capture: instructions originally named. At this point the chapter is
ready for human review — nothing else in the authoring flow is
outstanding.
Script
No dedicated wrapper — compass add test_scenario (scaffold), the QA
Validation Runner panel (capture), and a short inline Python/Pillow
snippet (crop) compose the flow. See Capture screenshots for the Currency
Pairs manual chapter for a fully worked example of every step above.
Tested by
The manual build (compass build --direct manual) confirms every real
image resolves and appears in the List of Figures; there is no automated
check that a screenshot's content matches its caption — that is what
the human review pass (recipe How do I document an entity?'s closing note)
is for.
See also
- How do I document an entity? — the recipe this one follows; defines the placeholder convention and the naming standard this recipe fills in.
- How do I ready up an environment? — the shared prerequisite chain this recipe's step 2 calls rather than duplicating.
- QA Validation Runner: in-app test tracking for the multi-worktree fleet — the panel this recipe drives.
- Capture screenshots for the Currency Pairs manual chapter — the worked exemplar scenario.
- Consolidate message boxes into one non-modal, copiable, standard-button ORE Studio dialog — the backlog capture for the modal-dialog gap this recipe currently has to work around by hand.