How do you architect a Playwright test to verify atomic transaction rollback across UI and API state?

μž‘μ„±μž

μΉ΄ν…Œκ³ λ¦¬:

← ν”Όλ“œλ‘œ
DEV Community · Styrow.dev · 2026-09-06 개발(SW)

Styrow.dev

🚨 Playwright E2E Architect Challenge:
How do you verify atomic transaction rollback across UI and API states, ensuring your tests don’t fall for transient UIs?

πŸ“Œ Problem Statement
Verifying atomic transaction rollback (e.g., order placement, payment, inventory) in E2E tests is complex. If any part fails, the entire transaction must revert, and all states (UI & backend) must reflect this consistently.
❌ Naive UI-only assertions are insufficient. The UI might briefly show “processing” while the backend asynchronously rolls back, leading to flaky tests.
This requires:
β€’ Precise failure injection mid-transaction.
β€’ Dual UI and API state verification post-rollback.
β€’ Resilient assertions for asynchronous state changes.

πŸ’‘ Solution & Code Walkthrough
We leverage Playwright’s powerful network interception, API testing, and robust assertion capabilities.

βœ… 1. Forced Failure Injection:
Use page.route to intercept an intermediate API call (e.g., inventory update) and force it to fail after a preceding successful step (e.g., payment).

// Assume originalStock fetched via request.newContext() pre-test
await page.route('**/api/inventory', async route => {
  // Fulfill with 500 to simulate inventory failure after payment
  await route.fulfill({ status: 500, body: '{"error": "Inventory Error"}' });
});

await page.goto('/checkout');
await page.fill('#productQuantity', '1');
await page.click('#placeOrder'); // Triggers payment then inventory call

Enter fullscreen mode Exit fullscreen mode

βœ… 2. Verification of Rollback (UI & API):
Assert the UI’s final error state AND verify the backend state directly via an apiContext to confirm resources (e.g., inventory) were restored.

// UI verification: Confirm a rollback/failure message
await expect(page.locator('.order-status')).toHaveText(/failed|rollback/i);

// API verification: Check backend state for rollback success
const apiContext = await request.newContext();
await expect.poll(async () => {
  const inventoryResponse = await apiContext.get('/api/inventory/productX');
  const { stock } = await inventoryResponse.json();
  return stock;
}, {
  message: 'Inventory should revert to original state.',
  intervals: [1000, 2000], // Retry checks every 1-2 seconds
  timeout: 15000 // Total wait for rollback
}).toBe(originalStock); // originalStock fetched before test start

Enter fullscreen mode Exit fullscreen mode

βœ… 3. Test Resilience:
expect.poll is crucial. It continuously retries assertions until the condition is met or a timeout occurs, preventing premature test failures due to transient states.

πŸ”‘ Key Takeaways
β€’ page.route: Inject specific failure scenarios by mocking network requests.
β€’ request.newContext(): Perform independent API calls for direct backend state validation.
β€’ expect.poll: Build resilient tests by gracefully waiting for asynchronous operations (like backend rollbacks) to complete.
β€’ Combine UI and API assertions for comprehensive and reliable transaction verification.

❓ Quick Summary Q&A
Q: Why not use page.waitForTimeout()?
A: waitForTimeout is flaky. expect.poll smartly waits for a condition, making tests robust.
Q: How is request.newContext() different from page.goto for API?
A: newContext() creates a fresh, UI-independent session ideal for direct API calls without browser overhead.

TAGS: playwright, e2e testing, api testing, transaction, rollback, test architecture, automation, network interception

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

πŸ“² 𝐅𝐑𝐄𝐄 πŒπŽππˆπ‹π„ 𝐀𝐏𝐏 β€” πŸ”πŸŽπŸŽ+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
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_20260905

🍎 𝐀𝐩𝐩 π’π­π¨π«πž (π’πŽπ’):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20260905&mt=8

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

μ›λ¬Έμ—μ„œ 계속 β†—