Dinoer

La sesión no se mantiene entre dos llamadas

Inicias sesión, la respuesta demuestra que funcionó, y la siguiente llamada vuelve a la página de inicio de sesión; o peor aún, informa de éxito pero no hace nada. ¿Qué está sucediendo realmente, y qué regla evita esto?

El síntoma. Divide un flujo de trabajo en dos llamadas. La primera autentica y guarda la sesión; la segunda la reutiliza. O bien, la segunda llamada te devuelve a la página de inicio de sesión, o —y esto es peor— retorna succes: true en aproximadamente un segundo y no modifica nada en el destino.

¿Qué está realmente sucediendo?

Una sesión guardada es un Playwright storage_state: cookies y localStorage, nada más. Hay dos cosas que no están incluidas en ella, y son las dos que te causan problemas.

El estado del DOM no está incluido. Una casilla que usted marcó, un <select> que usted configuró, un diálogo que usted abrió — todo desaparecido al reanudar. La página vuelve limpia. Su escenario se ejecuta entonces contra una página nueva, actúa sobre cualquier elemento al que el selector corresponda ahora e informa de éxito. Nada falla, porque nada salió mal desde el punto de vista de Dinoer: hizo clic en el selector, y el selector coincidió con algo.

La sesión del lado del servidor tampoco está presente. Muchas aplicaciones llaman a algo equivalente a session_regenerate_id() inmediatamente después de iniciar sesión. La cookie que guardaste es la que existía antes de la regeneración. El “snapshot” del lado del cliente es perfectamente válido y completamente inútil.

La regla

Nunca dividas un flujo de trabajo con estado. Inicia sesión, actúa y confirma en una sola llamada, incluso si eso significa iniciar sesión nuevamente.

Una sola llamada ejecuta una serie de acciones; esa es la finalidad del arreglo:

{"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"}
 ]}

Una instancia del navegador, una respuesta final. La versión dividida requiere un inicio de Playwright y una recarga del almacenamiento por llamada; es más lenta por paso y pierde el estado entre ellos.

Cuando la perseverancia es la herramienta adecuada

La persistencia de sesión no es una trampa, sino una herramienta con un propósito limitado: leer varias páginas autenticadas que no dependen unas de otras. Un panel de control, luego una página de configuración, luego un informe; cada uno independiente.

# Authenticate 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 you like
/opt/dinoer/venv/bin/python3 /opt/dinoer/shot.py \
  --url https://target.local/dashboard --guide-version 1.6 \
  --reprendre-session ~/session.json

La línea que hay que retener: la persistencia conserva quién es usted, no lo que estaba haciendo.

Lea la respuesta, no solo el veredicto

Cada llamada después de --reprendre-session le indica si la sesión se llevó a cabo:

"boussole": {
  "session_derive": true,
  "url_courante": "https://target.local/login",
  "dernier_code_http": 302
}

session_derive: true significa que usted ya no está donde creía estar. Vuelva a ejecutar el inicio de sesión completo, sin --reprendre-session.

Después lea dernier_code_http, porque dos fallos muy distintos parecen idénticos. Una sesión genuinamente expirada y un error de aplicación oculto tras display_errors=0 le devuelven ambos a la página de inicio de sesión con session_derive: true. Un 302 o 200 apunta a una expiración real — vuelva a iniciar sesión. Un 500 o un 4xx significa que la aplicación falló y su sesión nunca fue el problema; volver a iniciar sesión le hará perder el tiempo.

Una matiz: en una ejecución con varias acciones naviguer, este campo refleja solo la última navegación, lo cual no necesariamente es la que explica la desviación.

En resumen

  • Stateful: inicio de sesión, acción, confirmación: una llamada, una matriz de acciones.
  • Stateless: lectura de páginas autenticadas independientes: la persistencia es aceptable.
  • Después de cada reanudación: compruebe session_derive, luego dernier_code_http.
  • Un succes: true rápido en un flujo de trabajo que se esperaba que fuera lento es una advertencia, no un resultado.