Go SDK Reference
wrc-beta.xyz/wrc_go. Every method takes ctx context.Context as its first argument and returns an explicit error; both are omitted from the signatures below for brevity.AcceptLanguage
method on CloudBrowserAcceptLanguage() → stringAcceptLanguage returns the Accept-Language header value the session was provisioned with.
stringAddHeader
functionAddHeader(name string, value string) → HeaderModificationAddHeader builds a HeaderModification that adds a new request header.
Use HeaderModification.Before or HeaderModification.After to control where the header is inserted in the request line; otherwise it is appended at the end.
| name | string | header name |
| value | string | header value |
mod := wrc.AddHeader("X-Trace", "abc123")HeaderModificationHeaderModification ready to pass to CloudBrowser.ModifyRequestAfter
method on HeaderModificationAfter(name string) → HeaderModificationAfter positions an "add" modification immediately after the named existing header.
Mirror of HeaderModification.Before; only affects "add" modifications.
| name | string | anchor header name to insert after |
mod := wrc.AddHeader("X-Trace", "abc").After("User-Agent")HeaderModificationthe modified HeaderModificationApiKey
method on CloudBrowserApiKey() → stringApiKey returns the API key used to rent this session.
stringAt
functionAt(x float64, y float64) → *LocatorAt 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.
| x | float64 | viewport-relative x in CSS pixels |
| y | float64 | viewport-relative y in CSS pixels |
// Click at canvas-relative coordinates.
_, _ = browser.Click(ctx, wrc.At(120, 240))*Locator*Locator usable only as an action targetBefore
method on HeaderModificationBefore(name string) → HeaderModificationBefore positions an "add" modification immediately before the named existing header.
Only affects "add" modifications; ignored for edit/remove.
| name | string | anchor header name to insert before |
mod := wrc.AddHeader("X-Trace", "abc").Before("Cookie")HeaderModificationthe modified HeaderModificationClearCookies
method on CloudBrowserClearCookies()ClearCookies deletes every cookie in the browser context.
_ = browser.ClearCookies(ctx)| UNKNOWN_ERROR | the cookies could not be cleared |
Click
method on CloudBrowserClick(target *Locator) → *ElementResultClick 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.
| target | *Locator | locator describing what to click; At is also valid |
_, err := browser.Click(ctx, wrc.CSS("button.submit"))
if err != nil {
log.Fatal(err)
}*ElementResult*ElementResult with success, resolved frameId, backendNodeId,| CLICK_FAILED | the click could not be dispatched |
| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| TIMEOUT | the operation exceeded the server-side timeout |
ClickWith
method on CloudBrowserinherits ClickClickWith(target *Locator, opts ClickOpts) → *ElementResultClickWith is the customizable variant of CloudBrowser.Click.
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.
| target | *Locator | locator describing what to click; At is also valid |
| opts | ClickOpts | click customization; see ClickOpts |
// Right double-click on a context menu trigger.
_, err := browser.ClickWith(ctx, wrc.CSS("li.menu"), wrc_go.ClickOpts{
Button: "right",
ClickCount: 2,
})*ElementResult*ElementResult with success, resolved frameId, backendNodeId,| CLICK_FAILED | the click could not be dispatched |
| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| TIMEOUT | the operation exceeded the server-side timeout |
Close
method on CloudBrowserinherits StopBrowserClose()Close is the defer-friendly alias for CloudBrowser.StopBrowser that uses a background context.
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.
browser, err := wrc.RentBrowser(ctx, cfg)
if err != nil { log.Fatal(err) }
defer browser.Close()| UNKNOWN_ERROR | the stop API rejected the request |
ConnectSession
functionConnectSession(grpcUrl string, apiKey string, sessionId string) → *CloudBrowserConnectSession 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.
| grpcUrl | string | host:port of the session's gRPC endpoint |
| apiKey | string | API key authorizing access to the session |
| sessionId | string | id of the existing session to attach to |
browser, err := wrc.ConnectSession(ctx, "session-abc.wrc:443", apiKey, sessionId)
if err != nil {
log.Fatal(err)
}
defer browser.Close()*CloudBrowser*CloudBrowser attached to the existing session; the returned| UNKNOWN_ERROR | the gRPC connection could not be opened |
Cookie
functionCookie(name string, value string, domain string, path string) → CookieParamCookie builds a CookieParam in one line.
All four fields are required by the WRC.pdl spec — use this constructor instead of zero-initializing the struct yourself.
| name | string | cookie name |
| value | string | cookie value |
| domain | string | cookie domain (e.g. "example.com") |
| path | string | cookie path (e.g. "/") |
_ = browser.SetCookies(ctx, []wrc.CookieParam{
wrc.Cookie("session", "abc", "example.com", "/"),
})CookieParamCookieParam ready to pass to CloudBrowser.SetCookiesCountryCode
method on CloudBrowserCountryCode() → stringCountryCode returns the ISO-3166 country code the server allocated for this session (drives geo-IP and locale defaults).
stringCSS
functionCSS(selector string) → *LocatorCSS 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.
| selector | string | CSS selector matching the element |
// As a wait condition.
_, _ = browser.Wait(ctx, wrc.CSS("button.submit"))
// As an action target.
_, _ = browser.Click(ctx, wrc.CSS("button.submit"))*Locator*Locator usable as a wait condition or as an action targetDragBy
method on CloudBrowserDragBy(target *Locator, offsetX float64, offsetY float64) → *DragResultDragBy 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.
| target | *Locator | locator describing the element to pick up |
| offsetX | float64 | horizontal distance to drag, in CSS pixels |
| offsetY | float64 | vertical distance to drag, in CSS pixels |
_, err := browser.DragBy(ctx, wrc.CSS(".slider .handle"), 120, 0)
if err != nil {
log.Fatal(err)
}*DragResult*DragResult with the resolved frameId, backendNodeId and the| UNKNOWN_ERROR | the drag could not be performed |
DragTo
method on CloudBrowserDragTo(target *Locator, absoluteX float64, absoluteY float64) → *DragResultDragTo 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.
| target | *Locator | locator describing the element to pick up |
| absoluteX | float64 | horizontal drop coordinate in the root viewport |
| absoluteY | float64 | vertical drop coordinate in the root viewport |
_, err := browser.DragTo(ctx, wrc.CSS(".card"), 800, 400)
if err != nil {
log.Fatal(err)
}*DragResult*DragResult with the resolved frameId, backendNodeId and the| UNKNOWN_ERROR | the drag could not be performed |
EditHeader
functionEditHeader(name string, value string) → HeaderModificationEditHeader builds a HeaderModification that replaces an existing header's value.
Only useful when the request already carries the header — use AddHeader to introduce a new header.
| name | string | header name to overwrite |
| value | string | new value |
mod := wrc.EditHeader("User-Agent", "MyAgent/1.0")HeaderModificationHeaderModification ready to pass to CloudBrowser.ModifyRequestEvaluate
method on CloudBrowserEvaluate(expression string) → *EvaluateResultEvaluate 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.
| expression | string | JavaScript expression evaluated in the main frame |
res, err := browser.Evaluate(ctx, "document.title")
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Value)*EvaluateResult*EvaluateResult with either Value (for non-Element returns) or| UNKNOWN_ERROR | the expression threw or could not be compiled |
EvaluateInFrame
method on CloudBrowserinherits EvaluateEvaluateInFrame(frameId string, expression string) → *EvaluateResultEvaluateInFrame 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.
| frameId | string | id of the frame to evaluate in; empty falls back to the main frame |
| expression | string | JavaScript expression evaluated in the main frame |
pages, _ := browser.GetPages(ctx)
iframeId := pages[0].FrameTree.Children[0].FrameId
_, _ = browser.EvaluateInFrame(ctx, iframeId, "location.href")*EvaluateResult*EvaluateResult with either Value (for non-Element returns) or| UNKNOWN_ERROR | the expression threw or could not be compiled |
Fill
method on CloudBrowserFill(target *Locator, text string) → *ElementResultFill clicks the target, clears its content, then types text into it.
The browser scrolls the element into view, moves the cursor along a human-like path, clicks to focus, optionally clears existing content (Ctrl+A, Delete), then types the text character-by-character with QWERTZ keyboard simulation and human-like timing.
At is not a valid target — Fill requires an actual element.
| target | *Locator | locator describing the input element |
| text | string | text to type into the element |
_, err := browser.Fill(ctx, wrc.CSS("input[name=email]"), "user@example.com")*ElementResult*ElementResult with success, resolved frameId, backendNodeId| ELEMENT_NOT_FOUND | no element matched the locator |
| FILL_FAILED | the input could not be filled |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| TIMEOUT | the operation exceeded the server-side timeout |
FillWith
method on CloudBrowserinherits FillFillWith(target *Locator, text string, opts FillOpts) → *ElementResultFillWith is the customizable variant of CloudBrowser.Fill.
The browser scrolls the element into view, moves the cursor along a human-like path, clicks to focus, optionally clears existing content (Ctrl+A, Delete), then types the text character-by-character with QWERTZ keyboard simulation and human-like timing.
At is not a valid target — Fill requires an actual element.
| target | *Locator | locator describing the input element |
| text | string | text to type into the element |
| opts | FillOpts | fill customization; see FillOpts |
// Append to existing content instead of clearing first.
_, err := browser.FillWith(ctx, wrc.CSS("textarea"), " — appended", wrc_go.FillOpts{
NoClear: true,
})*ElementResult*ElementResult with success, resolved frameId, backendNodeId| ELEMENT_NOT_FOUND | no element matched the locator |
| FILL_FAILED | the input could not be filled |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| TIMEOUT | the operation exceeded the server-side timeout |
Fingerprint
method on CloudBrowserFingerprint() → stringFingerprint returns the browser fingerprint id in use for this session.
stringGetCookies
method on CloudBrowserGetCookies() → []CookieParamGetCookies returns all cookies currently stored in this session's browser context.
cookies, err := browser.GetCookies(ctx)
if err != nil {
log.Fatal(err)
}
for _, c := range cookies {
fmt.Println(c.Name, "=", c.Value)
}[]CookieParam[]CookieParam, one per cookie in the context| UNKNOWN_ERROR | the cookies could not be read |
GetDOM
method on CloudBrowserGetDOM(frameId string, depth int32) → stringGetDOM 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.
| frameId | string | id of the frame to dump; empty targets the main frame |
| depth | int32 | tree depth: -1 for the full tree, 0 for root only, N for |
tree, err := browser.GetDOM(ctx, "", -1)
if err != nil {
log.Fatal(err)
}
fmt.Println(tree)stringJSON string in CDP DOM.Node shape| UNKNOWN_ERROR | the DOM could not be retrieved |
GetDOMHash
method on CloudBrowserGetDOMHash(frameId string) → stringGetDOMHash 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.
| frameId | string | id of the frame to hash; empty targets the main frame |
hash, err := browser.GetDOMHash(ctx, "")
if err != nil {
log.Fatal(err)
}
if hash != lastHash {
// DOM changed → re-fetch
}string16-char hex string (the first 8 bytes of sha256 of the DOM JSON)| UNKNOWN_ERROR | the hash could not be computed |
GetObservation
method on CloudBrowserGetObservation(maxElementsPerFrame int32, maxTextLength int32) → *ObservationResultGetObservation 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.
| maxElementsPerFrame | int32 | hard cap on how many elements the server |
| maxTextLength | int32 | hard cap on per-element text content length in |
obs, err := browser.GetObservation(ctx, 200, 80)
if err != nil {
log.Fatal(err)
}
fmt.Println(obs.Text)*ObservationResult*ObservationResult with both a human-readable Text rendering| UNKNOWN_ERROR | the observation could not be produced |
GetPages
method on CloudBrowserGetPages() → []*PageInfoGetPages 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).
pages, err := browser.GetPages(ctx)
if err != nil {
log.Fatal(err)
}
for _, p := range pages {
fmt.Println(p.Url, p.Title)
}[]*PageInfo[]*PageInfo for every page currently open in the context| UNKNOWN_ERROR | the pages could not be enumerated |
GetSelection
method on CloudBrowserGetSelection() → stringGetSelection 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.
sel, err := browser.GetSelection(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println("user selected:", sel)stringthe selected text, or "" when nothing is selected| UNKNOWN_ERROR | the selection could not be read |
GrpcUrl
method on CloudBrowserGrpcUrl() → stringGrpcUrl returns the gRPC endpoint the session is connected to.
stringHighlightNode
method on CloudBrowserHighlightNode(backendNodeId int32, frameId string)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.
| backendNodeId | int32 | id of the node to highlight, or <= 0 to clear |
| frameId | string | id of the frame the node lives in; empty targets the main frame |
if err := browser.HighlightNode(ctx, res.BackendNodeId, res.FrameId); err != nil {
log.Fatal(err)
}| UNKNOWN_ERROR | the highlight could not be applied |
InAllFrames
method on LocatorInAllFrames() → *LocatorInAllFrames 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.
_, _ = browser.Wait(ctx, wrc.CSS("button.consent").InAllFrames())*Locatorthe same Locator for chainingInFrame
method on LocatorInFrame(id string) → *LocatorInFrame scopes this Locator to a specific frameId.
Use the frameId from a previous result or CloudBrowser.GetPages to target elements inside a known iframe.
| id | string | id of the frame to scope to |
pages, _ := browser.GetPages(ctx)
iframeId := pages[0].FrameTree.Children[0].FrameId
_, _ = browser.Click(ctx, wrc.CSS("button").InFrame(iframeId))*Locatorthe same Locator for chainingInsertText
method on CloudBrowserInsertText(text string)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.
| text | string | the text to insert at the caret |
if err := browser.InsertText(ctx, "hello world"); err != nil {
log.Fatal(err)
}| UNKNOWN_ERROR | the text could not be inserted |
InspectAtPosition
method on CloudBrowserInspectAtPosition(x float64, y float64) → *InspectResultInspectAtPosition 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.
| x | float64 | viewport-relative x in CSS pixels |
| y | float64 | viewport-relative y in CSS pixels |
res, err := browser.InspectAtPosition(ctx, 200, 300)
if err != nil {
log.Fatal(err)
}
fmt.Println(res.TagName, res.TextContent)*InspectResult*InspectResult with the resolved backendNodeId, frameId, tag| UNKNOWN_ERROR | the hit-test failed |
JS
functionJS(expression string) → *LocatorJS 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.
| expression | string | JavaScript expression evaluated in the target frame |
_, _ = browser.Wait(ctx, wrc.JS("window.__ready === true"))*Locator*Locator usable as a wait condition or as an action targetLoadHTML
method on CloudBrowserLoadHTML(url string, html string, headers []Header, statusCode int32)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.
| url | string | the URL pattern that, when navigated to, returns the html |
| html | string | the response body to serve |
| headers | []Header | extra response headers (Content-Type is set automatically) |
| statusCode | int32 | HTTP status code to serve; 0 means 200 |
_ = browser.LoadHTML(ctx, "https://example.com", "<h1>hi</h1>", nil, 0)
_, _ = browser.Navigate(ctx, "https://example.com", 0)| UNKNOWN_ERROR | the interceptor could not be installed |
ModifyRequest
method on CloudBrowserModifyRequest(urlPattern string, body string, timeoutMs float64, mods []HeaderModification) → *InterceptedRequestModifyRequest 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.
| urlPattern | string | URL wildcard to wait for |
| body | string | replacement request body; empty leaves the original body |
| timeoutMs | float64 | per-call timeout in milliseconds; 0 uses the server default |
| mods | []HeaderModification | header modifications built with AddHeader / EditHeader / RemoveHeader |
req, err := browser.ModifyRequest(ctx, "*/api/me", "", 5000, []wrc.HeaderModification{
wrc.AddHeader("X-Trace", "abc123"),
})
if err != nil {
log.Fatal(err)
}
fmt.Println("forwarded headers:", req.Headers)*InterceptedRequest*InterceptedRequest carrying the method/URL/headers/body that| UNKNOWN_ERROR | no matching request appeared within the timeout |
MoveTo
method on CloudBrowserMoveTo(target *Locator) → *ElementResultMoveTo 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).
| target | *Locator | locator describing where to move; At is also valid |
_, err := browser.MoveTo(ctx, wrc.CSS("nav .menu"))
if err != nil {
log.Fatal(err)
}*ElementResult*ElementResult with the resolved frameId, backendNodeId,| UNKNOWN_ERROR | the move could not be completed |
NewBrowserConfig
functionNewBrowserConfig(apiKey string, rentDuration int, proxyHost string, proxyPort int, proxyUsername string, proxyPassword string) → *BrowserConfigNewBrowserConfig returns a BrowserConfig populated with the required rental fields. Optional fields are configured via the chainable With… setters before passing the config to RentBrowser.
| apiKey | string | API key authenticating the rental |
| rentDuration | int | lifetime of the session in seconds |
| proxyHost | string | upstream proxy host (empty string disables the proxy) |
| proxyPort | int | upstream proxy port (ignored when proxyHost is empty) |
| proxyUsername | string | proxy auth user (empty for unauthenticated proxies) |
| proxyPassword | string | proxy auth password (empty for unauthenticated proxies) |
cfg := wrc.NewBrowserConfig("sk_…", 600, "", 0, "", "").
WithCountryCode("DE").
WithTimezone("Europe/Berlin")*BrowserConfig*BrowserConfig ready to be customized further or passed to RentBrowserNode
functionNode(backendNodeId int32) → *LocatorNode 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.
| backendNodeId | int32 | DevTools backendNodeId of the target element |
res, _ := browser.Click(ctx, wrc.CSS("button.open"))
_, _ = browser.Click(ctx, wrc.Node(res.BackendNodeId))*Locator*Locator usable only as an action targetPressKey
method on CloudBrowserPressKey(key string, code string, modifiers int32, location int32)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.
| key | string | DOM KeyboardEvent.key value (e.g. "Enter", "a", "ArrowLeft") |
| code | string | DOM KeyboardEvent.code value (e.g. "Enter", "KeyA"); empty falls back to key |
| modifiers | int32 | bit-flag combination: Alt=1, Ctrl=2, Meta=4, Shift=8 |
| location | int32 | DOM KeyboardEvent.location: 0=standard, 1=left, 2=right, 3=numpad |
// Ctrl+A
_ = browser.PressKey(ctx, "a", "KeyA", 2, 0)
_ = browser.ReleaseKey(ctx, "a", "KeyA", 2, 0)| UNKNOWN_ERROR | the event could not be dispatched |
ReleaseKey
method on CloudBrowserinherits PressKeyReleaseKey(key string, code string, modifiers int32, location int32)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.
| key | string | DOM KeyboardEvent.key value (e.g. "Enter", "a", "ArrowLeft") |
| code | string | DOM KeyboardEvent.code value (e.g. "Enter", "KeyA"); empty falls back to key |
| modifiers | int32 | bit-flag combination: Alt=1, Ctrl=2, Meta=4, Shift=8 |
| location | int32 | DOM KeyboardEvent.location: 0=standard, 1=left, 2=right, 3=numpad |
_ = browser.PressKey(ctx, "Shift", "ShiftLeft", 0, 1)
_ = browser.ReleaseKey(ctx, "Shift", "ShiftLeft", 0, 1)| UNKNOWN_ERROR | the event could not be dispatched |
RemoveHeader
functionRemoveHeader(name string) → HeaderModificationRemoveHeader builds a HeaderModification that drops a header from the request.
| name | string | header name to remove |
mod := wrc.RemoveHeader("Cookie")HeaderModificationHeaderModification ready to pass to CloudBrowser.ModifyRequestRentBrowser
functionRentBrowser(config *BrowserConfig) → *CloudBrowserRentBrowser rents a new browser session and returns a connected handle.
Calls the WRC 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.
| config | *BrowserConfig | rental parameters built with NewBrowserConfig |
cfg := wrc.NewBrowserConfig("sk_…", 600, "", 0, "", "")
browser, err := wrc.RentBrowser(ctx, cfg)
if err != nil {
log.Fatal(err)
}
defer browser.Close()*CloudBrowser*CloudBrowser ready to drive the rented session; call| UNKNOWN_ERROR | the rent API rejected the request or the gRPC |
ScrollTo
method on CloudBrowserScrollTo(target *Locator) → *ElementResultScrollTo 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.
| target | *Locator | locator describing the element to bring into view; |
_, err := browser.ScrollTo(ctx, wrc.CSS("#footer"))
if err != nil {
log.Fatal(err)
}*ElementResult*ElementResult with the resolved frameId, backendNodeId,| UNKNOWN_ERROR | the element could not be scrolled into view |
SelectByIndex
method on CloudBrowserSelectByIndex(target *Locator, index int32) → *SelectOptionResultSelectByIndex 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.
| target | *Locator | locator describing the <select> element |
| index | int32 | zero-based option index |
_, err := browser.SelectByIndex(ctx, wrc.CSS("select#country"), 2)*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SelectByIndexWith
method on CloudBrowserinherits SelectByIndexSelectByIndexWith(target *Locator, index int32, opts SelectOpts) → *SelectOptionResultSelectByIndexWith is the customizable variant of CloudBrowser.SelectByIndex.
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.
| target | *Locator | locator describing the <select> element |
| index | int32 | zero-based option index |
| opts | SelectOpts | select customization; see SelectOpts |
// Pick the option silently, no input/change events.
_, err := browser.SelectByIndexWith(ctx, wrc.CSS("select#hidden"), 0, wrc_go.SelectOpts{
NoEvents: true,
})*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SelectByText
method on CloudBrowserinherits SelectByIndexSelectByText(target *Locator, text string) → *SelectOptionResultSelectByText picks the <option> whose visible (trimmed) text matches the given string exactly.
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.
| target | *Locator | locator describing the <select> element |
| text | string | the visible option text to match |
_, err := browser.SelectByText(ctx, wrc.CSS("select#country"), "Germany")*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SelectByTextWith
method on CloudBrowserinherits SelectByTextSelectByTextWith(target *Locator, text string, opts SelectOpts) → *SelectOptionResultSelectByTextWith is the customizable variant of CloudBrowser.SelectByText.
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.
| target | *Locator | locator describing the <select> element |
| text | string | the visible option text to match |
| opts | SelectOpts | select customization; see SelectOpts |
_, err := browser.SelectByTextWith(ctx, wrc.CSS("select#country"), "Germany", wrc_go.SelectOpts{
NoEvents: true,
})*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SelectByValue
method on CloudBrowserinherits SelectByIndexSelectByValue(target *Locator, value string) → *SelectOptionResultSelectByValue picks the <option> whose value attribute matches the given string exactly.
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.
| target | *Locator | locator describing the <select> element |
| value | string | the value attribute to match |
_, err := browser.SelectByValue(ctx, wrc.CSS("select#country"), "DE")*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SelectByValueWith
method on CloudBrowserinherits SelectByValueSelectByValueWith(target *Locator, value string, opts SelectOpts) → *SelectOptionResultSelectByValueWith is the customizable variant of CloudBrowser.SelectByValue.
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.
| target | *Locator | locator describing the <select> element |
| value | string | the value attribute to match |
| opts | SelectOpts | select customization; see SelectOpts |
_, err := browser.SelectByValueWith(ctx, wrc.CSS("select#country"), "DE", wrc_go.SelectOpts{
NoEvents: true,
})*SelectOptionResult*SelectOptionResult with the resolved selectedIndex,| ELEMENT_NOT_FOUND | no element matched the locator |
| FRAME_NOT_FOUND | the requested frame does not exist |
| INVALID_LOCATOR | target is empty or has multiple targets set |
| PAGE_NOT_ALIVE | the page has been closed |
| SELECT_FAILED | the option could not be selected |
| TIMEOUT | the operation exceeded the server-side timeout |
SessionId
method on CloudBrowserSessionId() → stringSessionId returns the unique server-assigned id for this browser session.
stringSetApiEndpoint
functionSetApiEndpoint(endpoint string)SetApiEndpoint overrides the HTTP rent/stop endpoint.
Defaults to http://wrc-beta.xyz:8004. Call this before any RentBrowser/StopBrowser call if you need to point at a private WRC deployment.
| endpoint | string | base URL of the rent/stop service, with no trailing slash |
wrc.SetApiEndpoint("https://wrc.internal.example.com")SetBlockList
method on CloudBrowserSetBlockList(patterns []string)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.
| patterns | []string | URL wildcards to block; nil or empty clears the list |
_ = browser.SetBlockList(ctx, []string{
"*.doubleclick.net/*",
"*googletagmanager.com*",
})| UNKNOWN_ERROR | the blocklist could not be applied |
SetCookies
method on CloudBrowserSetCookies(cookies []CookieParam)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. Use Cookie to build entries inline.
| cookies | []CookieParam | cookies to write; empty slice is a no-op |
_ = browser.SetCookies(ctx, []wrc.CookieParam{
wrc.Cookie("auth", "tok", "example.com", "/"),
})| UNKNOWN_ERROR | the cookies could not be written |
SetProxy
method on CloudBrowserSetProxy(proxyHost string, proxyPort int32, proxyUsername string, proxyPassword string)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.
| proxyHost | string | upstream proxy host; empty disables the proxy |
| proxyPort | int32 | upstream proxy port; ignored when proxyHost is empty |
| proxyUsername | string | proxy auth user (empty for unauthenticated proxies) |
| proxyPassword | string | proxy auth password (empty for unauthenticated proxies) |
_ = browser.SetProxy(ctx, "proxy.example.com", 8080, "user", "pass")| UNKNOWN_ERROR | the proxy could not be applied |
SetStaticPaths
method on CloudBrowserSetStaticPaths(blobName string, patterns []string)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.
| blobName | string | server-side identifier of the snapshot to serve from |
| patterns | []string | URL wildcards to redirect to the cache; nil/empty disables |
_ = browser.SetStaticPaths(ctx, "snap-2026-05", []string{"*.example.com/*"})| UNKNOWN_ERROR | the static paths could not be configured |
SolveCaptcha
method on CloudBrowserSolveCaptcha(timeoutMs int32, retryAmount int32) → stringSolveCaptcha 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.
| timeoutMs | int32 | how long to wait for a captcha to appear, in |
| retryAmount | int32 | number of retries on a failed solve before giving up |
if _, err := browser.SolveCaptcha(ctx, 0, 2); err != nil {
log.Fatal(err)
}stringempty string on success — the solution is applied server-side| UNKNOWN_ERROR | no captcha appeared within timeoutMs, or the |
Steady
method on LocatorSteady(ms float64) → *LocatorSteady 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.
| ms | float64 | steady-state duration in milliseconds; 0 disables |
_, _ = browser.Wait(ctx, wrc.CSS(".banner").Steady(0))*Locatorthe same Locator for chainingStopBrowser
functionStopBrowser(apiKey string, sessionId string)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.
| apiKey | string | API key the session was rented with |
| sessionId | string | id of the session to release |
_ = wrc.StopBrowser(context.Background(), apiKey, sessionId)| UNKNOWN_ERROR | the stop API rejected the request |
Timeout
functionTimeout(ms float64) → WaitArgTimeout overrides the CloudBrowser.Wait timeout.
When omitted, DefaultWaitTimeoutMs (30s) is used. Pass once per Wait call as one of the variadic arguments.
| ms | float64 | timeout in milliseconds |
_, _ = browser.Wait(ctx, wrc.CSS("#done"), wrc.Timeout(5000))WaitArga WaitArg suitable for passing to WaitTimezone
method on CloudBrowserTimezone() → stringTimezone returns the IANA timezone the session was provisioned with (e.g. "Europe/Berlin").
stringUnstableWithFakeGpu
method on BrowserConfigUnstableWithFakeGpu(renderer string, vendor string, extensions []string) → *BrowserConfigUnstableWithFakeGpu 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.
| renderer | string | value to return for UNMASKED_RENDERER_WEBGL |
| vendor | string | value to return for UNMASKED_VENDOR_WEBGL |
| extensions | []string | list returned by getSupportedExtensions() |
cfg.UnstableWithFakeGpu("ANGLE", "Google Inc.", []string{"OES_texture_float"})*BrowserConfigthe modified *BrowserConfig for chainingVisible
method on LocatorVisible(v bool) → *LocatorVisible 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.
| v | bool | true to require visibility, false to skip the check |
_, _ = browser.Wait(ctx, wrc.CSS("#hidden").Visible(false))*Locatorthe same Locator for chainingWait
method on CloudBrowserWait(args ...WaitArg) → *WaitResultWait blocks until any of the supplied locators matches.
Pass one or more Locators (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.
| args | ...WaitArg | one or more Locators plus optional wait-level options; |
// Wait for either a success banner or a JS condition, max 5s.
_, err := browser.Wait(ctx,
wrc.CSS(".success"),
wrc.JS("window.__ready === true"),
wrc.Timeout(5000),
)
if err != nil {
log.Fatal(err)
}*WaitResult*WaitResult for the first matching condition (carries the| UNKNOWN_ERROR | the wait failed (no condition matched within the |
WaitForAnyRequest
method on CloudBrowserWaitForAnyRequest(timeoutMs float64, patterns []RequestPattern) → int32, *InterceptedRequestWaitForAnyRequest 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 patternsi.Abort is true the request is dropped with an empty 200 response instead of being sent to the network.
| timeoutMs | float64 | per-call timeout in milliseconds; 0 uses the server default |
| patterns | []RequestPattern | one or more URL patterns (with optional Abort flags) |
idx, req, err := browser.WaitForAnyRequest(ctx, 5000, []wrc.RequestPattern{
{URL: "*/api/login"},
})
if err != nil {
log.Fatal(err)
}
_ = idx
fmt.Println(req.Method, req.Url)int32, *InterceptedRequestint32 index of the matched pattern, *InterceptedRequest with| UNKNOWN_ERROR | the wait timed out or no patterns were supplied |
WaitForAnyResponse
method on CloudBrowserinherits WaitForAnyRequestWaitForAnyResponse(timeoutMs float64, patterns []RequestPattern) → int32, *InterceptedResponseWaitForAnyResponse 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 patternsi.Abort is true the page receives an empty 200 instead of the real response.
| timeoutMs | float64 | per-call timeout in milliseconds; 0 uses the server default |
| patterns | []RequestPattern | one or more URL patterns (with optional Abort flags) |
idx, resp, err := browser.WaitForAnyResponse(ctx, 5000, []wrc.RequestPattern{
{URL: "*/api/login"},
})
if err != nil {
log.Fatal(err)
}
_ = idx
fmt.Println(resp.StatusCode)int32, *InterceptedResponseint32 index of the matched pattern, *InterceptedResponse with| UNKNOWN_ERROR | the wait timed out or no patterns were supplied |
WithCountryCode
method on BrowserConfigWithCountryCode(countryCode string) → *BrowserConfigWithCountryCode 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.
| countryCode | string | ISO-3166 country code (e.g. "DE", "US") |
cfg := wrc.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithCountryCode("DE")*BrowserConfigthe modified *BrowserConfig for chainingWithFingerprint
method on BrowserConfigWithFingerprint(fingerprint string) → *BrowserConfigWithFingerprint 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.
| fingerprint | string | server-side fingerprint id |
cfg := wrc.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithFingerprint("fp_abc123")*BrowserConfigthe modified *BrowserConfig for chainingWithRenderer
method on BrowserConfigWithRenderer(enabled bool) → *BrowserConfigWithRenderer toggles the WebRTC live-render stream for the session.
Disabled by default. Enable when you need a live-UI experience (the user_frontend stream, screenshots, etc.); disable in pure-automation scenarios to save backend resources.
| enabled | bool | true to enable the WebRTC renderer, false to disable |
cfg := wrc.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithRenderer(true)*BrowserConfigthe modified *BrowserConfig for chainingWithTimezone
method on BrowserConfigWithTimezone(timezone string) → *BrowserConfigWithTimezone sets the IANA timezone for the rented session.
| timezone | string | IANA timezone (e.g. "Europe/Berlin") |
cfg := wrc.NewBrowserConfig(apiKey, 600, "", 0, "", "").WithTimezone("Europe/Berlin")*BrowserConfigthe modified *BrowserConfig for chaining