Playwright API testing exercises: validate filtering and bad input

API tests can validate a contract before a browser UI is involved. This exercise checks every returned item, then proves that an invalid filter is rejected.

Before you start

Assert the filtered result and validation error

Add these two tests to your project. The request context is isolated from browser pages, and each test uses its own server sandbox.

import { test, expect } from '@playwright/test';
import { randomUUID } from 'node:crypto';

test('vegetarian filter returns only vegetarian pizzas', async ({ request }) => {
  const response = await request.get('https://funapi.dev/api/pizza/v1/menu', {
    headers: { 'X-Sandbox-ID': randomUUID() },
    params: { vegetarian: 'true' }
  });
  expect(response.status()).toBe(200);
  const body = await response.json();
  expect(body.data.length).toBeGreaterThan(0);
  expect(body.total).toBe(body.data.length);
  for (const pizza of body.data) expect(pizza.vegetarian).toBe(true);
});

test('invalid filter is rejected', async ({ request }) => {
  const response = await request.get('https://funapi.dev/api/pizza/v1/menu', {
    headers: { 'X-Sandbox-ID': randomUUID() },
    params: { vegetarian: 'sometimes' }
  });
  expect(response.status()).toBe(400);
  expect((await response.json()).error).toBe('Bad Request');
});

Inspect a deliberate server error

As a separate exploration, GET /api/pizza/v1/oven/status returns 500 by design. If you add a test for it, assert 500 explicitly rather than treating the training endpoint as an outage.

Expected result

Two passing tests: 200 with a nonempty vegetarian result, and 400 for the invalid filter. No order is created.

Common pitfalls

Download this practice guide · Download the practice Postman collection

Last updated