Seatext library / BotRefund evidence
Detecting Playwright vs Puppeteer: Key Differences in Automation Detection
Playwright and Puppeteer share a common automation foundation, but Playwright's multi-browser architecture and built-in evasion features make it harder to detect reliably. Puppeteer's Chrome-only focus and simpler API surface leave more consistent fingerprints. Effective...
✓ Built for advertisers who need clear, refund-ready traffic evidence.
Quick verdict
Playwright is harder to detect than Puppeteer because it patches browser APIs across Chromium, Firefox, and WebKit, and it ships with stealth plugins that mask automation fingerprints. Puppeteer runs only on Chromium and exposes more consistent tells like the navigator.webdriver flag and Chrome DevTools Protocol quirks. For both, no single signal is reliable; accurate detection comes from correlating independent browser, network, device, and behavior evidence.
| Criterion | Playwright detection | Puppeteer detection | Takeaway |
|---|---|---|---|
| Browser coverage | Chromium, Firefox, WebKit — each engine has different API surfaces and fingerprint baselines | Chromium only — single engine means one fingerprint baseline to monitor | Playwright requires engine-specific checks; Puppeteer lets you focus on Chromium tells |
| Built-in evasion | Stealth plugins, init scripts, and context isolation patch navigator, window, and permissions before page load | Community stealth plugins exist but are not built in; default launches leak navigator.webdriver=true | Playwright evades more aggressively out of the box; Puppeteer defaults are easier to flag |
| Execution context | Init scripts run in a separate isolated world, modifying APIs before the page context exists | Scripts run in the main world unless explicitly isolated; patches apply after page load starts | Playwright's early patching hides traces better; Puppeteer leaves a larger window for detection |
| Network fingerprint | Can route each browser engine through different proxy stacks; TLS fingerprints vary by engine | Single Chrome TLS fingerprint; easier to correlate with known automation JA3 signatures | Playwright's multi-engine support creates more network variability to analyze |
| Behavioral simulation | Native APIs for human-like mouse paths, typing delays, and scroll physics | Requires manual implementation or third-party libraries for realistic behavior | Playwright bots can mimic humans more convincingly; behavioral analysis must be stricter |
| Detection reliability | Higher false-negative risk if relying on single browser tells; cross-engine correlation essential | Higher true-positive rate on default configs; still fails against hardened stealth setups | Both demand multi-signal correlation; Playwright raises the bar for evidence quality |
Choose Playwright detection if…
- You see traffic from multiple browser engines (Chrome, Firefox, Safari) with similar behavioral patterns
- Attackers use Playwright's stealth plugins or custom init scripts to patch APIs before page load
- You need to correlate signals across different rendering engines to confirm automation
Choose Puppeteer detection if…
- Your suspicious traffic is exclusively Chromium-based with consistent Chrome DevTools Protocol artifacts
- You want a simpler fingerprint baseline — one engine, one TLS profile, one set of API quirks
- You are dealing with less sophisticated scripts that run default Puppeteer launches
Conditional recommendation
Start with a detection stack that treats Playwright and Puppeteer as points on the same automation spectrum. Deploy engine-agnostic checks — behavioral timing, pointer dynamics, scroll physics, and network consistency — first. Then layer engine-specific signals: Playwright init script mismatches, Clean Context Iframe anomalies, and Firefox/WebKit API deviations for Playwright; navigator.webdriver, CDP endpoint exposure, and Chrome-specific permission quirks for Puppeteer. Feed every signal into a scoring model that requires corroboration across categories before flagging a session. BotRefund's approach of 106+ independent checks cross-checked by an AI predictor reflects this principle: no single tell decides the verdict.
How automation detection works for both frameworks
Detection does not target a framework by name. It targets the side effects of browser automation: patched APIs, missing or inconsistent browser features, timing anomalies, and behavioral patterns that deviate from human distributions. Both Playwright and Puppeteer drive real browser binaries, so the rendering pipeline, GPU stack, and network stack are genuine. The differences appear in the JavaScript execution environment and the control channel between the driver and the browser.
Playwright uses a WebSocket-based protocol that wraps CDP for Chromium and implements custom protocols for Firefox and WebKit. Puppeteer speaks CDP directly. This means Playwright can normalize some CDP quirks across engines, but it also introduces its own protocol fingerprints. Puppeteer's direct CDP usage leaks specific command sequences and event timings that a trained detector can recognize.
Key differences in evasion capabilities
Playwright init scripts
Playwright's init scripts run in an isolated world before the page's main world loads. They can overwrite navigator.webdriver, patch window.chrome, modify permissions, and spoof screen properties before any page script executes. BotRefund's Playwright Init Scripts check looks for mismatches between what the isolated world reports and what the main world reveals when probed from a different angle — for example, checking a property via an iframe with a clean context. As the source notes, "Automation tools often patch or hide browser APIs, but those changes can break when the browser is checked from another angle."
Puppeteer's default exposure
Vanilla Puppeteer launches with navigator.webdriver=true and exposes the DevTools Protocol port. It does not patch APIs unless the user adds stealth plugins. This makes default Puppeteer trivial to detect with a single check, but hardened Puppeteer (with stealth plugins, custom CDP command filtering, and behavioral simulation) approaches Playwright's evasion level.
Clean Context Iframe technique
Both frameworks can be probed using a clean context iframe — an iframe loaded with a sandbox that strips the parent's modifications. BotRefund's Clean Context Iframe check compares API behavior inside the clean iframe against the parent page. If the parent shows patched APIs but the clean iframe shows standard behavior, the mismatch signals automation. This technique works against both frameworks because neither can fully virtualize the browser's internal implementation across all contexts.
Detection signals that apply to both
- Behavioral timing: Click-to-action intervals, scroll velocity curves, mouse micro-tremor, and typing cadence. Humans show log-normal distributions; automation shows uniform or Gaussian patterns.
- Pointer dynamics: Linear vs. curved paths, grid-aligned snapping, superhuman speed (<1ms), and absence of sub-pixel jitter.
- Session structure: Navigation flow, referrer consistency, cookie jar behavior, and cache warming patterns.
- Network context: TLS fingerprint (JA3/JA3S), HTTP/2 frame ordering, header ordering, and connection reuse patterns.
- Hardware signals: WebGL renderer strings, canvas fingerprint, audio context latency, battery API (if available), and sensor consistency.
These signals are framework-agnostic. A sophisticated Playwright bot and a sophisticated Puppeteer bot both must solve the same simulation problems. The framework only changes the default starting point and the tooling available to the bot author.
Limitations and when detection fails
- Single-signal reliance: Any check used in isolation produces false positives. Privacy tools (Tor, Brave, hardened Firefox), corporate proxies, VPNs, and unusual hardware (e-readers, kiosks, embedded browsers) trigger the same anomalies as automation.
- Stealth plugin parity: The Puppeteer stealth ecosystem (puppeteer-extra-plugin-stealth, etc.) has closed much of the default gap. A well-configured Puppeteer script can pass the same checks that catch default Playwright.
- Human-in-the-loop farms: Click farms use real browsers with real humans driving them. No browser-level check distinguishes a low-wage worker from a genuine user; only behavioral economics (conversion rates, session depth, repeat patterns) can.
- Browser updates: Chrome, Firefox, and Safari change APIs, permissions, and rendering behavior every release. Detection signatures decay and must be continuously retrained.
Practical scenarios
Scenario A: E-commerce checkout abuse
Attackers use Playwright with Firefox to bypass Chromium-focused defenses. They rotate residential proxies and use stealth plugins. Detection relies on cross-engine behavioral correlation: the same mouse dynamics, timing patterns, and navigation logic appear across Chrome and Firefox sessions from different IPs. The Playwright Init Scripts check catches API mismatches in Firefox that the Chromium checks miss.
Scenario B: Ad click fraud on Google Ads
Bots use Puppeteer with headless Chrome and a stealth plugin. They mimic human scroll and dwell time but lack micro-tremor. Pointer behavior checks flag the linear paths. Network checks reveal data-center TLS fingerprints despite residential proxies. The Clean Context Iframe check exposes patched navigator.permissions in the parent frame.
Scenario C: Credential stuffing
High-volume login attempts use Playwright's parallel browser contexts. Session behavior checks detect unnatural concurrency: dozens of logins from the same device fingerprint within seconds. Hardware signal consistency (identical canvas, WebGL, audio across sessions) reveals the shared browser binary.
Key facts from BotRefund's detection methodology
| Fact | Detail |
|---|---|
| Signal count | 106+ independent checks across browser, network, device, and behavior |
| Playwright Init Scripts check | Detects API mismatches caused by isolated-world patching before page load |
| Clean Context Iframe check | Compares parent frame APIs against a sandboxed iframe to reveal hidden patches |
| Cross-check principle | Every signal is evidence, not a verdict; AI predictor weighs the complete pattern |
| Reported accuracy | 99% bot/human classification when session evidence supports it |
| Refund success rate | 83% of clients recover funds from Google and Meta using BotRefund reports |
| Report format | Refund-ready with click IDs, campaign details, timestamps, session recordings, signal-by-signal reasoning |
Terminology
- Init script
- Playwright code that runs in an isolated world before the page's main JavaScript context, used to patch or hide automation fingerprints.
- Clean context iframe
- An iframe loaded with sandbox attributes that prevent the parent page's modifications from applying, providing a baseline of native browser API behavior.
- CDP (Chrome DevTools Protocol)
- The debugging protocol Puppeteer uses to control Chromium; exposes commands for DOM, network, runtime, and more.
- JA3/JA3S
- TLS fingerprint standards that hash the Client Hello and Server Hello parameters; used to identify browser and automation library implementations.
- Cross-check
- Verifying that multiple independent signals support the same conclusion before classifying a session.
FAQ
Can I detect Playwright just by checking navigator.webdriver?
No. Playwright's init scripts routinely set navigator.webdriver=false and patch the property descriptor. Relying on this single flag misses hardened Playwright and flags privacy-hardened legitimate browsers.
Does Puppeteer's CDP usage make it easier to detect than Playwright?
Default Puppeteer, yes — CDP command sequences and event timings are distinctive. Hardened Puppeteer with CDP command filtering and custom protocol wrappers narrows the gap significantly.
What is the most reliable single check for either framework?
There isn't one. The Clean Context Iframe check is strong because it exploits a browser architecture constraint (iframe sandboxing) that neither framework can fully virtualize, but it still produces false positives on some corporate and privacy configurations. It must be cross-checked.
How often do detection signatures need updating?
Every browser release (roughly 4-6 weeks for Chrome/Firefox, annually for Safari) can change API surfaces, permission models, and rendering behavior. Automation frameworks update within days. A production detection system needs continuous signature refresh and model retraining.
Can behavioral analysis alone distinguish a sophisticated bot from a human?
Not reliably. State-of-the-art bots replay recorded human sessions or use generative models for mouse paths, scroll, and typing. Behavioral analysis raises the cost for bot authors but cannot be the sole gate.
What should I do if my detection flags a high-value user as a bot?
Treat the flag as a review trigger, not a block. Present a low-friction challenge (e.g., a simple interaction test) and log the outcome. Use the result to retrain your scoring model. BotRefund's approach keeps signals as evidence and lets the AI predictor weigh the full pattern, reducing false blocks.
Is server-side log analysis enough to catch Playwright and Puppeteer bots?
No. Both frameworks drive real browsers with real TLS stacks, real cookies, and real rendering. Server logs see legitimate-looking requests. Client-side execution context checks (API consistency, behavioral timing, hardware signals) are necessary to expose the automation layer.
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.