Rayrun
← Back to Discord Forum

Do the getby* locators automatically wait to locate the element?

As in, if the element does not quite yet exist on the page, will the, for example, await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible(); , will there be any waiting for it to be visible?

Or await expect(page.getByRole('heading', { name: 'Sign up' })); will it automatically wait to find/locate/get the element?

This thread is trying to answer question "Do the getby* locators in Playwright automatically wait to locate an element on a webpage?"

13 replies

GG @herod, you just advanced to Playwright community level 2! Keep up the amazing work.

First example will wait

Hi, yes - Playwright has built in auto-waiting that retries actions multiple times until the desired state is achieved or the timeout is exceeded. For the expect assertion the default timeout is 5 seconds, so Playwright will retry the command inside of the expect for this time (you can see it happening if you open a debug mode). You can read more about timeouts and auto waiting in the documenation. (https://playwright.dev/docs/test-timeouts and https://playwright.dev/docs/actionability#assertions)

Okay, I think I confused the questions or rather confused what I was asking. The 1st example is automatically wait because I of the expect, not because of the getByRole() correct?

More to the point, does getByRole() automatically wait? i.e page.getByRole('heading', { name: 'Sign up' })

What I've seen, or think I've seen, is that PW automatically waits on Actions, but not on something like an assertion. Something like checking whether something is displayed or not. It won't wait on that unless it is wrapped in an assertion, i.e. within an expect

refactoreric
@herod: page.locator or page.getBy* are not async functions. So there is no auto-waiting there. They are just constructing an object which resolves lazily when doing some action on it. The actions and the expect library matchers are doing the auto-waiting/auto-retrying.

page.locator or page.getBy* are not async functions. So there is no auto-waiting there. They are just constructing an object which resolves lazily when doing some action on it. The actions and the expect library matchers are doing the auto-waiting/auto-retrying.

GG @refactoreric, you just advanced to Playwright community level 10! Keep up the amazing work.

I think I understand the question here as I have a similar problem to solve.

There is a cookie notice that I would like to close if its visible and the issue is it is not visible immediately.

so if I use this logic

if (page.closeButton.isVisible()) {
    await closeButton.click()
}

This does not wait for the button to be visible.

I cant do the following code

await closeButton.click()

Because the close button is not there across all our environments so in some it would pass and in others it would fail

I also can not do the soft assertions as these still flag the test as a failure if the button is not visible.

Does anyone have any suggestions?

I could add an env var for all envs that show the close button and do this

if (process.env.hasPendo) {
    await closeButton.click()
}

but only a last resort

I found a good solution actually was not that hard

try {
      await closePendoButton.click();
    } catch {
      return;
    }

just wrap in a try, if its not there it will return and continue and if it is there it will wait for it to be visible a click it

Answer

Sure, let's dive into getBy* locators in Playwright. These locators are pretty smart - they automatically wait for the element to show up in the DOM. This is super handy when dealing with dynamic web pages where elements might take a bit to load or become visible.

Here's an example. Let's say you're using page.getByTestId('elementId'). Playwright will patiently wait until an element with the specified test ID (data-testid) pops up in the DOM before returning it. This means you always get a valid reference to the element and don't have to worry about timing issues when elements aren't immediately available.

import { test } from '@playwright/test';

test('getByTestId example', async ({ page }) => {
  await page.goto('https://ray.run');
  const element = await page.getByTestId('elementId');
  // your test code here
});

This automatic waiting behavior of getBy* locators makes your tests more reliable and resilient. You can write code that assumes elements are already present in the DOM without worrying about explicit waits or timeouts.

Just remember, this waiting behavior is specific to getBy* locators. If you're using a different type of locator or method, make sure to check its documentation for information on waiting behavior.

In a nutshell, getBy* locators in Playwright handle timing issues automatically, simplifying your test code and boosting test stability.

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.