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');
