Dinoer

The session does not survive between two calls

You sign in, the answer shows it worked, and the next call lands on the sign-in page, or reports success and does nothing. What is happening, and the rule that avoids it.

The symptom. You split a task across two calls. The first signs in and saves the session; the second reuses it. Either the second call lands on the sign-in page or, worse, it returns succes: true quickly and changes nothing on the target.

What is happening

A saved session is a Playwright storage_state: cookies and local storage, nothing else. Two things are missing from it, and they are the two that break the task.

The state of the page. A ticked box, a chosen option, an open dialog: all gone on resume. The page comes back clean, your scenario runs against it, clicks whatever the selector now matches, and reports success. Nothing fails, from Dinoer’s point of view: the selector matched something.

The session on the server. Many applications issue a new session identifier right after sign-in. If the cookie you saved predates that change, it is valid on the client side and useless on the server.

The rule

Never split a task that depends on the state of the page. Sign in, act and check in a single call, even if that means signing in again.

One call takes a list of actions; that is what the list is for:

{"url": "https://target.local/login",
 "actions": [
   {"type": "remplir", "selecteur": "input[name=\"username\"]", "valeur": "depuis_secrets", "secret_cle": "username"},
   {"type": "remplir", "selecteur": "input[name=\"password\"]", "valeur": "depuis_secrets", "secret_cle": "password"},
   {"type": "cliquer", "selecteur": "button[type=\"submit\"]"},
   {"type": "attendre_selecteur_present", "selecteur": ".user-menu"},
   {"type": "cliquer", "selecteur": "#next-step"}
 ]}

One browser start, one answer. Split into several calls, the same task starts the browser and reloads the session each time, and loses the page state in between.

When saving the session is the right tool

Saving a session has one narrow use: reading several signed-in pages that do not depend on each other. A dashboard, then a settings page, then a report, each complete on its own.

# Sign in once
/opt/dinoer/venv/bin/python3 /opt/dinoer/shot.py \
  --url https://target.local/login --guide-version 1.6 \
  --actions login.json --sauver-session ~/session.json

# Read as many independent pages as needed
/opt/dinoer/venv/bin/python3 /opt/dinoer/shot.py \
  --url https://target.local/dashboard --guide-version 1.6 \
  --reprendre-session ~/session.json

The session carries who you are, not what you were doing.

Read the answer, not only the verdict

After --reprendre-session, the answer tells you where you stand:

"boussole": {
  "url_courante": "https://target.local/login",
  "dernier_code_http": 200,
  "session_derive": {"url_sauvegardee": "https://target.local/dashboard",
                     "url_reprise": "https://target.local/login",
                     "avertissement": "…"}
}

session_derive appears when the page you ended on is not the one on which the session was saved: whatever that page held is gone. It also appears when you resume on another page on purpose, so compare url_courante with the address you asked for. If you landed on the sign-in page, the session no longer holds: sign in again, without --reprendre-session. --auth-indicator, with a selector that only exists once signed in, answers the question directly in auth_status.

Then read dernier_code_http. An expired session and an application error can both end on the sign-in page. A 200 or a 302 points to an expiry: sign in again. A 500 or a 4xx means the application failed and the session was never the problem; signing in again will not help.

On a run with several naviguer actions, this field reflects the last navigation only, which is not necessarily the one that explains the problem.

In short

  • A task that depends on the page state: one call, one list of actions.
  • Reading independent signed-in pages: saving the session is fine.
  • After a resume: compare url_courante with the page you asked for, then read dernier_code_http.
  • A quick succes: true on a task you expected to be slow is a warning, not a result.