💥 Playwright Hardcore: Dynamic Backend Failures in UI Tests!
Your SPA uses microservices. Test UI resilience against ProductService 500s or timeouts, ensuring proper error handling without over-mocking.
📌 Problem Statement
• SPAs need robust UI error handling for flaky microservices.
• Simulate dynamic backend failures (ProductService 500s/timeouts) in Playwright to validate UI degradation/retries.
• Goal: Realistic, isolated failure toggling within one test scenario.
💡 Solution & Code Walkthrough
page.route() enables dynamic network interception. We'll use a failProductService flag to switch ProductService responses between success, HTTP 500, and network timeout.
import { test, expect, Page } from '@playwright/test';
let failProductService = false;
test.beforeEach(async ({ page }) => {
await page.route('**/api/products', async (route) => {
if (failProductService) {
const errorType = Math.random() < 0.5 ? '500' : 'network';
if (errorType === '500') {
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({ message: 'Product service unavailable' }),
});
} else {
await route.abort('failed');
}
} else {
await route.continue();
}
});
});
test('should handle dynamic product service failures gracefully', async ({ page }) => {
await page.goto('/your-app-path');
// 1. Simulate ProductService failure (e.g., 500/timeout)
failProductService = true;
await page.reload();
await expect(page.getByText(/product.*unavailable|failed to load products/i)).toBeVisible();
// ... assert UI state (error message, retry button)
// 2. Simulate ProductService recovery
failProductService = false;
await page.getByRole('button', { name: 'Retry' }).click(); // Assuming a retry button
await expect(page.getByText('Loading Products...')).not.toBeVisible();
await expect(page.getByTestId('product-list')).toBeVisible(); // Verify products loaded
});
✅ page.route() isolates /api/products interception.
✅ failProductService dynamically toggles backend states.
❌ Avoid static stubs for realistic intermittency.
🔑 Key Takeaways
• page.route() offers granular network control for UI testing.
• Dynamic flags within page.route() simulate realistic, intermittent backend issues.
• This approach validates UI resilience and error handling without backend changes.
❓ Quick Summary Q&A
• Dynamic failures? Use page.route() with a mutable flag (failProductService) to control responses (500, abort, continue).
• Why page.route()? Enables dynamic state changes for realistic, intermittent failure/recovery tests.
TAGS: playwright, e2e testing, ui testing, test automation, service virtualization, frontend testing, network mocking
────────────────────────────────────────
👉 Elevate your testing skills! For more advanced Playwright strategies and interview prep, download our app:
────────────────────────────────────────
📲 𝐅𝐑𝐄𝐄 𝐌𝐎𝐁𝐈𝐋𝐄 𝐀𝐏𝐏 — 𝟔𝟎𝟎+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
Practice real-world interview scenarios offline on the free QA Automation & SDET Prep app:
🤖 𝐆𝐨𝐨𝐠𝐥𝐞 𝐏𝐥𝐚𝐲 (𝐀𝐧𝐝𝐫𝐨𝐢𝐝):
https://play.google.com/store/apps/details?id=com.app.seleniuminterviewquestions&referrer=utm_source%3Ddevto%26utm_medium%3Darticle%26utm_campaign%3Dselenium_20260916
🍎 𝐀𝐩𝐩 𝐒𝐭𝐨𝐫𝐞 (𝐢𝐎𝐒):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20260916&mt=8
────────────────────────────────────────
────────────────────────────────────────
Top comments (0)