CDP Extras
Introduction
In Vision, the standard Chrome DevTools Protocol is extended with its own human-like input and virtual mouse commands. They help make automation less detectable for anti-fraud systems: instead of instant, "robotic" actions, text entry and cursor movement look natural — as if performed by a real user.
Two extensions are available:
- Human Type — human-like text entry with natural delays between keystrokes.
- VirtualMouse — a virtual cursor with smooth, human-like movement and clicks.
These commands are Vision extensions and are not available in stock Chromium or Chrome.
CDP Extras are available starting from the Base plan and higher.
Connecting
CDP Extras commands are sent within a regular CDP session to an already running profile — through any automation library that supports the Chrome DevTools Protocol (Playwright, Puppeteer, etc.).
You can connect only to profiles launched via the API. The host and port for the connection are returned in the response to the profile launch request.
Connecting to the browser
How to connect to a running profile via Playwright, Puppeteer and other libraries
Human Type
The Input.typeText command types text into the currently focused editable element, imitating manual input: characters appear one by one with a random delay between keystrokes.
Parameters
Prop
Type
Example
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:19397');
const context = browser.contexts()[0];
const page = await context.newPage();
const client = await context.newCDPSession(page);
await page.goto('https://example.com');
// Text is typed into the currently focused editable element
await client.send('Input.typeText', {
text: 'Typed with Human Type',
minDelay: 55,
maxDelay: 130,
});
await browser.close();
})();import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp('http://127.0.0.1:19397')
context = browser.contexts[0]
page = await context.new_page()
client = await context.new_cdp_session(page)
await page.goto('https://example.com')
# Text is typed into the currently focused editable element
await client.send('Input.typeText', {
'text': 'Typed with Human Type',
'minDelay': 55,
'maxDelay': 130,
})
await browser.close()
asyncio.get_event_loop().run_until_complete(main())VirtualMouse
VirtualMouse creates a virtual cursor for the page and moves it toward the target along a smoothed trajectory with small deviations — the way a real user's hand would move — and then performs a click.
Available commands:
VirtualMouse.create— creates the per-page virtual cursor.VirtualMouse.configure— changes movement settings for later commands.VirtualMouse.move— moves the cursor tox,y(CSS pixels relative to the viewport).VirtualMouse.click— moves the cursor (if coordinates are provided) and performs a left click. Without coordinates, the current cursor position is used.VirtualMouse.destroy— removes the virtual cursor.
Movement parameters
Passed to VirtualMouse.create and VirtualMouse.configure.
Prop
Type
Click parameters
Passed to VirtualMouse.click.
Prop
Type
Example
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:19397');
const context = browser.contexts()[0];
const page = await context.newPage();
const client = await context.newCDPSession(page);
await page.goto('https://example.com');
// Create the virtual cursor
await client.send('VirtualMouse.create', {
speed: 1.2,
x: 100,
y: 100,
noiseScale: 1.0,
includeReaction: true,
seed: 12345,
});
try {
await client.send('VirtualMouse.move', { x: 500, y: 240 });
await client.send('VirtualMouse.click', { duration: 40 });
} finally {
// Remove the cursor in any case
await client.send('VirtualMouse.destroy');
}
await browser.close();
})();import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp('http://127.0.0.1:19397')
context = browser.contexts[0]
page = await context.new_page()
client = await context.new_cdp_session(page)
await page.goto('https://example.com')
# Create the virtual cursor
await client.send('VirtualMouse.create', {
'speed': 1.2,
'x': 100,
'y': 100,
'noiseScale': 1.0,
'includeReaction': True,
'seed': 12345,
})
try:
await client.send('VirtualMouse.move', {'x': 500, 'y': 240})
await client.send('VirtualMouse.click', {'duration': 40})
finally:
# Remove the cursor in any case
await client.send('VirtualMouse.destroy')
await browser.close()
asyncio.get_event_loop().run_until_complete(main())Ready-made examples
Full working examples for JavaScript and Python are collected in a separate repository.
browser-vision/cdp-extras
Examples of using Human Type and VirtualMouse from your own automation code