Recently, I was working on automating a test case where we generate a report from our product. Once the report is ready, a Download button appears in the UI — but not instantly.
This process can take up to 5 minutes, depending on the report size and backend processing.
So I asked myself:
“Should we keep reloading the page until the button appears?
Or should we use the API to check the status, then go to the UI?”
To answer this, I tried both approaches using Playwright with Python.
The Real Use Case
The user clicks “Generate Report.”
While generating, the UI shows the text (Generating...).
After some time, this changes, and a Download button appears.
The goal of the test is to detect when the report is ready and then verify the download works.
Understanding API States
Our backend provides a status code (state
) via API that tells us what’s going on:
So instead of blindly waiting for the UI to update, I thought —
Why not use this backend status to make a smarter wait?
Two Approaches I Tried
1. UI-Only Waiting (With Page Reloads)
Keep refreshing the page in a loop.
After each reload, check if the Download button is visible.
Once it appears, click and verify.
Worked fine, but felt a bit rough — browser was busy the whole time, and the logic felt heavy.
2. API Polling + UI Sync
Call the report status API repeatedly (every few seconds).
If
state = 1
, keep waiting.When
state = 2
, reload the page once, check for the button, and continue.
This approach was more structured and lighter on the browser.
The script only touched the UI when it knew the backend was ready.
When API Polling Makes Sense
✅ You should use API polling when:
The wait time is long (over 1 minute).
You have a reliable backend API that gives clear status.
You want more control over timing and retries.
Your UI is slow or unpredictable during these waits.
When Not to Use API Polling
❌ Avoid it when:
The wait is short (10–20 seconds) — not worth the complexity.
No API is available for the state you're tracking.
The test is specifically focused on verifying UI behavior, not backend readiness.
Final Thoughts
Both methods worked in my case, but API polling gave me:
A cleaner flow
Less UI noise (no repeated reloads)
More control over how I handle long waits
Sometimes, it’s not just about “does the test pass?”
It’s about how maintainable the test is.
If your app provides helpful API states — use them!
Let the API handle the waiting, and let the UI do what it does best: interaction and visual checks.