Diwall

English
Download 1.24.4

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, then dernier_code_http.
  • A fast succes: true on a workflow you expected to be slow is a warning, not a result.