How do you architect a Playwright test to verify atomic transaction rollback across UI and API state?
Description and use
The test verifies atomic transaction rollback by injecting a failure in an intermediate API call, asserting both UI and backend states, and using polling for resilience.
Problem
Verifying atomic transaction rollback (e.g., order placement, payment, inventory) in E2E tests is complex. Naive UI-only assertions are insufficient because the UI may briefly show a processing state while the backend asynchronously rolls back, leading to flaky tests.
Outcome
The test reliably verifies that a transaction rolls back across UI and backend, avoiding flakiness by injecting failures, asserting UI and API states, and polling for asynchronous completion.
Workflow
- 1. 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).
- 2. Trigger the checkout flow to cause the payment and inventory calls.
- 3. Assert the UI shows a rollback/failure message using expect(page.locator('.order-status')).toHaveText(/failed|rollback/i).
- 4. Create a new API context with request.newContext() to independently query the backend state.
- 5. Use expect.poll to repeatedly fetch the inventory endpoint until the stock value matches the original stock captured before the test.
- 6. Confirm the rollback succeeded by comparing the final stock to the original stock.
- 7. Rely on expect.poll for resilience against transient states.
Evidence
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).
Assert the UI’s final error state AND verify the backend state directly via an apiContext to confirm resources (e.g., inventory) were restored.
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.
- Record date: 2026-09-11T15:00:48.965Z