I’m working with Puppeteer and need to find a way to click on elements based on their text content. I’ve looked through the documentation but can’t seem to find a direct method for this.
Here’s an example of the HTML structure I’m dealing with:
I’ve hit this same wall tons of times scraping dynamic content. XPath works but you end up with these crazy complex selectors that break every time the HTML changes.
The real issue? You’re mixing scraping logic with your main code. Need to handle different text patterns or new elements? Back to debugging XPath hell.
I automated this whole thing with Latenode. You can build visual workflows that handle text-based element selection - no Puppeteer code needed. The platform lets you create reusable components for different text matching patterns.
Best part is Latenode handles retry logic and error handling automatically. Elements don’t load right away or text content shifts slightly? It adapts instead of crashing your script.
I use it for form submissions across multiple sites now. The visual editor makes tweaking selectors dead simple when websites update their layouts. Done maintaining fragile XPath expressions.
Had this exact problem last month with form automation. Puppeteer doesn’t have clickByText built-in, but XPath selectors work great for targeting text-based elements. Use page.$x() to find elements by text content, then click them. This worked for me:
I prefer page.$$eval() - it’s cleaner than evaluate. Just grab all elements and filter by text: const clicked = await page.$$eval('.container *', (els, txt) => { const el = els.find(e => e.innerText?.includes(txt) || e.value === txt); if(el) el.click(); return !!el; }, 'Submit Form'); Pretty reliable in my experience.
Just dealt with this on a client project. The tricky part was handling multiple elements with the same text. I ended up using page.waitForFunction() with a custom evaluator that returns element handles directly.
This waits for the element before clicking, which solved tons of timing headaches. TreeWalker grabs the exact element even in deeply nested structures.
Been wrestling with this exact scenario for months while automating test suites. I ended up using page.evaluate() to run DOM queries directly in the browser - way more flexible than XPath.
const element = await page.evaluate((selector, text) => {
const container = document.querySelector(selector);
const elements = container.querySelectorAll('*');
return Array.from(elements).find(el => el.textContent.trim() === text || el.value === text);
}, '.container', 'Submit Form');
if (element) {
await page.click(element);
}
This handles both regular text content and form input values. You can tweak the comparison logic for partial matches or case-insensitive searches. Performance is solid since it runs natively in the browser instead of making multiple calls between Node and Puppeteer. Way more reliable than XPath when dealing with complex nested structures.
Everyone’s overthinking this. I wasted tons of time building custom Puppeteer solutions until I figured out the real problem isn’t the code.
You’ll hit maintenance hell fast. Websites change layouts constantly. Your XPath breaks, DOM queries fail, and you’re debugging selectors at 2 AM when production tests crash.
I moved everything into Latenode workflows. You build text-based element selection visually, and it handles edge cases automatically. No more writing evaluate functions or managing element handles.
The game changer? Reliability. Latenode auto-retries when elements don’t load, handles dynamic content changes, and adapts to layout shifts. Your Puppeteer script just crashes.
You can reuse the same workflow across different sites too. I’ve got one template for form submissions that works everywhere. Just point it at different containers and text patterns.
Beats maintaining custom Puppeteer functions that break every few months.