The answer @aknuds1 gave is perfect but you may make it even more convenient for yourself by creating a helper such as this one. This resolves to true
if the element is visible and to false
otherwise.
function isElementVisible(page, selector, timeout = 150) {
return new Promise((resolve) => {
page.waitForSelector(selector, {visible: true, timeout}).then(() => {
resolve(true);
}).catch(() => {
resolve(false);
});
});
}
Usage
in pure JS with Puppeteer
let isVisible = await isElementVisible(page, selector)
isVisible = await isElementVisible(page, selector, 300)
and if you happen to use Jest or another framework
expect(await isElementVisible(page, selector)).toBeTrue();
in the case of Jest (and most other frameworks), you can go even further and create a custom matcher to extend the existing ones. (https://jestjs.io/docs/expect#expectextendmatchers)
expect.extend({
async toHaveVisible(page, selector, timeout = 150) {
let isVisible = await isElementVisible(page, selector, timeout);
if (isVisible) {
return {
message: () => `expected ${selector} not to be visible`,
pass: true
};
} else {
return {
message: () => `expected ${selector} to be visible`,
pass: false
};
}
}
});
await expect(page).toHaveVisible(selector);
await expect(page).not.toHaveVisible(anotherSelector);
await expect(page).not.toHaveVisible(yetAnotherSelector, 300);
elem.getBoundingClientRect()
returns distinctive data you can test against. – Undershortselem.getBoundingClientRect()
returns a{}
on console.log, whether the element is ready or not :( – Behead.evaluate()
in Puppeteer. – LoudermilkJSON.stringify(elem.getBoundingClientRect())
? The reason it probably matters is thatelem.getBounding...
is a read-onlyDOMRect
rather than a plain object, so Puppeteer's serialization seems to be affected and doesn't capture the full object. – Loudermilk