Seatext library / BotRefund evidence

How to Test If a Website Is Blocking Playwright: A Practical Detection Guide

Run a minimal Playwright script that visits the target site and checks for CAPTCHAs, unexpected redirects, JavaScript challenges, or missing content. Compare the rendered DOM and network responses against a known‑good browser session to...

Built for advertisers who need clear, refund-ready traffic evidence.

Quick test: run a minimal Playwright script

Create a new Node project, install Playwright, and run the script below. It opens the target URL in Chromium, waits for network idle, then logs the page title, URL after navigation, and whether a CAPTCHA element appears.

const { chromium } = require('playwright');

async function testBlock(url) {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext();
  const page = await context.newPage();
  
  const response = await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });
  
  console.log('Status:', response?.status());
  console.log('Final URL:', page.url());
  console.log('Title:', await page.title());
  
  // Common CAPTCHA selectors
  const captcha = await page.$('iframe[src*="captcha"], [id*="captcha"], [class*="captcha"], [data-testid*="captcha"]');
  console.log('CAPTCHA detected:', !!captcha);
  
  // Check for challenge pages
  const bodyText = await page.textContent('body');
  const challengeKeywords = ['challenge', 'blocked', 'access denied', 'rate limit', 'please verify'];
  const hasChallenge = challengeKeywords.some(k => bodyText.toLowerCase().includes(k));
  console.log('Challenge page detected:', hasChallenge);
  
  await browser.close();
}

testBlock('https://example.com').catch(console.error);

If the status is 200 but the title shows a challenge page, a CAPTCHA element exists, or the final URL redirects to a verification endpoint, the site is likely blocking or challenging Playwright.

Why sites block Playwright

Anti‑bot services look for automation fingerprints. BotRefund's detection suite includes a Playwright Init Scripts check that flags mismatches between patched browser APIs and the underlying browser implementation. As BotRefund explains, "Automation tools often patch or hide browser APIs, but those changes can break when the browser is checked from another angle." This signal is one of 106 independent checks used to build a reliable picture of whether a visit is human or automated.

Step‑by‑step testing procedure

  1. Baseline with a real browser. Open the target URL in a regular Chrome profile. Note the title, visible content, and network requests in DevTools.
  2. Run headless Playwright. Use the script above. Compare status code, final URL, title, and body text against the baseline.
  3. Run headed Playwright. Launch with headless: false. Some blockers only trigger in headless mode.
  4. Add a realistic context. Set a common user‑agent, viewport, locale, and timezone. Disable navigator.webdriver via context.addInitScript().
  5. Capture network logs. Listen for page.on('response') and log responses with status 403, 429, 503, or redirects to known challenge domains.
  6. Screenshot diff. Take full‑page screenshots in both real and automated sessions. Visual differences often reveal hidden overlays or missing dynamic content.

Interpreting the script output

The console prints four key values. Understanding each helps you decide whether Playwright was blocked.

  • Status: A 200 status means the server delivered a page. A 403, 429, or 503 usually indicates a block at the HTTP layer.
  • Final URL: If the URL changes to something like /challenge or /verify, the site redirected you to a verification flow.
  • Title: Compare the title with the baseline. A generic title such as "Just a moment..." or "Access denied" signals a challenge page.
  • CAPTCHA detected: true means an iframe or element matching common CAPTCHA selectors was found. This is a strong indicator of a bot block.
  • Challenge page detected: The script scans the body text for keywords. true suggests a JavaScript or server‑side challenge even if no visible CAPTCHA appears.

When two or more of these signals differ from the baseline, you can confidently label the site as blocking Playwright.

Checklist: CAPTCHA vs. JavaScript challenge vs. IP‑based block

Use this quick list to classify the type of block you encounter.

  1. CAPTCHA present
    • Visible iframe from hCaptcha, reCAPTCHA, Turnstile, or a custom provider.
    • Requires mouse click, checkbox, or image selection.
    • Script will return CAPTCHA detected: true.
  2. JavaScript challenge
    • Page loads a blank or minimal DOM, then replaces it after a short delay.
    • Network shows a request to /cdn-cgi/challenge-platform or similar.
    • No visible CAPTCHA, but Challenge page detected: true and the title often reads "Checking your browser...".
  3. IP‑based block
    • Immediate 403/429 response without any DOM changes.
    • Same response occurs in a regular Chrome session when using the same IP.
    • Switching to a residential proxy makes the page load normally, confirming an IP reputation issue.

Troubleshooting table for common Playwright detection signals

SignalWhat it meansTypical cause
navigator.webdriver = trueAutomation flag exposedDefault Playwright context; can be masked with addInitScript.
Missing window.chrome.runtimeChrome‑specific API absentPlaywright Chromium may lack Chrome extensions APIs.
WebGL vendor mismatchGPU fingerprint differsHeadless rendering often reports generic values.
Canvas hash differsCanvas fingerprint anomalyHeadless browsers add subtle noise.
Redirect to challenge.example.comServer‑side verification flowBot detection service (e.g., Cloudflare, Akamai).
HTTP 429 / 503Rate‑limit or temporary blockHigh request volume or suspicious IP.
CAPTCHA iframe detectedHuman verification requiredBot detection service recognizing automation.

