Stealth Techniques for Browser Automation
Browser automation stealth is not invisibility. Learn what Playwright emulation can control, how detection spans multiple signal layers, and how to run reproducible tests you’re authorized to perform.

Browser automation stealth techniques cannot guarantee that a script will be invisible to a website. Changing a user agent or browser property may affect one signal, but detection can also use HTTP headers, browser environment details, network behavior, and consistency across attributes and time. The safe, useful goal for Playwright is usually controlled emulation for compatibility testing or authorized measurement—not defeating a third-party site’s anti-bot controls.
This guide explains the signal layers, what current studies found in their specific test setups, how to configure reproducible Playwright tests, and how to record blocks as outcomes. It includes runnable Playwright examples and an API option for pages you are authorized to capture.
1. What “stealth” can and cannot mean
In legitimate testing, browser emulation means setting known browser or device characteristics—such as viewport, locale, timezone, touch support, and color scheme—to check how a site behaves under those conditions. Playwright supports these settings and predefined device configurations. They are useful controlled test profiles; they do not prove that every detail matches a physical device or that a site will treat automation as a human visitor.
“Stealth” is often used more broadly to mean hiding automation from a site’s defenses. That is not a reliable property you can switch on. A 2026 study of six LLM-based web agents on protected honeysites found that its tested agents were distinguishable across network, HTTP, and browser layers. In that experiment, some stealth techniques increased detectability. Those findings apply to the study’s agents and honeysites, not every website or automation tool. Read the study.
For a site you own or have permission to assess, define the actual question first: Does a checkout layout fit a small viewport? Does a locale change date formatting? Does a consent flow work? Record the browser, operating system, configuration, test data, and response. If a site returns a challenge or block, preserve it as a measurement result rather than trying to conceal the test.
2. A layered model of browser detection
There is no universal public taxonomy for proprietary anti-bot systems. The following model synthesizes the research reviewed here and helps explain why changing one browser setting is not a guarantee.

| Signal layer | What may be observed | What to take away |
|---|---|---|
| HTTP and headers | Request headers and how they relate to the claimed browser | A header change can affect a test result, but it does not determine the whole outcome. |
| Browser environment | JavaScript-visible values and capabilities, such as screen, locale, or touch characteristics | Emulation can set documented environment values for testing. It does not promise that all detectable properties are emulated. |
| Network and cross-layer behavior | Signals evaluated across network activity, HTTP requests, and browser behavior | Consistency across layers matters; a page may assess more than the browser’s JavaScript environment. |
| Consistency over attributes and time | Whether a collection of fingerprint attributes agrees and remains coherent | Arbitrarily changing fields may create mismatches rather than a credible test configuration. |
A 2026 study measured four browser configurations across 10,000 websites, for 40,000 page visits. It reported a 15% soft-block rate for Chromium headless versus 7% for the other tested configurations. The figures describe that sample and its definitions; they are not expected rates for a particular site. The study attributed 82% of observed blocks to bot detection, with 59% vendor-confirmed and 23% inferred from condition-dependent blocking. See the study and its methods.
In a separate header-spoofing experiment in that study, 75% of Chromium-headless-only blocks were attributed to header-level signals alone. This is specific to that experiment. It does not mean headers explain 75% of blocks generally. The same paper observed JavaScript environment probing and cautioned that blocking can cause sample loss and distort web measurements.
A 2024 study sent half a million requests from 20 bot services to a honeysite protected by two anti-bot services. It reported average evasion rates of 52.93% against DataDome and 44.56% against BotD, and examined inconsistent fingerprint attributes as a detection signal. These figures are not a typical success rate for stealth tools; they belong to that study’s setup. Read the paper.
3. Use Playwright emulation for controlled tests
Playwright documents emulation for user agent, screen and viewport, touch, geolocation, locale, timezone, permissions, and color scheme. Pick only the settings that correspond to a test requirement. Start from an official device profile when useful, and record the chosen profile and browser version. A predefined device configuration assumes a platform; treat it as a reproducible configuration, not a perfect clone of every device bearing that name. Playwright emulation documentation.

