</>

Technology

Playwright

Difficulty

Advanced

Interview Question

How do you use Playwright for API testing?

Answer

API Testing with Playwright

Playwright includes a built-in HTTP client for API testing — no browser needed.

Using the request Fixture

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

test('GET users list', async ({ request }) => {
  const response = await request.get('/api/users');

  expect(response.ok()).toBeTruthy();
  expect(response.status()).toBe(200);

  const body = await response.json();
  expect(body.users).toHaveLength(10);
  expect(body.users[0]).toHaveProperty('email');
});

POST Request

TypeScript
test('create a new user', async ({ request }) => {
  const response = await request.post('/api/users', {
    data: {
      name: 'John Doe',
      email: 'john@test.com',
      role: 'viewer',
    },
    headers: {
      'Authorization': 'Bearer admin-token-123',
      'Content-Type': 'application/json',
    },
  });

  expect(response.status()).toBe(201);
  const user = await response.json();
  expect(user.id).toBeTruthy();
  expect(user.email).toBe('john@test.com');
});

PUT and DELETE

TypeScript
test('update user', async ({ request }) => {
  const response = await request.put('/api/users/123', {
    data: { name: 'Jane Doe' },
  });
  expect(response.status()).toBe(200);
});

test('delete user', async ({ request }) => {
  const response = await request.delete('/api/users/123');
  expect(response.status()).toBe(204);
});

API Base URL Configuration

TypeScript
// playwright.config.ts
export default defineConfig({
  use: {
    baseURL: 'https://api.myapp.com',
    extraHTTPHeaders: {
      'Accept': 'application/json',
      'X-API-Version': '2',
    },
  },
});

Authenticated API Requests

TypeScript
// Create authenticated context
const apiContext = await request.newContext({
  baseURL: 'https://api.myapp.com',
  extraHTTPHeaders: {
    Authorization: `Bearer ${process.env.API_TOKEN}`,
  },
});

const response = await apiContext.get('/api/admin/users');

API + UI Combined Test

TypeScript
test('create user via API, verify in UI', async ({ page, request }) => {
  // Create test data via API (fast)
  const apiRes = await request.post('/api/users', {
    data: { name: 'Test User', email: 'testuser@test.com' },
    headers: { Authorization: `Bearer ${process.env.ADMIN_TOKEN}` },
  });
  const { id } = await apiRes.json();

  // Verify in UI
  await page.goto(`/admin/users/${id}`);
  await expect(page.getByRole('heading')).toHaveText('Test User');

  // Cleanup via API
  await request.delete(`/api/users/${id}`, {
    headers: { Authorization: `Bearer ${process.env.ADMIN_TOKEN}` },
  });
});

Response Assertions

TypeScript
const response = await request.get('/api/products');

// Status
expect(response.status()).toBe(200);
expect(response.ok()).toBe(true);           // status 200-299

// Headers
expect(response.headers()['content-type']).toContain('application/json');

// Body
const data = await response.json();
expect(data).toMatchObject({ status: 'active' });

// Text response
const text = await response.text();
expect(text).toContain('success');

Follow AutomateQA

Related Topics