DEV Community

Silviu Technology
Silviu Technology

Posted on

React: mide la UX de un inbox de prueba

Cuando un formulario depende de un correo de verificación, solemos medir si el mensaje llegó. Eso es importante, pero no alcanza. La persona también necesita saber si el inbox está cargando, si ya se revisó, si el código expiró o si debe intentar otra vez. Un inbox de prueba puede recibir el mensaje correcto y aun así ofrecer una experiencia confusa.

En proyectos de frontend me funciona tratar esa pantalla como una parte del producto, no como una ventana tecnica que solo sirve para QA. Si la interfaz tiene estados explícitos, foco estable y una lectura clara en móvil, es mas sencillo detectar los problemas del flujo completo. Este enfoque sirve tanto para un correo desechable usado durante una demo como para una bandeja aislada de pruebas automatizadas.

La UX del inbox también se puede medir

Antes de escribir componentes, separo tres preguntas:

  1. ¿La persona sabe qué está esperando?
  2. ¿Puede distinguir un mensaje nuevo de uno viejo?
  3. ¿Tiene una acción segura cuando el correo no aparece?

Un layout con una animación bonita no responde por sí solo a ninguna de ellas. En cambio, un encabezado que dice “Buscando el correo de verificación”, una marca de tiempo y un botón “Comprobar de nuevo” crean un modelo mental bastante mas útil.

También conviene conectar la interfaz con el flujo que la rodea. Por ejemplo, una lista de direcciones de prueba puede seguir las mismas reglas de aislamiento que unas seed lists para onboarding. Cuando el inbox es parte de una prueba de registro, esa relación evita que el equipo culpe al frontend por un mensaje enviado a otra dirección.

Un modelo de estados pequeño en React

No usaría un booleano llamado loading para representar toda la pantalla. Como mínimo, el inbox necesita distinguir entre cargar, vacío, listo, error y expirado. Un tipo pequeño hace visibles esas decisiones:

type InboxState =
  | { kind: "loading" }
  | { kind: "empty"; checkedAt: number }
  | { kind: "ready"; subject: string; receivedAt: number }
  | { kind: "expired" }
  | { kind: "error"; message: string };

function InboxStatus({ state }: { state: InboxState }) {
  switch (state.kind) {
    case "loading":
      return <p role="status">Buscando el correo...</p>;
    case "empty":
      return <p role="status">Todavía no hay mensajes. Puedes comprobar de nuevo.</p>;
    case "ready":
      return <p role="status">Nuevo mensaje recibido: {state.subject}</p>;
    case "expired":
      return <p role="alert">Esta dirección ya no está disponible. Crea otra para continuar.</p>;
    case "error":
      return <p role="alert">No pudimos revisar el inbox: {state.message}</p>;
  }
}
Enter fullscreen mode Exit fullscreen mode

La ventaja no es solo de tipado. El componente obliga a producto y QA a decidir qué se muestra en cada momento. Un mensaje vacío no debería parecer un fallo de red, y una dirección expirada no debería ofrecer un botón que seguirá haciendo polling para siempre. Si el sistema usa un servicio tipo tempail o tempail mail en una prueba manual, esa diferencia de estado ayuda a no confundir una bandeja vacía con una dirección que ya caducó.

Para mantener el foco, el cambio de estado debería actualizar una región de texto, no desmontar todo el formulario. El botón de volver a comprobar puede conservar su posición y su nombre. Eso hace el flujo mas predecible con teclado y tambien simplifica los tests de interacción.

CSS para que esperar no se sienta lento

El rendimiento percibido nace de detalles pequeños. Reservo un espacio para el mensaje y para la lista, incluso cuando todavía no hay datos. Así el contenido recibido no empuja el botón hacia abajo cuando llega.

.inbox-panel {
  min-height: 12rem;
  contain: layout paint;
}

.inbox-status {
  min-block-size: 3rem;
  display: grid;
  align-items: center;
}

.inbox-message {
  content-visibility: auto;
  contain-intrinsic-size: 0 5rem;
}
Enter fullscreen mode Exit fullscreen mode

No aplicaría content-visibility a un control que debe estar disponible de inmediato, pero puede ser practico en una lista larga de mensajes. Para una bandeja pequeña, lo mas importante es evitar saltos de layout y no mostrar un spinner que ocupa toda la pantalla por una consulta de pocos cientos de milisegundos.

Accesibilidad: anunciar lo necesario

role="status" es útil para cambios informativos como “mensaje recibido”. Reservaría role="alert" para errores que necesitan atención inmediata. Si todo se anuncia como alerta, la experiencia se vuelve ruidosa, sobre todo cuando el polling ocurre cada pocos segundos.

El texto visual no debe depender solo del color. Un estado expirado puede usar un icono, pero también necesita una frase y una acción. El foco visible del botón debe tener contraste suficiente y no desaparecer al usar un reset de estilos. En móvil, además, el área táctil y el orden de lectura importan mas que una tarjeta compacta.

Para los mensajes de incidentes o fallos intermitentes, puede ser útil enlazar la interfaz con runbooks cortos para incidentes de email. El usuario final no necesita ver el runbook, claro, pero el equipo que mantiene la pantalla sí necesita una ruta de diagnóstico coherente.

Qué medir en una prueba real

No hace falta instrumentar veinte eventos. Empezaría con cuatro:

  • tiempo desde “enviado” hasta “recibido”;
  • cantidad de comprobaciones antes de encontrar el mensaje;
  • porcentaje de sesiones que terminan en expiración o error;
  • activaciones de “comprobar de nuevo” después de que el mensaje ya llegó.

El último dato es curioso: si se activa mucho, quizá el mensaje recibido no destaca, la actualización no se anuncia o el usuario no confía en el estado mostrado. Una métrica de backend puede decir que todo está bien mientras la interfaz comunica lo contrario.

Checklist antes de publicar

  • Cada estado tiene texto visible y una acción razonable.
  • El inbox conserva la posición del botón al recibir datos.
  • El foco no salta durante el polling.
  • Los cambios informativos usan una región status y no una alerta global.
  • La lista funciona sin depender del color.
  • Hay una forma de distinguir mensaje nuevo, viejo y expirado.
  • Los errores dejan una siguiente acción clara.

Q&A

¿Necesito un inbox complejo para una prueba de signup?

No. Un panel con estado, asunto, hora de recepción y una acción de reintento suele ser suficiente. La complejidad debe aparecer solo cuando una necesidad concreta la justifique.

¿Conviene consultar cada segundo?

Generalmente no. Un intervalo moderado con un límite de tiempo y una acción manual suele ser mas amable con el navegador y con el servicio de correo. Cuando el mensaje llegue, detén el polling y registra el resultado.

¿Qué pasa si el correo de prueba expira?

Muéstralo como un estado propio, explica la consecuencia y permite crear una nueva dirección. Ocultar la expiración detrás de un “sin mensajes” deja a la persona adivinando por que la prueba no avanza.

Top comments (0)