DEV Community

Styrow.dev
Styrow.dev

Posted on Originally published at styrow.dev

How would you design an end-to-end test suite using Playwright to verify a complex web application's offline capabilitie

⚡️ Offline-First Apps: How do you TEST the "impossible"?
Designing an end-to-end test for a complex web app's offline capabilities with Playwright, focusing on Service Workers, IndexedDB, and data sync, demands a sophisticated strategy.

📌 Problem Statement
Our field technician SPA needs robust offline-first validation:
• Create/edit reports while offline.
• Automatic backend sync on reconnect.
• Data consistency across sessions (offline, close, reopen).
• Accurate UI status for offline/syncing.

💡 Solution & Code Walkthrough
Playwright offers powerful APIs for network control and browser context interaction.

✅ Simulate Network Changes:
Use setOffline() to toggle connectivity.

// Go offline
await page.context().setOffline(true);
// Go online
await page.context().setOffline(false);
Enter fullscreen mode Exit fullscreen mode

✅ Verify Service Worker (SW) Registration:
Ensure the SW is active and controlling the page.

const serviceWorker = (await page.context().serviceWorkers())[0];
expect(serviceWorker).toBeDefined(); // SW registered
// await serviceWorker.evaluate(() => self.registration.scope); // Evaluate SW state
Enter fullscreen mode Exit fullscreen mode

✅ Inspect IndexedDB Data:
Access IndexedDB via page.evaluate() to assert local data state.

const localData = await page.evaluate(async () => {
  const db = await new Promise(resolve => {
    const request = indexedDB.open('MyAppDB', 1);
    request.onsuccess = () => resolve(request.result);
  });
  const transaction = db.transaction(['reports'], 'readonly');
  const store = transaction.objectStore('reports');
  return new Promise(resolve => store.getAll().onsuccess = e => resolve(e.target.result));
});
expect(localData).toContainEqual({ id: 'report-123', status: 'pending' });
Enter fullscreen mode Exit fullscreen mode

✅ Trigger & Monitor Data Synchronization:
Toggle network, then wait for UI feedback or direct IndexedDB updates.

// Perform offline action (e.g., create report)
await page.context().setOffline(true);
await page.locator('#create-report').click();
// Go online to trigger sync
await page.context().setOffline(false);
// Wait for sync completion UI element
await expect(page.locator('.sync-status')).toHaveText('Synced!');
Enter fullscreen mode Exit fullscreen mode

✅ Handle Race Conditions:
Use waitForFunction or waitForResponse to await specific state changes.

// Wait for IDB update after sync
await page.waitForFunction(async () => {
  // Assume getDbConnection() is a helper for IndexedDB connection
  const db = await getDbConnection();
  const transaction = db.transaction(['reports'], 'readonly');
  const store = transaction.objectStore('reports');
  const reports = await new Promise(resolve => store.getAll().onsuccess = e => resolve(e.target.result));
  return reports.some(r => r.status === 'synced');
}, { timeout: 10000 });
Enter fullscreen mode Exit fullscreen mode

🔑 Key Takeaways
• page.context().setOffline() is crucial for network simulation.
• page.context().serviceWorkers() provides direct SW access.
• page.evaluate() bridges Playwright to browser-side APIs (IndexedDB).
• Strategic use of waitFor methods prevents flaky tests due to async operations.

❓ Quick Summary Q&A
Q: How to simulate offline? A: page.context().setOffline(true).
Q: How to check IndexedDB? A: Use page.evaluate() to run browser-side IDB code.
Q: Why waitForFunction? A: To reliably await dynamic, asynchronous state changes.

TAGS: playwright, e2e testing, offline-first, service workers, indexeddb, automation, web testing

────────────────────────────────────────
Download our app for more dev insights & interview prep!
────────────────────────────────────────

📲 𝐅𝐑𝐄𝐄 𝐌𝐎𝐁𝐈𝐋𝐄 𝐀𝐏𝐏 — 𝟔𝟎𝟎+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
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_20261012

🍎 𝐀𝐩𝐩 𝐒𝐭𝐨𝐫𝐞 (𝐢𝐎𝐒):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20261012&mt=8

────────────────────────────────────────
────────────────────────────────────────

Top comments (0)