Skip to content

botonomus.cdp

The native Chrome DevTools Protocol driver. Timeouts are in seconds.

botonomus.cdp

Botonomus' native Chrome DevTools Protocol driver.

Stdlib only, no Node.js process, and Runtime.enable is never sent: detectors read that command's side effects as CDP automation. DOM work runs in a private isolated world.

Browser

Browser(connection: Connection, context: Context)

A connected browser.

Attributes:

Name Type Description
connection

The browser-level CDP connection.

context

The default context.

connect async classmethod

connect(websocket_url: str) -> Browser

Connect and attach to every existing (non-DevTools) page.

version async

version() -> dict[str, Any]

Browser.getVersion result (product, revision, user agent, protocol).

close async

close() -> None

Ask the browser to exit, then drop the connection.

disconnect async

disconnect() -> None

Drop the connection and leave the browser running.

Context

Context(connection: Connection)

The browser's default context: pages and cookies share the dedicated profile.

Attributes:

Name Type Description
pages list[Page]

Pages attached so far, in attachment order.

connection property

connection: Connection

The browser-level connection this context belongs to.

new_page async

new_page(url: str = 'about:blank') -> Page

Open a new tab at url and attach to it.

cookies async

cookies() -> list[dict[str, Any]]

All cookies in the profile, in CDP Network.Cookie form.

add_cookies async

add_cookies(cookies: list[dict[str, Any]]) -> None

Set cookies. A url key is expanded to domain, path and secure.

clear_cookies async

clear_cookies() -> None

Delete every cookie in the profile.

IsolatedContext

IsolatedContext(connection: Connection, context_id: str)

An in-memory browser context: its own cookies, storage and cache, no profile on disk.

Contexts share the browser process (and its GPU and network processes) but never a renderer, so they are isolated like separate browsers at a fraction of the memory. Chrome treats them as off-the-record.

Attributes:

Name Type Description
id

The CDP browserContextId.

pages list[Page]

Open pages of this context, in opening order (closed ones are dropped).

closed

Whether the context has been disposed.

connection property

connection: Connection

The browser-level connection this context belongs to.

create async classmethod

create(connection: Connection, *, proxy_server: str | None = None, proxy_bypass: str | None = None) -> IsolatedContext

Create a context, optionally with its own proxy.

Parameters:

Name Type Description Default
connection Connection

The browser-level connection.

required
proxy_server str | None

scheme://host:port without credentials; None uses the browser's proxy settings.

None
proxy_bypass str | None

Comma-separated hosts that bypass proxy_server.

None

new_page async

new_page(url: str = 'about:blank') -> Page

Open a tab in this context at url and attach to it.

cookies async

cookies() -> list[dict[str, Any]]

This context's cookies, in CDP Network.Cookie form.

add_cookies async

add_cookies(cookies: list[dict[str, Any]]) -> None

Set cookies. A url key is expanded to domain, path and secure.

clear_cookies async

clear_cookies() -> None

Delete every cookie in this context.

close async

close() -> None

Dispose of the context and every tab in it. Idempotent.

CDPSession

CDPSession(connection: Connection, session_id: str | None)

Commands and events scoped to one attached target (or the browser if None).

Attributes:

Name Type Description
connection

The shared connection.

session_id

Flattened session id, or None for browser-level commands.

send async

send(method: str, params: dict[str, Any] | None = None, timeout: float | None = 60.0) -> dict[str, Any]

Send a command on this session. See Connection.send.

on

on(event: str, handler: Handler) -> None

Register an event handler on this session.

off

off(event: str, handler: Handler) -> None

Remove an event handler from this session.

wait_for async

wait_for(event: str, predicate: Callable[[dict[str, Any]], bool] | None = None, timeout: float | None = 30.0) -> dict[str, Any]

Await a matching event on this session. See Connection.wait_for.

Connection

Connection(socket: WebSocket)

A browser-level CDP connection multiplexing every attached target session.

Commands are matched to responses by id; events are dispatched to handlers keyed by (session_id, method). Commands pending on a session fail with TargetClosedError as soon as that session detaches.

Attributes:

Name Type Description
closed

Set once the socket has closed.

connect async classmethod

connect(url: str) -> Connection

Open the websocket at url and start the reader task.

session

session(session_id: str | None = None) -> CDPSession

