TestRelic

API Testing

How do I write API tests that capture request and response analytics with TestRelic, using the request fixture — no browser required?

API testing with TestRelic captures analytics about HTTP requests, responses, timing, and test results through the request fixture, without launching a browser.

No browser required

API tests run without launching a browser, making them faster and more lightweight than E2E tests.

Setting up the API fixture

Extend the base Playwright fixture with testRelicApiFixture in your test files:

tests/api/posts.spec.ts
import { test as base } from '@playwright/test';
import { testRelicApiFixture } from '@testrelic/playwright-analytics/api-fixture';
import { expect } from '@testrelic/playwright-analytics/fixture';

const test = base.extend(testRelicApiFixture);

test('fetch posts', { tag: ['@api'] }, async ({ request }) => {
  const response = await request.get('https://jsonplaceholder.typicode.com/posts');
  expect(response.status()).toBe(200);

  const posts = await response.json();
  expect(posts).toBeInstanceOf(Array);
});

Import expect from TestRelic (either .../api-fixture or .../fixture) so assertions are captured — it behaves exactly like Playwright's expect.

When a run opens the API workspace

A run is routed to the API workspace when every test in it is an API test — tagged @api, under an api/ path, in a dedicated API project, or using the API request fixture. Mixed UI + API runs are not reclassified. Request and response cookies are captured with their values masked, shown in the API Cookies tab.

CRUD patterns

tests/api/crud.spec.ts
import { test as base } from '@playwright/test';
import { testRelicApiFixture } from '@testrelic/playwright-analytics/api-fixture';
import { expect } from '@testrelic/playwright-analytics/fixture';

const test = base.extend(testRelicApiFixture);
const BASE_URL = 'https://jsonplaceholder.typicode.com';

test('complete CRUD workflow', { tag: ['@api', '@crud'] }, async ({ request }) => {
  const createRes = await request.post(`${BASE_URL}/posts`, {
    data: { title: 'Test', body: 'Content', userId: 1 },
  });
  expect(createRes.status()).toBe(201);
  const post = await createRes.json();

  const readRes = await request.get(`${BASE_URL}/posts/${post.id}`);
  expect(readRes.status()).toBe(200);

  const updateRes = await request.put(`${BASE_URL}/posts/${post.id}`, {
    data: { ...post, title: 'Updated' },
  });
  expect(updateRes.status()).toBe(200);

  const deleteRes = await request.delete(`${BASE_URL}/posts/${post.id}`);
  expect(deleteRes.status()).toBe(200);
});

Chaining API calls

tests/api/chaining.spec.ts
test('API chaining - user and posts', { tag: ['@api', '@chain'] }, async ({ request }) => {
  const userResponse = await request.get('https://jsonplaceholder.typicode.com/users/1');
  const user = await userResponse.json();

  const postsResponse = await request.get('https://jsonplaceholder.typicode.com/posts', {
    params: { userId: user.id },
  });
  const posts = await postsResponse.json();
  expect(posts.every((post) => post.userId === user.id)).toBe(true);
});

Authentication

tests/api/auth-token.spec.ts
test('bearer token authentication', { tag: ['@api', '@auth'] }, async ({ request }) => {
  const response = await request.get('https://api.example.com/protected', {
    headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
  });
  expect(response.status()).toBe(200);
});

Sensitive data

Always use environment variables for API keys, tokens, and passwords. Configure redactPatterns (see Configuration) so sensitive values never appear in reports.

Configuration for API-only reporters

playwright.config.ts
export default defineConfig({
  reporter: [
    ['@testrelic/playwright-analytics', {
      outputPath: './test-results/api-analytics.json',
      includeStackTrace: true,
      includeCodeSnippets: true,
      redactPatterns: [/api_key=[^&\s]+/gi, /password=[^&\s]+/gi],
    }],
  ],
});

Running API tests

Terminal
npx playwright test --grep @api
npx playwright test tests/api/posts.spec.ts

Best practices

  • Keep credentials in environment variables, never hardcoded.
  • Validate response shape, not just status code.
  • Test error paths (404s, timeouts) as well as happy paths.
  • Clean up created test data in a finally block.

Next steps

Was this page helpful?

On this page