Ir al contenido
RECDiagnosticSDK
04 / REPLAY

Reproduce el bug en tu propio dispositivo.

Elige una sesión grabada: las peticiones que coinciden reciben las respuestas grabadas y todo lo demás va a la red sin cambios.
  • Grabada en un teléfonoUn tester encuentra un bug. La sesión se guarda en su teléfono y te la comparte como archivo.
  • Editada en Session StudioAbre una sesión grabada y cambia un estado, una cabecera o un cuerpo: un 500, una lista vacía, un token caducado.
  • Creada desde cero en Session Studio¿Aún sin sesión ni backend? Escribe respuestas mock ruta por ruta y expórtalas como una sesión.

Archivo de sesión

Dx_4f2a9c1.json

Tu dispositivo

Replay activo3 peticiones
TransferViewController10:32:08
GET/v1/beneficiariesreplay20097ms
GET/v1/limitsnetwork20088ms
POST/v1/transfersreplay422302ms

1 petición que no estaba grabada fue a la red

Tu app recibe las respuestas del archivo, como si vinieran del servidor.

Cómo usarlo

Cuatro pasos, en el dispositivo.

  1. 1

    Trae el archivo

    Impórtalo desde el selector de Archivos en History, o usa una sesión grabada en este teléfono.

    HistoryImport trace

  2. 2

    Ábrelo en History

    Elige la sesión y luego Replay.

    Replay

  3. 3

    Elige el modo de matching

    Strict compara los query params, Ignore query no. Detalles más abajo.

    Replay (strict)Replay (ignore query)

  4. 4

    Usa tu app

    Un borde rojo indica que el replay está activo. Las peticiones servidas llevan una insignia REPLAY en Live. Stop termina el replay.

    REPLAYStop

En la pestaña Replay puedes dejar fuera del replay cualquier petición.

Qué pasa con cada petición

Encontrada: respuesta del archivo. No encontrada: red.

Cada petición que lanza tu app pasa las mismas comprobaciones, en este orden. La primera petición grabada que las supera todas da su respuesta.

  1. 1¿Está activo el replay?Con el replay desactivado, nada cambia.no →
  2. 2¿Mismo método y misma ruta?GET /v1/transactions solo coincide con GET /v1/transactions. El dominio no se compara.no →
  3. 3¿Se puede reproducir esta respuesta?La respuesta grabada debe ser JSON, y la petición no debe estar excluida en la pestaña Replay.no →
  4. 4¿Mismos query params?Solo en modo Strict. Ignore query se salta esta comprobación.no →

sí

Respuesta del archivo

La petición nunca sale a la red. El SDK construye una respuesta HTTP a partir del archivo (estado, cabeceras, cuerpo) y se la da a tu app como si viniera del servidor.

Enviada a la red

En cuanto falla una comprobación, la petición sale como siempre, sin tocar, y recibe la respuesta del servidor real.

Lado a lado: qué se compara

Petición de tu appPetición del archivo
MétodoGETGETComparado: igual
Dominioapi.lumen-bank.exampleuat.lumen-bank.exampleNo se compara
Ruta/v1/transactions/v1/transactionsComparado: igual
Query params?sort=date&page=2?page=2&sort=dateSegún el modo
CabecerasAuthorization: Bearer eyJ…a91Authorization: Bearer eyJ…f07No se compara
Cuerpo——No se compara

Modos de matching

Strict o Ignore query.

El modo solo cambia cómo se comparan los query params. El método y la ruta siempre deben ser iguales.

Replay (strict)

Mismos parámetros con los mismos valores. Su orden no importa.

Replay (ignore query)

Los parámetros no se comparan. Útil cuando cambian en cada llamada (un número de página, una fecha).

En el archivo: GET /v1/transactions?page=2&sort=date
Replay (strict)Replay (ignore query)
GET /v1/transactions?sort=date&page=2coincidecoincide
GET /v1/transactions?page=3&sort=dateno coincidecoincide

