Prepare any webpage for clean interaction by detecting and removing disruptive overlays (cookie banners, GDPR consent, modals, popups, newsletter signups, paywalls, login walls). Uses a cached database of 300+ known CMPs (Consent-O-Matic + EasyList) combined with heuristic DOM scanning. Produces portable JS recipes for any browser tool (Playwright, CDP, cmux-browser). ALWAYS use this skill before taking screenshots, scraping content, or automating interaction on any webpage that might have overlays blocking the view or preventing interaction. Triggers on: page prep, clean page, remove overlays, dismiss cookie banner, page blocked, overlay cleanup, consent banner, prepare page, unblock page, clear popups, cookie popup.
100
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
Consult this reference when heuristic detection finds overlays but cannot compose a dismiss recipe.
CSS selectors that commonly match close/dismiss buttons:
[aria-label*="close"]
[aria-label*="Close"]
.close-btn
.close-button
button.close
button:has(svg) /* X icons — check proximity to overlay */
[data-dismiss]
[data-close]
[data-action="close"]
.modal-close
.dialog-closeEvaluation order: prefer aria-label selectors (semantic) over class-based (fragile).
For button:has(svg), confirm the button is visually inside or adjacent to the overlay.
| CMP | Selector |
|---|---|
| OneTrust | #onetrust-accept-btn-handler |
| Cookiebot | #CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll |
| TrustArc | .truste-consent-button, #truste-consent-button |
| Quantcast | .qc-cmp2-summary-buttons button[mode="primary"] |
| Didomi | #didomi-notice-agree-button |
| LiveRamp | .lfr-btn.lfr-btn--primary |
| Axeptio | [data-testid="accept-all"] inside #axeptio_overlay |
| Osano | .osano-cm-accept-all |
| CookieYes | .cky-btn-accept |
| Usercentrics | button[data-testid="uc-accept-all-button"] |
Try each selector with document.querySelector(selector) — null means not present on this page.
Known CMPs that render inside shadow roots and are invisible to normal querySelector:
Usercentrics v2:
document.querySelector('#usercentrics-root')
?.shadowRoot
?.querySelector('button[data-testid="uc-accept-all-button"]')
?.click();General traversal pattern:
document.querySelector('#host')?.shadowRoot?.querySelector('button')Diagnosis: if no overlays are detected but the page is visibly blocked, try shadow DOM traversal.
Walk document.querySelectorAll('*') and check .shadowRoot on each element.
Common CSS applied to html or body that blocks scrolling:
| Property | Value |
|---|---|
overflow | hidden |
position | fixed (on body — freezes scroll position) |
touch-action | none |
height + overflow | 100vh + hidden (locks viewport) |
Fix — inject via page.evaluate():
document.documentElement.style.cssText +=
';overflow:auto!important;height:auto!important;position:static!important';
document.body.style.cssText +=
';overflow:auto!important;height:auto!important;position:static!important';Overlays that appear after initial page load:
| Type | Trigger | Common selectors |
|---|---|---|
| Newsletter signup | 15-60s delay or scroll % | .newsletter-modal, [class*="subscribe"] |
| Exit-intent | Mouse leaves viewport | .exit-intent, [class*="exit"] |
| Re-consent | Cookie expired | CMP selectors from §2 |
| Paywall | Article scroll depth | .paywall, [class*="paywall"], [class*="meter"] |
Strategy: