Playwright API Testing — The Complete Guide (2026)
Skip Postman for automated checks — Playwright's request context runs API + UI tests in one runner, one report, and one CI job. Full setup, auth patterns, contract snapshots, and a worked login-to-checkout suite.

Last updated 2026-07-20 · 12 min read · By Avinash K
Playwright's request context is the most under-used API testing feature in QA. It gives you HTTP calls, shared auth state, and trace-viewer debugging inside the same runner as your UI tests — which means one report, one CI job, and no more "Postman collection last updated 2023" tickets.
Key takeaways
- Set up
request.newContext()in 5 lines.- Reuse the browser's auth cookies for API calls (no double login).
- Snapshot response contracts to catch breaking changes.
- A full login → create order → assert API + UI worked example.
1. Basic setup
import { test, expect } from '@playwright/test';
test('GET /api/health returns 200', async ({ request }) => {
const res = await request.get('/api/health');
expect(res.status()).toBe(200);
expect(await res.json()).toMatchObject({ status: 'ok' });
});The request fixture is built into every test — no plugin, no extra package.
2. Sharing auth with the browser
// global-setup.ts
import { request } from '@playwright/test';
export default async () => {
const ctx = await request.newContext();
const res = await ctx.post('/api/login', { data: { email, password } });
await ctx.storageState({ path: 'auth.json' });
};
// playwright.config.ts
use: { storageState: 'auth.json' }Now every UI test and every API test reuses the same session — no duplicate login, no flaky token expiry.
3. Contract snapshots
test('order response contract', async ({ request }) => {
const res = await request.post('/api/orders', { data: { sku: 'ABC', qty: 1 } });
expect(await res.json()).toMatchSnapshot('order.json');
});The first run writes the snapshot; every subsequent run fails on shape drift. Cheaper than a full Pact setup for internal APIs.
4. Login → API → UI worked example
test('checkout via API, verify in UI', async ({ page, request }) => {
const order = await request.post('/api/orders', {
data: { sku: 'ABC', qty: 2 },
});
const { id } = await order.json();
await page.goto(`/orders/${id}`);
await expect(page.getByRole('heading', { name: /order confirmed/i })).toBeVisible();
});See Playwright fixtures deep dive for how to wrap this in a fixture, and the locators guide for the UI half. Full docs: playwright.dev/docs/api-testing.