Is there a way to watch for the visibility of an element similar to how waitForRequest
works - https://playwright.dev/docs/api/class-page#page-wait-for-request
The problem I'm trying to solve is a flaky test that checks that a loading spinner has been displayed. In some cases the loading spinner is displayed and hidden so quickly that the expect(element).toBeVisible()
runs when the element has already hidden itself again.
I can see in the trace that immediately after the click the element is visible but has hidden by the time the expect runs.
Initially I did use unickq's answer but even this has failed on occassion. Here is the most robust solution I have found.
Mock the route that the spinner is appearing for and only fufill
the request when you have asserted if the spinner is visible.
https://playwright.dev/docs/mock#modify-api-responses
test('check spinner appears', () => {
await page.route('*/**/api/v1/spinner-is-visible-until-i-resolve', async route => {
expect(spinner).toBeVisible();
await route.fulfill();
});
await makeApiRequestButton.click();
});
If you want more actions and assertions in your test you can add a promise so the test doesn't run on before the spinner has been checked.
test('check spinner appears', () => {
let gateResolve;
const gatePromise = new Promise((resolve) => {
gateResolve = resolve;
});
await page.route('*/**/api/v1/spinner-is-visible-until-i-resolve', async route => {
expect(spinner).toBeVisible();
await route.fulfill();
gateResolve();
});
await makeApiRequestButton.click();
await gatePromise;
// do something else now the spinner has gone
});