I wonder if there's a similar way as in Selenium to wait for text to appear for a particular element. I've tried something like this, but it doesn't seem to wait:
await page.waitForSelector('.count', {visible: true});
I wonder if there's a similar way as in Selenium to wait for text to appear for a particular element. I've tried something like this, but it doesn't seem to wait:
await page.waitForSelector('.count', {visible: true});
You can use waitForFunction
. See https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforfunctionpagefunction-options-args
Including @elena's solution for completeness of the answer:
await page.waitForFunction('document.querySelector(".count").innerText.length == 7');
Apart from the method presented in the answer from nilobarp, there are two more ways to do this:
Using the pseudo selector :empty
it is possible to find elements that contain no child nodes or text. Combining this with the :not
selector, we can use page.waitForSelector
to query for a selector which is not empty:
await page.waitForSelector('.count:not(:empty)');
If you not only want to make sure that the element is not empty, but also want to check for the text it contains, you can use an XPath expression using page.waitForXPath
:
await page.waitForXPath("//*[@class='count' and contains(., 'Expected text')]");
This line will only resolve after there is an element on the page which has the attribute class="count"
and contains the text Expected text
.
The best solution you can do using waitForFunction()
(avoid weird function as string):
const selector = '.count';
await page.waitForFunction(
selector => document.querySelector(selector).value.length > 0,
{},
selector
);
Depends of the type of the text, replace value
by innerText
.
Check puppeteer API
You can also just simply use page.waitFor()
to pass a function or CSS selector for which to wait.
Wait for Function
If the element is an input
field, we can check that the .count
element exists before checking that a value
is present to avoid potential errors:
await page.waitFor(() => {
const count = document.querySelector('.count');
return count && count.value.length;
});
If the element is not an input
field, we can check that the .count
element exists before checking that innerText
is present to avoid potential errors:
await page.waitFor(() => {
const count = document.querySelector('.count');
return count && count.innerText.length;
});
Wait for CSS Selector
If the element is an input
field that contains a placeholder
, and you want to check if a value
currently exists, you can use :not(:placeholder-shown)
:
await page.waitFor('.count:not(:placeholder-shown)');
If the element is an input
field that does not contain a placeholder
, and you want to check if the value
attribute contains a string, you can use :not([value=""])
:
await page.waitFor('.count:not([value=""])');
If the element is not an input
field that does not have any child element nodes, we can use :not(:empty)
to wait for the element to contain text:
await page.waitFor('.count:not(:empty)');
Wait for XPath
Otherwise, you can use page.waitForXPath()
to wait for an XPath expression to locate element(s) on the page.
The following XPath expressions will work even if there are additional classes present on the element other than count
. In other words, it will work like .count
, rather than [class="count"]
.
If the element is an input
field, you can use the following expression to wait for the value
attribute to contain a string:
await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " test ") and string-length(@value) > 0]')
If the element is not an input
field, you can use the following expression to wait for the element to contain text:
await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " count ") and string-length(text()) > 0]');
await page.waitFor((name) => {
return document.querySelector('.top .name')?.textContent == name;
}, {timeout: 60000}, test_client2.name);
waitForXPath
is simple and works well for finding an element with specific text.
const el = await page.waitForXPath('//*[contains(text(), "Text to check")]');