Mock API Responses in Playwright – Speed Up Your Tests the Smart Way

Day 3: Mock API Responses in Playwright – Speed Up Your Tests the Smart Way



Tired of flaky tests caused by backend failures or slow APIs? Learn how to intercept and mock API responses with Playwright’s route.fulfill().

Why You Should Mock APIs in UI Tests

When you're writing end-to-end (E2E) tests, you often hit a wall:

  • The API server is down or unstable
  • Real API data keeps changing
  • You can’t simulate edge cases like 500 errors or timeouts

In such cases, your tests become unreliable or slow.

That’s where mocking comes in. By simulating the API response using Playwright’s powerful routing features, you can eliminate backend dependency — and write faster, more stable tests.


🚀 What is page.route() and route.fulfill()?

Playwright allows you to intercept network requests before they reach the server using page.route().

Using route.fulfill(), you can instantly return a custom response (JSON, HTML, text, etc.) without touching the backend.

Here’s the syntax:

await page.route('**/api/user', route =>
  route.fulfill({
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify({ id: 101, name: 'Bug Hacker' }),
  })
);

This intercepts any request to /api/user and returns your mock JSON response immediately.


🔧 Practical Example – Mocking a User API

Imagine your profile page fetches user data via GET /api/user. You want your test to pass even if the backend is unavailable.

Here’s how to mock that request:

test('Profile loads mock user', async ({ page }) => {
  await page.route('**/api/user', route =>
    route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ name: 'Test User', id: 1 }),
    })
  );

  await page.goto('https://yourapp.com/profile');
  await expect(page.getByText('Test User')).toBeVisible();
});

✅ Your test now:

  • Doesn’t rely on real APIs
  • Loads faster
  • Is predictable and CI-ready


🤯 What You Can Mock

You’re not limited to JSON APIs. You can mock:

  • HTML pages
  • XML responses
  • Image files
  • Status codes (e.g., 404, 500)
  • Headers and cookies

Here's how to simulate an error:

await page.route('**/api/user', route =>
  route.fulfill({ status: 500, body: 'Internal Server Error' })
);

This is great for testing how your UI handles errors — modals, alerts, retries, etc.


🎯 Real-World Use Cases

Here’s when mocking with Playwright becomes a superpower:

Scenario Why Mock?
API under development Start frontend testing before backend is ready
Third-party APIs Avoid external rate limits and network flakiness
Performance testing Simulate slow/fast API responses
Edge case testing Trigger 404s, 500s, empty lists, or weird formats
Offline mode Simulate network failures with zero real requests

📌 Tips for Effective Mocking

  1. Use **/path patterns to match multiple endpoints.
  2. Always match Content-Type headers properly.
  3. Keep mock data in separate JSON files for reusability.
  4. Combine mocking with test tags like @mocked for clean CI pipelines.

🚨 Gotchas to Avoid

  • If your test relies on actual DB updates, mocking won’t reflect that
  • Don’t over-mock — test real APIs too (separately)
  • Make sure your mocked data is realistic and covers different user roles or scenarios

💡 Final Thoughts

Mocking API responses using Playwright is not cheating — it’s a smart way to stabilize, speed up, and gain control over your tests.

Instead of chasing intermittent backend failures, focus on what matters: the user experience.

And that’s exactly what Playwright enables — with just a few lines of code.


🔥 Coming Up Next – Day 4

Tomorrow, we’ll dive into another challenge for testers: handling modals, alerts, and popups in Playwright.

Subscribe or follow along — let’s automate smarter, not harder!


📲 Stay in the Loop

💬 Share this post if you found it helpful. Tag a QA friend who needs this tip!


Previous Post Next Post

Contact Form