IA aplicada - Vibecoding - Playwright - Testing
5 min lectura

Tu app de IA falla con 429: prueba que nadie pierda su mensaje

Simula un error 429 con Playwright y comprueba que tu app de IA conserve el borrador, explique el fallo y permita reintentar sin duplicados.

Tu app de IA falla con 429: prueba que nadie pierda su mensaje

Escribes tres párrafos para que tu app de IA los analice. Pulsas «Enviar», el proveedor devuelve un error y el campo queda vacío. Para ti fue un fallo de red; para el usuario fue trabajo perdido. Ese es el tipo de problema que una prueba del modelo no detecta: la API puede fallar correctamente y la interfaz aun así tratar mal a la persona.

Esta guía propone un ensayo reproducible del estado visible de la app cuando el endpoint que usa la interfaz responde 429. No estamos midiendo la calidad del modelo ni configurando otro proveedor. El objetivo es comprobar tres contratos de producto: el texto del usuario sobrevive, el error se explica sin prometer que la petición se completó, y existe una salida clara para reintentar. Es útil antes de abrir una beta, después de cambiar la lógica de envío o cuando una herramienta de vibecoding reescribe el componente de chat.

Qué significa 429 y qué debería ver el usuario

El estándar HTTP define 429 como «Too Many Requests»: se alcanzó un límite de solicitudes durante un periodo. La respuesta puede indicar con Retry-After cuánto esperar, pero ese encabezado no es obligatorio. No presupongas que cada 429 significa que tu cuenta se quedó sin dinero, que el modelo está caído o que el usuario hizo algo mal. Tu producto conoce sus propios límites y debe traducirlos en una instrucción honesta: «No pudimos responder ahora; tu mensaje sigue aquí. Vuelve a intentarlo».

Antes de escribir la prueba, decide dónde vive el borrador. Si borras el textarea en cuanto se hace clic, guarda una copia en el estado de la conversación y restáurala al fallar. Si tu producto muestra el mensaje como enviado, márcalo como pendiente o fallido sin duplicarlo. El criterio observable es que la persona no tenga que reescribirlo. No muestres una respuesta vacía como si fuera un resultado; tampoco dispares reintentos invisibles sin un límite claro.

Diagrama: mensaje conservado, error 429 visible y reintento sin perder el texto

Una prueba de navegador que fuerza el fallo

Playwright permite interceptar la solicitud del navegador con page.route() y responder desde la prueba con route.fulfill(). Así no dependes de gastar cuota real ni de esperar a que el proveedor falle. El ejemplo supone que tu UI llama a /api/chat y expone nombres accesibles en español. Ajusta URL, selectores, idioma y texto de error a tu aplicación; si la prueba falla porque no hay un aviso accesible, ese resultado también merece atención.

import { test, expect } from '@playwright/test';

test('conserva el borrador cuando la API responde 429', async ({ page }) => {
  await page.route('**/api/chat', async route => {
    await route.fulfill({
      status: 429,
      contentType: 'application/json',
      body: JSON.stringify({ error: 'rate_limited' }),
    });
  });

  await page.goto('http://localhost:3000/chat');
  const draft = page.getByRole('textbox', { name: 'Mensaje' });
  await draft.fill('Resume este contrato en tres puntos');
  await page.getByRole('button', { name: 'Enviar' }).click();

  await expect(page.getByRole('alert')).toContainText(/intenta de nuevo/i);
  await expect(draft).toHaveValue('Resume este contrato en tres puntos');
  await expect(page.getByRole('button', { name: 'Reintentar' })).toBeEnabled();
});

Guárdalo, por ejemplo, como tests/chat-429.spec.ts. Con un servidor local activo y Playwright instalado en el proyecto, ejecútalo mediante npx playwright test tests/chat-429.spec.ts. Este ejemplo está diseñado para adaptarse: no he ejecutado la prueba contra tu app ni afirmo que sus selectores coincidan con los de tu producto. El valor está en el contrato que deja explícito.

Amplía el ensayo sin convertirlo en una batería frágil

Haz una segunda variante para pérdida de conexión: en lugar de route.fulfill(), usa route.abort() y comprueba la misma preservación del borrador. En una tercera, simula un éxito después del fallo y verifica que un reintento manual produce una sola respuesta y un solo mensaje enviado. Para este último caso debes adaptar la forma JSON que espera tu cliente; inventar un formato universal daría una falsa sensación de cobertura. Si tu backend ofrece un identificador idempotente para mensajes, comprueba que no se creen dos operaciones al reintentar.

Prueba además el teclado y el móvil. El aviso debe ser visible y anunciable, el foco no debería perderse en un modal inútil y el botón de reintento no debe quedar fuera de pantalla. Si el proveedor envía Retry-After, puedes ofrecer una espera específica; si no, evita inventar un contador exacto. Son decisiones de interfaz, no propiedades automáticas de Playwright.

Cuándo dar la prueba por buena

La prueba está completa cuando puedes mostrar un 429 simulado, leer el aviso, localizar tu texto original, decidir cuándo reintentar y verificar que la conversación no gana mensajes fantasma. Registra una captura del estado de error en tu revisión, pero no la confundas con una captura del proveedor real: la red se ha simulado deliberadamente. Si tu app tiene distintos caminos para streaming y respuesta completa, cubre ambos. Una prueba verde del endpoint no basta si el usuario todavía puede perder su trabajo.

Fuentes: RFC 6585, sección 4 (429); documentación oficial de Playwright sobre interceptación de red; aserciones de Playwright.

Recibe lo nuevo en tu correo

Workshops gratis, herramientas y novedades de IA aplicadas a negocio, sin humo.

🎓 Workshops en vivo🛠️ Herramientas nuevas⚡ Novedades de IA

Sin spam. Te das de baja cuando quieras.

Comentarios

Aún no hay comentarios. Sé el primero.

Deja un comentario