Unified Testing (Browser + API)
How do I combine E2E browser testing with API testing in a single TestRelic test, using both the page and request fixtures?
Unified testing combines browser-based E2E testing with API testing in a single test. TestRelic captures both navigation timelines and API call details together, in one report.
Best of both worlds
Unified testing is ideal for scenarios where you need to verify API data is correctly displayed in the UI, or set up data via API before testing UI interactions.
Using both fixtures
Import from @testrelic/playwright-analytics/fixture and use both page and request in the same test:
import { test, expect } from '@testrelic/playwright-analytics/fixture';
test('API data matches UI', { tag: ['@unified'] }, async ({ page, request }) => {
const apiResponse = await request.get('https://jsonplaceholder.typicode.com/users/1');
expect(apiResponse.status()).toBe(200);
const user = await apiResponse.json();
await page.goto('https://example.com/users/1');
await expect(page.locator('.user-name')).toHaveText(user.name);
});Fixture usage
Unlike API-only tests, which require testRelicApiFixture, unified tests use the standard TestRelic fixture — it provides both page and request with full tracking.
Common patterns
API sets up data, UI verifies it:
test('create post via API and verify in UI', { tag: ['@unified'] }, async ({ page, request }) => {
const createResponse = await request.post('https://jsonplaceholder.typicode.com/posts', {
data: { title: 'Test Post from API', body: 'Created via API', userId: 1 },
});
expect(createResponse.status()).toBe(201);
await page.goto('https://jsonplaceholder.typicode.com/posts');
});Cross-validate data between API and UI:
test('user data consistency across UI and API', { tag: ['@unified'] }, async ({ page, request }) => {
const apiResponse = await request.get('https://api.example.com/users/1');
const apiUserData = await apiResponse.json();
await page.goto('https://example.com/users/1');
const uiName = await page.locator('.user-name').textContent();
expect(uiName).toBe(apiUserData.name);
});Sequential API → UI → API workflow:
test('create → search → update', { tag: ['@unified'] }, async ({ page, request }) => {
const createResponse = await request.post('https://api.example.com/products', {
data: { name: 'Test Product', price: 99.99 },
});
const product = await createResponse.json();
await page.goto('https://example.com/products');
await page.fill('input[name="search"]', product.name);
await expect(page.locator('.product-card', { hasText: product.name })).toBeVisible();
await request.put(`https://api.example.com/products/${product.id}`, {
data: { ...product, price: 89.99 },
});
});Configuration
export default defineConfig({
reporter: [
['@testrelic/playwright-analytics', {
outputPath: './test-results/analytics-timeline.json',
includeStackTrace: true,
includeCodeSnippets: true,
includeNetworkStats: true,
redactPatterns: [/api_key=[^&\s]+/gi, /password=[^&\s]+/gi],
}],
],
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});Running unified tests
npx playwright test --grep @unifiedBest practices
- Prefer API for setup — it's faster than driving the browser to create fixtures.
- Cross-validate — always compare API data against extracted UI text, don't assume.
- Use the
requestfixture, notpage.fetch(), for API calls made inside browser tests — it bypasses CORS. - Wait after async writes — give the server time to process before reloading the UI to check a change.
Next steps
API Testing
How do I write API tests that capture request and response analytics with TestRelic, using the request fixture — no browser required?
Browser Test Reports
What does a TestRelic browser test report contain, and how do I analyze the navigation timeline, network stats, and failure diagnostics?