Writing a scenario
A JSON file, a list of actions, twenty-one verbs. How to build one that still works next month, and the two habits that decide whether it does.
A scenario is a JSON file: where to go, and what to do there. It is Diwall’s unit of work — you will write them, reuse them, and put them under version control.
{
"nom": "check-dashboard",
"url": "https://target.local/login",
"actions": [
{"type": "remplir_som", "id": 2, "valeur": "depuis_secrets", "secret_cle": "username"},
{"type": "remplir_som", "id": 3, "valeur": "depuis_secrets", "secret_cle": "password"},
{"type": "cliquer_som", "id": 5},
{"type": "attendre_selecteur_present", "selecteur": ".user-menu"}
]
}
Two fields are required: url and actions. Everything else is optional, and
the file is validated before a browser starts — a typo in a key name stops the
run immediately rather than halfway through.
Start by looking
You cannot write actions for a page you have not read. Capture it first:
diwall-shot --url https://target.local/login --som --a11y --guide-version 1.3
elements_som gives you the numbers, a11y_tree gives you the selectors and
the structure. Write the scenario from that output, not from memory of what the
page probably looks like.
The twenty-one verbs
| Family | Actions |
|---|---|
| Act | cliquer, cliquer_som, cliquer_visuel, remplir, remplir_som, defiler |
| Inside a frame | cliquer_iframe, remplir_iframe |
| Move | naviguer |
| Wait | attendre, attendre_absence, attendre_selecteur_present, attendre_navigation, attendre_url, attendre_reseau_calme, pause |
| Observe | capturer, evaluer |
| Compose | declencher_scenario, nettoyer_overlay, attendre_mfa_ntfy |
The _som variants take a number from the capture; the plain ones take a CSS
selector. Prefer numbers when the page is stable and selectors when you have
something unique to match on.
Each verb’s parameters, required and optional, are in the cheat sheet.
Habit one — wait for a signal, never for a duration
A
pauseis a bet on how long something takes. You will lose it, in both directions.
{"type": "cliquer_som", "id": 7},
{"type": "attendre_absence", "selecteur": ".spinner"},
{"type": "attendre_selecteur_present", "selecteur": ".result"}
Set a pause to ten seconds and an operation taking fifteen gives you a capture of a job still running — success reported, nothing verified. One taking two wastes eight seconds on every single run.
Waiting for a DOM signal makes the scenario take exactly as long as the work
does. Keep pause for a deliberate delay, not for a guess.
Habit two — assert before you act
Put a check at the top. If the page is not the one you expect, the scenario stops before typing anything anywhere:
{"type": "evaluer", "script": "document.title", "contient": "Sign in"}
This costs nothing and it is what stands between a redirect you did not notice and a password typed into a stranger’s form. The credential scenario shipped with Diwall opens exactly this way.
auth_indicator does the same at the file level — a selector that only exists
when authenticated, checked automatically:
{"auth_indicator": ".user-menu", "url": "…", "actions": [...]}
Options the file can carry itself
Some flags belong to the target, not to the person running the scenario. Put them in the file so it stays self-contained:
| Property | For |
|---|---|
wait_until | a target that never goes network-idle |
shadow_dom | components inside open shadow roots |
som_brut | opt out of the hybrid SoM resolver, back to raw re-indexing (rarely needed — the hybrid default already reports drift) |
http_credentials | HTTP Basic authentication |
intention | a sentence recorded in the operations log |
Whoever reuses your scenario then does not need to know the target’s quirks.
Never write a credential
{"type": "remplir_som", "id": 3,
"valeur": "depuis_secrets", "secret_cle": "password"}
The scenario names a key; the encrypted directory holds the value. This is what makes a scenario safe to commit, and the publication check refuses to publish when it finds a password in clear text in one.
In short
- Capture the page first; write the scenario from the output.
urlandactionsare required — everything else is optional.- Wait for signals, not durations.
- Assert the page before acting on it.
- Put target-specific options in the file so it travels alone.
- A credential is always a
secret_cle, never a value.