Network Mocking & Interception
Use Playwright's network interception to isolate your monitors from third-party flakes, simulate errors, and test edge cases without real API calls.
Synthetic monitoring is often victim to "Third-Party Flakiness." If an analytics script or a non-critical chat widget fails, you don't want your Critical Alert to fire. Playwright's page.route() allows you to intercept, modify, or block network requests to ensure your monitors focus on what matters.
Blocking Unnecessary Requests
To speed up your checks and reduce noise, you can block non-essential scripts like Google Analytics or Intercom.
import { test } from '@playwright/test';
test.beforeEach(async ({ page }) => {
// Block analytics and ads
await page.route('**/*.{google-analytics.com,googletagmanager.com}/**', route => route.abort());
});Mocking API Responses
If you want to monitor a specific UI state (like an "Empty State" or an "Account Expired" banner) without actually modifying your production data, you can mock the API response.
test('displays empty state when no projects exist', async ({ page }) => {
// Intercept the projects API and return an empty array
await page.route('**/api/projects', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([])
});
});
await page.goto('/dashboard');
await expect(page.getByText('No projects found')).toBeVisible();
});Simulating Edge Cases
1. Slow API Responses
Test how your application handles high latency. Does it show a loading spinner or just a blank screen?
await page.route('**/api/data', async route => {
await new Promise(f => setTimeout(f, 5000)); // Delay 5 seconds
await route.continue();
});2. API Errors (500 Internal Server Error)
Ensure your app shows a graceful error message to users instead of crashing.
await page.route('**/api/user/profile', route => {
route.fulfill({
status: 500,
body: 'Internal Server Error'
});
});Modifying Requests/Responses
Sometimes you want the real data, but with one small tweak for testing purposes.
await page.route('**/api/user', async route => {
const response = await route.fetch();
const json = await response.json();
// Inject a 'Pro' flag to test the premium UI
json.isPro = true;
await route.fulfill({ response, json });
});Best Practices
- Isolate the Cause: Use mocking to determine if a failure is caused by your frontend logic or a flaky backend dependency.
- Don't Mock Everything: In synthetic monitoring, you usually want to test the real production API. Save heavy mocking for specialized "UI-only" checks.
- Use
routeFromHAR: For complex scenarios, you can record a "Happy Path" and replay it to ensure the UI behaves consistently.
Next Steps
Resilient Locators: Best Practices for Stable Monitors
Learn how to use Playwright locators effectively to build synthetic monitors that survive UI changes. Master getByRole, getByLabel, and data-testid.
Playwright for Synthetic Monitoring: The Definitive Guide
Master the use of Playwright for continuous production monitoring. Learn why Playwright is the gold standard for synthetic checks and how to optimize it for reliability.