Browser tools reference
Native tools come from @blopai/browser-harness and are exposed to
the Blop agent loop. You don’t call them directly in a Blop test. The agent
picks the right tool for your goal, but knowing the catalog helps you write
actionable goals. For a task-oriented overview, see
Browser tools.
Locator forms
Section titled “Locator forms”Most action tools accept a target. The agent picks the most specific form
available:
type Target = | { role: string; name?: string } | { label: string } | { text: string } | { selector: string } // CSS or XPath | string; // Auto-detectedNavigation
Section titled “Navigation”| Tool | Parameters |
|---|---|
browser_goto |
{ url: string } |
browser_get_url |
— |
browser_expect_url |
{ url: string; exact?: boolean } |
browser_wait_for_url |
{ url: string; exact?: boolean; timeoutMs?: number } |
browser_reload |
— |
browser_go_back |
— |
browser_go_forward |
— |
Page inspection
Section titled “Page inspection”| Tool | Parameters | Returns |
|---|---|---|
browser_snapshot |
— | URL, title, body excerpt (max 4000 chars) |
browser_screenshot |
{ name?: string } |
Saved file path |
browser_set_viewport |
{ width: number; height: number } |
New viewport dimensions |
browser_get_viewport |
— | Current { width, height } |
| Tool | Parameters |
|---|---|
browser_click |
{ target: Target } |
browser_double_click |
{ target: Target } |
browser_right_click |
{ target: Target } |
browser_hover |
{ target: Target } |
browser_drag_and_drop |
{ source: Target; target: Target } |
Keyboard
Section titled “Keyboard”| Tool | Parameters |
|---|---|
browser_type |
{ target: Target; text: string } |
browser_press |
{ key: string; target?: Target } |
browser_tab |
{ shift?: boolean } |
browser_focus |
{ target: Target } |
browser_blur |
— |
browser_clear |
{ target: Target } |
browser_press accepts standard Playwright key names: Enter, Tab,
Escape, ArrowDown, Control+A, etc.
| Tool | Parameters |
|---|---|
browser_check |
{ target: Target } |
browser_uncheck |
{ target: Target } |
browser_select_option |
{ target: Target; values: string | string[] } |
browser_upload_file |
{ target: Target; paths: string[] } |
Assertions
Section titled “Assertions”Every browser_expect_* tool auto-retries until the condition holds or
timeoutMs elapses (default 5000 ms), so transient UI states such as
in-flight network requests or animations don’t produce flaky failures. On
failure, the error includes the current URL, page title, and a trimmed ARIA
snapshot so the agent can self-correct.
| Tool | Purpose | Parameters |
|---|---|---|
browser_expect_text |
Visible text appears on the page, or inside target when given |
{ text: string; target?: Target; timeoutMs?: number } |
browser_wait_for_text |
Wait until text appears | { text: string; timeoutMs?: number } |
browser_wait_for_selector |
Wait until selector appears | { selector: string; timeoutMs?: number } |
browser_get_text |
Read text from element or whole body | { target?: Target } |
browser_expect_visible |
Element is visible | { target: Target; timeoutMs?: number } |
browser_expect_hidden |
Element is hidden or detached | { target: Target; timeoutMs?: number } |
browser_expect_value |
Input/textarea/select/editable has expected value | { target: Target; value: string; timeoutMs?: number } |
browser_expect_checked |
Checkbox or radio is in expected state | { target: Target; checked?: boolean; timeoutMs?: number } |
browser_expect_enabled |
Element is enabled | { target: Target; timeoutMs?: number } |
browser_expect_disabled |
Element is disabled | { target: Target; timeoutMs?: number } |
browser_expect_count |
Number of matching elements (equal, at_least, or at_most) |
{ target: Target; count: number; comparison?: string; timeoutMs?: number } |
browser_expect_attribute |
Element has an attribute, optionally with an exact or contained value | { target: Target; attribute: string; value?: string; contains?: boolean; timeoutMs?: number } |
browser_expect_focused |
Element has keyboard focus | { target: Target; timeoutMs?: number } |
browser_get_attribute |
Read an attribute from an element | { target: Target; attribute: string } |
Data extraction
Section titled “Data extraction”browser_extract reads structured data from every element a target matches
in one call. The agent uses it to ground claims about lists, rankings,
sorts, and counts in actual page data instead of reading rows one at a time.
| Tool | Parameters | Returns |
|---|---|---|
browser_extract |
{ target: Target; fields?: string[]; limit?: number } |
JSON array of per-element records plus the total match count |
Each entry in fields is "text" (default), "value", "html", or
"attribute:<name>" (for example "attribute:href"). limit defaults to
30 and is capped at 100; the result flags truncation.
Diagnostics
Section titled “Diagnostics”| Tool | Parameters | Returns |
|---|---|---|
browser_console_logs |
{ level?: "error" | "all"; limit?: number } |
Recent console messages, uncaught page errors, and failed network requests |
The default error level returns console errors, page errors, and failed
requests only. The agent checks this before failing a test as an app bug so
the failure reason can cite the underlying exception or failed request.
Each requestfailed entry is tagged with its scope relative to the page
origin:
[first-party]— the request target shares the page origin. A genuine app bug; cite it as evidence when failing the test.[third-party]— the request target is an external service (form providers likeweb3forms.com, payment/checkout providers likestripe.com/paypal.com, captcha, analytics, etc.). How the agent treats a[third-party]failure depends on the sandbox’s confirmed internet egress:- Egress confirmed (default for non-containerized runs and containerized
runs with internet access): the request reached the internet but the
provider refused it (CORS, auth, wrong key). The agent reports it as a
real configuration issue the site owner must investigate, and exercises the
real flow end-to-end using provider test modes (e.g. Stripe test card
4242 4242 4242 4242). - No egress (air-gapped or firewall-restricted sandbox): the failure is a test-environment limitation, not a site defect. The agent does not fail the site solely because a third-party endpoint is unreachable; it notes the caveat in the finish reason and keeps evaluating the rest of the flow.
- Egress confirmed (default for non-containerized runs and containerized
runs with internet access): the request reached the internet but the
provider refused it (CORS, auth, wrong key). The agent reports it as a
real configuration issue the site owner must investigate, and exercises the
real flow end-to-end using provider test modes (e.g. Stripe test card
When the log contains [third-party] failures, browser_console_logs appends a
note spelling out the test-environment caveat and returns
metadata.thirdPartyFailures with the count.
Sandbox internet egress
Section titled “Sandbox internet egress”The runner probes the shared Playwright container’s outbound internet access
once at startup (a HEAD request to https://1.1.1.1/ via docker exec) and
caches the result for the container’s lifetime. The outcome is forwarded to
the agent prompt as hasInternetEgress, which selects which of the two
third-party rules above the agent follows. Non-containerized (host-browser)
runs assume egress is whatever the host has and do not probe.
Batched execution
Section titled “Batched execution”browser_run_steps executes up to 20 tool steps in sequence within a single
agent turn. The agent uses it once a flow is predictable (fill, click,
assert) to cut model round-trips; each inner step is still recorded as its
own action, so reports and the live progress stream are unchanged. Execution
stops at the first failing step and the result names the step that failed.
| Tool | Parameters |
|---|---|
browser_run_steps |
{ steps: { tool: string; input?: object }[] } |
finish_test and nested browser_run_steps are not allowed inside a batch.
Lifecycle
Section titled “Lifecycle”| Tool | Parameters | Notes |
|---|---|---|
record_critical_point |
{ id: string; description: string; status: "pending" | "passed" | "failed"; evidence?: string; screenshot?: string } |
Tracks each explicit requirement; finish_test can’t pass while a point is pending or failed. |
finish_test |
{ status: "passed" | "failed"; reason: string } |
Required final call. A test that never reaches finish_test is recorded as error. |
Internals
Section titled “Internals”For tooling that needs to construct a tool bridge directly:
createBrowserTools(options)
Section titled “createBrowserTools(options)”function createBrowserTools(options: { page: Page; // Playwright Page testId: string; screenshotDir: string; actions: BlopAction[]; // Mutable; tools push here screenshots: string[]; // Mutable; tools push here finishState: FinishState; // Mutable; finish_test writes here browserLogs?: BlopBrowserLog[]; // Console/pageerror/requestfailed feed for browser_console_logs baseUrl?: string;}): Promise<NativeToolBridge[]>NativeToolBridge
Section titled “NativeToolBridge”type NativeToolBridge = { name: string; // e.g. "browser_click" description: string; parameters: Record<string, unknown>; // JSON Schema for tool parameters promptSnippet: string; execute: (input: Record<string, unknown>) => NativeToolResult;};FinishState
Section titled “FinishState”type FinishState = { status: BlopTestStatus | null; reason: string | null;};