DEV Community

Cover image for Cómo Validar Respuestas API con Playwright Tests
Roobia
Roobia

Posted on • Originally published at apidog.com

Cómo Validar Respuestas API con Playwright Tests

Tus pruebas de Playwright pueden pasar aunque la API esté devolviendo datos incorrectos. El botón de login funciona, el dashboard renderiza y el gráfico aparece, pero un endpoint puede responder 200 OK con un payload mal formado o con una regla de negocio incorrecta. Para cerrar esa brecha, combina Playwright para validar flujos de UI con aserciones de API basadas en contrato. Herramientas como Apidog te permiten validar esquemas, contratos OpenAPI y escenarios encadenados con el mismo rigor que aplicas a tus pruebas end-to-end.

Prueba Apidog hoy

TL;DR

Valida APIs en Playwright usando la fixture request, interceptores page.route y una especificación OpenAPI compartida. Usa Apidog para ejecutar escenarios de API más profundos contra esa misma especificación: validación de esquemas, lógica de negocio, mocks y flujos encadenados. Ejecuta ambas suites en CI para que cualquier cambio de contrato falle rápido.

Introducción

Playwright facilita las pruebas de API con request.get, request.post y aserciones como:

expect(response.status()).toBe(200);
Enter fullscreen mode Exit fullscreen mode

El problema aparece cuando la suite crece. Muchas pruebas terminan validando solo códigos de estado, sin comprobar la forma real del response, sin una fuente de verdad compartida y sin una forma consistente de mockear APIs cuando el backend está inestable.

La solución práctica:

  1. Usa openapi.yaml como contrato.
  2. Haz que Playwright consuma fixtures derivadas de ese contrato.
  3. Importa la misma especificación en Apidog.
  4. Ejecuta Playwright y Apidog en el mismo pipeline de CI.

Si quieres instalar la herramienta antes de seguir, puedes descargar Apidog.

También puedes revisar este contexto adicional sobre herramientas de prueba de API para ingenieros de QA.

La brecha entre Playwright y las aserciones de API

Una prueba típica de Playwright comprueba que el usuario puede:

  1. Iniciar sesión.
  2. Navegar a una página.
  3. Ver un componente renderizado.

Eso valida la experiencia visible, pero no garantiza que la API haya devuelto datos correctos.

Tres fallos comunes que suelen escaparse:

1. Cambios en la forma del payload

El backend cambia:

{
  "total_count": 10
}
Enter fullscreen mode Exit fullscreen mode

por:

{
  "totalCount": 10
}
Enter fullscreen mode Exit fullscreen mode

La UI puede seguir mostrando algo, pero el contrato se rompió.

2. Deriva de lógica de negocio

Un endpoint de descuentos aplica un 10% en lugar del 15% esperado. La UI muestra lo que recibe, por lo que la prueba visual pasa.

3. Rutas de error sin cobertura

Playwright suele cubrir el happy path. Las rutas 400, 401, 409, 429 o 500 quedan fuera si no tienes una suite de API dedicada.

La división recomendable es:

  • Playwright: flujos de UI, navegación, interacción del usuario, interceptación de red y aserciones ligeras sobre responses críticos.
  • Apidog: validación de esquemas, contratos OpenAPI, escenarios encadenados, mocks y rutas de error.

Ambas capas deben consumir la misma especificación OpenAPI. Para profundizar en este enfoque, revisa el artículo sobre herramientas de desarrollo de API design-first.

Cómo compartir fixtures entre Playwright y Apidog

La pieza central debe ser un archivo:

openapi.yaml
Enter fullscreen mode Exit fullscreen mode

o:

openapi.json
Enter fullscreen mode Exit fullscreen mode

Ubícalo en la raíz del repositorio y úsalo como fuente de verdad.

Ejemplo de estructura:

.
├── apidog/
│   └── scenarios/
│       └── checkout.json
├── fixtures/
│   └── order.json
├── tests/
│   ├── fixtures/
│   │   └── api.ts
│   └── orders.spec.ts
├── openapi.yaml
└── playwright.config.ts
Enter fullscreen mode Exit fullscreen mode

Fixture compartida de Playwright

// tests/fixtures/api.ts
import { test as base, APIRequestContext, expect } from '@playwright/test';
import { readFileSync } from 'fs';
import path from 'path';

type ApiFixtures = {
  apiRequest: APIRequestContext;
  authToken: string;
  sampleOrder: Record<string, unknown>;
};