Varias coincidencias

Varias peticiones del archivo coinciden. ¿Cuál se sirve?

En un archivo compartido, la misma petición suele grabarse varias veces: una pantalla visitada dos veces, un pull to refresh. Para el modo elegido, todas coinciden con la misma petición de la app: forman un grupo.

Petición de tu app

GET /v1/accounts

GET /v1/accounts×3mismo método, ruta y query

  1. HomeViewController10:32:04{ "balance": 1200 }Servida
  2. TransferViewController10:32:09{ "balance": 1200 }Nunca se alcanza
  3. HomeViewController10:32:15{ "balance": 960 }Nunca se alcanza

El Replay sirve la primera, en orden de navegación. No la última.

Elige tú la respuesta, en la pestaña Replay

  1. 1Pon Sorting en Grouped: las peticiones que coinciden entre sí aparecen juntas, con su número.
  2. 2Desactiva las peticiones que no quieres servir.
  3. 3Deja activa solo la que quieres: pasa a ser la primera, y el Replay la sirve.

GET /v1/accounts×3mismo método, ruta y query

  1. desactivadaHomeViewController10:32:04{ "balance": 1200 }Nunca se alcanza
  2. desactivadaTransferViewController10:32:09{ "balance": 1200 }Nunca se alcanza
  3. activaHomeViewController10:32:15{ "balance": 960 }Servida

Los grupos siguen el modo: en Strict, mismo método, ruta y query; en Ignore query, mismo método y ruta. Session Studio muestra los mismos grupos antes del replay.

Bueno saberlo

Las reglas detrás del matching.

  • Solo respuestas JSONUna petición cuya respuesta grabada no es JSON nunca se reproduce: sale a la red.
  • Servida al instanteLa duración grabada no se reproduce: la respuesta llega de inmediato.
  • Compruébalo antes del replaySession Studio muestra, ruta por ruta, qué respuesta grabada servirá el Replay.

Un problema abierto

Hacer matching con toda la petición.

Nuestro primer objetivo era un matching completo: mismo método, misma ruta, mismas cabeceras, mismo cuerpo. Con sesiones reales, rechazaba peticiones que eran claramente las mismas.

Grabada el lunes

POST /v1/transfers

Cabeceras

Content-Type: application/jsonAuthorization: Bearer eyJhbGciOi…Qx7← cambia cada vezX-Request-Timestamp: 1759734610← cambia cada vez

Cuerpo

{
  "amount": 240  "beneficiaryId": "b_1029"  "nonce": "8f1c2a…"← cambia cada vez}
Enviada hoy

POST /v1/transfers

Cabeceras

Content-Type: application/jsonAuthorization: Bearer eyJhbGciOi…L2m← cambia cada vezX-Request-Timestamp: 1760090412← cambia cada vez

Cuerpo

{
  "amount": 240  "beneficiaryId": "b_1029"  "nonce": "d40b9e…"← cambia cada vez}

Comparadas parte por parte

  • Método: igual
  • Ruta: igual
  • Cabeceras: distinto
  • Cuerpo: distinto

El matching completo dice que no. Y sin embargo, es la misma petición.

Un token, una marca de tiempo, un nonce: valores que cambian en cada sesión, incluso para el mismo usuario, bastan para rechazar una respuesta que debería servirse. Por eso el Replay compara el método, la ruta y, en modo Strict, los query params, y deja fuera las cabeceras y el cuerpo.

Las ideas que hemos explorado

  • Ignorar una lista de campos que se sabe que cambian (tokens, marcas de tiempo, identificadores).
  • Dejarte elegir, ruta por ruta, qué campos deben ser iguales.
  • Servir la petición grabada más parecida en lugar de una idéntica.

Ninguna es aún lo bastante buena, así que el problema sigue abierto. Si tienes una idea, o un caso que el Replay no resuelve bien, cuéntanoslo.

Contáctanos