SmartERP Documentation An Ashewa Technology Solutions Platform

Screenshots

Take screenshots with a script, in English and Amharic, and keep them current.

Every screenshot on this site is taken by a script, not pasted in by hand. That makes them the same size and style everywhere, gives each one an English and an Amharic version, keeps sensitive data out, and lets you find out when one has gone out of date.

How it fits together#

  1. A shot list in smarterp_docs/shots/ says what to capture: the page, the steps, the languages, the alt text and the caption.
  2. smarterp_docs/tools/shots.py opens a real browser, follows the steps, and writes PNG files to static/img/ and a record of each one to static/img/manifest.json.
  3. A page shows an image by its asset id, on a line of its own.
![Search as you type]({asset:docs-search})

The site chooses the image for the reader's language, and a dark version when there is one. The alt text and the caption come from the manifest, in both languages.

Set up once#

You need Python 3 and a browser that Playwright can drive:

pip install playwright
playwright install chromium

Take the screenshots#

python3 smarterp_docs/tools/shots.py

The script starts the documentation preview itself, so nothing else has to be running. It prints each file it writes, its size, and any problem. It exits with an error if anything failed, so it is safe to use in an automated check.

OptionWhat it does
--only IDTake only this asset. Repeat it for several.
--lang amTake only this language.
--checkWrite nothing. Report which images are out of date.
--listList the shots and stop.
--base-url URLPoint the shot lists at another site, such as a SmartERP demo database.
--optimiseRecompress each PNG without loss. Needs Pillow.
--pruneDelete image files the manifest no longer lists.

Write a shot list#

A shot list is a JSON file in smarterp_docs/shots/. This one takes two images, English and Amharic, of the home page:

{
  "base": "preview",
  "defaults": {"viewport": [1280, 760], "languages": ["en", "am"], "themes": ["light"]},
  "shots": [
    {
      "id": "docs-home",
      "url": "/docs/{lang}",
      "steps": [{"wait_for": ".card"}],
      "annotate": [
        {"target": ".search", "text": {"en": "Search box.", "am": "α‹¨ααˆˆαŒ‹ ሳαŒ₯αŠ•α’"}}
      ],
      "alt": {"en": "The documentation home page.", "am": "α‹¨αˆ˜αˆ˜αˆͺያው መነሻ ገጽፒ"},
      "caption": {"en": "The home page.", "am": "መነሻ ገጽፒ"}
    }
  ]
}
FieldMeaning
idThe asset id: lower-case letters, digits and single hyphens.
urlThe page to open. {lang} becomes en or am.
stepsThings to do first, each with one key: goto, click, hover, fill, press, wait_for, wait, scroll_to.
capture"viewport" (the default), "full_page", or {"selector": ".callout"} for one element.
maskSelectors to blur before the picture is taken.
annotateElements to outline and number. The text of each becomes a numbered list under the picture.
themes["light"], or ["light", "dark"] to also take a dark version.
alt, captionRequired in every language.

A value in a step can differ by language, for example {"fill": [".search input", {"en": "approval", "am": "αˆ›αŒ½α‹°α‰…"}]}. It can also read an environment variable, as in $ENV:ODOO_PASSWORD, so a password never sits in a file.

What the script protects you from#

  • No image without words. A shot without alt text or a caption in both languages is refused before a browser starts, and the content tests fail if a page uses an image that has none.
  • No secrets. Before each picture the script reads the visible text. An email address outside the allowed domains, an API key, a token, a password or a phone number stops that image from being saved, and the run fails. The rules are in shots/_policy.json. Anything in mask is blurred and left out of the scan.
  • A size limit. An image over 250 KB is reported, so pages stay light on a slow connection.
  • Files that match the record. The tests check that every file in static/img/ is in the manifest, that its checksum and size still match, and that every image a page shows exists.

Warning

Take screenshots only from demo data, never from a live system with customer names, prices or staff details. The scan catches common patterns, not everything a person would recognise.

Keep them current#

Run the check after a change to the screens:

python3 smarterp_docs/tools/shots.py --check

For each language it reopens the page and compares what is on it with what was there when the picture was taken. An image that no longer matches is reported as stale. Take it again, look at it, and commit the new file with the manifest.

Screens from SmartERP itself#

The shot lists that ship with this module capture the documentation site. To capture SmartERP's own screens, such as the approval queue, point a shot list at a running SmartERP that holds demo data, and sign in with steps that read the account from the environment:

ODOO_USER=demo ODOO_PASSWORD=... python3 smarterp_docs/tools/shots.py --base-url http://localhost:8069

Use only SmartERP's own screens and this site. Never show another company's product or brand.

Checklist#

  • The shot list has alt text and a caption in English and Amharic, and an editor who reads Amharic has checked the Amharic.
  • python3 smarterp_docs/tools/shots.py finishes with no problem.
  • You have looked at every image, in both languages.
  • The page shows the image by its asset id, in both languages, at the same place.
  • python3 smarterp_docs/tools/run_offline_tests.py passes.
Last updated: 2026-10-16