The session does not survive between two calls
You log in, the capture proves it worked, and the next call lands back on the login page — or worse, reports success and does nothing. What is actually happening, and the rule that avoids it.
The symptom. You split a workflow across two calls. The first authenticates
and saves the session; the second reuses it. Either the second call lands back
on the login page, or — and this one is worse — it returns succes: true in
about a second and changes nothing on the target.
What is actually happening
A saved session is a Playwright storage_state: cookies and localStorage,
nothing else. Two things are not in it, and they are the two that break you.
The DOM state is not in it. A checkbox you ticked, a <select> you set, a
dialog you opened — all gone on resume. The page comes back clean. Your
numbered actions then run against a fresh page, hit whatever element now
carries that number, and report success. Nothing errors, because nothing went
wrong from Diwall’s point of view: it clicked element 7, and element 7 existed.
The server-side session is not in it either. Many applications call
something equivalent to session_regenerate_id() right after login. The cookie
you saved is the one from before the regeneration. The client-side snapshot
is perfectly valid and perfectly useless.
The rule
Never split a stateful workflow. Log in, act and confirm in a single call, even when that means logging in again.
Measured on a real target: the single-call version took 7.5 seconds and worked; the split version took 1.1 seconds and silently did nothing. The fast one is the one that failed.
A single call takes an array of actions — that is the whole point of the array:
diwall-shot --url https://target.local/login --som --guide-version 1.3 \
--actions '[
{"type": "remplir_som", "id": 4, "valeur": "depuis_secrets", "secret_cle": "username"},
{"type": "remplir_som", "id": 5, "valeur": "depuis_secrets", "secret_cle": "password"},
{"type": "cliquer_som", "id": 7},
{"type": "attendre_selecteur_present", "selecteur": ".user-menu"},
{"type": "cliquer_som", "id": 12}
]'
One browser launch, one final capture. The split version costs a Playwright start, a storage reload and a full SoM redraw per call — it is slower per step and it loses your state between them.
When persistence is the right tool
Session persistence is not a trap, it is a tool with a narrow purpose: reading several authenticated pages that do not depend on each other. A dashboard, then a settings page, then a report — each one self-contained.
# Authenticate once
diwall-shot --url https://target.local/login --som --guide-version 1.3 \
--actions login.json --sauver-session ~/session.json
# Read as many independent pages as you like
diwall-shot --url https://target.local/dashboard --som --guide-version 1.3 \
--reprendre-session ~/session.json
Since v1.11.1 the session file is no longer deleted at end of run, so chained
calls are safe. Add --sauver-session again only to refresh the stored state
on purpose.
The line to hold: persistence carries what you are, not what you were doing.
Read the answer, not just the verdict
Every call after --reprendre-session tells you whether the session held:
"boussole": {
"session_derive": true,
"url_courante": "https://target.local/login",
"dernier_code_http": 302
}
session_derive: true means you are no longer where you thought you were.
Re-run the full login, without --reprendre-session.
Then read dernier_code_http, because two very different failures look
identical. A genuinely expired session and an application error hidden behind
display_errors=0 both dump you on the login page with session_derive: true.
A 302 or 200 points to a real expiry — log in again. A 500 or a 4xx
means the application broke and your session was never the problem; logging in
again will waste your time.
One nuance: on a run with several naviguer actions, this field reflects the
last navigation only, which is not necessarily the one that explains the
drift.
In short
- Stateful — login, act, confirm: one call, one array of actions.
- Stateless — reading independent authenticated pages: persistence is fine.
- After every resume: check
session_derive, thendernier_code_http. - A fast
succes: trueon a workflow you expected to be slow is a warning, not a result.