Standard Playwright and Selenium launches expose automation signals. Production multi-account workflows attach to anti-detect profiles via CDP instead of spawning raw headless Chrome.
Why not default launch()?
navigator.webdriverflag- Inconsistent Canvas/WebGL between runs
- Headless user-agent and plugin gaps
- Shared storage across logical accounts
Playwright pattern (CDP)
// 1. Launch profile via API → get wsEndpoint // 2. Connect instead of launch const browser = await chromium.connectOverCDP(wsEndpoint); const context = browser.contexts()[0] ?? await browser.newContext(); const page = context.pages()[0] ?? await context.newPage();
Selenium pattern
options = ChromeOptions()
options.add_experimental_option("debuggerAddress", "127.0.0.1:PORT")
driver = webdriver.Chrome(options=options)
Managed profiles (Multilogin)
Multilogin exposes CDP endpoints per profile with fingerprint presets and proxy binding — reducing DIY spoofing. Setup walkthrough: Multilogin automation guide. Scripts: @Multilogin_Scripts_Bot.
Validation checklist
- Confirm
navigator.webdriver === false - Audit timezone vs proxy IP country
- Diff Canvas hash — two cold starts, same profile
- Load target site — watch for immediate challenge
Full audit: fingerprint checklist. Block triage: fix automation blocks.
Disclosure: MLX-MMO affiliated with Multilogin. SAAS50 · MIN50 — promo page.