Documentation
¶
Overview ¶
Package browserscale is the official Go SDK for browserscale — real Chromium browsers in the cloud, driven over gRPC.
Rent an isolated browser session, navigate, interact with the page using human-like input, intercept network traffic, manage cookies, and stream live video — all from idiomatic, context-first Go.
A minimal end-to-end program:
ctx := context.Background()
cfg := browserscale.NewBrowserConfig("YOUR_API_KEY", 300, "", 0, "", "")
browser, err := browserscale.RentBrowser(ctx, cfg)
if err != nil {
log.Fatal(err)
}
defer browser.Close()
if _, err := browser.Navigate(ctx, "https://example.com", 0); err != nil {
log.Fatal(err)
}
if _, err := browser.Wait(ctx, browserscale.CSS("h1")); err != nil {
log.Fatal(err)
}
res, err := browser.Evaluate(ctx, "document.title")
if err != nil {
log.Fatal(err)
}
fmt.Println("title:", res.Value)
Full documentation, guides and the complete API reference live at https://browserscale.cloud/docs.
Index ¶
- Constants
- Variables
- func SetApiEndpoint(endpoint string)
- func StopBrowser(ctx context.Context, apiKey string, sessionId string) error
- type BrowserConfig
- func (c *BrowserConfig) UnstableWithFakeGpu(renderer string, vendor string, extensions []string) *BrowserConfig
- func (c *BrowserConfig) WithCountryCode(countryCode string) *BrowserConfig
- func (c *BrowserConfig) WithFingerprint(fingerprint string) *BrowserConfig
- func (c *BrowserConfig) WithTimezone(timezone string) *BrowserConfig
- type ClickOpts
- type CloudBrowser
- func (c *CloudBrowser) AcceptLanguage() string
- func (c *CloudBrowser) ApiKey() string
- func (c *CloudBrowser) ClearCookies(ctx context.Context) error
- func (c *CloudBrowser) ClearStorage(ctx context.Context, origin string) error
- func (c *CloudBrowser) Click(ctx context.Context, target *Locator) (*ElementResult, error)
- func (c *CloudBrowser) ClickWith(ctx context.Context, target *Locator, opts ClickOpts) (*ElementResult, error)
- func (c *CloudBrowser) Close() error
- func (c *CloudBrowser) CountryCode() string
- func (c *CloudBrowser) DragBy(ctx context.Context, target *Locator, offsetX, offsetY float64) (*DragResult, error)
- func (c *CloudBrowser) DragTo(ctx context.Context, target *Locator, absoluteX, absoluteY float64) (*DragResult, error)
- func (c *CloudBrowser) Evaluate(ctx context.Context, expression string) (*EvaluateResult, error)
- func (c *CloudBrowser) EvaluateInFrame(ctx context.Context, frameId, expression string) (*EvaluateResult, error)
- func (c *CloudBrowser) Fill(ctx context.Context, target *Locator, text string) (*ElementResult, error)
- func (c *CloudBrowser) FillWith(ctx context.Context, target *Locator, text string, opts FillOpts) (*ElementResult, error)
- func (c *CloudBrowser) Fingerprint() string
- func (c *CloudBrowser) GetCookies(ctx context.Context) ([]CookieParam, error)
- func (c *CloudBrowser) GetDOM(ctx context.Context, frameId string, depth int32) (string, error)
- func (c *CloudBrowser) GetDOMHash(ctx context.Context, frameId string) (string, error)
- func (c *CloudBrowser) GetObservation(ctx context.Context, maxElementsPerFrame, maxTextLength int32) (*ObservationResult, error)
- func (c *CloudBrowser) GetPages(ctx context.Context) ([]*PageInfo, error)
- func (c *CloudBrowser) GetSelection(ctx context.Context) (string, error)
- func (c *CloudBrowser) GetStorage(ctx context.Context, origin string) ([]StorageOriginEntry, error)
- func (c *CloudBrowser) GrpcUrl() string
- func (c *CloudBrowser) HighlightNode(ctx context.Context, backendNodeId int32, frameId string) error
- func (c *CloudBrowser) InsertText(ctx context.Context, text string) error
- func (c *CloudBrowser) InspectAtPosition(ctx context.Context, x, y float64) (*InspectResult, error)
- func (c *CloudBrowser) LoadHTML(ctx context.Context, url, html string, headers []Header, statusCode int32) error
- func (c *CloudBrowser) ModifyRequest(ctx context.Context, urlPattern, body string, timeoutMs float64, ...) (*InterceptedRequest, error)
- func (c *CloudBrowser) MoveTo(ctx context.Context, target *Locator) (*ElementResult, error)
- func (c *CloudBrowser) Navigate(ctx context.Context, url string, timeoutMs float64) (*NavigateResult, error)
- func (c *CloudBrowser) PressKey(ctx context.Context, key, code string, modifiers, location int32) error
- func (c *CloudBrowser) ReadCanvas(ctx context.Context, target *Locator) (*ReadCanvasResult, error)
- func (c *CloudBrowser) ReadCanvasWith(ctx context.Context, target *Locator, opts ReadCanvasOpts) (*ReadCanvasResult, error)
- func (c *CloudBrowser) ReleaseKey(ctx context.Context, key, code string, modifiers, location int32) error
- func (c *CloudBrowser) Screenshot(ctx context.Context, format string, quality int32) (*ScreenshotResult, error)
- func (c *CloudBrowser) ScrollTo(ctx context.Context, target *Locator) (*ElementResult, error)
- func (c *CloudBrowser) SelectByIndex(ctx context.Context, target *Locator, index int32) (*SelectOptionResult, error)
- func (c *CloudBrowser) SelectByIndexWith(ctx context.Context, target *Locator, index int32, opts SelectOpts) (*SelectOptionResult, error)
- func (c *CloudBrowser) SelectByText(ctx context.Context, target *Locator, text string) (*SelectOptionResult, error)
- func (c *CloudBrowser) SelectByTextWith(ctx context.Context, target *Locator, text string, opts SelectOpts) (*SelectOptionResult, error)
- func (c *CloudBrowser) SelectByValue(ctx context.Context, target *Locator, value string) (*SelectOptionResult, error)
- func (c *CloudBrowser) SelectByValueWith(ctx context.Context, target *Locator, value string, opts SelectOpts) (*SelectOptionResult, error)
- func (c *CloudBrowser) SessionId() string
- func (c *CloudBrowser) SetBlockList(ctx context.Context, patterns []string) error
- func (c *CloudBrowser) SetCookies(ctx context.Context, cookies []CookieParam) error
- func (c *CloudBrowser) SetProxy(ctx context.Context, proxyHost string, proxyPort int32, ...) error
- func (c *CloudBrowser) SetStaticPaths(ctx context.Context, blobName string, patterns []string) error
- func (c *CloudBrowser) SetStorage(ctx context.Context, storage []StorageOriginEntry) error
- func (c *CloudBrowser) SolveCaptcha(ctx context.Context, timeoutMs, retryAmount int32) (string, error)
- func (c *CloudBrowser) StopBrowser(ctx context.Context) error
- func (c *CloudBrowser) Timezone() string
- func (c *CloudBrowser) Wait(ctx context.Context, args ...WaitArg) (*WaitResult, error)
- func (c *CloudBrowser) WaitForAnyRequest(ctx context.Context, timeoutMs float64, patterns []RequestPattern) (int32, *InterceptedRequest, error)
- func (c *CloudBrowser) WaitForAnyResponse(ctx context.Context, timeoutMs float64, patterns []RequestPattern) (int32, *InterceptedResponse, error)
- type CookieParam
- type CookiePartitionKey
- type DragResult
- type ElementResult
- type EvaluateResult
- type FillOpts
- type FrameInfo
- type Header
- type HeaderModification
- type HeaderModificationAction
- type InspectResult
- type InterceptedRequest
- type InterceptedResponse
- type Locator
- type NavigateResult
- type ObservationResult
- type PageInfo
- type ReadCanvasOpts
- type ReadCanvasResult
- type Rect
- type RequestPattern
- type ScreenshotResult
- type SelectOptionResult
- type SelectOpts
- type StorageItem
- type StorageOriginEntry
- type WaitArg
- type WaitResult
Constants ¶
const ( // DefaultWaitTimeoutMs is the timeout used by Wait when no // browserscale.Timeout(ms) option is passed. DefaultWaitTimeoutMs = 30000.0 // DefaultVisible is the visibility flag baked into browserscale.CSS(...) and // browserscale.JS(...). For JS expressions returning a non-Element value // (boolean, string, number, plain object) the flag is a no-op. // Use .Visible(false) on the returned Locator to opt out. DefaultVisible = true // DefaultSteadyMs is the steady-time (in ms) baked into browserscale.CSS(...) and // browserscale.JS(...). For JS expressions returning a non-Element value the // value is a no-op. Use .Steady(ms) (or .Steady(0) to disable) on the // returned Locator to override. DefaultSteadyMs = 500.0 )
const AllFrames = "ALL_FRAMES"
AllFrames is the sentinel for "match in every frame on the page". Use it for any field documented as accepting a frameId — both Locator.InFrame and XxxOpts.InFrame.
Variables ¶
var ApiEndpoint = "https://api.browserscale.cloud"
Functions ¶
func SetApiEndpoint ¶
func SetApiEndpoint(endpoint string)
SetApiEndpoint overrides the HTTP rent/stop endpoint.
Defaults to `https://api.browserscale.cloud`. Call this before any RentBrowser/StopBrowser call if you need to point at a private browserscale deployment.
@param endpoint - base URL of the rent/stop service, with no trailing slash
@example
browserscale.SetApiEndpoint("https://browserscale.internal.example.com")
func StopBrowser ¶
StopBrowser releases a session without needing a CloudBrowser handle.
Useful when a session id was persisted across processes and the rental outlived the original handle. Only calls the rent stop endpoint; there is no gRPC connection to close in this form.
@param apiKey - API key the session was rented with @param sessionId - id of the session to release
@throws UNKNOWN_ERROR - the stop API rejected the request
@example
_ = browserscale.StopBrowser(context.Background(), apiKey, sessionId)
Types ¶
type BrowserConfig ¶
type BrowserConfig struct {
// contains filtered or unexported fields
}
BrowserConfig holds all parameters for renting a browser session. Use NewBrowserConfig with the required fields, then chain optional setters.
func NewBrowserConfig ¶
func NewBrowserConfig(apiKey string, rentDuration int, proxyHost string, proxyPort int, proxyUsername string, proxyPassword string) *BrowserConfig
NewBrowserConfig returns a BrowserConfig populated with the required rental fields. Optional fields are configured via the chainable With… setters before passing the config to RentBrowser.
@param apiKey - API key authenticating the rental @param rentDuration - lifetime of the session in seconds @param proxyHost - upstream proxy host (empty string disables the proxy) @param proxyPort - upstream proxy port (ignored when proxyHost is empty) @param proxyUsername - proxy auth user (empty for unauthenticated proxies) @param proxyPassword - proxy auth password (empty for unauthenticated proxies)
@returns *BrowserConfig ready to be customized further or passed to RentBrowser
@example
cfg := browserscale.NewBrowserConfig("sk_…", 600, "", 0, "", "").
WithCountryCode("DE").
WithTimezone("Europe/Berlin")
func (*BrowserConfig) UnstableWithFakeGpu ¶
func (c *BrowserConfig) UnstableWithFakeGpu(renderer string, vendor string, extensions []string) *BrowserConfig
UnstableWithFakeGpu overrides WebGL UNMASKED_RENDERER_WEBGL, UNMASKED_VENDOR_WEBGL and getSupportedExtensions().
Unstable API — likely to be reshaped or removed without notice. Use only when you have a specific WebGL-fingerprint requirement.
@param renderer - value to return for UNMASKED_RENDERER_WEBGL @param vendor - value to return for UNMASKED_VENDOR_WEBGL @param extensions - list returned by getSupportedExtensions()
@returns the modified *BrowserConfig for chaining
@example
cfg.UnstableWithFakeGpu("ANGLE", "Google Inc.", []string{"OES_texture_float"})
func (*BrowserConfig) WithCountryCode ¶
func (c *BrowserConfig) WithCountryCode(countryCode string) *BrowserConfig
WithCountryCode sets the geo-IP country code for the rented session.
Drives both the assigned exit-IP region and the locale defaults (Accept- Language, timezone fallback) when those are not overridden separately.
@param countryCode - ISO-3166 country code (e.g. "DE", "US")
@returns the modified *BrowserConfig for chaining
@example
cfg := browserscale.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithCountryCode("DE")
func (*BrowserConfig) WithFingerprint ¶
func (c *BrowserConfig) WithFingerprint(fingerprint string) *BrowserConfig
WithFingerprint pins a specific browser fingerprint id for the session.
When omitted the server picks a fingerprint based on the country code. Pass a known id (e.g. one returned by a previous rental) to keep fingerprints stable across sessions.
@param fingerprint - server-side fingerprint id
@returns the modified *BrowserConfig for chaining
@example
cfg := browserscale.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithFingerprint("fp_abc123")
func (*BrowserConfig) WithTimezone ¶
func (c *BrowserConfig) WithTimezone(timezone string) *BrowserConfig
WithTimezone sets the IANA timezone for the rented session.
@param timezone - IANA timezone (e.g. "Europe/Berlin")
@returns the modified *BrowserConfig for chaining
@example
cfg := browserscale.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithTimezone("Europe/Berlin")
type ClickOpts ¶
type ClickOpts struct {
// InFrame overrides the locator's own frame.
// Empty = use the locator's frame (or the main frame if none).
// Pass a specific frameId, or [AllFrames], to search elsewhere.
InFrame string
// Button is the mouse button to use.
// Valid: "left" (default), "right", "middle".
Button string
// ClickCount controls single/double-click.
// 0 or 1 = single click (default), 2 = double-click.
ClickCount int32
// Action selects the mouse phase.
// "" or "click" = full mouseDown+mouseUp (default).
// "press" only dispatches mouseDown.
// "release" only dispatches mouseUp at the current cursor position.
Action string
}
ClickOpts customizes a CloudBrowser.ClickWith call. Zero/empty values mean "use the server default".
type CloudBrowser ¶
type CloudBrowser struct {
// contains filtered or unexported fields
}
CloudBrowser is the SDK-side handle for an active browserscale browser session.
One CloudBrowser corresponds to exactly one browser context, which is implicitly bound to its primary page server-side. The proto's page_id field is currently ignored server-side, so the SDK never sets it.
func ConnectSession ¶
func ConnectSession(ctx context.Context, grpcUrl string, apiKey string, sessionId string) (*CloudBrowser, error)
ConnectSession attaches to an already-running session via gRPC.
Use this when you have a session id and gRPC URL from a previous RentBrowser (for example stored across process restarts). Unlike RentBrowser this does not call the rent API — the session must already exist server-side.
@param grpcUrl - the session's gRPC endpoint as returned by CloudBrowser.GrpcUrl,
e.g. "grpcs://api.browserscale.cloud:443" (TLS) or "grpc://host:port" (plaintext)
@param apiKey - API key authorizing access to the session @param sessionId - id of the existing session to attach to
@returns *CloudBrowser attached to the existing session; the returned
handle owns no rental, so calling Close only closes the gRPC connection
@throws UNKNOWN_ERROR - the gRPC connection could not be opened
@example
browser, err := browserscale.ConnectSession(ctx, "grpcs://api.browserscale.cloud:443", apiKey, sessionId)
if err != nil {
log.Fatal(err)
}
defer browser.Close()
func RentBrowser ¶
func RentBrowser(ctx context.Context, config *BrowserConfig) (*CloudBrowser, error)
RentBrowser rents a new browser session and returns a connected handle.
Calls the browserscale rent endpoint with the supplied BrowserConfig, opens a gRPC connection to the assigned session host, and returns a ready-to-use CloudBrowser. On any failure the partially-rented session is best-effort released.
@param config - rental parameters built with NewBrowserConfig
@returns *CloudBrowser ready to drive the rented session; call
[CloudBrowser.Close] or [CloudBrowser.StopBrowser] when done
@throws UNKNOWN_ERROR - the rent API rejected the request or the gRPC
connection could not be established
@example
cfg := browserscale.NewBrowserConfig("sk_…", 600, "", 0, "", "")
browser, err := browserscale.RentBrowser(ctx, cfg)
if err != nil {
log.Fatal(err)
}
defer browser.Close()
func (*CloudBrowser) AcceptLanguage ¶
func (c *CloudBrowser) AcceptLanguage() string
AcceptLanguage returns the Accept-Language header value the session was provisioned with.
func (*CloudBrowser) ApiKey ¶
func (c *CloudBrowser) ApiKey() string
ApiKey returns the API key used to rent this session.
func (*CloudBrowser) ClearCookies ¶
func (c *CloudBrowser) ClearCookies(ctx context.Context) error
ClearCookies deletes every cookie in the browser context.
@throws UNKNOWN_ERROR - the cookies could not be cleared
@example
_ = browser.ClearCookies(ctx)
func (*CloudBrowser) ClearStorage ¶
func (c *CloudBrowser) ClearStorage(ctx context.Context, origin string) error
ClearStorage deletes localStorage in the browser context.
@param origin - if non-empty, only this origin's storage is deleted
(e.g. "https://example.com"); empty string deletes all origins
@throws UNKNOWN_ERROR - the storage could not be cleared
@example
// Wipe one origin. _ = browser.ClearStorage(ctx, "https://example.com") // Wipe everything. _ = browser.ClearStorage(ctx, "")
func (*CloudBrowser) Click ¶
func (c *CloudBrowser) Click(ctx context.Context, target *Locator) (*ElementResult, error)
Click triggers a single left mouse click on the given target.
The browser scrolls the element into view if needed, moves the cursor along a human-like path, then dispatches a full mouseDown+mouseUp at a randomized point inside the element's bounding rect.
@param target - locator describing what to click; At is also valid
@returns *ElementResult with success, resolved frameId, backendNodeId,
post-scroll isVisible, element bounds and the root-viewport (rootX, rootY) where the click landed
@throws INVALID_LOCATOR - target is empty or has multiple targets set @throws ELEMENT_NOT_FOUND - no element matched the locator @throws FRAME_NOT_FOUND - the requested frame does not exist @throws CLICK_FAILED - the click could not be dispatched @throws TIMEOUT - the operation exceeded the server-side timeout @throws PAGE_NOT_ALIVE - the page has been closed
@see CloudBrowser.ClickWith for right-click, double-click,
press/release-only, or frame override
@example
_, err := browser.Click(ctx, browserscale.CSS("button.submit"))
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) ClickWith ¶
func (c *CloudBrowser) ClickWith(ctx context.Context, target *Locator, opts ClickOpts) (*ElementResult, error)
ClickWith is the customizable variant of CloudBrowser.Click.
@inheritDoc CloudBrowser.Click @param opts - click customization; see ClickOpts
@example
// Right double-click on a context menu trigger.
_, err := browser.ClickWith(ctx, browserscale.CSS("li.menu"), browserscale.ClickOpts{
Button: "right",
ClickCount: 2,
})
func (*CloudBrowser) Close ¶
func (c *CloudBrowser) Close() error
Close is the defer-friendly alias for CloudBrowser.StopBrowser that uses a background context.
@inheritDoc CloudBrowser.StopBrowser
@example
browser, err := browserscale.RentBrowser(ctx, cfg)
if err != nil { log.Fatal(err) }
defer browser.Close()
func (*CloudBrowser) CountryCode ¶
func (c *CloudBrowser) CountryCode() string
CountryCode returns the ISO-3166 country code the server allocated for this session (drives geo-IP and locale defaults).
func (*CloudBrowser) DragBy ¶
func (c *CloudBrowser) DragBy(ctx context.Context, target *Locator, offsetX, offsetY float64) (*DragResult, error)
DragBy picks up the target and drops it at an offset relative to the pickup point.
The browser presses the left mouse button at a pickup point inside the element, drags along a human-like path to (pickupX+offsetX, pickupY+offsetY), then releases. At is not a valid target — drag needs a real element.
@param target - locator describing the element to pick up @param offsetX - horizontal distance to drag, in CSS pixels @param offsetY - vertical distance to drag, in CSS pixels
@returns *DragResult with the resolved frameId, backendNodeId and the
final cursor position (rootX, rootY) where the drop happened
@throws UNKNOWN_ERROR - the drag could not be performed
@example
_, err := browser.DragBy(ctx, browserscale.CSS(".slider .handle"), 120, 0)
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) DragTo ¶
func (c *CloudBrowser) DragTo(ctx context.Context, target *Locator, absoluteX, absoluteY float64) (*DragResult, error)
DragTo picks up the target and drops it at absolute root-viewport coordinates.
Same gesture as CloudBrowser.DragBy, but the drop destination is in page coordinates rather than relative to the pickup point.
@param target - locator describing the element to pick up @param absoluteX - horizontal drop coordinate in the root viewport @param absoluteY - vertical drop coordinate in the root viewport
@returns *DragResult with the resolved frameId, backendNodeId and the
final cursor position (rootX, rootY) where the drop happened
@throws UNKNOWN_ERROR - the drag could not be performed
@example
_, err := browser.DragTo(ctx, browserscale.CSS(".card"), 800, 400)
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) Evaluate ¶
func (c *CloudBrowser) Evaluate(ctx context.Context, expression string) (*EvaluateResult, error)
Evaluate runs a JavaScript expression in the page's main frame.
The expression's return value is JSON-serialized server-side and parsed eagerly into EvaluateResult.Value. When the expression returns a DOM element the EvaluateResult.Value is left empty and the element metadata (BackendNodeId, IsVisible, Bounds) is populated instead — use Node(id) in subsequent calls to act on it.
@param expression - JavaScript expression evaluated in the main frame
@returns *EvaluateResult with either Value (for non-Element returns) or
BackendNodeId + IsVisible + Bounds (for Element returns)
@throws UNKNOWN_ERROR - the expression threw or could not be compiled
@example
res, err := browser.Evaluate(ctx, "document.title")
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Value)
func (*CloudBrowser) EvaluateInFrame ¶
func (c *CloudBrowser) EvaluateInFrame(ctx context.Context, frameId, expression string) (*EvaluateResult, error)
EvaluateInFrame runs a JavaScript expression in the given frame.
Same semantics as CloudBrowser.Evaluate but targets a specific frame instead of the main frame. Useful for evaluating inside OOPIFs (out-of- process iframes) found via CloudBrowser.GetPages.
@inheritDoc CloudBrowser.Evaluate @param frameId - id of the frame to evaluate in; empty falls back to the main frame
@example
pages, _ := browser.GetPages(ctx) iframeId := pages[0].FrameTree.Children[0].FrameId _, _ = browser.EvaluateInFrame(ctx, iframeId, "location.href")
func (*CloudBrowser) Fill ¶
func (c *CloudBrowser) Fill(ctx context.Context, target *Locator, text string) (*ElementResult, error)
Fill clicks the target and types text into it, appending to any existing content.
The browser scrolls the element into view, moves the cursor along a human-like path, clicks to focus, then types the text character-by- character with QWERTZ keyboard simulation and human-like timing.
To overwrite the field instead of appending, use CloudBrowser.FillWith with ClearFirst: true.
At is not a valid target — Fill requires an actual element.
@param target - locator describing the input element @param text - text to type into the element
@returns *ElementResult with success, resolved frameId, backendNodeId
and the root-viewport (rootX, rootY) where the element was clicked
@throws INVALID_LOCATOR - target is empty or has multiple targets set @throws ELEMENT_NOT_FOUND - no element matched the locator @throws FRAME_NOT_FOUND - the requested frame does not exist @throws FILL_FAILED - the input could not be filled @throws TIMEOUT - the operation exceeded the server-side timeout @throws PAGE_NOT_ALIVE - the page has been closed
@see CloudBrowser.FillWith for clearing existing content or
overriding the target frame
@example
_, err := browser.Fill(ctx, browserscale.CSS("input[name=email]"), "user@example.com")
func (*CloudBrowser) FillWith ¶
func (c *CloudBrowser) FillWith(ctx context.Context, target *Locator, text string, opts FillOpts) (*ElementResult, error)
FillWith is the customizable variant of CloudBrowser.Fill.
@inheritDoc CloudBrowser.Fill @param opts - fill customization; see FillOpts
@example
// Wipe the field first, then type fresh content.
_, err := browser.FillWith(ctx, browserscale.CSS("input[name=email]"), "user@example.com", browserscale.FillOpts{
ClearFirst: true,
})
func (*CloudBrowser) Fingerprint ¶
func (c *CloudBrowser) Fingerprint() string
Fingerprint returns the browser fingerprint id in use for this session.
func (*CloudBrowser) GetCookies ¶
func (c *CloudBrowser) GetCookies(ctx context.Context) ([]CookieParam, error)
GetCookies returns all cookies currently stored in this session's browser context.
@returns []CookieParam, one per cookie in the context
@throws UNKNOWN_ERROR - the cookies could not be read
@example
cookies, err := browser.GetCookies(ctx)
if err != nil {
log.Fatal(err)
}
for _, c := range cookies {
fmt.Println(c.Name, "=", c.Value)
}
func (*CloudBrowser) GetDOM ¶
GetDOM returns a JSON string in CDP DOM.Node shape for the requested frame.
The shape matches Chrome DevTools' Protocol DOM.Node — useful for piping into agent loops or visualizers that already speak CDP. For a much smaller agent-oriented payload, prefer CloudBrowser.GetObservation instead.
@param frameId - id of the frame to dump; empty targets the main frame @param depth - tree depth: -1 for the full tree, 0 for root only, N for
root + N descendant levels
@returns JSON string in CDP DOM.Node shape
@throws UNKNOWN_ERROR - the DOM could not be retrieved
@example
tree, err := browser.GetDOM(ctx, "", -1)
if err != nil {
log.Fatal(err)
}
fmt.Println(tree)
func (*CloudBrowser) GetDOMHash ¶
GetDOMHash returns sha256[:8] of the full-tree DOM JSON for cheap polling-based change detection.
Computing a hash is much cheaper than transferring the full tree — pair this with CloudBrowser.GetDOM only when the hash differs from your last snapshot.
@param frameId - id of the frame to hash; empty targets the main frame
@returns 16-char hex string (the first 8 bytes of sha256 of the DOM JSON)
@throws UNKNOWN_ERROR - the hash could not be computed
@example
hash, err := browser.GetDOMHash(ctx, "")
if err != nil {
log.Fatal(err)
}
if hash != lastHash {
// DOM changed → re-fetch
}
func (*CloudBrowser) GetObservation ¶
func (c *CloudBrowser) GetObservation(ctx context.Context, maxElementsPerFrame, maxTextLength int32) (*ObservationResult, error)
GetObservation returns a compact, agent-friendly description of every interactable element currently visible on the page, together with a truncated view of the surrounding text.
The result is intended as input for LLM/agent loops where a full DOM dump would be too large; the server filters down to elements that are actually visible and interactable.
@param maxElementsPerFrame - hard cap on how many elements the server
returns per frame; 0 means use the server default
@param maxTextLength - hard cap on per-element text content length in
characters; 0 means use the server default
@returns *ObservationResult with both a human-readable Text rendering
and a Json payload of the structured observation
@throws UNKNOWN_ERROR - the observation could not be produced
@example
obs, err := browser.GetObservation(ctx, 200, 80)
if err != nil {
log.Fatal(err)
}
fmt.Println(obs.Text)
func (*CloudBrowser) GetPages ¶
func (c *CloudBrowser) GetPages(ctx context.Context) ([]*PageInfo, error)
GetPages returns all open pages (tabs and popups) for this session's browser context.
Each PageInfo carries the page's URL, title, viewport and a full nested frame tree (out-of-process iframes are children of the page's main frame).
@returns []*PageInfo for every page currently open in the context
@throws UNKNOWN_ERROR - the pages could not be enumerated
@example
pages, err := browser.GetPages(ctx)
if err != nil {
log.Fatal(err)
}
for _, p := range pages {
fmt.Println(p.Url, p.Title)
}
func (*CloudBrowser) GetSelection ¶
func (c *CloudBrowser) GetSelection(ctx context.Context) (string, error)
GetSelection returns the current text selection.
Walks every frame and returns the first non-empty selection found — useful for "copy what the user highlighted" flows. Returns an empty string when nothing is selected anywhere.
@returns the selected text, or "" when nothing is selected
@throws UNKNOWN_ERROR - the selection could not be read
@example
sel, err := browser.GetSelection(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println("user selected:", sel)
func (*CloudBrowser) GetStorage ¶
func (c *CloudBrowser) GetStorage(ctx context.Context, origin string) ([]StorageOriginEntry, error)
GetStorage returns the localStorage contents of this session's browser context, grouped by origin.
The storage database is read directly in the browser process, so no page needs to be open. Only first-party localStorage is included — sessionStorage is per-tab and not covered.
@param origin - if non-empty, only this origin is returned
(e.g. "https://example.com"); empty string returns all origins
@returns []StorageOriginEntry, one per origin with localStorage data
@throws UNKNOWN_ERROR - the storage could not be read
@example
storage, err := browser.GetStorage(ctx, "")
if err != nil {
log.Fatal(err)
}
for _, e := range storage {
for _, item := range e.Items {
fmt.Println(e.Origin, item.Key, "=", item.Value)
}
}
func (*CloudBrowser) GrpcUrl ¶
func (c *CloudBrowser) GrpcUrl() string
GrpcUrl returns the gRPC endpoint the session is connected to.
func (*CloudBrowser) HighlightNode ¶
func (c *CloudBrowser) HighlightNode(ctx context.Context, backendNodeId int32, frameId string) error
HighlightNode paints a debug overlay over the node identified by backendNodeId.
Useful for visual debugging of agent flows — the overlay stays until the next call. Pass backendNodeId <= 0 to clear any current highlights.
@param backendNodeId - id of the node to highlight, or <= 0 to clear @param frameId - id of the frame the node lives in; empty targets the main frame
@throws UNKNOWN_ERROR - the highlight could not be applied
@example
if err := browser.HighlightNode(ctx, res.BackendNodeId, res.FrameId); err != nil {
log.Fatal(err)
}
func (*CloudBrowser) InsertText ¶
func (c *CloudBrowser) InsertText(ctx context.Context, text string) error
InsertText pastes text at the current caret using IME-style input.
No individual key events are dispatched; the entire string is committed at once via Input.insertText. Whatever element currently has focus receives the text. Use CloudBrowser.Click or CloudBrowser.Fill first if you need a specific element to be focused.
@param text - the text to insert at the caret
@throws UNKNOWN_ERROR - the text could not be inserted
@example
if err := browser.InsertText(ctx, "hello world"); err != nil {
log.Fatal(err)
}
func (*CloudBrowser) InspectAtPosition ¶
func (c *CloudBrowser) InspectAtPosition(ctx context.Context, x, y float64) (*InspectResult, error)
InspectAtPosition hit-tests at the viewport-relative (x, y) and returns the topmost element under that point.
Mirrors what the live-UI overlay does on hover. Elements with pointer-events:none are skipped — the result is the actual click target, not the visually-topmost node.
@param x - viewport-relative x in CSS pixels @param y - viewport-relative y in CSS pixels
@returns *InspectResult with the resolved backendNodeId, frameId, tag
name, trimmed textContent, visibility and bounds
@throws UNKNOWN_ERROR - the hit-test failed
@example
res, err := browser.InspectAtPosition(ctx, 200, 300)
if err != nil {
log.Fatal(err)
}
fmt.Println(res.TagName, res.TextContent)
func (*CloudBrowser) LoadHTML ¶
func (c *CloudBrowser) LoadHTML(ctx context.Context, url, html string, headers []Header, statusCode int32) error
LoadHTML serves a synthetic response for the next navigation to url.
Registers a one-shot interceptor that intercepts the next request to url and replies with the supplied html and headers instead of going to the network. Useful for snapshotted pages, test fixtures, and offline replays. Pair with CloudBrowser.Navigate to trigger the load.
@param url - the URL pattern that, when navigated to, returns the html @param html - the response body to serve @param headers - extra response headers (Content-Type is set automatically) @param statusCode - HTTP status code to serve; 0 means 200
@throws UNKNOWN_ERROR - the interceptor could not be installed
@example
_ = browser.LoadHTML(ctx, "https://example.com", "<h1>hi</h1>", nil, 0) _, _ = browser.Navigate(ctx, "https://example.com", 0)
func (*CloudBrowser) ModifyRequest ¶
func (c *CloudBrowser) ModifyRequest(ctx context.Context, urlPattern, body string, timeoutMs float64, mods []HeaderModification) (*InterceptedRequest, error)
ModifyRequest waits for the next request whose URL matches urlPattern, applies the supplied header modifications (and optional body replacement), then forwards the modified request.
One-shot: consumes the first matching request. Pass nil/empty mods to leave headers untouched and only override the body.
@param urlPattern - URL wildcard to wait for @param body - replacement request body; empty leaves the original body @param timeoutMs - per-call timeout in milliseconds; 0 uses the server default @param mods - HeaderModification entries; see HeaderModification for the fields
@returns *InterceptedRequest carrying the method/URL/headers/body that
were actually sent on the wire after modifications were applied
@throws UNKNOWN_ERROR - no matching request appeared within the timeout
@example
req, err := browser.ModifyRequest(ctx, "*/api/me", "", 5000, []browserscale.HeaderModification{
{Action: browserscale.HeaderModificationAdd, Name: "X-Trace", Value: "abc123"},
{Action: browserscale.HeaderModificationRemove, Name: "Cookie"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println("forwarded headers:", req.Headers)
func (*CloudBrowser) MoveTo ¶
func (c *CloudBrowser) MoveTo(ctx context.Context, target *Locator) (*ElementResult, error)
MoveTo moves the mouse cursor over the given target.
The browser scrolls the target into view first if necessary, then animates the cursor along a human-like path to the element's random center area (or to the viewport coordinate when target is At).
@param target - locator describing where to move; At is also valid
@returns *ElementResult with the resolved frameId, backendNodeId,
post-scroll isVisible, element bounds and the root-viewport (rootX, rootY) where the cursor ended up
@throws UNKNOWN_ERROR - the move could not be completed
@example
_, err := browser.MoveTo(ctx, browserscale.CSS("nav .menu"))
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) Navigate ¶
func (c *CloudBrowser) Navigate(ctx context.Context, url string, timeoutMs float64) (*NavigateResult, error)
Navigate navigates the page to url.
Returns once the primary main-frame navigation commits (the response is received and a new document is selected), before DOMContentLoaded or load fire. Cross-origin redirects are followed.
@param url - destination URL @param timeoutMs - per-call timeout in milliseconds; 0 uses the server default
@returns *NavigateResult with the final resolved URL and the frameId of
the main frame after navigation
@throws UNKNOWN_ERROR - the navigation failed or timed out
@example
_, err := browser.Navigate(ctx, "https://example.com", 0)
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) PressKey ¶
func (c *CloudBrowser) PressKey(ctx context.Context, key, code string, modifiers, location int32) error
PressKey fires a single key-down event.
Only the keydown half is dispatched — pair with CloudBrowser.ReleaseKey for a full press cycle. The event targets whichever element currently has focus.
@param key - DOM KeyboardEvent.key value (e.g. "Enter", "a", "ArrowLeft") @param code - DOM KeyboardEvent.code value (e.g. "Enter", "KeyA"); empty falls back to key @param modifiers - bit-flag combination: Alt=1, Ctrl=2, Meta=4, Shift=8 @param location - DOM KeyboardEvent.location: 0=standard, 1=left, 2=right, 3=numpad
@throws UNKNOWN_ERROR - the event could not be dispatched
@example
// Ctrl+A _ = browser.PressKey(ctx, "a", "KeyA", 2, 0) _ = browser.ReleaseKey(ctx, "a", "KeyA", 2, 0)
func (*CloudBrowser) ReadCanvas ¶ added in v1.1.0
func (c *CloudBrowser) ReadCanvas(ctx context.Context, target *Locator) (*ReadCanvasResult, error)
ReadCanvas reads the pixels of a <canvas> element directly in the renderer, bypassing the origin-clean (tainted) security check and without executing any page JavaScript — so cross-origin/tainted canvases (common in captchas) read fine where a normal toDataURL / getImageData would throw a SecurityError.
@param target - locator for the <canvas>; CSS, JS or Node
([At] coordinates are not valid — a real element is required)
@returns *ReadCanvasResult with the base64 image in DataBase64, the canvas
Width/Height, resolved frameId/backendNodeId and the OriginClean flag
@throws INVALID_LOCATOR - target is empty, uses At(x,y), or has multiple targets @throws ELEMENT_NOT_FOUND - no element matched the locator @throws FRAME_NOT_FOUND - the requested frame does not exist @throws TIMEOUT - the operation exceeded the server-side timeout @throws PAGE_NOT_ALIVE - the page has been closed
@see CloudBrowser.ReadCanvasWith for format, quality, or a sub-rectangle
@example
res, err := browser.ReadCanvas(ctx, browserscale.CSS("#game canvas"))
if err != nil {
log.Fatal(err)
}
img, _ := base64.StdEncoding.DecodeString(res.DataBase64)
os.WriteFile("canvas.png", img, 0o644)
func (*CloudBrowser) ReadCanvasWith ¶ added in v1.1.0
func (c *CloudBrowser) ReadCanvasWith(ctx context.Context, target *Locator, opts ReadCanvasOpts) (*ReadCanvasResult, error)
ReadCanvasWith is the customizable variant of CloudBrowser.ReadCanvas.
@inheritDoc CloudBrowser.ReadCanvas @param opts - format, quality, sub-rectangle and frame override; see ReadCanvasOpts
@example
// Read the left half of the canvas as JPEG at quality 80.
res, err := browser.ReadCanvasWith(ctx, browserscale.CSS("canvas"),
browserscale.ReadCanvasOpts{Format: "jpeg", Quality: 80, SW: 150, SH: 300})
func (*CloudBrowser) ReleaseKey ¶
func (c *CloudBrowser) ReleaseKey(ctx context.Context, key, code string, modifiers, location int32) error
ReleaseKey fires a single key-up event.
Mirror of CloudBrowser.PressKey. Same parameter semantics; use this to close a press cycle that was started with PressKey.
@inheritDoc CloudBrowser.PressKey
@example
_ = browser.PressKey(ctx, "Shift", "ShiftLeft", 0, 1) _ = browser.ReleaseKey(ctx, "Shift", "ShiftLeft", 0, 1)
func (*CloudBrowser) Screenshot ¶
func (c *CloudBrowser) Screenshot(ctx context.Context, format string, quality int32) (*ScreenshotResult, error)
Screenshot captures a single image of the page's current frame and returns it as base64-encoded image bytes.
The capture uses a one-shot surface copy (the same mechanism as CDP Page.captureScreenshot), so it is independent of any active live stream and works with both GPU (hardware) and software compositing.
@param format - "png" (default), "jpeg", or "webp"; pass "" for PNG
@param quality - encode quality 0-100 for "jpeg"/"webp" (ignored for
"png"); pass 0 to use the server default (90)
@returns *ScreenshotResult with the base64 image in DataBase64 and the
physical pixel Width/Height
@throws UNKNOWN_ERROR - the screenshot could not be captured
@example
shot, err := browser.Screenshot(ctx, "png", 0)
if err != nil {
log.Fatal(err)
}
img, _ := base64.StdEncoding.DecodeString(shot.DataBase64)
os.WriteFile("page.png", img, 0o644)
func (*CloudBrowser) ScrollTo ¶
func (c *CloudBrowser) ScrollTo(ctx context.Context, target *Locator) (*ElementResult, error)
ScrollTo scrolls the given element into view.
Whatever scroll container is closest to the element does the scrolling — nested scroll containers and out-of-process iframe chains are walked automatically. At is not a valid target here; scrolling needs a real element.
@param target - locator describing the element to bring into view;
[At] is rejected
@returns *ElementResult with the resolved frameId, backendNodeId,
post-scroll isVisible and the element's bounds after the scroll
@throws UNKNOWN_ERROR - the element could not be scrolled into view
@example
_, err := browser.ScrollTo(ctx, browserscale.CSS("#footer"))
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) SelectByIndex ¶
func (c *CloudBrowser) SelectByIndex(ctx context.Context, target *Locator, index int32) (*SelectOptionResult, error)
SelectByIndex picks the <option> at the zero-based index inside the targeted <select> element.
Sets the option as selected on the targeted <select>, then fires the standard input + change events (unless suppressed via CloudBrowser.SelectByIndexWith with SelectOpts.NoEvents).
At is not a valid target — Select requires an actual <select> element.
@param target - locator describing the <select> element @param index - zero-based option index
@returns *SelectOptionResult with the resolved selectedIndex,
selectedValue and selectedText after the change
@throws INVALID_LOCATOR - target is empty or has multiple targets set @throws ELEMENT_NOT_FOUND - no element matched the locator @throws FRAME_NOT_FOUND - the requested frame does not exist @throws SELECT_FAILED - the option could not be selected
(out of range, or element is not a <select>)
@throws TIMEOUT - the operation exceeded the server-side timeout @throws PAGE_NOT_ALIVE - the page has been closed
@see CloudBrowser.SelectByIndexWith for suppressing events or
overriding the target frame
@see CloudBrowser.SelectByValue, CloudBrowser.SelectByText
for matching by `value` attribute or visible text instead
@example
_, err := browser.SelectByIndex(ctx, browserscale.CSS("select#country"), 2)
func (*CloudBrowser) SelectByIndexWith ¶
func (c *CloudBrowser) SelectByIndexWith(ctx context.Context, target *Locator, index int32, opts SelectOpts) (*SelectOptionResult, error)
SelectByIndexWith is the customizable variant of CloudBrowser.SelectByIndex.
@inheritDoc CloudBrowser.SelectByIndex @param opts - select customization; see SelectOpts
@example
// Pick the option silently, no input/change events.
_, err := browser.SelectByIndexWith(ctx, browserscale.CSS("select#hidden"), 0, browserscale.SelectOpts{
NoEvents: true,
})
func (*CloudBrowser) SelectByText ¶
func (c *CloudBrowser) SelectByText(ctx context.Context, target *Locator, text string) (*SelectOptionResult, error)
SelectByText picks the <option> whose visible (trimmed) text matches the given string exactly.
@inheritDoc CloudBrowser.SelectByIndex @param text - the visible option text to match
@example
_, err := browser.SelectByText(ctx, browserscale.CSS("select#country"), "Germany")
func (*CloudBrowser) SelectByTextWith ¶
func (c *CloudBrowser) SelectByTextWith(ctx context.Context, target *Locator, text string, opts SelectOpts) (*SelectOptionResult, error)
SelectByTextWith is the customizable variant of CloudBrowser.SelectByText.
@inheritDoc CloudBrowser.SelectByText @param opts - select customization; see SelectOpts
@example
_, err := browser.SelectByTextWith(ctx, browserscale.CSS("select#country"), "Germany", browserscale.SelectOpts{
NoEvents: true,
})
func (*CloudBrowser) SelectByValue ¶
func (c *CloudBrowser) SelectByValue(ctx context.Context, target *Locator, value string) (*SelectOptionResult, error)
SelectByValue picks the <option> whose `value` attribute matches the given string exactly.
@inheritDoc CloudBrowser.SelectByIndex @param value - the `value` attribute to match
@example
_, err := browser.SelectByValue(ctx, browserscale.CSS("select#country"), "DE")
func (*CloudBrowser) SelectByValueWith ¶
func (c *CloudBrowser) SelectByValueWith(ctx context.Context, target *Locator, value string, opts SelectOpts) (*SelectOptionResult, error)
SelectByValueWith is the customizable variant of CloudBrowser.SelectByValue.
@inheritDoc CloudBrowser.SelectByValue @param opts - select customization; see SelectOpts
@example
_, err := browser.SelectByValueWith(ctx, browserscale.CSS("select#country"), "DE", browserscale.SelectOpts{
NoEvents: true,
})
func (*CloudBrowser) SessionId ¶
func (c *CloudBrowser) SessionId() string
SessionId returns the unique server-assigned id for this browser session.
func (*CloudBrowser) SetBlockList ¶
func (c *CloudBrowser) SetBlockList(ctx context.Context, patterns []string) error
SetBlockList replaces the session's URL blocklist.
Any request whose URL matches one of the supplied patterns is blocked before it leaves the browser. Patterns are simple URL wildcards (`*` matches any character span). Pass a nil/empty slice to clear the blocklist and let everything through.
@param patterns - URL wildcards to block; nil or empty clears the list
@throws UNKNOWN_ERROR - the blocklist could not be applied
@example
_ = browser.SetBlockList(ctx, []string{
"*.doubleclick.net/*",
"*googletagmanager.com*",
})
func (*CloudBrowser) SetCookies ¶
func (c *CloudBrowser) SetCookies(ctx context.Context, cookies []CookieParam) error
SetCookies writes the supplied cookies into the browser context.
Existing cookies with the same (name, domain, path) tuple are overwritten. Pass an empty slice for a no-op.
@param cookies - cookies to write; empty slice is a no-op
@throws UNKNOWN_ERROR - the cookies could not be written
@example
secure := true
httpOnly := true
sameSite := "Lax"
_ = browser.SetCookies(ctx, []browserscale.CookieParam{
{
Name: "auth",
Value: "tok",
Domain: "example.com",
Path: "/",
Secure: &secure,
HTTPOnly: &httpOnly,
SameSite: &sameSite,
},
})
func (*CloudBrowser) SetProxy ¶
func (c *CloudBrowser) SetProxy(ctx context.Context, proxyHost string, proxyPort int32, proxyUsername, proxyPassword string) error
SetProxy changes the runtime proxy for this session.
Takes effect for new requests immediately; in-flight requests keep their original routing. Pass an empty proxyHost to clear the proxy and route directly.
@param proxyHost - upstream proxy host; empty disables the proxy @param proxyPort - upstream proxy port; ignored when proxyHost is empty @param proxyUsername - proxy auth user (empty for unauthenticated proxies) @param proxyPassword - proxy auth password (empty for unauthenticated proxies)
@throws UNKNOWN_ERROR - the proxy could not be applied
@example
_ = browser.SetProxy(ctx, "proxy.example.com", 8080, "user", "pass")
func (*CloudBrowser) SetStaticPaths ¶
func (c *CloudBrowser) SetStaticPaths(ctx context.Context, blobName string, patterns []string) error
SetStaticPaths configures the session to serve cached static responses for requests matching the given patterns from blobName.
Useful for replaying frozen page assets (HTML/JS/CSS/images) without hitting the origin every time. The cache backend itself (blob storage, CDN, …) is configured server-side. Pass an empty patterns slice to disable caching for this session.
@param blobName - server-side identifier of the snapshot to serve from @param patterns - URL wildcards to redirect to the cache; nil/empty disables
@throws UNKNOWN_ERROR - the static paths could not be configured
@example
_ = browser.SetStaticPaths(ctx, "snap-2026-05", []string{"*.example.com/*"})
func (*CloudBrowser) SetStorage ¶
func (c *CloudBrowser) SetStorage(ctx context.Context, storage []StorageOriginEntry) error
SetStorage writes localStorage entries into the browser context, grouped by origin.
Accepts the same structure GetStorage returns, so a dump can be fed back verbatim. Existing keys are overwritten. Works without any open page; pages that are already open will not observe the writes until they reload.
@param storage - entries to write, grouped by origin
@throws UNKNOWN_ERROR - the storage could not be written
@example
_ = browser.SetStorage(ctx, []browserscale.StorageOriginEntry{
{
Origin: "https://example.com",
Items: []browserscale.StorageItem{
{Key: "token", Value: "abc123"},
{Key: "theme", Value: "dark"},
},
},
})
func (*CloudBrowser) SolveCaptcha ¶
func (c *CloudBrowser) SolveCaptcha(ctx context.Context, timeoutMs, retryAmount int32) (string, error)
SolveCaptcha detects and solves the first supported bot-challenge it finds anywhere on the page.
Detection covers the common challenge types you run into in the wild. The challenge is completed in-page server-side (the resulting token / bypass cookies are wired into the page automatically), so callers can ignore the returned string.
@param timeoutMs - how long to wait for a captcha to appear, in
milliseconds; 0 uses the server default (60s)
@param retryAmount - number of retries on a failed solve before giving up
@returns empty string on success — the solution is applied server-side
@throws UNKNOWN_ERROR - no captcha appeared within timeoutMs, or the
detected captcha could not be solved within retryAmount attempts
@example
if _, err := browser.SolveCaptcha(ctx, 0, 2); err != nil {
log.Fatal(err)
}
func (*CloudBrowser) StopBrowser ¶
func (c *CloudBrowser) StopBrowser(ctx context.Context) error
StopBrowser releases the session and closes the gRPC connection.
Calls the browserscale stop endpoint to release the rental, then closes the underlying gRPC connection. Safe to call multiple times — subsequent calls on a closed connection return an error from the second close.
@throws UNKNOWN_ERROR - the stop API or the gRPC close returned an error
@see CloudBrowser.Close - same operation with a background context
@example
defer browser.StopBrowser(context.Background())
func (*CloudBrowser) Timezone ¶
func (c *CloudBrowser) Timezone() string
Timezone returns the IANA timezone the session was provisioned with (e.g. "Europe/Berlin").
func (*CloudBrowser) Wait ¶
func (c *CloudBrowser) Wait(ctx context.Context, args ...WaitArg) (*WaitResult, error)
Wait blocks until any of the supplied locators matches.
Pass one or more [Locator]s (built with CSS, JS, …) plus optional wait-level arguments such as Timeout. When several locators are supplied, the first one to match wins; the others are abandoned.
Defaults applied automatically:
- timeout: DefaultWaitTimeoutMs (30s) — override with Timeout
- per-locator visible/steady: DefaultVisible (true) and DefaultSteadyMs (500) for CSS and JS locators. For JS expressions returning a non-Element value (bool/string/number/object) both flags are no-ops. Override with Locator.Visible / Locator.Steady on individual locators.
Node and At are not valid wait conditions — they only make sense as action targets — and produce an error at send time.
@param args - one or more [Locator]s plus optional wait-level options;
at least one [Locator] is required
@returns *WaitResult for the first matching condition (carries the
matched condition's index, frameId, backendNodeId and bounds)
@throws UNKNOWN_ERROR - the wait failed (no condition matched within the
timeout, the condition was invalid, or the call lacked any condition)
@example
// Wait for either a success banner or a JS condition, max 5s.
_, err := browser.Wait(ctx,
browserscale.CSS(".success"),
browserscale.JS("window.__ready === true"),
browserscale.Timeout(5000),
)
if err != nil {
log.Fatal(err)
}
func (*CloudBrowser) WaitForAnyRequest ¶
func (c *CloudBrowser) WaitForAnyRequest(ctx context.Context, timeoutMs float64, patterns []RequestPattern) (int32, *InterceptedRequest, error)
WaitForAnyRequest blocks until the next request whose URL matches one of the supplied patterns is observed.
Returns the matched pattern's index and the captured request. When patterns[i].Abort is true the request is dropped with an empty 200 response instead of being sent to the network.
@param timeoutMs - per-call timeout in milliseconds; 0 uses the server default @param patterns - one or more URL patterns (with optional Abort flags)
@returns int32 index of the matched pattern, *InterceptedRequest with
the captured method/URL/headers/body, and an error
@throws UNKNOWN_ERROR - the wait timed out or no patterns were supplied
@example
idx, req, err := browser.WaitForAnyRequest(ctx, 5000, []browserscale.RequestPattern{
{URL: "*/api/login"},
})
if err != nil {
log.Fatal(err)
}
_ = idx
fmt.Println(req.Method, req.Url)
func (*CloudBrowser) WaitForAnyResponse ¶
func (c *CloudBrowser) WaitForAnyResponse(ctx context.Context, timeoutMs float64, patterns []RequestPattern) (int32, *InterceptedResponse, error)
WaitForAnyResponse blocks until the next response whose URL matches one of the supplied patterns is observed.
Same shape as CloudBrowser.WaitForAnyRequest but on the response phase. When patterns[i].Abort is true the page receives an empty 200 instead of the real response.
@inheritDoc CloudBrowser.WaitForAnyRequest
@returns int32 index of the matched pattern, *InterceptedResponse with
the captured status/headers/body, and an error
@example
idx, resp, err := browser.WaitForAnyResponse(ctx, 5000, []browserscale.RequestPattern{
{URL: "*/api/login"},
})
if err != nil {
log.Fatal(err)
}
_ = idx
fmt.Println(resp.StatusCode)
type CookieParam ¶
type CookieParam struct {
Name string
Value string
URL *string
Domain string
Path string
Secure *bool
HTTPOnly *bool
SameSite *string
Expires *float64
Priority *string
SourceScheme *string
SourcePort *int
PartitionKey *CookiePartitionKey
}
CookieParam is one cookie returned by GetCookies / passed to SetCookies. Name, Value, Domain, and Path are the common required identity fields; optional attributes mirror the browser's CookieParam shape: URL, Secure, HTTPOnly, SameSite, Expires, Priority, SourceScheme, SourcePort, and PartitionKey.
type CookiePartitionKey ¶
CookiePartitionKey describes CHIPS partitioning metadata for partitioned cookies.
type DragResult ¶
type DragResult struct {
Success bool
FrameId string
BackendNodeId int32
StartX float64
StartY float64
EndX float64
EndY float64
}
DragResult is the outcome of a [CloudBrowser.Drag] gesture: the resolved source element and the start/end coordinates of the performed drag.
type ElementResult ¶
type ElementResult struct {
Success bool
FrameId string
BackendNodeId int32
IsVisible bool
Bounds Rect
RootX float64
RootY float64
}
ElementResult is the outcome of an element interaction such as CloudBrowser.Click, CloudBrowser.Fill or CloudBrowser.ScrollTo: the resolved element plus the root-relative coordinates the action was performed at.
type EvaluateResult ¶
EvaluateResult carries the outcome of a JS evaluate call.
If the expression returned a DOM element, BackendNodeId/IsVisible/Bounds are populated and Value is nil. Otherwise Value holds the parsed JSON value (string/number/bool/[]any/map[string]any/nil). On parse failure Value falls back to the raw server string so the caller is never empty- handed.
type FillOpts ¶
type FillOpts struct {
// InFrame overrides the locator's own frame.
// Empty = use the locator's frame (or the main frame if none).
// Pass a specific frameId, or [AllFrames], to search elsewhere.
InFrame string
// ClearFirst, when true, wipes the field's existing content with
// Ctrl+A, Delete before typing. Default (false) appends to whatever
// is already there.
ClearFirst bool
}
FillOpts customizes a CloudBrowser.FillWith call. Zero/empty values mean "use the server default".
type FrameInfo ¶
type FrameInfo struct {
FrameId string
Url string
IsOOPIF bool
HasJSContext bool
IsLoading bool
IsVisible bool
AbsoluteRect Rect
RelativeRect Rect
Children []*FrameInfo
}
FrameInfo describes a single frame within a page's frame tree.
type Header ¶
Header is a single HTTP header (name/value pair) on an intercepted request or response.
type HeaderModification ¶
type HeaderModification struct {
// Action selects what happens: HeaderModificationAdd inserts a new
// header, HeaderModificationEdit replaces an existing header's value,
// HeaderModificationRemove drops the header.
Action HeaderModificationAction
// Name is the header name the action applies to.
Name string
// Value is the header value for add/edit; ignored for remove.
Value string
// Before positions an "add" immediately before the named existing
// header; otherwise the header is appended at the end. Ignored for
// edit/remove.
Before string
// After positions an "add" immediately after the named existing
// header. Mirror of Before; ignored for edit/remove.
After string
}
HeaderModification is one entry passed to CloudBrowser.ModifyRequest. Build it as a plain struct literal.
type HeaderModificationAction ¶
type HeaderModificationAction string
HeaderModificationAction is the verb of a HeaderModification. Matches the add/edit/remove action strings; use the HeaderModificationXxx constants.
const ( HeaderModificationAdd HeaderModificationAction = "add" HeaderModificationEdit HeaderModificationAction = "edit" HeaderModificationRemove HeaderModificationAction = "remove" )
type InspectResult ¶
type InspectResult struct {
BackendNodeId int32
FrameId string
TagName string
TextContent string
IsVisible bool
Bounds Rect
}
InspectResult describes the topmost element hit at viewport-relative (x, y). BackendNodeId == 0 means nothing was found at that position.
type InterceptedRequest ¶
type InterceptedRequest struct {
Method string
Url string
Headers []Header
Body string
ResourceType string
}
InterceptedRequest describes an outgoing request captured by CloudBrowser.WaitForAnyRequest.
type InterceptedResponse ¶
InterceptedResponse describes a network response captured by CloudBrowser.WaitForAnyResponse.
type Locator ¶
type Locator struct {
// contains filtered or unexported fields
}
Locator is the universal "what element / what condition" type. It is used both as a wait condition (passed to Wait) and as a target for element actions (passed to Click, Fill, etc.).
Not every field is meaningful in every context:
- selector / jsExpression → both wait and actions
- backendNodeId → actions only (Wait rejects it)
- visible / steadyTime → wait only (silently ignored by actions)
- x / y → actions only (Wait rejects it)
- frameId → both, may be overridden by call-level browserscale.InFrame() / browserscale.InAllFrames() options
Use the CSS / JS / Node / At constructors instead of building this struct by hand.
func At ¶
At targets viewport coordinates instead of an element.
Useful for clicking inside a canvas, hovering decorative regions, or dispatching events at synthetic positions. Action-only — using it in CloudBrowser.Wait returns an error at send time. Note that only Click and MoveTo accept At; Scroll, Drag, Fill and Select all require a real element.
@param x - viewport-relative x in CSS pixels @param y - viewport-relative y in CSS pixels
@returns *Locator usable only as an action target
@example
// Click at canvas-relative coordinates. _, _ = browser.Click(ctx, browserscale.At(120, 240))
func CSS ¶
CSS waits for / targets an element matching the given CSS selector.
When used in CloudBrowser.Wait, the returned Locator carries the SDK defaults DefaultVisible (true) and DefaultSteadyMs (500). Override per call with Locator.Visible / Locator.Steady (use `.Steady(0)` to disable the steady check).
When used as an action target (Click, etc.) the visible/steady fields are ignored — there are no corresponding fields on the action requests.
@param selector - CSS selector matching the element
@returns *Locator usable as a wait condition or as an action target
@example
// As a wait condition.
_, _ = browser.Wait(ctx, browserscale.CSS("button.submit"))
// As an action target.
_, _ = browser.Click(ctx, browserscale.CSS("button.submit"))
func JS ¶
JS waits for / targets the result of a JavaScript expression.
Same wait defaults as CSS ([DefaultVisible]=true, [DefaultSteadyMs]=500); these only apply when the expression returns a DOM Element. For non-Element truthy values (boolean, string, number, plain object) both fields are no-ops and the condition matches as soon as the value is truthy.
Use Locator.Visible(false) / Locator.Steady(0) on the returned Locator to opt out.
@param expression - JavaScript expression evaluated in the target frame
@returns *Locator usable as a wait condition or as an action target
@example
_, _ = browser.Wait(ctx, browserscale.JS("window.__ready === true"))
func Node ¶
Node targets an element by its DevTools backendNodeId.
Use this when you already have a backendNodeId from a previous result (e.g. WaitResult or EvaluateResult) and want to act on the exact same element without re-resolving by selector. Action-only — using it in CloudBrowser.Wait returns an error at send time.
@param backendNodeId - DevTools backendNodeId of the target element
@returns *Locator usable only as an action target
@example
res, _ := browser.Click(ctx, browserscale.CSS("button.open"))
_, _ = browser.Click(ctx, browserscale.Node(res.BackendNodeId))
func (*Locator) InAllFrames ¶
InAllFrames scopes this Locator to every frame.
Equivalent to `.InFrame(AllFrames)`. Use this when an element might appear inside any of several frames and you do not want to enumerate them.
@returns the same Locator for chaining
@example
_, _ = browser.Wait(ctx, browserscale.CSS("button.consent").InAllFrames())
func (*Locator) InFrame ¶
InFrame scopes this Locator to a specific frameId.
Use the frameId from a previous result or CloudBrowser.GetPages to target elements inside a known iframe.
@param id - id of the frame to scope to
@returns the same Locator for chaining
@example
pages, _ := browser.GetPages(ctx)
iframeId := pages[0].FrameTree.Children[0].FrameId
_, _ = browser.Click(ctx, browserscale.CSS("button").InFrame(iframeId))
func (*Locator) Steady ¶
Steady requires the element to keep a stable position and size for at least ms milliseconds before the wait matches.
Pass 0 to disable the default DefaultSteadyMs (500). Has no effect for JS expressions that return a non-Element value, nor when the Locator is used as an action target.
@param ms - steady-state duration in milliseconds; 0 disables
@returns the same Locator for chaining
@example
_, _ = browser.Wait(ctx, browserscale.CSS(".banner").Steady(0))
func (*Locator) Visible ¶
Visible enforces or disables the visibility check for this Locator's wait condition.
Pass false to opt out of the default DefaultVisible (true). Has no effect when the Locator is used as an action target — actions never check visibility before dispatching.
@param v - true to require visibility, false to skip the check
@returns the same Locator for chaining
@example
_, _ = browser.Wait(ctx, browserscale.CSS("#hidden").Visible(false))
type NavigateResult ¶
type NavigateResult struct {
}
NavigateResult reports where a CloudBrowser.Navigate call ended up after redirects.
type ObservationResult ¶
ObservationResult is the compact page snapshot returned by CloudBrowser.GetObservation — the visible, interactive elements rendered as prompt-friendly text and as JSON.
type PageInfo ¶
type PageInfo struct {
PageId string
BrowserContextId string
Url string
Title string
Viewport Rect
FrameTree FrameInfo
}
PageInfo describes an open page (tab or popup) inside a browser context.
type ReadCanvasOpts ¶ added in v1.1.0
type ReadCanvasOpts struct {
// InFrame overrides the locator's own frame.
// Empty = use the locator's frame (or the main frame if none).
// Pass a specific frameId, or [AllFrames], to search elsewhere.
InFrame string
// Format is the output encoding.
// "" or "png" (default), "jpeg", "webp", or "rgba" for the raw
// unpremultiplied RGBA pixel buffer.
Format string
// Quality is the encode quality 0-100 for "jpeg"/"webp" (ignored otherwise).
// 0 = server default (90).
Quality int32
// SX, SY, SW, SH is an optional sub-rectangle in canvas pixels (mirrors
// getImageData(sx, sy, sw, sh)). The full canvas is read when SW/SH <= 0.
SX, SY, SW, SH int32
}
ReadCanvasOpts customizes a CloudBrowser.ReadCanvasWith call. Zero/empty values mean "use the server default".
type ReadCanvasResult ¶ added in v1.1.0
type ReadCanvasResult struct {
Success bool
FrameId string
BackendNodeId int32
DataBase64 string
Width int32
Height int32
OriginClean bool
}
ReadCanvasResult is the pixel readback of a <canvas>, returned by CloudBrowser.ReadCanvas. DataBase64 holds the encoded image bytes (PNG by default) or the raw RGBA buffer when Opts.Format == "rgba". OriginClean reports whether the canvas was untainted (informational; the read succeeds either way).
type RequestPattern ¶
RequestPattern matches a URL pattern in WaitForAnyRequest/Response. Set Abort to true to drop the request with an empty 200 response instead of letting it through to the network.
type ScreenshotResult ¶
ScreenshotResult is a single captured image of the page, returned by CloudBrowser.Screenshot. DataBase64 holds the encoded image bytes (PNG by default); Width and Height are in physical pixels.
type SelectOptionResult ¶
SelectOptionResult reports which <option> a SelectByXxx call ended up selecting.
type SelectOpts ¶
type SelectOpts struct {
// InFrame overrides the locator's own frame.
// Empty = use the locator's frame (or the main frame if none).
// Pass a specific frameId, or [AllFrames], to search elsewhere.
InFrame string
// NoEvents picks the option silently without firing input/change
// events. Default (false) fires the standard events.
NoEvents bool
}
SelectOpts customizes a SelectByXxxWith call. Zero/empty values mean "use the server default".
type StorageItem ¶
StorageItem is a single localStorage key/value pair.
type StorageOriginEntry ¶
type StorageOriginEntry struct {
Origin string
Items []StorageItem
}
StorageOriginEntry groups the localStorage entries of one origin (e.g. "https://example.com"). GetStorage returns these and SetStorage accepts the same shape, so a dump can be fed back verbatim.
type WaitArg ¶
type WaitArg interface {
// contains filtered or unexported methods
}
WaitArg is the marker interface for everything Wait accepts: a Locator (treated as a condition) or a wait-level option such as Timeout / InFrame / InAllFrames.
func Timeout ¶
Timeout overrides the CloudBrowser.Wait timeout.
When omitted, DefaultWaitTimeoutMs (30s) is used. Pass once per Wait call as one of the variadic arguments.
@param ms - timeout in milliseconds
@returns a WaitArg suitable for passing to Wait
@example
_, _ = browser.Wait(ctx, browserscale.CSS("#done"), browserscale.Timeout(5000))
type WaitResult ¶
type WaitResult struct {
Index int32
FrameId string
BackendNodeId int32
IsVisible bool
Bounds Rect
}
WaitResult is the outcome of a CloudBrowser.Wait / [CloudBrowser.WaitForAny] call: which condition matched (Index, in argument order) and where the matched element lives.