A view scoped to one target session, or the browser when None.

send async

send(method: str, params: dict[str, Any] | None = None, session_id: str | None = None, timeout: float | None = 60.0) -> dict[str, Any]

Send a command and await its result.

Raises:

Type Description
ProtocolError

If the browser returns an error.

TargetClosedError

If the connection or session closes first.

TimeoutError

If timeout seconds elapse.

on

on(event: str, handler: Handler, session_id: str | None = None) -> None

Register handler for event on session_id.

off

off(event: str, handler: Handler, session_id: str | None = None) -> None

Remove a previously registered handler; unknown handlers are ignored.

wait_for async

wait_for(event: str, predicate: Callable[[dict[str, Any]], bool] | None = None, session_id: str | None = None, timeout: float | None = 30.0) -> dict[str, Any]

Await the next event whose params satisfy predicate.

Raises:

Type Description
TimeoutError

If no matching event arrives within timeout seconds.

TargetClosedError

If the session detaches or the connection closes first.

close async

close() -> None

Close the socket, stop the reader and fail pending commands.

EvaluationError

Bases: BotonomusError

JavaScript threw during evaluation.

NavigationError

Bases: BotonomusError

The browser reported a navigation failure.

ProtocolError

ProtocolError(method: str, error: dict[str, object])

Bases: BotonomusError

The browser rejected a CDP command.

Attributes:

Name Type Description
method

The CDP method that failed.

code

The protocol error code, if the browser supplied one.

TargetClosedError

Bases: BotonomusError, ConnectionError

The connection or target session went away while a command was pending.

TimeoutError_

Bases: BotonomusError, TimeoutError

A page operation did not complete within its timeout.

Subclasses the built-in TimeoutError, so except TimeoutError works.

Keyboard

Keyboard(session: CDPSession)

A virtual US-layout keyboard dispatching trusted key events.

Parameters:

Name Type Description Default
session CDPSession

The page session to dispatch events on.

required

down async

down(key: str, *, modifiers: int = 0) -> None

Press a key without releasing it.

Printing keys send keyDown with text (which also produces the keypress/input); others send rawKeyDown.

Parameters:

Name Type Description Default
key str

Key name or single character, see key_definition.

required
modifiers int

CDP modifier bitmask (ALT, CONTROL, META, SHIFT) reported on the event.

0

Raises:

Type Description
ValueError

If the key is not on a US keyboard.

up async

up(key: str, *, modifiers: int = 0) -> None

Release a key.

Parameters:

Name Type Description Default
key str

Key name or single character, see key_definition.

required
modifiers int

CDP modifier bitmask reported on the event.

0

Raises:

Type Description
ValueError

If the key is not on a US keyboard.

press async

press(key: str, *, delay: float = 0.0) -> None

Press and release a key, holding Shift around it when the key needs it.

Parameters:

Name Type Description Default
key str

Key name or single character, see key_definition.

required
delay float

Seconds to hold the key down.

0.0

Raises:

Type Description
ValueError

If the key is not on a US keyboard.

type async

type(text: str, *, delay: float = 0.0) -> None

Type text character by character.

US-layout characters are typed as real key presses. Others (for example Georgian or emoji) are inserted as composed text, which is how an IME delivers them, rather than being forced onto a wrong physical key.

Parameters:

Name Type Description Default
text str

Text to type.

required
delay float

Seconds to wait after each character.

0.0

insert_text async

insert_text(text: str) -> None

Insert text as one composition, without key events.

Parameters:

Name Type Description Default
text str

Text to insert into the focused element.

required

Mouse

Mouse(session: CDPSession, *, clock: Callable[[], float] = monotonic)

A virtual mouse whose events match a real Windows mouse field for field.

The mouse remembers its position and held buttons. Every event carries the buttons bitmask; every event sent while a button is held carries force 0.5, so PointerEvent.pressure is 0.5 exactly as for hardware. Presses are counted like Windows does: a press of the same button within DOUBLE_CLICK_TIME seconds and inside a DOUBLE_CLICK_SIZE-pixel rectangle around the previous press continues the sequence (detail 2, 3, ...); anything else starts again at 1.

tangentialPressure, tiltX, tiltY and twist are left to Chromium's defaults (all 0), which are the values a mouse reports.

Parameters:

