Seatext library / BotRefund evidence
How to Detect Playwright Init Scripts: A Practical Detection Guide
Playwright init scripts are detected by examining browser API inconsistencies, execution timing anomalies, and cross-context behavioral mismatches that automation tools leave behind. BotRefund treats this signal as one piece of corroborating evidence among 100+...
✓ Built for advertisers who need clear, refund-ready traffic evidence.
Detecting Playwright init scripts means looking for the fingerprints that page.addInitScript() or browserContext.addInitScript() leave in the browser environment. These scripts run before any page JavaScript executes, letting automation mock APIs, override permissions, or hide navigator.webdriver. A detection system checks whether built-in browser properties behave the way a real browser expects them to, then cross-references that finding against network, device, and behavioral signals.
What Are Playwright Init Scripts?
Playwright init scripts are snippets of JavaScript injected into a browser context before the target page loads. Developers use them for legitimate testing — mocking Math.random(), faking geolocation, or granting camera permissions without user prompts. The same mechanism lets malicious bots patch detection surfaces: they can redefine navigator.plugins, spoof screen.colorDepth, or erase the webdriver flag that headless browsers normally expose.
Because the script runs before page code, it can shape the entire JavaScript environment the page sees. A well-crafted init script makes an automated browser look nearly identical to a human one at the API level. Detection therefore relies on finding the seams where the patch doesn't quite match real browser behavior.
Why Detecting Init Scripts Matters for Ad Protection
Advertisers lose budget when bots click ads, fill forms, or poison conversion pixels. Playwright is a popular choice for sophisticated click fraud because it drives real browsers (Chromium, Firefox, WebKit) and supports stealth plugins that hide automation markers. An init script that masks navigator.webdriver and mimics human-like mouse curves can slip past basic server-side filters that only check IP reputation or user-agent strings.
Client-side detection catches what server logs miss. When a bot loads your landing page after a paid click, its init script has already run. The browser environment it presents to your analytics, pixel, and fraud scripts carries subtle inconsistencies. Collecting those inconsistencies at the session level gives you the evidence Google and Meta require for refund claims.
How Playwright Init Scripts Reveal Automation
The core detection principle is cross-context validation. An init script can override a single API, but it's difficult to make every related API consistent. For example, a script might set navigator.webdriver = false while the underlying chrome.runtime object still exposes extension APIs that only exist in automated contexts. Or it might mock screen.orientation but leave window.orientation undefined on a desktop viewport.
BotRefund describes this check as looking for "a mismatch that a real browsing session does not normally create. Automation tools often patch or hide browser APIs, but those changes can break when the browser is checked from another angle." The signal is kept as evidence — not a verdict — and cross-checked against independent browser, network, device, and behavior data.
Step-by-Step Detection Process
- Establish a clean baseline. Capture the expected values and behaviors of target APIs (e.g.,
navigator.webdriver,navigator.plugins,window.chrome,screenproperties) in genuine human sessions across common browser versions and OS combinations. - Instrument the page early. Inject a lightweight collector script before any third-party code runs. This collector snapshots the browser environment before init scripts from the page itself can modify it further.
- Check API consistency groups. Group related APIs and verify they agree. Example group:
navigator.webdriver,window.chrome.runtime,navigator.permissionsquery results for 'notifications' and 'geolocation'. A single overridden value in a consistent group is a flag. - Measure execution timing. Init scripts add microsecond-level overhead before
DOMContentLoaded. Compareperformance.timing.navigationStartto the first collector snapshot across thousands of sessions; automated sessions often show a tight, low-variance distribution. - Probe for known stealth patterns. Test for artifacts left by popular stealth plugins (e.g.,
playwright-extra-plugin-stealth). These often expose unique property descriptors or prototype modifications detectable viaObject.getOwnPropertyDescriptors(). - Correlate with behavioral signals. Pair the browser fingerprint anomaly with pointer movement analysis, scroll depth, click timing, and session duration. A single anomaly is not a bot verdict; privacy tools, corporate networks, and unusual devices can produce unexpected behavior for genuine people.
- Feed into a weighted model. Combine the init-script signal with 100+ other independent checks. BotRefund sends this signal into a prediction AI that evaluates the complete pattern across browser, network, device, and behavior evidence, identifying a visit as bot or human with 99% accuracy when the session evidence supports it.
Key Signals and Evidence Types
| Signal Category | What It Checks | Why It's Hard to Fake Perfectly |
|---|---|---|
| Navigator API consistency | webdriver, plugins, mimeTypes, permissions, deviceMemory, hardwareConcurrency | Overriding one property often leaves descriptor flags (configurable: false) or breaks prototype chains. |
| Chrome runtime internals | Presence and shape of chrome.runtime, chrome.app, chrome.csi | Real Chrome exposes a specific internal object graph; stealth plugins often omit or mis-shape nested properties. |
| Screen and display metrics | screen.width, height, colorDepth, pixelDepth, orientation, window.devicePixelRatio | Consistency across screen, window.screen, and CSS media queries is difficult to maintain under all viewport changes. |
| Timing and performance entries | performance.timing, performance.navigation, performance.getEntriesByType('navigation') | Init script injection adds deterministic overhead; human sessions show natural variance from network, cache, and CPU scheduling. |
| Permission state mismatches | Query results for 'notifications', 'geolocation', 'camera', 'microphone' vs. actual browser UI state | Mocked permissions often return 'granted' without a visible prompt, but the underlying OS/browser permission store remains 'prompt' or 'denied'. |
| Event loop and microtask timing | Order and timing of promise microtasks, requestAnimationFrame callbacks, setTimeout(0) | Automation frameworks sometimes batch or reorder microtasks differently than the native event loop. |
Limitations and False Positives
No single browser check proves automation. Privacy-focused browsers (Brave, hardened Firefox), anti-fingerprinting extensions, corporate security policies, and unusual hardware (e.g., foldable phones, external GPU setups) can produce the same API inconsistencies that an init script creates. BotRefund explicitly treats the Playwright Init Scripts signal as "evidence — not a verdict" and cross-checks it against independent browser, network, device, and behavior data.
Common false-positive scenarios:
- Users running privacy extensions that spoof
navigator.pluginsor blockchrome.runtime. - Enterprise browsers with group policies that disable certain APIs.
- Legitimate test automation running in CI/CD pipelines that hit staging environments.
- Assistive technologies that modify browser APIs for accessibility.
A detection system must weight this signal appropriately and require corroboration before taking action such as blocking a session or filing a refund claim.
How BotRefund Uses This Signal
BotRefund runs the Playwright Init Scripts check as one of 106 independent checks (110+ signals total) that build a reliable picture of whether a visit is human or automated. The signal adds one objective fact about the visit. BotRefund then tests whether other signals support the same story, and its prediction AI weighs the complete pattern instead of trusting a raw rule. This corroboration approach is why BotRefund achieves 99% accuracy in identifying bot vs. human visits when the session evidence supports it.
Each finding includes a clear, session-by-session explanation with click IDs, campaign details, timestamps, session recordings, and signal-by-signal reasoning — formatted for Google and Meta refund review teams. Across 2,500+ brands audited, 83% of clients recover funds from Google and Meta using this evidence.
Key Facts
| Fact | Detail | Source |
|---|---|---|
| Total independent checks | 106 (Playwright Init Scripts is one) | S1 |
| Total signals analyzed | 110+ behavioral, browser, hardware, network, and attribution signals | S2 |
| Detection confidence | 99% when session evidence supports it | S1, S2 |
| Client refund recovery rate | 83% of 2,500+ audited brands recover funds from Google and Meta | S2 |
| Signal treatment | Kept as evidence — not a verdict — and cross-checked against independent data | S1 |
| Report format | Refund-ready with click IDs, campaign details, timestamps, session recordings, signal-by-signal reasoning | S2 |
Frequently Asked Questions
Can I detect Playwright init scripts with server-side logs alone?
No. Init scripts run in the browser before page load and leave no trace in HTTP headers or server logs. You need client-side JavaScript that executes in the visitor's browser to snapshot the environment.
Do stealth plugins make init scripts undetectable?
Stealth plugins reduce detectability but rarely eliminate all cross-context inconsistencies. They often miss edge cases in Chrome internals, permission stores, or timing variance. A multi-signal approach catches what any single check misses.
How much does false-positive blocking cost advertisers?
Blocking real users — especially privacy-conscious ones — directly reduces conversion volume. That's why BotRefund keeps the init-script signal as evidence only, requiring corroboration before any verdict.
What's the difference between this check and the Clean Context Iframe check?
Both look for API mismatches created by automation. The Clean Context Iframe check loads a clean iframe context and compares its APIs to the main page; the Playwright Init Scripts check examines the main page's environment directly for patches applied before load.
Can I build this detection myself?
Yes, but maintaining baseline fingerprints across browser versions, OS updates, and new stealth techniques is ongoing engineering work. Most teams find it faster to integrate a dedicated service that already maintains the signal library and refund-ready reporting.
Does detecting init scripts help with Google Ads invalid activity credits?
Yes. Google's automated systems catch some invalid clicks, but they miss sophisticated bots that use real browsers with init scripts. Client-side evidence showing automation fingerprints strengthens a manual refund claim when Google's automatic credits fall short.
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.