Search code examples
automated-testsplaywrightretry-logic

Playwright retry policy for text appearing


I have a use case for needing to reload a page until some text is populated on a page. I'm new to both Playwright and Javascript and am trying to find a good pattern for doing this.

My current method uses the async-retry library:

 const customerName = await this.page.locator(this.elements.customerName);
 const expectedCustomerName = 'Dave'
  
  async checkCustomerNameRetry() {
    try {
      await retry(
        async () => {
          await this.page.reload();
          await customerName.waitFor({state: 'visible'});
          await expect(customerName).toContainText(expectedCustomerName);
        }, {retries: 10, factor: 1, minTimeout: 1000, maxTimeout: 5000}
      );
    } catch (Error) {
      logger.log(`Could not find customer name after 10 retries`);
    }
  }

This seems sub-optimal - not least because of the unnecessary page.reload() even before the first check. I wonder if there's a better utility method I could use using plain Playwright api?


Solution

  • They implemented an expect.poll for this sort of scenario: https://playwright.dev/docs/testing-library#replacing-waitfor

    The whole statement must complete with the expected result, or Playwright will retry it until success or timeout. In your case, it'd be something like (sorry, typing this directly in the response box, so please forgive any typos or syntax errors):

    await expect.poll(async () => {
      await this.page.reload();
      await customerName.waitFor({state: 'visible'});
      return customerName;
    }).toBe(expectedCustomerName);