export const test = base.extend<ApiFixtures>({
  apiRequest: async ({ playwright }, use) => {
    const ctx = await playwright.request.newContext({
      baseURL: process.env.API_BASE_URL ?? 'https://api.staging.example.com',
      extraHTTPHeaders: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
    });

    await use(ctx);
    await ctx.dispose();
  },

  authToken: async ({ apiRequest }, use) => {
    const res = await apiRequest.post('/auth/token', {
      data: {
        email: 'qa@example.com',
        password: process.env.QA_PASSWORD,
      },
    });

    expect(res.status()).toBe(200);

    const body = await res.json();
    await use(body.access_token);
  },

  sampleOrder: async ({}, use) => {
    const raw = readFileSync(
      path.join(__dirname, '..', '..', 'fixtures', 'order.json'),
      'utf8',
    );

    await use(JSON.parse(raw));
  },
});

export { expect };
Enter fullscreen mode Exit fullscreen mode

Ahora, en vez de importar desde @playwright/test, importa desde tu fixture:

import { test, expect } from './fixtures/api';
Enter fullscreen mode Exit fullscreen mode

Ejemplo de prueba de API con Playwright

// tests/orders.spec.ts
import { test, expect } from './fixtures/api';

test('POST /orders returns a valid order with 15 percent discount', async ({
  apiRequest,
  authToken,
  sampleOrder,
}) => {
  const res = await apiRequest.post('/orders', {
    headers: {
      Authorization: `Bearer ${authToken}`,
    },
    data: {
      ...sampleOrder,
      coupon: 'SAVE15',
    },
  });

  expect(res.status()).toBe(201);

  const body = await res.json();

  expect(body).toMatchObject({
    id: expect.any(String),
    status: 'pending',
    discount_pct: 15,
    total_cents: expect.any(Number),
  });

  expect(body.total_cents).toBeLessThan(sampleOrder.subtotal_cents);
});
Enter fullscreen mode Exit fullscreen mode

Playwright valida la semántica importante del flujo. Apidog valida el contrato completo contra el esquema Order definido en openapi.yaml.

En Apidog:

  1. Importa openapi.yaml.
  2. Crea un escenario para POST /orders.
  3. Usa el mismo payload de fixtures/order.json.
  4. Activa la validación de esquema JSON contra el componente Order.
  5. Encadena el resultado con pasos como GET /orders/{id} o POST /orders/{id}/cancel.

Si estás empezando con pruebas basadas en especificación, consulta el tutorial sobre flujos de trabajo de API de diseño primero.

Para equipos que vienen de Postman, esta guía sobre alternativas autoalojadas a Postman puede servir como referencia de migración.

Configura el flujo Apidog + Playwright

Paso 1: Usa una sola especificación OpenAPI

Coloca openapi.yaml en la raíz del repositorio.

Buenas prácticas:

  • Revisión obligatoria en PR.
  • Cambios incompatibles requieren versionado.
  • Los examples deben representar payloads reales.
  • Las fixtures deben derivarse de la especificación o mantenerse alineadas con ella.

Si aún no tienes OpenAPI, genera una primera versión desde tu framework. FastAPI, NestJS y otros frameworks pueden emitir una especificación inicial.

Paso 2: Conecta Playwright

Instala Playwright:

npm init playwright@latest
Enter fullscreen mode Exit fullscreen mode

Añade scripts:

{
  "scripts": {
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui"
  }
}
Enter fullscreen mode Exit fullscreen mode

Ejemplo básico de playwright.config.ts:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  retries: 2,
  use: {
    baseURL: process.env.WEB_BASE_URL ?? 'http://localhost:3000',
    trace: 'on-first-retry',
  },
});
Enter fullscreen mode Exit fullscreen mode

Paso 3: Crea escenarios de Apidog

En Apidog:

  1. Importa openapi.yaml.
  2. Crea un escenario por flujo crítico:
    • Registro.
    • Login.
    • Checkout.
    • Reembolso.
    • Webhooks.
    • Cancelación de pedido.
  3. Añade variables de entorno.
  4. Añade scripts previos a la request si necesitas tokens.
  5. Añade aserciones posteriores a la respuesta.
  6. Exporta el escenario para ejecución en CI.

Ejemplo de ejecución:

apidog-cli run ./apidog/scenarios/checkout.json
Enter fullscreen mode Exit fullscreen mode

Paso 4: Usa page.route para aislar la UI

Cuando no quieras depender del backend real, intercepta la llamada desde Playwright:

test('dashboard renders cached order list when offline', async ({
  page,
  sampleOrder,
}) => {
  await page.route('**/api/orders', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        orders: [sampleOrder],
      }),
    });
  });

  await page.goto('/dashboard');

  await expect(page.getByTestId('order-row')).toHaveCount(1);
});
Enter fullscreen mode Exit fullscreen mode