Install and run a minimal test
The following example uses Node.js, Playwright Test, and a page you control. Install dependencies and the browser once, then save the test as tests/emulation.spec.js.
npm init -y
npm install --save-dev @playwright/test
npx playwright install chromium
const { test, expect } = require('@playwright/test');
test('renders the account page at a mobile viewport', async ({ browser }) => {
const context = await browser.newContext({
viewport: { width: 390, height: 844 },
screen: { width: 390, height: 844 },
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
locale: 'en-US',
timezoneId: 'America/Los_Angeles',
colorScheme: 'light'
});
const page = await context.newPage();
await page.goto('https://your-staging.example/account', {
waitUntil: 'domcontentloaded',
timeout: 30000
});
await expect(page.getByRole('heading', { name: 'Account' })).toBeVisible();
await page.screenshot({ path: 'account-mobile.png', fullPage: true });
await context.close();
});
Replace the example host and expected heading with your staging page and its real content. Run it with npx playwright test. The explicit context keeps the test configuration visible in code and limits accidental state sharing.
Use a predefined device as a named test profile
Playwright provides device descriptors that can be applied to a browser context. This is convenient when a test is about a supported device profile. Pin Playwright and browser versions in the project’s dependency and CI setup, and include those versions in test artifacts so another run can use the same environment.
const { chromium, devices } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({ ...devices['iPhone 13'] });
const page = await context.newPage();
await page.goto('https://your-staging.example/', {
waitUntil: 'domcontentloaded',
timeout: 30000
});
await page.screenshot({ path: 'device-profile.png', fullPage: true });
await browser.close();
})();
Check the Playwright device list in the version installed by your project; descriptor availability can evolve. For visual comparison, keep the operating system and browser versions stable. Playwright recommends isolated tests, controlled data, and stable OS and browser versions for visual regression. Playwright Best Practices.
4. Build repeatable, authorized measurements
- Write the test question. State the page, behavior, device or locale condition, and expected result. Avoid “make it look human” as a test objective.
- Use a permitted environment. Prefer staging, a test account, a documented API, or a written authorization for external measurement.
- Control state and data. Use isolated browser contexts, stable fixtures, and known cookies or storage state. Reset state between cases where carryover would alter results.
- Pin the runtime. Record Playwright, browser, and operating system versions. Keep them fixed for visual regression or comparisons across runs.
- Capture evidence. Save screenshots, relevant console and navigation errors, timestamps, the effective test configuration, and the response category.
- Report blocks as results. A challenge, redirect, blank page, or changed response may be evidence about the measurement environment. Do not treat it as a cue to escalate evasion.
These practices make failures easier to reproduce and help avoid mistaking environment drift for a product regression. They also make a negative result useful: a test can honestly say that a route was blocked under a named configuration.
5. Self-managed Playwright or a hosted browser?
| Approach | Good fit | Compare | Evidence limit |
|---|---|---|---|
| Self-managed Playwright | QA, compatibility work, and authorized measurement where control matters | Browser and OS pinning, isolation, debugging, data control, deployment effort | Official emulation support is a testing capability, not a promise of anti-bot acceptance. |
| Managed browser automation | Teams that prefer a hosted browser API and provider-managed infrastructure | Browser binaries, session behavior, deployment needs, privacy, pricing, support, independent evaluation | Provider feature pages describe vendor claims; confirm capabilities and terms for your use case. |
Browserless documents BrowserQL stealth and fingerprinting features. That is a vendor description, not independent evidence that a service is undetectable or succeeds on a given target. The research reviewed here did not establish a comparative success rate or verify affiliate terms. Browserless BrowserQL documentation.
6. Troubleshooting
| Symptom | Likely cause | Practical fix |
|---|---|---|
| Test passes locally but fails in CI | Different browser, OS, fonts, time, or test data | Pin browser and runtime versions, control fixtures, and log the CI environment. |
| Page is blank or incomplete in a screenshot | Navigation ended before the relevant content rendered, or the app depends on data that was not ready | Wait for a specific visible selector or app-ready condition. Prefer an explicit condition to an arbitrary long sleep. |
| Expected mobile layout does not appear | Only viewport dimensions were changed, while the test also depends on touch or mobile settings | Set the relevant documented context values together, then inspect the actual layout and record the profile. |
| Locale-dependent text differs | Locale or timezone is uncontrolled, or the app uses account-level preferences | Set Playwright locale and timezone; control the test account’s own preferences as well. |
| Website returns a challenge or block | The site’s controls classified the request under its own policy and signals | For an owned site, use staging or an allowlisted test route. For authorized measurement, record the outcome and contact the site owner where needed. |
| Flaky visual diffs | Dynamic content, animations, timestamps, or environment drift | Use controlled data, stable versions, and app-level fixtures. Disable or stabilize known dynamic content in the test environment. |
7. Performance, reliability, and cost
Self-hosted browser automation gives you direct control over the browser process and test data, but your team owns browser installation, concurrency, resource limits, cleanup, and failure handling. Reusing a browser process while creating a fresh context per independent test often reduces setup overhead while keeping page state separate. Close pages, contexts, and browsers in cleanup paths, especially in long-running workers.
Keep waits specific. Waiting for a page’s full network quiet can be unreliable on applications with polling or long-lived connections; a clear selector or app readiness signal is often more dependable. Set navigation and test timeouts based on the application’s expected behavior, and retain error context rather than retrying every failure blindly. Retries can help distinguish transient infrastructure faults from consistent product failures, but report the original failure and retry count.
For self-managed Playwright, direct costs include compute, storage, and engineering time; the research provides no comparable cost benchmark. A hosted service shifts some infrastructure work to a provider, so compare its current plan limits, retention and privacy terms, and supported regions before adoption. Do not infer commercial effectiveness from a feature label.
Or skip the browser setup
If the task is to capture a page you are allowed to access, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. See the API documentation for parameters.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-site.example -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://your-site.example"},
timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
f.write(r.content)
Node.js:
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://your-site.example'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletters popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server gives AI agents tools for taking screenshots, getting page information, and capturing PDFs. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. These are capture features, not a promise to defeat a site’s access controls.
Sign up for 1,000 free screenshots a month, with no card.
FAQ
Can you run Playwright without being detected?
There is no general guarantee. Detection methods and thresholds vary by site, and research has observed signals at multiple layers. Use Playwright emulation for tests you own or are authorized to run.
Does a device preset make a test equivalent to a physical phone?
It supplies a documented set of emulation values. It is useful for controlled checks, but should not be described as a perfect physical-device replica.
Should I install a stealth plugin?
For compatibility testing, begin with documented emulation and a reproducible setup. The evidence here does not establish that a stealth package makes automation reliably undetectable.
How should I report an anti-bot block?
Include the target environment, date, browser and OS versions, configuration, and observed response. Make clear whether the block was directly confirmed or inferred.
Sources
- Playwright: Best Practices
- Playwright: Emulation
- Detecting Bot Detection: Prevalence, Techniques, and Implications for Web Measurement Research (2026)
- On the Internet, Nobody Knows You’re an LLM Bot: Unmasking Web Agents with Multi-Layer Fingerprinting (2026)
- FP-Inconsistent: Detecting Evasive Bots using Browser Fingerprint Inconsistencies (2024)
- Browserless: BrowserQL stealth documentation


