Free tools Windows power users keep installed
One-click scans. No signup required.
Use a Puppeteer locator with a condition that identifies the element you mean—such as distinctive text or a stable parent relationship—instead of clicking the shared class alone. A locator can filter matching elements and wait for the target to be ready before clicking it.
Click the matching element by a distinguishing condition
For example, if several elements have the class item and the intended one contains the text “Target,” filter the locator by that text:
As an Amazon Associate I earn from qualifying purchases.
await page
.locator('.item')
.filter(el => el.textContent?.trim() === 'Target')
.click();
Replace .item and 'Target' with a selector and condition from your page. This is a pattern, not a universal selector: without the page’s markup, no one can know which condition uniquely identifies your target. Puppeteer’s interaction guide recommends locators for selecting and interacting with elements. The filter callback runs in the browser context, so it cannot directly access Node.js variables. If the predicate needs a value from Node, use Puppeteer’s documented string-function pattern for passing it.
Choose a selector that identifies the intended element
Prefer a stable attribute or meaningful parent
If the target has a stable, unique attribute, or sits inside a uniquely identifiable card, dialog, or section, use that relationship to narrow the selector. For instance, .product-card[data-id="42"] .item is appropriate only if that attribute and structure actually exist and remain meaningful on the page. Avoid relying on generated classes or incidental structure when a more stable identifier is available.
#1 Best Overall
Filter by text when the label is distinctive
Text filtering is useful when the target’s text distinguishes it from the other matches. Check for duplicate labels, whitespace, nested text, and localization: any of these can make a text-only condition ambiguous or fragile. If necessary, combine the text condition with a more specific parent or attribute.
Use accessibility information when it is distinctive
Puppeteer supports ARIA selectors based on computed accessible name and role. Use one when the target’s role and accessible name reliably identify it, and confirm those values on the page first. For example:
Rank #2
await page.locator('::-p-aria([name="Save changes"][role="button"])').click();
Use position only when order is meaningful
An index or nth-style choice can select a particular match, but it identifies the element by its current position, not by what the element is. Use it only if the order itself is stable and significant; inserted, removed, or sorted items can silently change what that position means.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Check how many elements match
When you are unsure whether your selector is unique, inspect its matches with Puppeteer’s query API:
const matches = await page.$$('.item');
console.log(matches.length);
page.$$() returns an array of all matching elements; an empty array means there were no matches. page.$() returns the first match or null, while page.$eval() runs a callback on the first match and throws if none exists. These APIs help inspect or query the DOM, but a query by itself does not provide the locator’s interaction-readiness checks. Dispose of element handles when finished with lower-level handle workflows.
Why a bare shared-class click can hit the wrong item
page.click('.item') scrolls the matched element into view and clicks its center. If multiple elements match, Puppeteer’s documented behavior is to click the first one; if none match, the call throws. That may be different from the intended target even though the selector is valid.
Rank #4
Locators are more expressive for this task: they can filter candidates and automatically wait for documented readiness conditions, including visibility, enabled state, viewport position, and bounding-box stability. Locator actions are retried when an action fails because the element is not ready. A locator still needs a condition that identifies the right element; waiting does not make an ambiguous selector unique.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Wait for navigation when the click changes pages
If clicking the target triggers navigation, wait for it concurrently with the click so the navigation does not race ahead of the wait:
Best Value
- Used Book in Good Condition
const [response] = await Promise.all([
page.waitForNavigation(),
page.locator('.item').filter(el => el.textContent?.trim() === 'Target').click(),
]);
Use this only when the click is expected to navigate. Adapt the locator condition to the actual target. For interactions that update the current page without navigation, wait for an appropriate page condition instead.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot a click that fails or targets the wrong element
- The wrong repeated item is clicked: The selector likely matches several elements. Add a real discriminator, such as a stable attribute, parent relationship, or distinctive text filter.
- The locator finds no target: Confirm the selector, text, and accessible name against the rendered page. Consider whether content has loaded yet or whether the element is inside a frame or shadow root.
- The text filter matches more than one item: Add another condition, such as a meaningful container or attribute. Text is not inherently unique.
- A positional choice changes after page updates: Replace it with an identity-based condition unless the ordering is intentionally part of the requirement.
- The element is found but not ready to click: Prefer a locator interaction over a raw query, and verify that the target becomes visible and enabled in the page state.
- The click triggers navigation but the script misses it: Start
waitForNavigation()together with the click usingPromise.all(). - The example works nowhere else unchanged: That is expected; selectors and labels must reflect the target page’s DOM, frame, and shadow-root structure. Puppeteer also documents text, ARIA, XPath, and shadow-DOM selector facilities when CSS alone is not suitable.
Or skip the browser setup
If you need a screenshot rather than an interactive click, ScreenshotNeo can capture a page with one GET request. It is not a replacement for Puppeteer when your task requires clicking an element and then interacting with the page.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed along with supported newsletter popups and chat widgets before capture; those cleanup steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 shots a month without a card; paid plans start at $5 for 3,000 shots.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchSign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




