local browser = require("browser")Creates a new browser tab with an isolated browsing context (separate cookies, storage, cache).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
registry_name |
string? |
nil |
Process registry name for the manager |
options |
table? |
{} |
Tab options (see below) |
Options:
| Key | Type | Default | Description |
|---|---|---|---|
default_timeout |
string |
"30s" |
Default timeout for most operations |
default_navigation_timeout |
string |
"60s" |
Default timeout for navigation operations |
Returns: Tab object on success, or nil, error_string on failure.
Errors: CDP_CONNECTION_FAILED, TIMEOUT, MAX_TABS_REACHED
local tab, err = browser.new_tab()
if err then return nil, err end
-- With options
local tab, err = browser.new_tab(nil, {
default_timeout = "15s",
default_navigation_timeout = "30s",
})All Tab methods block the calling process until complete or timeout. They do not block other Wippy processes.
All fallible methods return (value?, string?) — check the error before using the value.
Navigates to a URL and waits for the page load event.
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
string |
— | URL to navigate to |
options.timeout |
string? |
navigation timeout | Override timeout |
Returns { url, frame_id, loader_id } on success.
local resp, err = tab:goto("https://example.com")
local resp, err = tab:goto("https://slow-site.com", { timeout = "120s" })Reloads the current page and waits for the load event.
| Parameter | Type | Default | Description |
|---|---|---|---|
options.timeout |
string? |
navigation timeout | Override timeout |
Navigates back in history. Returns error if there is no previous entry.
Navigates forward in history. Returns error if there is no next entry.
Returns the current page URL.
Waits for a Page.loadEventFired event. Use this after an action that triggers navigation (e.g., clicking a link).
| Parameter | Type | Default | Description |
|---|---|---|---|
options.timeout |
string? |
navigation timeout | Override timeout |
tab:click("a.next-page")
local resp, err = tab:wait_for_navigation({ timeout = "30s" })Waits for an element matching the CSS selector to appear in the DOM.
| Parameter | Type | Default | Description |
|---|---|---|---|
selector |
string |
— | CSS selector |
options.timeout |
string? |
default timeout | Override timeout |
options.visible |
boolean? |
false |
Wait until the element is visible |
tab:wait_for_selector("#results")
tab:wait_for_selector(".modal", { visible = true, timeout = "10s" })Waits for a JavaScript function to return a truthy value.
| Parameter | Type | Default | Description |
|---|---|---|---|
js_fn |
string |
— | JS function (arrow or regular) |
options.timeout |
string? |
default | Override timeout |
options.poll_interval |
integer? |
100 |
Polling interval in milliseconds |
tab:wait_for_function("() => document.querySelectorAll('.item').length > 5")
tab:wait_for_function("() => window.dataReady === true", { timeout = "15s" })Waits until no network requests have been sent or completed for a specified duration.
| Parameter | Type | Default | Description |
|---|---|---|---|
options.idle_time |
integer? |
500 |
Quiet period in milliseconds |
options.timeout |
string? |
default | Override timeout |
tab:wait_for_network_idle()
tab:wait_for_network_idle({ idle_time = 1000, timeout = "30s" })Returns the full HTML of the page (document.documentElement.outerHTML).
Returns the trimmed text content of the first element matching the selector.
local title = tab:text("h1")Returns an array of trimmed text contents for all matching elements.
local items = tab:text_all(".product-name")
for _, name in ipairs(items) do
print(name)
endReturns the value of an attribute on the first matching element.
local href = tab:attribute("a.download", "href")Returns an array of attribute values for all matching elements.
local links = tab:attribute_all("nav a", "href")Returns the value of an input, select, or textarea element.
local search_text = tab:value("#search-input")Returns true if the element exists and is visible (has non-zero dimensions and is not hidden via CSS). Returns false on any error.
Returns true if the element exists in the DOM. Returns false otherwise.
Returns true if the element is not disabled. Returns false otherwise.
Returns true if a checkbox or radio button is checked. Returns false otherwise.
Returns the number of elements matching the selector. Returns 0 if none match.
local n = tab:count(".search-result")Clicks the center of the first element matching the selector. Scrolls the element into view if needed.
tab:click("#submit")Types text into an input element character by character, dispatching key events.
| Parameter | Type | Default | Description |
|---|---|---|---|
selector |
string |
— | CSS selector for the input |
text |
string |
— | Text to type |
options.clear |
boolean? |
true |
Clear existing value before typing |
tab:type("#email", "user@example.com")
tab:type("#search", " more text", { clear = false }) -- appendPresses a special key by name.
Supported keys: Enter, Tab, Escape, Backspace, Delete, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Home, End, PageUp, PageDown, Space
tab:press("Enter")
tab:press("Escape")Selects an option in a <select> dropdown.
| Parameter | Type | Description |
|---|---|---|
selector |
string |
CSS selector for the <select> |
value |
string |
Select by value attribute |
value |
{ value = "..." } |
Select by value attribute |
value |
{ index = N } |
Select by 0-based index |
value |
{ text = "..." } |
Select by visible text |
tab:select("#country", "US")
tab:select("#country", { index = 0 })
tab:select("#country", { text = "United States" })Checks a checkbox if it is not already checked.
Unchecks a checkbox if it is currently checked.
Moves the mouse to the center of the element.
Focuses the element via JavaScript.
Sets files on a <input type="file"> element.
| Parameter | Type | Description |
|---|---|---|
selector |
string |
CSS selector for the file input |
file_path |
string | {string} |
Path or array of paths to upload |
tab:upload("#avatar", "/path/to/photo.jpg")
tab:upload("#docs", { "/path/a.pdf", "/path/b.pdf" })Evaluates a JavaScript expression and returns the result.
When called with extra arguments, the expression is treated as a function and called with those arguments.
-- Simple expression
local title = tab:eval("document.title")
local count = tab:eval("document.querySelectorAll('.item').length")
-- With arguments (expression used as function body)
local text = tab:eval(
"(sel) => document.querySelector(sel)?.textContent",
"#my-element"
)
-- Multiple arguments
local result = tab:eval(
"(a, b) => a + b",
10, 20
)Evaluates a JavaScript expression that returns a Promise. Waits for the Promise to resolve.
local data = tab:eval_async([[
const resp = await fetch('/api/data');
return await resp.json();
]])Captures a screenshot and returns the raw image bytes.
Calling conventions:
-- Viewport screenshot (PNG)
local bytes = tab:screenshot()
-- Element screenshot
local bytes = tab:screenshot("#chart")
-- Full page screenshot
local bytes = tab:screenshot({ full_page = true })
-- JPEG with quality
local bytes = tab:screenshot({ format = "jpeg", quality = 80 })Options (when passing a table):
| Key | Type | Default | Description |
|---|---|---|---|
full_page |
boolean? |
false |
Capture the entire scrollable page |
format |
string? |
"png" |
Image format: "png" or "jpeg" |
quality |
integer? |
— | JPEG quality 1-100 (JPEG only) |
Generates a PDF of the current page and returns the raw bytes.
| Key | Type | Default | Description |
|---|---|---|---|
format |
string? |
"A4" |
Paper size: A3, A4, A5, Letter, Legal, Tabloid |
landscape |
boolean? |
false |
Landscape orientation |
print_background |
boolean? |
true |
Include CSS backgrounds |
margin |
table? |
{} |
{ top, bottom, left, right } with CSS units |
local pdf = tab:pdf()
local pdf = tab:pdf({
format = "Letter",
landscape = true,
margin = { top = "1in", bottom = "1in", left = "0.5in", right = "0.5in" },
})Intercepts a file download triggered by the action function. The download is captured in-memory — no disk I/O required.
| Parameter | Type | Default | Description |
|---|---|---|---|
action_fn |
function |
— | Function that triggers the download |
options.timeout |
string? |
default timeout | Max time to wait for download |
Download detection: A response is treated as a download if any of these conditions are met:
Content-Dispositionheader containsattachmentContent-Dispositionheader contains afilenameparameterContent-Typeis a known binary/document type (application/pdf,application/octet-stream,application/zip, etc.)
Error propagation: If action_fn returns (nil, error_string), the error is propagated immediately instead of waiting for timeout. Use return in the action function:
local dl, err = tab:expect_download(function()
return tab:click("#download-btn") -- error propagated if element not found
end, { timeout = "30s" })Returns:
{
data = "...", -- raw bytes (string)
filename = "report.pdf", -- from Content-Disposition or URL
mime_type = "application/pdf", -- from Content-Type header
size = 145832, -- byte count
}local dl, err = tab:expect_download(function()
tab:click("#download-btn")
end, { timeout = "30s" })
if err then return nil, err end
print(dl.filename, dl.size)Sets the viewport dimensions.
tab:set_viewport(1920, 1080)Overrides the User-Agent header.
tab:set_user_agent("MyBot/1.0")Sets extra HTTP headers sent with every request.
tab:set_headers({
["Accept-Language"] = "en-US",
["X-Custom"] = "value",
})Changes the default timeout for all subsequent operations on this tab.
tab:set_timeout("15s")Blocks network requests for specified resource types. Useful for faster scraping.
Supported types: image, stylesheet, font, media, script, xhr, fetch, websocket, document, manifest, texttrack, eventsource, other
tab:block_resources({ "image", "stylesheet", "font", "media" })Closes the tab and releases its browser context. The tab object becomes unusable.
Returns true if the tab is still open.
Returns the CDP session ID.
Returns the current default timeout.
Returns the current default navigation timeout.
Sends a raw CDP command through the manager and returns the result. Use this for CDP methods not covered by the high-level API.
| Parameter | Type | Default | Description |
|---|---|---|---|
method |
string |
— | CDP method name |
params |
table? |
{} |
CDP method parameters |
timeout |
string? |
default timeout | Override timeout |
local result, err = tab:send_command("Page.getNavigationHistory")
local result, err = tab:send_command("Network.setCacheDisabled", { cacheDisabled = true })Returns the raw CDP event channel for building custom event loops.