What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Handle a cookie prompt by locating the control that represents the user choice you intend to make, clicking it with Puppeteer’s locator API, and waiting for the correct result. Locators wait for visibility, enabled state, viewport placement, and a stable bounding box, which makes them safer than an immediate selector query when a banner appears after navigation or other asynchronous work.
There is no universal cookie-banner selector. Inspect the target site, choose a stable attribute or accessible name, and test the behavior for each locale and layout you automate. A click in the consent interface and direct cookie-storage manipulation are separate operations; writing a cookie is not automatically equivalent to recording a user’s choice through the site’s interface.
A complete Puppeteer pattern
The following script opens a page, uses an accessible-name selector for a visible “Reject all” button, and handles either navigation or a same-page update. Replace the URL and selector with values from the site you are automating.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
try {
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 60_000
});
const reject = page.locator(
'::-p-aria([name="Reject all"][role="button"])'
);
// Use this branch when the consent action causes a navigation.
await Promise.all([
page.waitForNavigation({
waitUntil: 'domcontentloaded',
timeout: 30_000
}).catch(() => null),
reject.click()
]);
// If the site stays on the same document, wait for its result instead.
// For example, wait until the banner is hidden or removed:
// await page.waitForFunction(() => !document.querySelector('#cookie-banner'));
console.log('Consent action completed');
} finally {
await browser.close();
}
})();
The waitForNavigation call is intentionally started before the click. This prevents a race in which the navigation begins before Puppeteer has installed its listener. Do not use the generic button selector in production unless it uniquely identifies the consent control; it is shown only to illustrate the synchronization pattern.
Choose the intended consent action first
Automation should express the choice your test, crawler, or application is meant to make. “Accept all,” “Reject all,” “Save preferences,” and a granular category choice have different effects. Do not silently convert a test that should reject optional cookies into one that accepts them simply because the accept button is easier to find.
Define the expected result
- Record which control was clicked and, when relevant, which categories were enabled.
- Decide whether the expected outcome is a new page, a modal closing, a banner disappearing, a preference panel opening, or a network request completing.
- Keep legal and policy decisions separate from browser mechanics. The ability to click a control does not establish that the choice is legally required or sufficient in a particular jurisdiction.
Inspect the real interface
Cookie banners are ordinary site-specific UI, not a standardized DOM component. Use your browser’s inspector to identify stable IDs, data attributes, button roles, or labels. Check the page in the same locale, viewport, and device mode that your automation will use. A selector that works on a desktop English page may not match a translated mobile layout.
Build selectors that survive markup changes
Stable attributes and site-owned hooks
A selector based on a documented test ID or a stable consent-specific attribute is usually less fragile than a long chain of div elements. Prefer a selector whose meaning is clear to a maintainer, such as a consent button with a stable data attribute. Avoid depending on generated class names or the position of a button among unrelated buttons.
#1 Best Overall
Accessible names and ARIA selectors
When the visible label and role are reliable, Puppeteer’s ARIA selector syntax can express the intent directly:
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallawait page.locator(
'::-p-aria([name="Reject all"][role="button"])'
).click();
Text selectors can also help when the wording is stable:
await page.locator('::-p-text(Reject all)').click();
These forms still depend on the site’s actual text, role, and localization. They do not create a universal selector. If a translation changes “Reject all” to another phrase, provide a locale-specific selector or map the approved labels for that locale.
Open shadow roots
Some consent controls are rendered inside an open shadow root. Puppeteer’s deep-selector support can cross that boundary; use the deep combinator together with a selector for the actual control. For example, a site-specific path might look like:
Rank #2
await page.locator('cookie-banner >>> button[data-action="reject"]').click();
Inspect the component before adopting this pattern. Closed shadow roots, a changed component name, or a different action attribute requires another strategy.
Free tools Windows power users keep installed
One-click scans. No signup required.
Frames and preference dialogs
If inspection shows that the banner is inside a frame, first identify the correct frame and then create the locator in that frame rather than on the top-level page. If the first click opens a preference panel, treat opening the panel and saving the choice as two separate actions, each with its own locator and postcondition. This avoids clicking a hidden control from the initial banner when the site expects a second confirmation.
Synchronize clicks with what the page does next
When the click navigates
Start the navigation wait and click together:
const [response] = await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.locator('button[data-consent="reject"]').click()
]);
console.log(response ? 'Navigation observed' : 'No response object');
The selector above is illustrative; use the selector you validated on the target site. A navigation wait can time out on a site that updates the current document without navigating, so do not use it by default for every banner.
When the page stays in place
Wait for a meaningful state change instead of an arbitrary sleep. Examples include the banner becoming hidden, a preference dialog disappearing, or a site-owned state attribute changing:
await page.locator('button[data-consent="reject"]').click();
await page.waitForFunction(() => {
const banner = document.querySelector('#cookie-banner');
return !banner || getComputedStyle(banner).display === 'none';
});
If the site performs asynchronous work after the click, wait for the resulting condition that your next step actually needs. A fixed delay can be useful as a last resort for a known animation, but it is less reliable than a state-based wait.
When the banner appears late
Do not query immediately after goto and assume the prompt exists. A locator waits for the element and checks action preconditions, so it is appropriate when consent UI is injected after scripts run. Set a bounded timeout for a site that may legitimately have no banner, and handle that absence explicitly:
const reject = page.locator('::-p-aria([name="Reject all"][role="button"])');
try {
await reject.click({ timeout: 10_000 });
console.log('Rejected optional cookies');
} catch (error) {
console.log('No usable reject control appeared:', error.message);
}
Do not swallow every error as “no banner.” A timeout, a detached element, a blocked page, and a selector mismatch have different causes. Log the URL, locale, viewport, and a screenshot or HTML snapshot when diagnosing failures.
Cookie storage is not the consent interface
Current Puppeteer API guidance deprecates page-level cookie methods and points to browser or browser-context methods for browser storage work. A storage operation can be useful for setting up an isolated test state, but it should not be presented as proof that a visitor made a consent choice through the site’s UI.
Keep storage setup scoped to the browser context used by the test. For example, where supported by your installed Puppeteer version:
Recommended Free Tools
const context = page.browserContext();
await context.setCookie({
name: 'example_state',
value: 'test-value',
domain: 'example.com',
path: '/'
});
Verify the method and cookie fields against the Puppeteer version you have installed. Use the consent interface when your objective is to exercise the site’s real preference flow; use context storage methods when your objective is to prepare or inspect browser state.
Reliability checklist for production scripts
- Use a fresh context when isolation matters. A previous run may already have a consent cookie, so the banner will not appear.
- Set the locale and viewport deliberately. Labels, layout, and even the presence of a compact banner can vary.
- Prefer one purposeful locator. Long descendant chains and positional selectors break when the site changes its markup.
- Wait for outcomes, not time. Pair navigation waits with clicks only when navigation is expected; otherwise wait for a same-page state.
- Capture diagnostics. Save the current URL, console errors, a screenshot, and relevant HTML when a control is missing or obscured.
- Bound every wait. A missing banner should produce a controlled result, not a test that hangs indefinitely.
- Revalidate after site releases. Consent components are often changed independently of the rest of the page.
Common failures and fixes
“No element found” or locator timeout
The banner may be late, localized, inside a frame or shadow root, or absent because a stored consent state already exists. Confirm the page URL and locale, inspect the live DOM, and use a locator timeout appropriate to the site. If no banner is a valid outcome, branch on that condition instead of treating it as a fatal error.
The selector matches the wrong button
Generic text such as “Continue” can identify several controls. Add the role, accessible name, consent-specific attribute, or a container boundary. Log the matched element’s text and attributes during development.
Click intercepted or element not actionable
Another overlay may cover the control, the element may be outside the viewport, or the page may still be animating. Puppeteer locators check action preconditions; inspect the overlay and wait for the consent control to become actionable rather than forcing a click that does not represent a user action.
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 →Navigation wait times out
The click probably updates the current page instead of navigating, or the site performs a client-side transition. Replace the navigation wait with a meaningful same-page condition. Conversely, if navigation is real, ensure the listener is created in the same Promise.all as the click.
Rank #4
The banner returns on every run
Each run may use a new context, the site may require more than one preference action, or the consent state may be stored under a different domain. Decide whether repeatable banner handling or persistent state is the goal, then configure the context accordingly and verify the resulting storage.
The page is a bot check, blank, or failed load
These are page-load problems, not selector problems. Record the response and console output, confirm the URL is reachable in the same environment, and avoid claiming that a consent click succeeded when the intended document never loaded.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance and maintenance choices
For a small test suite, one browser with separate pages or contexts is usually simpler than launching a browser for every URL. Reuse a browser carefully: isolate cookies when tests must not share consent state, and close pages and contexts after each job. Avoid waiting for network idle solely to find a banner; many pages keep analytics or advertising requests open. Wait for the banner locator and then for the post-click condition your test needs.
Keep selectors and expected labels in configuration when you support multiple sites or locales. A mapping makes changes reviewable and lets you report “unsupported consent variant” instead of guessing. Pin and periodically update Puppeteer, because selector behavior and browser support are version-sensitive; check the official Puppeteer documentation for the release installed in your project.
Or skip the browser setup
If your goal is a clean screenshot rather than testing the consent flow itself, ScreenshotNeo handles the capture through one request. Before the shot it accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It also provides an MCP server for AI agents, including Claude and Cursor, with take_screenshot, get_page_info, and capture_pdf tools.
Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. This cURL request captures Stripe as a WebP file:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo includes full-page capture with lazy images loaded, element capture by CSS selector, dark mode, 12 device presets plus custom viewports, retina scale, PDF controls, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors or network idle, request and resource blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots, with yearly billing giving two months free.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsBest Value
- Used Book in Good Condition
Sign up for the free ScreenshotNeo plan to get 1,000 screenshots a month with no card.
Frequently Asked Questions
Should a test fail when no consent banner appears?
Only if the banner is required for that test. Otherwise record an explicit “not present” result and continue; a missing banner can be a valid outcome when consent state is already stored or the site does not display one.
How can I support several consent vendors in one crawler?
Keep a per-site or per-locale selector and expected-outcome configuration, then choose the matching entry from the URL, hostname, or known page variant. Do not fall back to an unrelated generic button.
What should I archive when consent automation breaks after a redesign?
Archive the failing URL, locale, viewport, console messages, current HTML, and a screenshot. Those artifacts show whether the failure is a changed label, a new frame or shadow root, an overlay, or a page-load problem.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →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.