Importante: page.route no reemplaza una suite de API. Sirve para aislar la UI. La validación profunda del endpoint debe ejecutarse en Apidog.

Paso 5: Ejecuta ambas suites en CI

Ejemplo con GitHub Actions:

name: tests

on: [push, pull_request]

jobs:
  playwright:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test

  apidog:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm i -g apidog-cli
      - run: apidog-cli run ./apidog/scenarios/checkout.json --reporters cli,junit
Enter fullscreen mode Exit fullscreen mode

Si cualquiera de los jobs falla, el PR no debe mergearse.

La documentación de GitHub Actions cubre matrices, caché y artefactos si necesitas escalar el pipeline.

Para equipos sin QA dedicado, esta guía sobre herramientas de prueba de API para ingenieros de QA ayuda a definir ownership.

Paso 6: Detecta desviaciones del contrato

Añade un job diario que compare la especificación actual con la versión validada por CI.

Objetivo:

  • Detectar campos renombrados.
  • Detectar cambios de tipo.
  • Detectar responses sin schema.
  • Detectar examples obsoletos.

Esto evita el clásico problema de 200 OK con payload incorrecto.

Técnicas avanzadas

Activa trazas de Playwright

En playwright.config.ts:

use: {
  trace: 'on-first-retry',
}
Enter fullscreen mode Exit fullscreen mode

Cuando una prueba falle en CI, podrás inspeccionar:

  • Requests.
  • Responses.
  • DOM snapshots.
  • Console logs.
  • Screenshots.

Combínalo con reportes de Apidog para separar fallos de UI y fallos de API.

Usa mocks de Apidog para desarrollo local

Apidog puede levantar mocks desde OpenAPI. Úsalos cuando:

  • Staging esté caído.
  • El backend esté en despliegue.
  • Quieras desarrollar UI antes de que el endpoint esté listo.

Patrón recomendado:

  • Playwright contra mock para validar UI.
  • Apidog contra backend real para validar contrato.

Este enfoque también aparece en el artículo sobre generación de pruebas de API asistida por IA.

Limita los reintentos

En Playwright:

retries: 2
Enter fullscreen mode Exit fullscreen mode

Si una prueba necesita más de dos reintentos, probablemente es inestable.

En escenarios de API, aplica la misma regla: un retry por request como máximo.

Falla cerrado ante schema drift

Si Apidog detecta una incompatibilidad de esquema, el job debe fallar.

Evita convertir errores de contrato en warnings. Si necesitas una excepción temporal, usa una variable explícita:

ALLOW_SCHEMA_DRIFT=true
Enter fullscreen mode Exit fullscreen mode

Y exige una explicación en el PR.

Etiqueta las pruebas por prioridad

Ejemplo en Playwright:

test.describe('@smoke checkout', () => {
  test('user can complete checkout', async ({ page }) => {
    // ...
  });
});
Enter fullscreen mode Exit fullscreen mode

Estrategia:

  • @smoke: cada push.
  • @regression: PR hacia main.
  • @nightly: suite completa.
  • Escenarios de Apidog críticos: cada PR.
  • Escenarios de Apidog largos: nightly.

Errores comunes

Evita:

  • Validar solo status === 200.
  • Hardcodear tokens.
  • Mantener fixtures duplicadas.
  • Ejecutar Apidog solo desde la UI y no desde CI.
  • Usar page.route como sustituto de pruebas reales de API.
  • Tener una colección separada que no derive de OpenAPI.

Para APIs con IA o agentes, revisa la guía sobre cómo probar la API de agentes de IA.

Alternativas y comparación de herramientas

Stack Fortalezas Debilidades Mejor para
Solo Playwright con fixture request Una herramienta, rápido, nativo de la suite Validación de esquemas superficial, sin escenarios encadenados, cobertura débil de errores Equipos pequeños y APIs simples
Playwright + Postman Ecosistema maduro, Newman CLI Dos fuentes de verdad, colecciones que pueden desviarse de OpenAPI, coste de colaboración Equipos ya centrados en Postman
Playwright + Apidog OpenAPI como fuente única, validación de esquemas, mocks, CLI para CI, flujo design-first Dos herramientas que aprender, requiere disciplina de especificación Equipos que quieren pruebas basadas en contrato
Cypress + cy-api Familiar para usuarios de Cypress API testing limitado, plugins menos completos Proyectos existentes en Cypress
Pact Contratos fuertes entre servicios Curva de aprendizaje, broker, no orientado a UI Organizaciones con microservicios y muchos consumidores internos

Si vienes de herramientas SOAP, revisa las guías sobre alternativas a los scripts Groovy de SoapUI y alternativas a ReadyAPI.