Name Type Description Default
session CDPSession

The page session to dispatch events on.

required
clock Callable[[], float]

Monotonic clock in seconds, used for multi-click timing.

monotonic

position property

position: tuple[float, float]

The current pointer position in CSS pixels relative to the viewport.

buttons property

buttons: int

Bitmask of held buttons (1 left, 2 right, 4 middle), as in MouseEvent.

move async

move(x: float, y: float, *, steps: int = 1) -> None

Move the pointer in a straight line, dispatching steps move events.

While a button is held the moves are drag moves: they carry the button, the buttons mask and force 0.5.

Parameters:

Name Type Description Default
x float

Destination x in CSS pixels.

required
y float

Destination y in CSS pixels.

required
steps int

Number of intermediate events; values below 1 count as 1.

1

down async

down(*, button: Button = 'left', click_count: int | None = None) -> None

Press a button at the current position.

Parameters:

Name Type Description Default
button Button

Button to press.

'left'
click_count int | None

Explicit MouseEvent.detail. None (default) derives it from the previous press using the double-click time and rectangle.

None

up async

up(*, button: Button = 'left', click_count: int | None = None) -> None

Release a button at the current position.

Parameters:

Name Type Description Default
button Button

Button to release.

'left'
click_count int | None

Explicit MouseEvent.detail. None (default) reuses the count of the matching press, which is what the OS reports.

None

click async

click(x: float, y: float, *, button: Button = 'left', delay: float = 0.0, click_count: int | None = None) -> None

Move to a point, then press and release a button there.

The move always comes first so the press never appears without a preceding mousemove (which would make movementX/Y implausible).

Parameters:

Name Type Description Default
x float

Target x in CSS pixels.

required
y float

Target y in CSS pixels.

required
button Button

Button to click.

'left'
delay float

Seconds to hold the button down.

0.0
click_count int | None

Explicit detail; None derives it automatically, so a second click soon after the first at the same spot is a double click.

None

dblclick async

dblclick(x: float, y: float, *, button: Button = 'left', delay: float = 0.0, interval: float = 0.08) -> None

Double-click a point: two clicks with detail 1 then 2.

The browser fires dblclick after the second release.

Parameters:

Name Type Description Default
x float

Target x in CSS pixels.

required
y float

Target y in CSS pixels.

required
button Button

Button to click.

'left'
delay float

Seconds to hold the button down on each click.

0.0
interval float

Seconds between the first release and the second press.

0.08

Raises:

Type Description
ValueError

If the clicks could not fall inside the double-click time.

wheel async

wheel(delta_x: float, delta_y: float) -> None

Scroll with the wheel at the current position.

Parameters:

Name Type Description Default
delta_x float

Horizontal scroll delta in CSS pixels.

required
delta_y float

Vertical scroll delta in CSS pixels.

required

Locator

Locator(page: Page, selector: str, index: int = 0)

A selector plus an index, evaluated in the page's isolated world.

Parameters:

Name Type Description Default
page Page

Owning page.

required
selector str

CSS, text=, xpath= or role= selector.

required
index int

Which match to use.

0

first property

first: Locator

The first match.

nth

nth(index: int) -> Locator

The index-th match of the same selector.

count async

count() -> int

Number of current matches.

is_visible async

is_visible() -> bool

Whether the element exists and has a visible, non-empty box.

is_enabled async

is_enabled() -> bool

Whether the element exists and is neither :disabled nor aria-disabled.

select_text async

select_text() -> None

Focus the element and select all of its text (input, textarea or editable).

wait_for async

wait_for(*, state: LocatorState = 'visible', timeout: float | None = None) -> None

Wait until the element reaches state.

Raises:

Type Description
ValueError

For an unknown state.

TimeoutError_

If the state is not reached in time.

scroll_into_view_if_needed async

scroll_into_view_if_needed() -> None

Centre the element if any part of it is outside the viewport.

bounding_box async

bounding_box() -> dict[str, float] | None

Viewport box {x, y, width, height}, or None if absent or empty.

click async

click(*, timeout: float | None = None, delay: float = 0.05) -> None

Click the element centre directly.

Use botonomus.Human (or humanize=True) for human-like paths.

Raises:

Type Description
EvaluationError

If the element has no box after scrolling.

focus async

focus() -> None