Common blocking signals to watch

  • HTTP 403, 429, or 503 on the initial navigation or critical XHR/fetch calls
  • Redirect to a challenge subdomain (e.g., challenge.example.com, cdn-cgi/challenge-platform)
  • CAPTCHA iframes from providers like hCaptcha, reCAPTCHA, Turnstile, or custom challenges
  • JavaScript challenges that require solving before the real content loads
  • Empty or skeleton DOM where the real browser shows full content
  • Missing cookies or localStorage values that the real browser sets

Advanced detection checks

Beyond the basic script, you can probe the specific fingerprints that anti‑bot systems evaluate:

  • navigator.webdriver — should be undefined in a real browser; Playwright sets it to true unless masked.
  • Chrome runtimewindow.chrome.runtime exists in real Chrome; often missing or incomplete in automation.
  • Permissions API — query navigator.permissions.query({name:'notifications'}); automation often returns a different state.
  • WebGL fingerprintgetParameter(UNMASKED_VENDOR_WEBGL) and UNMASKED_RENDERER_WEBGL should match a real GPU.
  • Canvas fingerprint — draw a known image and hash the output; headless browsers often produce different noise patterns.

BotRefund's approach cross‑checks these signals: "A single anomaly is not a bot verdict. Privacy tools, travel, corporate networks, and unusual devices can produce unexpected behavior for genuine people. BotRefund keeps this signal as evidence—not a verdict—and cross‑checks it against independent browser, network, device, and behavior data."

What to do if blocking is confirmed

  1. Use Playwright Stealth plugins. Community projects like playwright-stealth patch common fingerprints.
  2. Rotate residential proxies. Data‑center IPs are heavily flagged; residential or mobile IPs reduce reputation‑based blocks.
  3. Mimic human behavior. Add random delays, mouse movements, scroll patterns, and realistic click coordinates.
  4. Persist browser state. Reuse a user-data-dir with cookies and localStorage from a prior manual login.
  5. Consider a dedicated anti‑detect browser. Tools like Browserless, ScrapingBee, or Bright Data handle fingerprinting at scale.

Key facts

FactDetail
Playwright Init Scripts checkOne of 106 independent checks BotRefund uses to detect automation
Detection principleLooks for mismatches between patched browser APIs and underlying implementation
Single anomaly policyNot a verdict; cross‑checked against browser, network, device, and behavior data
BotRefund accuracy99% confidence in flagged bot traffic via corroboration across 110+ signals
Refund‑ready reportsInclude click IDs, campaign details, timestamps, session recordings, and signal‑by‑signal reasoning
Client recovery rate83% of 2,500+ audited brands recover funds from Google and Meta

Limitations of this testing approach

  • Some advanced blockers only activate after behavioral analysis (mouse heatmaps, scroll depth, dwell time). A single page load may not trigger them.
  • Results can vary by IP reputation, time of day, and geographic location.
  • Sites using client‑side fingerprinting (e.g., FingerprintJS, Castle) may require full session replay to evaluate.
  • This guide covers detection, not bypass. Bypassing may violate terms of service or laws; consult legal counsel.

Frequently asked questions

How do I know if a block is Playwright‑specific vs. IP‑based?

Run the same script from a residential IP and a data‑center IP. If only the data‑center IP gets blocked, it's IP reputation. If both get blocked with identical fingerprints, it's browser automation detection.

Can I test blocking without writing code?

Yes. Use npx playwright open to launch a headed browser with the Playwright devtools recorder, then navigate manually and observe console errors or network failures.

Does headless mode always trigger blocks?

Not always. Some sites only challenge headless; others challenge any automation fingerprint regardless of headless state. Test both modes.

What's the difference between a CAPTCHA and a JavaScript challenge?

A CAPTCHA requires human interaction (image selection, checkbox). A JavaScript challenge runs silently in the background (proof‑of‑work, token generation) and redirects once solved.

How often should I re‑test a target site?

Anti‑bot vendors update fingerprints weekly. Re‑test after any Playwright version upgrade, when scrapers start failing, or on a monthly schedule for critical targets.

Can BotRefund help me understand why my Playwright traffic is blocked?

BotRefund's client‑side pixel captures 110+ behavioral, browser, hardware, and network signals per session. Their reports show exactly which signals triggered a bot classification, including the Playwright Init Scripts check, so you can see the specific evidence used.

Is it legal to test if a site blocks Playwright?

Testing your own access is generally acceptable. Scraping or bypassing blocks on third‑party sites may violate Terms of Service, CFAA, or GDPR. Always review the site's robots.txt, ToS, and applicable law before proceeding.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Learn more

Visit the website for more information.

Learn more