Skip to main content

Overview

Some websites detect and block automated browsers. BAP provides a --stealth flag that applies anti-detection techniques at the Playwright level.
Stealth mode is designed for legitimate automation use cases (testing your own sites, accessibility auditing, etc.). Respect website terms of service.

Three Tiers

BAP’s stealth mode applies techniques progressively:
TierWhat It Does
BasicRemoves navigator.webdriver flag, sets standard user agent
StandardBasic + overrides navigator.plugins, navigator.languages, WebGL renderer strings
FullStandard + patches chrome.runtime, permissions.query, canvas fingerprint noise

CLI Usage

# Enable stealth mode (applies standard tier)
bap goto https://example.com --stealth

# Combine with other flags
bap goto https://example.com --stealth --headless=false

Connecting to an Existing Browser

For maximum stealth, launch Chrome manually with specific flags and connect via CDP:
# Launch Chrome with stealth-friendly flags
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --disable-blink-features=AutomationControlled \
  --user-data-dir=/tmp/chrome-stealth

# Connect BAP to the running Chrome instance
bap goto https://example.com --connect=ws://localhost:9222
This approach uses a real Chrome profile instead of Playwright’s Chromium, which some detection systems distinguish.

TypeScript SDK

// Standard stealth via launch options
await client.launch({
  browser: "chromium",
  channel: "chrome", // Use real Chrome instead of Playwright's Chromium
  headless: false, // Headful mode is harder to detect
  args: ["--disable-blink-features=AutomationControlled"],
});

// Or connect to manually-launched Chrome
await client.launch({
  cdpUrl: "ws://localhost:9222",
});

Best Practices

Set channel: "chrome" or channel: "msedge" instead of using Playwright’s bundled Chromium. Detection systems often check for Chromium-specific build artifacts.
Headless browsers have subtle differences (viewport handling, GPU compositing) that some detection scripts flag. Use headless: false for critical flows.
Use common viewport sizes (1920x1080, 1440x900) and up-to-date user agent strings. BAP’s emulation API makes this simple:
await client.setViewport({ width: 1920, height: 1080 });
await client.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...");
Rapid-fire actions are a bot signal. Space out actions naturally, especially on sites with aggressive detection.
Use userDataDir in browser/launch to maintain cookies, cached data, and browser fingerprint across sessions. Fresh profiles are a detection signal.