Focus the element and wait one rendered frame.

Without the frame wait the browser may not yet treat the element as the focused editable, and the first keystroke's text can be dropped.

fill async

fill(value: str) -> None

Replace the value as one composed input (fast, not keystroke by keystroke).

type async

type(text: str, *, delay: float = 0.0) -> None

Focus, then type text with real key events.

inner_text async

inner_text() -> str

The element's rendered text.

text_content async

text_content() -> str | None

The element's textContent, or None if absent.

get_attribute async

get_attribute(name: str) -> str | None

An attribute value, or None if the attribute is absent.

input_value async

input_value() -> str

The current value of an input, textarea or select.

all_inner_texts async

all_inner_texts() -> list[str]

Rendered text of every match.

Page

Page(connection: Connection, target_id: str, session: CDPSession)

One browser tab, attached through a flattened CDP session.

Timeouts are in seconds (Playwright uses milliseconds).

Attributes:

Name Type Description
target_id

CDP target identifier.

session

The page's CDP session.

mouse

Trusted mouse input.

keyboard

Trusted keyboard input.

viewport_size dict[str, int] | None

Always None: the native window size is never emulated.

default_timeout

Seconds used when an operation receives no timeout.

url

The main frame's current URL.

closed

Whether the target has been closed or detached.

main_frame_id property

main_frame_id: str

The CDP frame id of the main frame.

attach async classmethod

attach(connection: Connection, target_id: str) -> Page

Attach to an existing page target and initialize it.

goto async

goto(url: str, *, wait_until: WaitUntil = 'load', timeout: float | None = None) -> None

Navigate the main frame.

Parameters:

Name Type Description Default
url str

Destination URL.

required
wait_until WaitUntil

load, domcontentloaded or commit.

'load'
timeout float | None

Seconds; defaults to default_timeout.

None

Raises:

Type Description
NavigationError

If the browser reports a navigation error.

TimeoutError_

If the wanted lifecycle event does not arrive in time.

reload async

reload(*, timeout: float | None = None) -> None

Reload and wait for the main frame's load event.

set_content async

set_content(html: str) -> None

Replace the main frame's document with html.

title async

title() -> str

The document title.

content async

content() -> str

The serialized document HTML.

evaluate async

evaluate(expression: str, arg: Any = None, *, isolated_context: bool = True) -> Any

Evaluate an expression, or call a function source with arg.

Parameters:

Name Type Description Default
expression str

A JavaScript expression, or a function expression which is called with arg (JSON-serialized, never interpolated raw).

required
arg Any

Argument for a function expression.

None
isolated_context bool

True (default) runs in the private isolated world, which sees the DOM but not page globals and is invisible to the page. False runs in the page's main world, which is more observable.

True

Returns:

Type Description
Any

The JSON-serializable result.

Raises:

Type Description
EvaluationError

If the script throws.

locator

locator(selector: str) -> Locator

A lazy locator for selector (CSS, text=, xpath= or role=).

get_by_role

get_by_role(role: str, *, name: str | None = None, exact: bool = False) -> Locator

A locator by ARIA role and accessible name (implicit roles included).

get_by_text

get_by_text(text: str) -> Locator

A locator for elements whose own text contains text (case-insensitive).

wait_for_selector async

wait_for_selector(selector: str, *, state: LocatorState = 'visible', timeout: float | None = None) -> Locator

Wait until selector reaches state and return its locator.

wait_for_function async

wait_for_function(expression: str, *, timeout: float | None = None, interval: float = 0.1) -> Any

Poll expression in the isolated world until it is truthy; return it.

wait_for_load async

wait_for_load(state: WaitUntil = 'load', timeout: float | None = None) -> None

Wait until document.readyState reaches state.

screenshot async

screenshot(*, path: str | Path | None = None, full_page: bool = False, quality: int | None = None) -> bytes

Capture PNG (or JPEG when quality is set) and optionally write it.

Parameters:

Name Type Description Default
path str | Path | None

File to write, if any.

None
full_page bool

Capture the whole scrollable page instead of the viewport.

False
quality int | None

JPEG quality 0-100; PNG when None.

None

Returns:

Type Description
bytes

The encoded image.

bring_to_front async

bring_to_front() -> None

Activate this tab.

close async

close() -> None

Close the tab. Idempotent.