Para trabajo local, también puede servirte esta lista de extensiones de cliente REST para VSCode.

Casos de uso reales

Checkout en ecommerce

Playwright valida el flujo visible:

  1. Añadir producto al carrito.
  2. Aplicar cupón.
  3. Pagar.
  4. Ver confirmación.

Apidog valida la cadena de APIs:

  1. Crear intención de pago.
  2. Validar fraude.
  3. Confirmar pedido.
  4. Reducir inventario.
  5. Emitir webhook.

Si un proveedor cambia error_code por errorCode, Apidog lo detecta como cambio de contrato aunque la UI solo muestre un error genérico.

Dashboard SaaS con gráficos

Playwright valida que el gráfico renderice. Apidog valida que los endpoints de agregación devuelvan:

  • Sumas correctas.
  • Percentiles correctos.
  • Series agrupadas por tiempo.
  • Tipos y campos esperados.

Así detectas errores donde el gráfico “se ve bien”, pero los datos son incorrectos.

Webhooks fintech

Playwright cubre el portal de usuario. Apidog cubre:

  • Entrega de webhooks.
  • Reintentos.
  • Idempotencia.
  • Validación de firmas.
  • Rechazo de IDs duplicados.
  • Ventanas de consistencia eventual.

Conclusión

Playwright es excelente para probar flujos de navegador. No está diseñado para cubrir en profundidad contratos de API, esquemas y escenarios encadenados.

Una integración Playwright + Apidog te da:

  • OpenAPI como contrato compartido.
  • Fixtures reutilizables.
  • Validación de esquemas.
  • Mocks para desarrollo local.
  • CI con fallos rápidos.
  • Separación clara entre pruebas de UI y pruebas de API.
  • Menos falsos positivos por responses 200 OK incorrectos.

Empieza con un flujo crítico: checkout, registro o login. Crea la fixture de Playwright, importa la especificación en Apidog, construye el escenario equivalente y ejecuta ambas suites en CI.

FAQ

¿Puedo validar APIs en Playwright sin Apidog?

Sí. Puedes usar la fixture request de Playwright y aserciones manuales con expect. Esto funciona para códigos de estado y algunos campos importantes.

Para validación de esquemas, escenarios encadenados, mocks y rutas de error a escala, una herramienta dedicada como Apidog reduce trabajo manual. También puedes revisar la comparación de herramientas de prueba de API para ingenieros de QA.

¿Necesito una especificación OpenAPI?

Para obtener el máximo beneficio, sí.

Sin OpenAPI puedes ejecutar Playwright y Apidog en paralelo, pero pierdes la fuente de verdad compartida. Tendrás que mantener payloads y contratos manualmente en más de un lugar.

¿Cómo gestiono autenticación en ambas herramientas?

Usa un paso inicial que obtenga un token fresco desde tu endpoint de autenticación.

En Playwright, guárdalo en una fixture:

authToken: async ({ apiRequest }, use) => {
  const res = await apiRequest.post('/auth/token', {
    data: {
      email: 'qa@example.com',
      password: process.env.QA_PASSWORD,
    },
  });

  const body = await res.json();
  await use(body.access_token);
};
Enter fullscreen mode Exit fullscreen mode

En Apidog, usa una variable de entorno o un script previo a la request.

¿Apidog puede reemplazar completamente a Playwright?

No. Apidog valida APIs. Playwright valida navegadores.

Usa Playwright para:

  • Clicks.
  • Formularios.
  • Navegación.
  • Texto visible.
  • Estados de UI.
  • Renderizado.

Usa Apidog para:

  • Contratos.
  • Esquemas.
  • Workflows de API.
  • Mocks.
  • Rutas de error.
  • Escenarios encadenados.

¿Qué pasa si staging no es estable?

Usa mocks generados desde OpenAPI.

Patrón recomendado:

  1. Ejecuta Playwright contra el mock para no bloquear el desarrollo frontend.
  2. Ejecuta Apidog contra el backend real cuando staging esté disponible.
  3. Mantén ambos alineados con el mismo openapi.yaml.

¿Cómo mantengo la CI rápida?

Usa etiquetas y paralelización.

Ejemplo:

  • Smoke tests en cada push.
  • Regresión completa en PR hacia main.
  • Suite completa nocturna.
  • Playwright con workers.
  • Apidog CLI con ejecución paralela si aplica.

¿Necesito un plan de pago de Apidog para CI?

La CLI puede ejecutarse localmente y en CI para escenarios. Revisa la página de precios actual antes de adoptarlo a gran escala, especialmente si tu equipo necesita colaboración avanzada o funciones empresariales.

Top comments (0)