Hey guys, I’m trying to figure out how to click on elements that contain specific text in Puppeteer. I’ve looked through the API docs but can’t seem to find a straightforward method. Here’s an example of what I’m working with:
<div class="container">
<button>Click me</button>
<a href="#">Link text</a>
<span>Some content</span>
</div>
I want to be able to do something like this:
await page.clickText('Click me', '.container');
Is there a built-in way to do this in Puppeteer? Or do I need to come up with a custom solution? Any help would be awesome!
hey, i’ve found a neat trick for this! use page.$eval() with a custom selector. like:
await page.$eval('.container *', (el, text) => {
if (el.textContent.includes(text)) el.click();
}, 'Click me');
works gr8 for me. hope it helps!
I’ve been using Puppeteer for a while now, and I’ve found that the best way to click text-containing elements is to use a combination of page.evaluate() and document.evaluate(). Here’s a custom function I’ve developed that works really well:
async function clickElementByText(page, text, parentSelector = 'body') {
await page.evaluate((text, parentSelector) => {
const xpath = `.//*[contains(text(), '${text}')]`;
const element = document.evaluate(xpath, document.querySelector(parentSelector), null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (element) {
element.click();
} else {
throw new Error(`Element containing text '${text}' not found`);
}
}, text, parentSelector);
}
You can then use it like this:
await clickElementByText(page, 'Click me', '.container');
This approach has been reliable for me across various projects. It’s flexible and can handle different element types. Just make sure to add proper error handling in your actual implementation.
While the previous answers offer valid solutions, I’ve found success using Puppeteer’s built-in page.waitForSelector() method combined with a custom XPath selector. This approach is both efficient and reliable:
async function clickByText(page, text, parentSelector = 'body') {
const xpath = `${parentSelector}//*[contains(text(), '${text}')]`;
await page.waitForXPath(xpath);
const elements = await page.$x(xpath);
if (elements.length > 0) {
await elements[0].click();
} else {
throw new Error(`Element with text '${text}' not found`);
}
}
You can then use it like:
await clickByText(page, 'Click me', '//div[@class=\"container\"]');
This method is particularly useful when dealing with dynamically loaded content, as it waits for the element to appear before attempting to click it.