elementary

package module
v0.0.0-...-e675e33 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2026 License: MIT Imports: 24 Imported by: 0

README

Go Reference

Elementary

Elementary is a clean, reliable, and zero-boilerplate browser automation wrapper built natively for Go on top of Playwright. It simplifies browser lifecycle management, session switching, and element interaction into a highly readable, developer-friendly API.

By automating low-level setup, state coordination, and browser-driver recoveries, Elementary lets you focus strictly on writing your automation flows rather than fighting framework boilerplate.

Features

  • Zero-boilerplate browser, context, and page setup with a single function call.
  • Logical session and tab aliasing to easily open and jump between multiple isolated contexts and pages.
  • Automatic driver repair to programmatically intercept and self-heals corrupted browser binaries or execution timeouts during startup.
  • Smart selector auto-resolution supporting both XPath (the default) for advanced DOM traversal and CSS selectors for piercing web component shadow roots, with a one-line override if you'd rather default to CSS.
  • Optional stealth patching (Chromium only) that swaps in Patchright's driver patches to evade automated webdriver detectors.

Why Elementary?

While standard raw Playwright is incredibly capable, it requires significant code overhead to handle basic tasks. Here is a direct comparison of how Elementary simplifies your workflow:

Descriptive, Reusable Locators

Instead of a bare selector string, methods like ClickElement and GetElementText accept a Selector:

addToCartButton := Elementary.Selector{
    Value:       "css=shop-product-card .add-to-cart-button",
    Description: "add to cart button",
}
browser.ClickElement(addToCartButton, nil)

A Description makes screenshots, debug logs, and error messages read like "add to cart button" instead of a raw CSS/XPath expression. Declaring the selector once also means you can reuse it everywhere, instead of retyping the same string across your suite. Description is optional, so Elementary.Selector{Value: "css=#submit-button"} works fine on its own. Selector also takes an optional Timeout, so a flaky element can declare its own wait threshold a single time instead of at every call site:

slowWidget := Elementary.Selector{
    Value:       "css=#slow-widget",
    Description: "slow widget",
    Timeout:     15 * time.Second,
}
browser.ClickElement(slowWidget, nil)

Timeouts are resolved from most to least specific. A timeout passed at the call site always wins. If none is given, the selector's own Timeout is used. If that's also unset, the instance's default timeout applies.

A Value with no engine prefix (css=, xpath=, role=, text=, ...) is resolved as XPath by default, so Value: "//button[1]" and Value: "button" both work without a prefix. A bare CSS-style selector like .add-to-cart-button needs an explicit css= prefix, as shown above, since it isn't valid XPath on its own. If most of your selectors are CSS, call browser.SetDefaultSelectorEngine(Elementary.SELECTOR_ENGINE_CSS) once to flip the instance-wide default instead of prefixing every selector.

Setting up a Browser & Page

In standard raw Playwright, you must write ~25 lines of code, handle 4 separate pointer variables, and catch up to 4 potential errors just to safely open a single page:

// raw Playwright
pw, err := playwright.Run()
if err != nil {
    log.Fatalf("could not start playwright: %v", err)
}
defer pw.Stop()

browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{
    Headless: playwright.Bool(false),
})
if err != nil {
    log.Fatalf("could not launch browser: %v", err)
}
defer browser.Close()

context, err := browser.NewContext()
if err != nil {
    log.Fatalf("could not create context: %v", err)
}
defer context.Close()

page, err := context.NewPage()
if err != nil {
    log.Fatalf("could not create page: %v", err)
}

_, err = page.Goto("https://example.com")
if err != nil {
    log.Fatalf("could not navigate: %v", err)
}

In Elementary, this entire pipeline is initialized automatically:

// Elementary
browser := Elementary.Instance{}
err := browser.Initialize("default_session", "main_tab", Elementary.BROWSER_CHROME, 1280, 800, true, nil)
if err != nil {
    log.Fatalf("Failed to initialize: %v", err)
}
defer browser.Close()

browser.NavigateTo("https://example.com")
Multi-User / Multi-Session Interactions (Single Browser)

If you want to automate two users interacting on the same site at the same time (e.g., testing that when User A locks a product in their cart, User B sees it as "unavailable"), standard raw Playwright forces you to pass and manage multiple parallel context and page objects across your functions.

With Elementary, you simply use aliases to switch back and forth on a single instance:

// Create a separate, isolated session for User B (separate cookies/storage)
browser.NewContext("user_b_session", 1280, 800, nil)
browser.SwitchContext("user_b_session")
browser.NewPage("product_details")
browser.NavigateTo("https://example.com/product/123")

// User A adds the limited-stock product to their cart
browser.SwitchPage("user_a_session", "shopping_cart")
browser.NavigateTo("https://example.com/product/123")
addToCartButton := Elementary.Selector{Value: "css=.add-to-cart-btn", Description: "add to cart button"}
browser.ClickElement(addToCartButton, nil)

// User B checks the same product page and verifies it's now locked/unavailable
browser.SwitchPage("user_b_session", "product_details")
stockStatus := Elementary.Selector{Value: "css=.stock-status", Description: "stock status label"}
status, _ := browser.GetElementText(stockStatus, nil)
// status == "In someone else's cart"
Running Multiple Browsers Simultaneously (e.g., Chrome & Firefox)

To test cross-browser workflows or real-time multi-browser interactions, standard raw Playwright forces you to manage parallel driver processes, launch variables, and separate context and page pointers manually.

With Elementary, because state is fully encapsulated within each instance, you can spin up Chrome and Firefox side-by-side with almost no boilerplate:

// Chrome Instance
chrome := Elementary.Instance{}
chrome.Initialize("chrome_session", "tab_1", Elementary.BROWSER_CHROME, 1280, 800, true, nil)
chrome.NavigateTo("https://example.com")

// Firefox Instance (runs simultaneously in a separate process)
firefox := Elementary.Instance{}
firefox.Initialize("firefox_session", "tab_1", Elementary.BROWSER_FIREFOX, 1280, 800, true, nil)
firefox.NavigateTo("https://example.com")

// Both instances automate independently and simultaneously
checkoutButton := Elementary.Selector{Value: "css=.checkout-btn", Description: "checkout button"}
chrome.ClickElement(checkoutButton, nil)
firefox.ClickElement(checkoutButton, nil)
Selective Error Handling (Optional Steps)

In many real-world flows, some steps are strictly critical (like navigating to a product or clicking purchase), while other steps are completely optional (like attempting to dismiss a promotional pop-up newsletter modal on page entry).

With Elementary, you can cleanly run optional steps directly without assigning or catching their errors. If the optional element isn't present, the error is quietly ignored, and execution continues quietly:

// 1. Critical Step: We must load the main shop page
err := browser.NavigateTo("https://example.com/shop")
if err != nil {
    log.Fatalf("Shop page failed to load: %v", err)
}

// 2. Optional Step: Attempt to close the promotional newsletter banner. 
// If the banner does not appear during this session, the click fails, but 
// we completely ignore the error and proceed without any assignment boilerplate.
newsletterCloseButton := Elementary.Selector{Value: "css=#close-newsletter-popup-btn", Description: "newsletter popup close button"}
browser.ClickElement(newsletterCloseButton, nil)

// 3. Critical Step: Click the target product card. This must succeed.
addToCartButton := Elementary.Selector{Value: "css=shop-product-card .add-to-cart-button", Description: "add to cart button"}
err = browser.ClickElement(addToCartButton, nil)
if err != nil {
    log.Fatalf("Fatal: Failed to add item to cart: %v", err)
}

Installation

go get github.com/supercom32/elementary

Stealth Patching (Chromium only)

Elementary can patch the Playwright driver with Patchright's stealth patches before launch, for stronger anti-detection than injecting JS into the page. Enable it via BrowserOptions.StealthPatch:

browser := Elementary.Instance{}
err := browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, true, &Elementary.BrowserOptions{
    StealthPatch: true,
})

This is experimental and Chromium-only; passing it with Elementary.BROWSER_FIREFOX returns an error. It requires network access during Initialize to fetch a matching patchright-core release for your vendored Playwright driver version, and downloads real third-party content, so only enable it where that's acceptable.

The patch is never applied in place. On first use, Elementary builds a separate, patched copy of the driver in a sibling directory (e.g. ~/.cache/ms-playwright-go/1.61.1-stealth next to 1.61.1) and leaves the original driver install untouched. This means instances with and without StealthPatch can run side by side against the same cache without either affecting the other, and there's nothing to "corrupt": the original is only ever read, never written. Call browser.RestoreStealthPatch() (after Close()) to delete the patched copy and force it to be rebuilt on the next stealth-enabled Initialize.

Driving a Branded Browser Channel

BrowserOptions.Channel drives an already-installed branded browser (e.g. "chrome", "msedge") instead of the bundled Chromium build, matching Playwright's own channel launch option:

browser := Elementary.Instance{}
err := browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, true, &Elementary.BrowserOptions{
    Channel: "chrome",
})

This lets you target your local, real browser instead of Elementary's managed one. The requested channel must already be installed on the host. It's useful for evading browser fingerprinting, since a real Chrome install looks different (TLS fingerprint, version stamp, etc.) than the bundled Chromium build. StealthPatch is unaffected either way, since it patches the driver rather than the browser binary, so it applies regardless of which channel you launch.

Valid values are "chrome", "chrome-beta", "chrome-dev", "chrome-canary", "msedge", "msedge-beta", "msedge-dev", and "msedge-canary". The default, an empty string, uses Elementary's bundled/managed Chromium build rather than any locally-installed browser.

Overriding Launch Arguments

BrowserOptions.Args overrides the command-line arguments passed to the browser at launch, matching Playwright's own Args launch option. When left nil, Chromium launches with Elementary's default (--mute-audio) and Firefox launches with none:

browser := Elementary.Instance{}
err := browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, true, &Elementary.BrowserOptions{
    Args: []string{"--mute-audio", "--lang=fr-FR"},
})

Setting Args replaces the list entirely rather than appending to it. Elementary's Chromium default is --mute-audio. If you want to keep it alongside your own flags, include it explicitly as shown above.

Routing Traffic Through a Proxy

BrowserOptions.Proxy sends all of the browser's traffic through a proxy server, so sites see the proxy's address instead of yours. HTTP and SOCKS proxies are supported, and Bypass, Username, and Password are optional:

err := browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, false, &Elementary.BrowserOptions{
    Proxy: &Elementary.ProxyOptions{Server: "http://myproxy.com:3128", Username: "user", Password: "secret"},
})

Saving and Restoring a Login Session

SaveStorageState writes the current context's cookies and local storage to a JSON file. Pass that file as BrowserOptions.StorageStatePath to start a later session already logged in, including on sites that keep login tokens in local storage rather than cookies. Treat the file like a password, since it holds live session credentials:

err := browser.SaveStorageState("session.json")

// later, in a new run
err = browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, false, &Elementary.BrowserOptions{
    StorageStatePath: "session.json",
})

Handling Pop-up Dialogs

JavaScript alert, confirm, and prompt boxes never block a script: every dialog is answered automatically, by default with Cancel. SetDialogOptions changes the answer for every page from then on, and GetDialogs lists what was shown:

browser.SetDialogOptions(Elementary.DialogOptions{Accept: true, PromptText: "yes"})
browser.ClickElement(deleteButton, nil) // the "Are you sure?" box is answered with OK

for _, dialog := range browser.GetDialogs() {
    fmt.Println(dialog.Type, dialog.Message)
}

Downloading Files

DownloadByClicking clicks a link or button and saves the file it downloads, returning where it was saved. WaitForDownload does the same for any other trigger. The site's suggested file name is kept but made safe, and an existing file is never overwritten (a number is added instead, as in report (1).pdf):

path, err := browser.DownloadByClicking(invoiceLink, "./downloads", nil)

Working Inside Iframes

Payment forms, login widgets, and embedded editors often live inside an <iframe>. SwitchToFrame moves every element method (find, click, fill, read, wait, hover, upload, form controls, and downloads) inside that frame. Call it again to go into a frame nested inside it, SwitchToParentFrame to step out one level, and SwitchToMainFrame to return to the page. Changing to another tab or context, or calling NavigateTo or NavigateBack, always starts back on the main page:

paymentFrame := Elementary.Selector{Value: "css=iframe#payment", Description: "payment frame"}
browser.SwitchToFrame(paymentFrame)
browser.FillElement("4242 4242 4242 4242", cardNumberField, nil)
browser.SwitchToMainFrame()

JavaScript evaluation, ScrollPageBy, and mouse coordinate methods still act on the page as a whole.

Example

Here is a highly compact, single-browser example that demonstrates almost all of Elementary's core features (setup, timeouts, multiple tabs, selector auto-detection, screenshots, attributes, and visibility checks) in one short script.

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/supercom32/elementary"
)

func main() {
	// 1. Initialize our browser with our primary tab ("shop")
	browser := Elementary.Instance{}
	err := browser.Initialize("default_ctx", "shop", Elementary.BROWSER_CHROME, 1280, 800, true, nil)
	if err != nil {
		log.Fatalf("Initialization failed: %v", err)
	}
	defer browser.Close()

	// 2. Configure default timeouts globally once
	browser.SetTimeout(5 * time.Second)
	browser.SetNavigationTimeout(30 * time.Second)

	// --- SHOP TAB FLOW ---
	// Navigate to site and add a limited product to our cart (using CSS to pierce Shadow DOM)
	browser.NavigateTo("https://example.com/shop")
	addToCartButton := Elementary.Selector{Value: "css=shop-product-card .add-to-cart-button", Description: "add to cart button"}
	browser.ClickElement(addToCartButton, nil)

	// 3. Open a separate tab ("receipt") to verify real-time checkout updates
	browser.NewPage("receipt")
	browser.NavigateTo("https://example.com/checkout/status")

	// Read order attribute values and textual elements
	checkoutSummary := Elementary.Selector{Value: "css=checkout-summary", Description: "checkout summary"}
	statusMessage := Elementary.Selector{Value: "//div[@id='status-message']", Description: "status message"}
	price, _ := browser.GetElementAttribute("data-price", checkoutSummary, nil)
	status, _ := browser.GetElementText(statusMessage, nil)
	fmt.Printf("Order Status: %s | Price: %s\n", status, price)

	// Check if a modal is visible; if so, dismiss it using a custom inline timeout override
	cookieConsentModal := Elementary.Selector{Value: "//div[@class='cookie-consent']", Description: "cookie consent modal"}
	if browser.IsElementVisible(cookieConsentModal, nil) {
		opts := Elementary.ActionOptions{Timeout: 2 * time.Second}
		dismissButton := Elementary.Selector{Value: "//button[contains(text(), 'Dismiss')]", Description: "dismiss button"}
		browser.ClickElement(dismissButton, nil, opts)
	}

	// Switch back to the original "shop" tab and take a debug screenshot
	browser.SwitchPage("default_ctx", "shop")
	browser.SaveScreenshot("./debug", "final_shop_state.png")
}

Documentation

Index

Constants

View Source
const (
	IS_DEBUG_ENABLED      = false
	BROWSER_FIREFOX       = "firefox"
	BROWSER_CHROME        = "chromium"
	MOUSE_BUTTON_LEFT     = "left"
	MOUSE_BUTTON_MIDDLE   = "middle"
	MOUSE_BUTTON_RIGHT    = "right"
	UNTRACKED_PAGE        = -1
	NULL_PAGE             = -2
	NULL_CONTEXT          = -1
	SELECTOR_ENGINE_XPATH = "xpath"
	SELECTOR_ENGINE_CSS   = "css"
)

Variables

View Source
var (
	// ErrWindowsRestartRequired is returned when an automatic driver repair occurs on Windows, requiring the application to be restarted.
	ErrWindowsRestartRequired = errors.New("the simulation engine has been reset, but requires a program restart on Windows to unlock binaries")

	// ErrElementNotFound is wrapped by every action that must act on an element (ClickElement, FillElement,
	// HoverOverElement, HoverAndClickElement) when no element matches its selector within the timeout. Test for it
	// with errors.Is.
	ErrElementNotFound = errors.New("element not found")
)

BrowserOptions is a structure which encapsulates customization parameters for launching browser contexts. This enables runtime override of client metadata such as user agent headers to approximate diverse device families.

Functions

This section is empty.

Types

type ActionOptions

type ActionOptions struct {
	// Timeout bounds the action to an explicit duration. The zero value applies the
	// instance default for the action being performed.
	Timeout time.Duration

	// InfiniteTimeout removes the timeout bound entirely, allowing the action to wait
	// indefinitely. When set, this field takes precedence over Timeout.
	InfiniteTimeout bool
}

ActionOptions is a structure which encapsulates the optional configuration values accepted by action methods. This replaces raw millisecond integers and magic sentinel values with a single, explicit options object that mirrors the plain options structs used by Playwright itself.

type BrowserOptions

type BrowserOptions struct {
	UserAgent string

	// StealthPatch opts into launching against a separate, patched copy of the Chromium
	// driver built with Patchright's stealth patches. The original driver installation is
	// never modified, so Instances with and without StealthPatch can run side by side against
	// the same cache. Experimental: Chromium only, requires network access during Initialize
	// to fetch the patch and build the copy on first use. See stealthpatch.go.
	StealthPatch bool

	Channel string

	// Proxy routes all of the browser's traffic through a proxy server, per Playwright's proxy launch option. Nil
	// connects directly. It applies to every context the Instance creates.
	Proxy *ProxyOptions

	// StorageStatePath names a file previously written by SaveStorageState. When set, each context created with
	// these options starts with that file's cookies and local storage, restoring a saved login session. Empty
	// starts every context with a clean session.
	StorageStatePath string

	// Args overrides the command-line arguments passed to the browser at launch, per
	// Playwright's Args launch option. When nil, Chromium launches with Elementary's default
	// ("--mute-audio") and Firefox launches with none. Setting Args replaces the list entirely
	// rather than appending to it, so callers who want to keep the Chromium default alongside
	// their own flags must include it explicitly.
	Args []string
}

type CookieOptions

type CookieOptions struct {
	// Path is the cookie's path scope. Empty defaults to "/".
	Path string

	// Secure marks the cookie Secure, restricting it to HTTPS connections. Many sites require
	// this for session cookies served over HTTPS.
	Secure bool

	// HTTPOnly marks the cookie HttpOnly, making it inaccessible to page JavaScript.
	HTTPOnly bool

	// SameSite is the cookie's SameSite attribute: "Strict", "Lax", or "None". Empty leaves the
	// attribute unset, letting the browser apply its own default.
	SameSite string

	// ExpiresIn is how long from now the cookie should expire. The zero value creates a session
	// cookie that expires when the browser context closes.
	ExpiresIn time.Duration
}

CookieOptions is a structure which encapsulates the optional configuration values accepted by AddCookie, letting callers control a cookie's path, security flags, and lifetime instead of always getting a fixed set of defaults. The zero value creates a session cookie scoped to path "/" with no security flags set.

type DialogInfo

type DialogInfo struct {
	// ContextAlias is the alias of the browser context whose page showed the dialog.
	ContextAlias string

	// Type is the dialog kind: "alert", "confirm", "prompt", or "beforeunload".
	Type string

	// Message is the text the dialog displayed.
	Message string

	// DefaultValue is the pre-filled answer of a prompt() dialog, and empty for other types.
	DefaultValue string

	// PageURL is the address of the page that showed the dialog, when known.
	PageURL string

	// Accepted reports whether the dialog was answered with OK rather than Cancel.
	Accepted bool
}

DialogInfo is a structure which records one JavaScript dialog Elementary answered, as returned by GetDialogs.

type DialogOptions

type DialogOptions struct {
	// Accept answers dialogs with OK when true and with Cancel when false. Accepting a beforeunload dialog lets the
	// page be left; dismissing it keeps the page open.
	Accept bool

	// PromptText is the answer entered into prompt() dialogs when Accept is true. It is ignored for other dialog
	// types and when dismissing.
	PromptText string
}

DialogOptions is a structure which decides how Elementary answers JavaScript dialogs (alert, confirm, prompt, and beforeunload) on every page the Instance controls. The zero value dismisses every dialog, matching Playwright's own default.

type Instance

type Instance struct {
	// contains filtered or unexported fields
}

Instance is a structure which defines the primary orchestrator of the web automation engine. This maintains global state parameters including process pointers, active context registries, navigation limits, and current page scopes.

func (*Instance) AddCookie

func (shared *Instance) AddCookie(domain string, name string, value string, options ...CookieOptions) error

AddCookie is a method which allows you to insert a single designated cookie into the current browser context. This allows seeding targeted identification tags, tracking configurations, or authentication tokens prior to launching navigation pipelines. An optional CookieOptions controls the cookie's path, Secure, HttpOnly, and SameSite flags, and its lifetime. When no CookieOptions is supplied, the cookie is a session cookie scoped to path "/" with no security flags set. In addition, the following should be noted:

  • Only the first CookieOptions is used; any additional values are ignored.

  • A zero CookieOptions.ExpiresIn creates a session cookie that expires when the browser context closes, rather than a cookie with a fixed lifetime.

  • This method will return an error if no browser context is active or if the underlying Playwright instance fails to add the cookie to the active browser context.

Example:

err := agent.AddCookie(".example.com", "session_token", "secretXYZ", elementary.CookieOptions{
    Secure:    true,
    HTTPOnly:  true,
    SameSite:  "Lax",
    ExpiresIn: time.Hour,
})

func (*Instance) BlockPopups

func (shared *Instance) BlockPopups() error

BlockPopups is a method which allows you to intercept and close dynamically opened popup pages on the current browser context. This prevents marketing popups, blank targets, or ad redirections from interrupting active test procedures. In addition, the following should be noted:

  • Only pages opened by another page are closed. Tabs opened deliberately with NewPage stay open.

Example:

err := agent.BlockPopups()

func (*Instance) BlockRedirects

func (shared *Instance) BlockRedirects(blockedHosts ...string) error

BlockRedirects is a method which neutralizes navigation attempts away from the intended site on the current browser context. This prevents ad networks, tracking pixels, or hijacked pages from redirecting the active tab away from its loaded content mid-session. In addition, the following should be noted:

  • Script-driven navigation (location assignment, meta-refresh tags) is neutralized directly in the page via an injected script.

  • Main frame navigation requests are also gated at the network layer: once NavigateTo establishes a target hostname for the context, any subsequent top-level navigation request to a different hostname is aborted outright, regardless of whether it originated from a script, a synthetic click, or a real click on a hijacked full-page link. This is what actually stops sites that redirect via native anchor navigation rather than JavaScript location APIs.

  • Navigating to a different hostname on purpose still works; calling NavigateTo again simply updates the allowed hostname before its own request is evaluated.

  • Rejected navigations are cancelled rather than failed, so the tab stays on its current page instead of being replaced by the browser's error page.

  • blockedHosts is an optional list of additional hostnames (ad networks, trackers, etc.) to reject outright, for every resource type, regardless of the navigation gate above. Matching is by exact hostname or subdomain (e.g. "ads.example.com" matches a blocked "example.com"), not a partial/substring match, so unrelated domains that merely share a suffix (e.g. "notexample.com") are not blocked. When no hostnames are passed, no such hard blocking occurs, and only the navigation gate and script neutralization apply.

Example:

err := agent.BlockRedirects()
err := agent.BlockRedirects("profitabledisplaynetwork.com", "kettledroopingcontinuation.com")

func (*Instance) ClearCookies

func (shared *Instance) ClearCookies() error

ClearCookies is a method which purges all cookie definitions from the active browser context. This resets session states and forces anonymous interactions on subsequent HTTP operations. In addition, the following should be noted:

- This method will return an error if the underlying Playwright instance fails to clear the context's cookie jar.

Example:

err := agent.ClearCookies()

func (*Instance) ClearDialogs

func (shared *Instance) ClearDialogs()

ClearDialogs is a method which allows you to forget every dialog recorded so far, so a later GetDialogs call only reports dialogs shown after this point. It does not change how dialogs are answered.

Example:

agent.ClearDialogs()

func (*Instance) ClickElement

func (shared *Instance) ClickElement(selector Selector, locator playwright.Locator, options ...ActionOptions) error

ClickElement is a method which allows you to dispatch a mouse click event to the DOM node matched by the given selector. This simulates natural user click sequences to trigger navigation links, button submits, or option selections. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned instead of the click being attempted. In addition, the following should be noted:

  • This method is a thin wrapper around GetElement and ClickLocator. Selector resolution happens here; the click itself, along with before/after/failure screenshot capture, is owned by ClickLocator. Any caller that already holds a resolved playwright.Locator (e.g. from GetElement, GetVisibleElement, or its own querying) should call ClickLocator directly instead of re-resolving through a selector.

  • When no element is found, a "failure" screenshot is captured under the "click_element" action name, since ClickLocator is never reached in that case.

Example:

err := agent.ClickElement(elementary.Selector{Value: "css=#submit-button"}, nil, ActionOptions{Timeout: 3 * time.Second})
if errors.Is(err, elementary.ErrElementNotFound) {
    // the button never appeared
}

func (*Instance) ClickElementManually

func (shared *Instance) ClickElementManually(mouseButton string, element playwright.Locator, parentLocator playwright.Locator, options ...ActionOptions) error

ClickElementManually is a method which allows you to execute a hardware-style mouse click at the center of an element. This bypasses high-level click interceptors, addressing complex layouts where standard click emulation is restricted. mouseButton must be MOUSE_BUTTON_LEFT, MOUSE_BUTTON_MIDDLE, or MOUSE_BUTTON_RIGHT. In addition, the following should be noted:

  • The click lands on the center of the element's bounding box rather than its top-left corner, which can fall outside the element's visible shape (rounded corners, padding) and miss it entirely.

  • An unrecognized mouseButton, a nil element, or an element with no bounding box (for example one that is hidden or detached) returns an error rather than clicking somewhere unintended.

  • parentLocator is unused and kept only for signature compatibility.

Example:

err := agent.ClickElementManually(elementary.MOUSE_BUTTON_LEFT, locator, nil, ActionOptions{Timeout: time.Second})

func (*Instance) ClickLocator

func (shared *Instance) ClickLocator(element playwright.Locator, details string, options ...ActionOptions) error

ClickLocator is a method which dispatches a mouse click event directly against an already-resolved playwright.Locator. This is the single source of truth for click behavior in Elementary: it owns timeout resolution, the actual Click call, and all before/after/failure screenshot capture. ClickElement, and any other method that needs to click a resolved element, delegate to this method so that changes to click behavior or screenshot handling only need to be made in one place. In addition, the following should be noted:

  • details is a free-form descriptive string (typically the originating selector, but any identifying label works) used only for naming the captured screenshot files and for error messages. It has no effect on the click itself.

  • A nil element is treated as a caller error rather than allowed to panic against the playwright.Locator interface. A "failure" screenshot is still captured in this case, since a page snapshot at the moment of an invalid call is valuable diagnostic evidence.

Example:

selector := elementary.Selector{Value: "css=#submit-button"}
element, err := agent.GetElement(selector, nil, ActionOptions{Timeout: 3 * time.Second})
if err != nil {
    return err
}
err = agent.ClickLocator(element, selector.String(), ActionOptions{Timeout: 3 * time.Second})

func (*Instance) Close

func (shared *Instance) Close() error

Close is a method which disposes of the active browser session and pages. This performs a graceful teardown to reclaim allocated resources and stop background browser instances.

Example:

err := agent.Close()

func (*Instance) CloseAllContextInstances

func (shared *Instance) CloseAllContextInstances()

CloseAllContextInstances is a method which closes all active browser contexts managed by the instance. This guarantees thorough resource cleanup, terminating any lingering headless sandboxes upon agent shutdown.

Example:

agent.CloseAllContextInstances()

func (*Instance) CloseContext

func (shared *Instance) CloseContext(contextAlias string)

CloseContext is a method which tears down a target browser context and terminates its associated web pages. This releases allocated session memory and closes subprocess threads tied to the designated virtual profile.

Example:

agent.CloseContext("temporary-session")

func (*Instance) ClosePage

func (shared *Instance) ClosePage()

ClosePage is a method which shuts down the active page and redirects focus to the preceding tab in the active context stack. This is useful for recycling transient browser windows and maintaining stable tab focusing patterns.

Example:

agent.ClosePage()

func (*Instance) DownloadByClicking

func (shared *Instance) DownloadByClicking(selector Selector, destinationDirectory string, parentLocator playwright.Locator, options ...ActionOptions) (string, error)

DownloadByClicking is a method which allows you to click the element matched by selector and save the file the click downloads into destinationDirectory, returning the saved file's path. It is the common case of WaitForDownload and follows the same naming, overwrite, and directory rules. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned and nothing is clicked. In addition, the following should be noted:

  • Without an explicit timeout, from ActionOptions or the Selector itself, finding and clicking the element uses the element timeout and waiting for the download to start uses the navigation timeout. An explicit timeout applies to each of those steps.

Example:

path, err := agent.DownloadByClicking(elementary.Selector{Value: "css=a.invoice", Description: "invoice link"}, "./downloads", nil)

func (*Instance) EvaluateJavaScript

func (shared *Instance) EvaluateJavaScript(script string, args ...any) (any, error)

EvaluateJavaScript is a method which allows you to evaluate a JavaScript expression or function on the active page and get its result back. Unlike InjectJavaScript, which only reports whether evaluation failed, this returns the value the script produced, converted to Go: numbers become float64 or int, strings string, booleans bool, arrays []any, objects map[string]any, and undefined or null nil. Any args are passed to script when it is a function.

Example:

title, err := agent.EvaluateJavaScript("document.title")
sum, err := agent.EvaluateJavaScript("([a, b]) => a + b", []int{2, 3})

func (*Instance) FillElement

func (shared *Instance) FillElement(textToFill string, selector Selector, parentLocator playwright.Locator, options ...ActionOptions) error

FillElement is a method which allows you to focus a designated input element and type the specified text content. This simulates form input behaviors on fields, textual areas, or content-editable nodes. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned instead of the fill being attempted.

Example:

err := agent.FillElement("myPassword123", elementary.Selector{Value: "css=input[type='password']"}, nil, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) GetArrayOfUntrackedPageIndexes

func (shared *Instance) GetArrayOfUntrackedPageIndexes() []int

GetArrayOfUntrackedPageIndexes is a method which scans the active context for browser pages loaded outside of framework tracking. This detects auxiliary popup windows, dynamic redirects, and nested tabs that bypassed the NewPage registry.

Example:

indexes := agent.GetArrayOfUntrackedPageIndexes()

func (*Instance) GetCookies

func (shared *Instance) GetCookies() ([]playwright.Cookie, error)

GetCookies is a method which extracts all cookie parameters stored within the current browser context. This allows auditing active security cookies or extracting session state strings for verification.

Example:

cookies, err := agent.GetCookies()

func (*Instance) GetCurrentPage

func (shared *Instance) GetCurrentPage() playwright.Page

GetCurrentPage is a method which returns the active Playwright Page instance. This permits access to granular, low-level Playwright methods that are not exposed via standard framework wrappers.

Example:

page := agent.GetCurrentPage()

func (*Instance) GetCurrentUrlAddress

func (shared *Instance) GetCurrentUrlAddress() string

GetCurrentUrlAddress is a method which returns the active location address of the current page. This allows checking navigation progress or evaluating target redirect chains against expected route values.

Example:

url := agent.GetCurrentUrlAddress()

func (*Instance) GetDefaultSelectorEngine

func (shared *Instance) GetDefaultSelectorEngine() string

GetDefaultSelectorEngine is a method which returns the Playwright locator engine currently applied to unprefixed selector strings.

Example:

engine := agent.GetDefaultSelectorEngine()

func (*Instance) GetDialogs

func (shared *Instance) GetDialogs() []DialogInfo

GetDialogs is a method which allows you to list the JavaScript dialogs answered so far, oldest first, along with their messages and how each was answered. Only the most recent maxDialogHistory dialogs are kept. The returned slice is a copy, so changing it does not affect the recorded history.

Example:

for _, dialog := range agent.GetDialogs() {
    fmt.Println(dialog.Type, dialog.Message)
}

func (*Instance) GetElement

func (shared *Instance) GetElement(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) (playwright.Locator, error)

GetElement is a method which locates the first matching element after verifying it has attached to the DOM tree. This synchronizes element retrieval with asynchronous loading processes, securing reliable node references.

Example:

loc, err := agent.GetElement(elementary.Selector{Value: "css=.btn-login"}, nil, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) GetElementAttribute

func (shared *Instance) GetElementAttribute(attribute string, selector Selector, locator playwright.Locator, options ...ActionOptions) (string, error)

GetElementAttribute is a method which allows you to extract the value of a designated attribute from a target DOM element. This retrieves runtime properties such as hyperlinks, resource paths, or style classes from the rendered markup. An empty string is returned when no element matches the selector. In addition, the following should be noted:

  • Requesting the "value" attribute, in any letter case, reads the element's live value property instead of its markup attribute, so text typed into an input (for example via FillElement) is returned rather than the input's initial value. Elements that have no value property fall back to the markup attribute.

Example:

attribute, err := agent.GetElementAttribute("href", elementary.Selector{Value: "css=a.link"}, nil, ActionOptions{Timeout: 2 * time.Second})

func (*Instance) GetElementCountWithTimeout

func (shared *Instance) GetElementCountWithTimeout(locator playwright.Locator, options ...ActionOptions) (int, error)

GetElementCountWithTimeout is a method which retrieves the count of matching elements within a specified polling timeout. This accommodates slow asynchronous layouts that render lists gradually.

Example:

count, err := agent.GetElementCountWithTimeout(cardListLocator, ActionOptions{Timeout: 1500 * time.Millisecond})

func (*Instance) GetElementText

func (shared *Instance) GetElementText(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) (string, error)

GetElementText is a method that extracts the raw text content from an element. This is useful when scraping textual information, validating field values, or inspecting dynamic alerts.

Example:

text, err := agent.GetElementText(elementary.Selector{Value: "css=h1.title"}, nil, ActionOptions{Timeout: 1500 * time.Millisecond})

func (*Instance) GetElements

func (shared *Instance) GetElements(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) ([]playwright.Locator, error)

GetElements is a method that extracts all elements matching the specified selector. This is suited for iterating over lists, data grids, or matching child patterns inside a container element.

Example:

elements, err := agent.GetElements(elementary.Selector{Value: "css=ul.nav > li"}, nil, ActionOptions{Timeout: 2500 * time.Millisecond})

func (*Instance) GetFrameDepth

func (shared *Instance) GetFrameDepth() int

GetFrameDepth is a method which allows you to report how many frames deep element lookups currently are on the active page: 0 on the main page, 1 inside a top-level iframe, 2 inside an iframe nested in that one, and so on.

Example:

depth := agent.GetFrameDepth()

func (*Instance) GetLocatorCount

func (shared *Instance) GetLocatorCount(locator playwright.Locator) int

GetLocatorCount is a method which returns the total number of DOM nodes matched by the locator. This evaluates list sizes and structural density within the parsed document.

Example:

count := agent.GetLocatorCount(someListLocator)

func (*Instance) GetNavigationTimeout

func (shared *Instance) GetNavigationTimeout() time.Duration

GetNavigationTimeout is a method which returns the active timeout limit for page navigations. This allows inspecting current navigation wait thresholds to dynamically adjust load configurations for slower networks.

Example:

timeout := agent.GetNavigationTimeout()

func (*Instance) GetNumberOfElements

func (shared *Instance) GetNumberOfElements(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) (int, error)

GetNumberOfElements is a method which returns the total count of element nodes matching a selector. This checks list sizes, data grid rows, or pagination counts.

Example:

count, err := agent.GetNumberOfElements(elementary.Selector{Value: "css=div.product-card"}, nil, ActionOptions{Timeout: 2 * time.Second})

func (*Instance) GetPageInstance

func (shared *Instance) GetPageInstance(contextAlias string, pageAlias string) (int, *pageType)

GetPageInstance is a method which returns tracking data and reference points for a specific context page. This retrieves internal slice pointers and logical descriptors using context and page descriptors.

Example:

idx, page := agent.GetPageInstance("user-session", "checkout-tab")

func (*Instance) GetPlaywrightTimeout

func (shared *Instance) GetPlaywrightTimeout() time.Duration

GetPlaywrightTimeout is a method which returns the active timeout limit for internal Playwright operations. This allows inspecting current low-level driver execution thresholds.

Example:

timeout := agent.GetPlaywrightTimeout()

func (*Instance) GetScreenshotAsBinary

func (shared *Instance) GetScreenshotAsBinary(options ...ActionOptions) ([]byte, error)

GetScreenshotAsBinary is a method which captures a full-page snapshot and returns the binary payload. This retrieves the page's current visual state in-memory, permitting direct stream forwarding, API transmission, or instant processing.

By default the capture is bounded by the instance's element interaction timeout, which may be too short for full-page captures (e.g. while waiting on web fonts to load). Pass ActionOptions{InfiniteTimeout: true} or an explicit longer ActionOptions.Timeout to override this on a per-call basis.

Example:

data, err := agent.GetScreenshotAsBinary(ActionOptions{InfiniteTimeout: true})

func (*Instance) GetTimeout

func (shared *Instance) GetTimeout() time.Duration

GetTimeout is a method which returns the active timeout limit for element interactions. This allows inspecting current wait thresholds to dynamically adjust timing configurations for slow network targets.

Example:

timeout := agent.GetTimeout()

func (*Instance) GetVisibleElement

func (shared *Instance) GetVisibleElement(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) (playwright.Locator, error)

GetVisibleElement is a method that filters and returns the first visible element matching a selector. This ignores secondary, off-screen, or display-none duplicates of target selector fields.

Example:

visibleElement, err := agent.GetVisibleElement(elementary.Selector{Value: "css=button.active"}, nil, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) HoverAndClickElement

func (shared *Instance) HoverAndClickElement(selector Selector, locator playwright.Locator, xLocation int, yLocation int, options ...ActionOptions) error

HoverAndClickElement is a method which allows you to hover over the target element exactly as HoverOverElement does and then click it. This suits menus that only accept a click once they have been opened by hovering. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned and nothing is clicked.

Example:

err := agent.HoverAndClickElement(elementary.Selector{Value: "css=a.hover-menu"}, nil, 15, 15, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) HoverOverElement

func (shared *Instance) HoverOverElement(selector Selector, locator playwright.Locator, xLocation int, yLocation int, options ...ActionOptions) error

HoverOverElement is a method which allows you to scroll to and position the mouse cursor over the target element, at the offset xLocation and yLocation from the element's top-left corner, without clicking it. This triggers hover-based dropdowns, tooltips, or context menus. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned. Use HoverAndClickElement to also click once hovering. In addition, the following should be noted:

  • The hover is forced, skipping Playwright's actionability checks, so an element partly covered by another one can still be hovered.

  • When no ActionOptions or Selector timeout is given, the hover is bounded by a five second default rather than the instance's element timeout.

Example:

err := agent.HoverOverElement(elementary.Selector{Value: "css=a.hover-menu"}, nil, 15, 15, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) Initialize

func (shared *Instance) Initialize(defaultContextAlias string, defaultPageAlias string, browserType string, width int, height int, isVisible bool, browserOptions *BrowserOptions) error

Initialize is a method which spins up the browser simulation engines. This bootstraps a clean, sandboxed web browser environment tailored for headless scraping or automated testing, while managing driver setups and failures. In addition, the following should be noted:

- This method stores the initialization parameters such as width, height, browser type, and default aliases directly onto the instance to ensure that the engine can be cleanly restarted using identical initial conditions later if needed.

- This method attempts to automatically recover from driver startup failures by calling Repair, which resets only the driver, browser, and (if applicable) stealth-patch directories this Instance actually resolves to, then installing fresh browser binaries.

- This method returns the sentinel error ErrWindowsRestartRequired on Windows when a driver repair is performed, rather than abruptly exiting. This alerts the host application that a restart is required because Windows locks active binaries during the driver repair process.

Example:

err := agent.Initialize("main", "home", "chromium", 1280, 720, false, nil)

func (*Instance) InitializeDriver

func (shared *Instance) InitializeDriver(defaultContextAlias string, defaultPageAlias string, browserType string, width int, height int, isVisible bool, browserOptions *BrowserOptions) error

InitializeDriver is a method which downloads drivers, starts the browser backend, and provisions default state. This handles the low-level bootstrapping of the Playwright framework and configures initial session structures. In addition, the following should be noted:

  • This method launches a separate OS background process to run the Chromium or Firefox simulation engine. This means your host system must have sufficient permissions and memory to execute these external browser binaries. These background processes will persist in your operating system until the browser instance is explicitly closed.

  • This method modifies the shared playwrightInstance field, storing the newly initialized Playwright runner. This represents a stateful change that makes subsequent calls to this function act as a no-op if the instance is already running.

  • This method re-scaffolds default context and page structures by invoking the internal NewContext and NewPage methods. This populates the default browser tabs and contexts required for immediate automation.

Example:

err := agent.InitializeDriver("guest", "tab1", "chromium", 1024, 768, true, nil)

func (*Instance) InjectJavaScript

func (shared *Instance) InjectJavaScript(script string) error

InjectJavaScript is a method which evaluates arbitrary JavaScript expressions on the active page. This is suited for querying ephemeral DOM attributes, firing non-standard browser events, or mutating client-side variables dynamically.

Example:

err := agent.InjectJavaScript("console.log('injected');")

func (*Instance) IsChecked

func (shared *Instance) IsChecked(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) (bool, error)

IsChecked is a method which allows you to report whether the checkbox or radio button matched by selector is currently checked. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned, and an element that is not a checkbox or radio button also returns an error.

Example:

checked, err := agent.IsChecked(elementary.Selector{Value: "css=#terms", Description: "terms checkbox"}, nil)

func (*Instance) IsElementExist

func (shared *Instance) IsElementExist(selector Selector, locator playwright.Locator) bool

IsElementExist is a method which checks if an element is mapped within the DOM. This validates the presence of an element regardless of its current opacity, visibility, or rendering state.

Example:

exists := agent.IsElementExist(elementary.Selector{Value: "css=#sidebar"}, nil)

func (*Instance) IsElementVisible

func (shared *Instance) IsElementVisible(selector Selector, locator playwright.Locator) bool

IsElementVisible is a method which returns whether a designated element is rendered and occupies layout space. This avoids attempting interactions on elements that are hidden by dialog frames or display properties.

Example:

visible := agent.IsElementVisible(elementary.Selector{Value: "css=div.alert-box"}, someParentLocator)

func (*Instance) IsInitialized

func (shared *Instance) IsInitialized() bool

IsInitialized is a method which returns whether the underlying Playwright controller is active. This enables safe, preemptive checks before dispatching web driver operations, ensuring the automation engine is ready.

Example:

initialized := agent.IsInitialized()

func (*Instance) IsLocatorExists

func (shared *Instance) IsLocatorExists(locator playwright.Locator) bool

IsLocatorExists is a method which confirms whether a locator is bound to at least one valid node in the DOM. This pre-empts out-of-bounds exceptions when accessing collection elements.

Example:

exists := agent.IsLocatorExists(listLocator)

func (*Instance) LoadNetscapeCookies

func (shared *Instance) LoadNetscapeCookies(fileName string) error

LoadNetscapeCookies is a method which parses a Netscape cookie file and populates the active context jar. This restores identity structures and authorization states directly into the browser session. In addition, the following should be noted:

- This method parses individual fields separated by horizontal tabs and dynamically adds them to the context's cookie jar. This handles comment lines and blank rows gracefully, throwing detailed errors if structural parsing or expiration timestamp casting fails during execution.

- This method will return an error if the underlying Playwright instance fails to add any of the parsed cookies to the active browser context.

Example:

err := agent.LoadNetscapeCookies("saved_cookies.txt")

func (*Instance) MinimizeWindow

func (shared *Instance) MinimizeWindow(enforce bool) error

MinimizeWindow is a method which allows you to collapse the active browser window down to the taskbar via the Chrome DevTools Protocol, optionally keeping it collapsed afterward. This is useful for automation flows that need the browser process to keep running without its window remaining visible on screen. In addition, the following should be noted:

  • This method is only supported when the active browser is Chrome, since it relies on the Chrome DevTools Protocol's Browser domain. Calling it while any other browser is active returns an error without attempting the operation.

  • This method returns nil without effect if no page is currently active, since there is no window to target.

  • Enforcement is scoped to the window itself, identified by its Chrome DevTools Protocol window identifier, rather than to whichever tab happened to be active when enforce was passed as true. Closing that tab does not stop enforcement as long as another tab in the same window, tracked or not, remains open.

  • When enforce is true, this method starts a background watcher, or leaves an already running one in place, that polls the window state on minimizeWatcherPollInterval and re-minimizes it whenever it is no longer minimized. A separate watcher runs independently for each window that has been enforced, so minimizing one window has no effect on watchers already running against other windows.

  • When enforce is false, only the watcher for this specific window is stopped, and the window itself is minimized once and left alone afterward. Watchers running against other windows are left untouched.

Example:

err := agent.MinimizeWindow(true)

func (*Instance) MouseClick

func (shared *Instance) MouseClick(xLocation int, yLocation int) error

MouseClick is a method which allows you to trigger a single mouse click at specified horizontal and vertical canvas offsets. This is suited for targeting coordinate markers on static graphical surfaces that lack underlying HTML tag nodes. It returns an error if no page is active or the click fails, capturing a "failure" screenshot in either case.

Example:

err := agent.MouseClick(500, 400)

func (*Instance) MoveMouse

func (shared *Instance) MoveMouse() error

MoveMouse is a method which allows you to execute a mouse down, linear pointer sweep, and mouse release sequence. This approximates human mouse gestures across the canvas coordinates to satisfy basic anti-bot drag interactions. It returns an error if no page is active or any of the three mouse steps fails. In addition, the following should be noted:

  • The mouse button is still released when the sweep fails, so a failed call never leaves the button held down.

Example:

err := agent.MoveMouse()

func (*Instance) NavigateBack

func (shared *Instance) NavigateBack() error

NavigateBack is a method which allows you to trigger backwards navigation in the active browser tab's history. This emulates clicking the standard browser back button to handle multi-step layouts. The resulting page's hostname is recorded as the one BlockRedirects permits, and element lookups return to the main frame, since the frame chosen with SwitchToFrame belonged to the page being left. It returns an error if no page is active or the navigation fails; having no earlier history entry is not an error and simply leaves the page where it is.

Example:

err := agent.NavigateBack()

func (*Instance) NavigateTo

func (shared *Instance) NavigateTo(url string, options ...ActionOptions) error

NavigateTo is a method which allows you to load and open the target URL in the active page tab. Failed attempts are retried with an increasing pause between them until the navigation timeout elapses, so a briefly unreachable site gets several chances without the browser being hammered. In addition, the following should be noted:

  • Each retry is given only the time remaining before the overall deadline, so the total time spent never exceeds the navigation timeout.

  • The pause between attempts starts at navigationRetryInitialBackoff and doubles up to navigationRetryMaxBackoff.

  • A URL that cannot be parsed or has no scheme (for example "example.com" instead of "https://example.com") is rejected immediately instead of being retried, since no amount of retrying can make it load. Retrying also stops at once if the page is closed.

  • With ActionOptions{InfiniteTimeout: true}, failed navigations are retried indefinitely, still with the pause between attempts.

  • Element lookups return to the main frame before navigating, since any frame chosen with SwitchToFrame belonged to the page being left.

Example:

err := agent.NavigateTo("https://example.com", ActionOptions{Timeout: 10 * time.Second})

func (*Instance) NewContext

func (shared *Instance) NewContext(aliasName string, viewportWidth int, viewportHeight int, browserOptions *BrowserOptions) error

NewContext is a method which instantiates an isolated browser context mapping. This facilitates multi-session setups, allowing concurrent page pipelines to execute with customized dimensions and distinct request headers. In addition, the following should be noted:

  • This method automatically adds random viewport variations to the requested size. This prevents automated web servers from detecting identical static resolution fingerprints across repeatedly spawned browser automation sessions.

  • Every context answers JavaScript dialogs according to SetDialogOptions, including dialogs shown before that method is first called, so a dialog can never leave a page stuck waiting for an answer.

  • The user agent and saved session (StorageStatePath) are taken from browserOptions when it is non-nil, and from the BrowserOptions the Instance was initialized with otherwise. An empty UserAgent leaves Playwright's default user agent in place, and an empty StorageStatePath starts the context with a clean session.

Example:

err := agent.NewContext("guest-session", 1280, 720, nil)

func (*Instance) NewPage

func (shared *Instance) NewPage(aliasName string) error

NewPage is a method which allocates and configures a brand-new page inside the active context. This registers a logical tab where DOM traversals and automation scripts can execute independently of other tabs.

Example:

err := agent.NewPage("dashboard-tab")

func (*Instance) PressKey

func (shared *Instance) PressKey(key string) error

PressKey is a method which allows you to press a single key or key combination on the active page, sending it to whichever element currently has focus. key uses Playwright's key names, for example "Enter", "Tab", "Escape", "ArrowDown", "a", or a combination joined with "+" such as "Control+A" or "Shift+Tab". Use PressKeyOnElement to target a specific element instead of the focused one.

Example:

err := agent.PressKey("Enter")

func (*Instance) PressKeyOnElement

func (shared *Instance) PressKeyOnElement(key string, selector Selector, parentLocator playwright.Locator, options ...ActionOptions) error

PressKeyOnElement is a method which allows you to focus the element matched by selector and press a key or key combination on it, using the same key names as PressKey. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned and no key is pressed.

Example:

err := agent.PressKeyOnElement("Enter", elementary.Selector{Value: "css=#search", Description: "search box"}, nil)

func (*Instance) Repair

func (shared *Instance) Repair() error

Repair is a method which resets the specific driver, stealth-patch copy, and browser binary directories this Instance actually resolves to, then reinstalls them fresh. This performs the recovery step silently and registers the driver packages, returning any error encountered during cleanup. In addition, the following should be noted:

  • This method honors the PLAYWRIGHT_DRIVER_PATH and PLAYWRIGHT_BROWSERS_PATH environment variable overrides the same way InitializeDriver does, rather than assuming the default OS cache location. Repairing an Instance whose driver was installed to a custom location would otherwise silently miss the corrupted directory and reinstall to the wrong place.

  • This method never deletes the shared, unpatched driver directory when this Instance was configured with StealthPatch — only the stealth-patched sibling copy, via RestoreStealthPatch (see stealthpatch.go), is removed and rebuilt. A StealthPatch Instance never runs against the unpatched driver directory directly (it is only ever read from to build the sibling copy), so deleting it would serve no purpose for this Instance while forcing an unrelated plain Instance sharing the same cache to redo its driver install, or breaking it outright if that plain Instance's driver is still running. A plain Instance repairing its driver never touches a patched sibling's copy either. The browser binary directory remains shared either way — StealthPatch does not build a separate copy of it — so repairing it is a step every Instance sharing the cache genuinely depends on.

  • This method rebuilds the stealth-patched copy immediately when this Instance uses StealthPatch, so Repair alone leaves the Instance ready to relaunch without depending on Initialize's retry path to notice the copy is missing.

  • This method returns an error if the Instance's driver is still running rather than deleting directories out from under it; callers should call this after Close, not before, the same as RestoreStealthPatch.

Example:

err := agent.Repair()

func (*Instance) ResetContext

func (shared *Instance) ResetContext(contextAlias string, viewportWidth int, viewportHeight int, browserOptions *BrowserOptions) error

ResetContext is a method which allows you to close and regenerate a specified browser context. This discards all active cookies, cached storage pools, and session tracking states, returning the environment to a pristine state. It returns any error raised while creating the replacement context, so a failed reset is never mistaken for a successful one.

Example:

err := agent.ResetContext("main-session", 1920, 1080, nil)

func (*Instance) Restart

func (shared *Instance) Restart() error

Restart is a method which restarts the browser simulation engine using identical startup properties. This is valuable for re-establishing a pristine test environment to clear memory fragmentation or bypass frozen browser states. In addition, the following should be noted:

  • This method first calls Shutdown to terminate any active browser processes and clear state before invoking Initialize. This ensures that resources are fully released before a new browser engine is spun up.

  • This method restores any timeouts previously set via SetTimeout, SetNavigationTimeout, or SetPlaywrightTimeout, and any selector engine previously set via SetDefaultSelectorEngine, after Initialize completes. Initialize/InitializeDriver otherwise reset these to hardcoded defaults on every call, which would silently undo prior customization on every restart despite this method's "identical startup properties" contract.

Example:

err := agent.Restart()

func (*Instance) RestoreStealthPatch

func (shared *Instance) RestoreStealthPatch() error

RestoreStealthPatch is a method which removes a previously built patched driver copy, freeing the disk space it used and forcing the next StealthPatch-enabled Initialize to rebuild it from scratch. Because the stealth patch feature never modifies the original driver directory — StealthPatch-enabled and StealthPatch-disabled Instances always run against separate driver copies — this never needs to restore anything to the original; it only ever deletes the sibling copy. This is a no-op if no patched copy was ever built. Callers should call this after Close, not before: on Windows, deleting a directory that a still-running driver process has files open in fails with a sharing violation, so this returns an error if the Instance's driver is still running rather than failing with a confusing platform-specific error later.

Example:

err := agent.RestoreStealthPatch()

func (*Instance) RestoreWindow

func (shared *Instance) RestoreWindow() error

RestoreWindow is a method which allows you to undo a prior minimize by returning the active browser window to its normal state via the Chrome DevTools Protocol, and disables the background watcher, if any, enforcing that specific window. In addition, the following should be noted:

  • This method is only supported when the active browser is Chrome, since it relies on the Chrome DevTools Protocol's Browser domain. Calling it while any other browser is active returns an error without attempting the operation.

  • This method returns nil without effect if no page is currently active, since there is no window to target.

  • This method only stops the watcher for the window behind the currently active page. Watchers enforcing other windows are left running.

  • This method stops that watcher before restoring the window, so it cannot race the restore and immediately re-minimize it.

Example:

err := agent.RestoreWindow()

func (*Instance) SaveNetscapeCookies

func (shared *Instance) SaveNetscapeCookies(fileName string) error

SaveNetscapeCookies is a method which serializes active context cookies to an output file in the Netscape text format. This persists authentications, session parameters, and identity tokens for reuse across future automation sessions. In addition, the following should be noted:

  • This method will automatically attempt to delete any pre-existing cookie file matching the specified filename. This prevents file-write collisions and ensures that obsolete or expired credentials are not retained in the output destination file.

Example:

err := agent.SaveNetscapeCookies("my_cookies.txt")

func (*Instance) SaveScreenshot

func (shared *Instance) SaveScreenshot(path string, screenshotName string, options ...ActionOptions) error

SaveScreenshot is a method which captures a full-page snapshot and writes the output directly to disk. This is useful for archiving visual evidence, creating a clear execution audit trail, or inspecting rendering failures offline. In addition, the following should be noted:

  • This method obtains the screenshot bytes via GetScreenshotAsBinary and then persists them itself, rather than duplicating the capture logic or relying on Playwright's own Path-based save option (which would otherwise result in the same bytes being written to disk twice: once by Playwright and once by this method).

  • This method writes a file directly to the host filesystem, which requires appropriate write permissions for the target directory. If the directory does not exist, this method will attempt to create it automatically.

  • This method normalizes the filename by removing illegal characters and prepending a timestamp in the format YYYY-MM-DD_HH-MM-SS. This prevents naming collisions and filesystem issues across different operating systems.

Example:

err := agent.SaveScreenshot("./debug/", "failure_view.png", ActionOptions{InfiniteTimeout: true})

func (*Instance) SaveStorageState

func (shared *Instance) SaveStorageState(fileName string) error

SaveStorageState is a method which allows you to write the active browser context's full session, its cookies and the local storage of every origin it has visited, to fileName as JSON. Loading that file back through BrowserOptions.StorageStatePath restores the session, including logins that keep their tokens in local storage rather than cookies, which SaveNetscapeCookies alone cannot capture. In addition, the following should be noted:

  • An existing file at fileName is overwritten.

  • The file contains live session credentials, so it should be stored with the same care as a password.

Example:

err := agent.SaveStorageState("session.json")

func (*Instance) ScrollPageBy

func (shared *Instance) ScrollPageBy(xPixels int, yPixels int) error

ScrollPageBy is a method which allows you to scroll the active page by xPixels horizontally and yPixels vertically, relative to its current position. Positive values scroll right and down, negative values scroll left and up. This suits pages that load more results as you scroll. In addition, the following should be noted:

  • The scroll is instant even on pages that style scrolling as smooth, so the new position is in effect as soon as this returns. Scrolling past either end of the page simply stops there.

Example:

err := agent.ScrollPageBy(0, 800)

func (*Instance) ScrollToElement

func (shared *Instance) ScrollToElement(selector Selector, parentLocator playwright.Locator, options ...ActionOptions) error

ScrollToElement is a method which allows you to scroll the page, and any scrollable containers, just enough to bring the element matched by selector into view. Nothing scrolls if the element is already fully visible. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned.

Example:

err := agent.ScrollToElement(elementary.Selector{Value: "css=footer", Description: "page footer"}, nil)

func (*Instance) SelectOption

func (shared *Instance) SelectOption(selector Selector, values []string, parentLocator playwright.Locator, options ...ActionOptions) ([]string, error)

SelectOption is a method which allows you to choose one or more options in the <select> dropdown matched by selector, returning the values of the options that ended up selected. Each entry in values matches an option by either its value attribute or its visible label, so callers can pass whichever is more convenient. In addition, the following should be noted:

  • A single-choice dropdown selects only the first option matching any entry. Selecting several options requires the dropdown to carry the "multiple" attribute.

  • An empty values slice returns an error rather than clearing the selection. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned. If an entry matches no option, Playwright keeps waiting for it to appear until the timeout and then returns an error.

Example:

selected, err := agent.SelectOption(elementary.Selector{Value: "css=#country", Description: "country"}, []string{"Canada"}, nil)

func (*Instance) SetChecked

func (shared *Instance) SetChecked(selector Selector, checked bool, parentLocator playwright.Locator, options ...ActionOptions) error

SetChecked is a method which allows you to tick or untick the checkbox or radio button matched by selector, so it ends up checked when checked is true and unchecked when it is false. Calling it when the element is already in the requested state does nothing. If no element matches the selector within the timeout, an error wrapping ErrElementNotFound is returned. In addition, the following should be noted:

  • A radio button cannot be unchecked directly; passing false for a checked radio button returns an error. Check a different radio button in the same group instead.

Example:

err := agent.SetChecked(elementary.Selector{Value: "css=#terms", Description: "terms checkbox"}, true, nil)

func (*Instance) SetDefaultSelectorEngine

func (shared *Instance) SetDefaultSelectorEngine(engine string)

SetDefaultSelectorEngine is a method which overrides which Playwright locator engine unprefixed selector strings are parsed as (SELECTOR_ENGINE_XPATH or SELECTOR_ENGINE_CSS). Selectors that already declare their own engine (e.g. "css=.btn", "role=button", "text=Submit") are unaffected by this setting — it only applies when a selector has no engine prefix at all. Defaults to SELECTOR_ENGINE_XPATH, so calling this is only necessary to opt into a different default.

Example:

agent.SetDefaultSelectorEngine(elementary.SELECTOR_ENGINE_CSS)

func (*Instance) SetDialogOptions

func (shared *Instance) SetDialogOptions(options DialogOptions)

SetDialogOptions is a method which allows you to choose how every JavaScript dialog (alert, confirm, prompt, and beforeunload) is answered from now on, across every browser context the Instance controls, including contexts created later. Until this is called, every dialog is dismissed. In addition, the following should be noted:

  • The options are read at the moment each dialog appears, so a change takes effect for the very next dialog, including on pages that are already open.

  • The options persist across Restart.

Example:

agent.SetDialogOptions(elementary.DialogOptions{Accept: true, PromptText: "yes"})

func (*Instance) SetNavigationTimeout

func (shared *Instance) SetNavigationTimeout(timeout time.Duration)

SetNavigationTimeout is a method which overrides the default timeout threshold for page navigations. This adjusts how long driver operations wait for page loads, redirections, or URL changes to complete before failing.

Example:

agent.SetNavigationTimeout(45 * time.Second)

func (*Instance) SetPlaywrightTimeout

func (shared *Instance) SetPlaywrightTimeout(timeout time.Duration)

SetPlaywrightTimeout is a method which overrides the default timeout threshold for internal Playwright operations. This adjusts how long low-level Playwright execution loops wait before throwing system errors.

Example:

agent.SetPlaywrightTimeout(10 * time.Second)

func (*Instance) SetScreenshotOptions

func (shared *Instance) SetScreenshotOptions(options ScreenshotOptions) error

SetScreenshotOptions is a method which configures every aspect of automated screenshot capture in a single call: the target directory, which action stages trigger a capture, and optional TAR archiving. In addition, the following should be noted:

  • This method replaces the entire prior configuration rather than merging with it, so callers that only want to change one field must pass the others through unchanged (e.g. built from a previously stored ScreenshotOptions).

  • This method tears down and replaces any existing archiver whenever it is called, even if options.ArchiveFilename names the same file as before. Passing options.ArchiveFilename == "" disables archiving and closes (i.e. gzip-finalizes, see ArchiveFilename) any archiver currently open.

  • This method resolves the archive path as options.Directory joined with options.ArchiveFilename, so archiving requires both fields to be set.

Example:

err := agent.SetScreenshotOptions(elementary.ScreenshotOptions{
    Directory:       "./screenshots",
    BeforeAction:    true,
    AfterAction:     true,
    OnFailure:       true,
    ArchiveFilename: "archive.tar",
})

func (*Instance) SetTimeout

func (shared *Instance) SetTimeout(timeout time.Duration)

SetTimeout is a method which overrides the default timeout threshold for element interactions. This adjusts how long driver operations wait for selectors to resolve or become interactable before failing.

Example:

agent.SetTimeout(5 * time.Second)

func (*Instance) Shutdown

func (shared *Instance) Shutdown()

Shutdown is a method which executes an immediate reset of all active session fields. This halts the browser engine and discards context mappings without raising errors, returning instance registers back to their clean zero states. In addition, the following should be noted:

  • This method mutates internal state fields of the instance, nil-ing out playwrightInstance, browserInstance, contextInstances, and currentPage while setting context and page indices to 0. This prepares the instance for a clean re-initialization.

Example:

agent.Shutdown()

func (*Instance) SwitchContext

func (shared *Instance) SwitchContext(contextAlias string) error

SwitchContext is a method which transfers structural focus to a distinct browser context by alias. This redirects the target context pool, maintaining isolated cookiestores and state profiles across browser pipelines. In addition, the following should be noted:

- This method will return an error if the requested context alias is not found in the instances list, preventing silent state failures.

- This method clears the active page reference on success, ensuring the developer explicitly switches to a page under the new context.

Example:

err := agent.SwitchContext("admin-session")

func (*Instance) SwitchPage

func (shared *Instance) SwitchPage(contextAlias string, pageAlias string) bool

SwitchPage is a method which coordinates page targeting by shifting execution focus to a specified logical tab. This allows navigating between parent windows and spawned popup views seamlessly within the targeted context structure.

Example:

switched := agent.SwitchPage("guest-session", "landing-tab")

func (*Instance) SwitchToFrame

func (shared *Instance) SwitchToFrame(selector Selector, options ...ActionOptions) error

SwitchToFrame is a method which allows you to move into the iframe matched by selector, so that every element method (finding, clicking, filling, reading, waiting, hovering, uploading, form controls, and downloads) works inside that frame from then on. Calling it again while inside a frame moves into a frame nested within the current one. In addition, the following should be noted:

  • The selector is resolved within the current frame, and the element it matches must be an iframe or frame; anything else returns an error and leaves the current frame unchanged. If no element matches within the timeout, an error wrapping ErrElementNotFound is returned.

  • Any change of the active page, including switching away and back, opening or closing a page, or switching context, returns lookups to the main frame, as does NavigateTo or NavigateBack. A navigation the page starts on its own, such as a link click or a redirect, does not, since Elementary cannot tell it apart from one that only reloads part of the page.

  • JavaScript evaluation, ScrollPageBy, MouseClick, and MoveMouse still act on the page as a whole, not the frame. Use SwitchToParentFrame or SwitchToMainFrame to step back out.

  • The frame is looked up afresh on every action, so it keeps working if the frame reloads, as long as its selector still matches.

Example:

err := agent.SwitchToFrame(elementary.Selector{Value: "css=iframe#payment", Description: "payment frame"})
err = agent.FillElement("4242 4242 4242 4242", cardNumberSelector, nil)
agent.SwitchToMainFrame()

func (*Instance) SwitchToMainFrame

func (shared *Instance) SwitchToMainFrame()

SwitchToMainFrame is a method which allows you to leave every frame and return element lookups to the current page as a whole. It does nothing when already on the main page.

Example:

agent.SwitchToMainFrame()

func (*Instance) SwitchToParentFrame

func (shared *Instance) SwitchToParentFrame()

SwitchToParentFrame is a method which allows you to step out of the current frame into the frame that contains it, or into the main page when the current frame is a top-level iframe. It does nothing when already on the main page.

Example:

agent.SwitchToParentFrame()

func (*Instance) SwitchToSpawnedPage

func (shared *Instance) SwitchToSpawnedPage() bool

SwitchToSpawnedPage is a method which shifts active context focus to the most recently detected unmapped tab. This helps coordinate Page manipulation during complex identity provider flows, SSO checks, or multi-window dialog runs.

Example:

success := agent.SwitchToSpawnedPage()

func (*Instance) SwitchToUntrackedPage

func (shared *Instance) SwitchToUntrackedPage(pageIndex int) bool

SwitchToUntrackedPage is a method which re-targets page execution focus to an untracked index slot. This gains control over recently discovered browser tabs or child windows spawned by user interactions or redirection blocks.

Example:

success := agent.SwitchToUntrackedPage(1)

func (*Instance) Terminate

func (shared *Instance) Terminate() error

Terminate is a method which stops all running contexts and terminates backend browser processes. This guarantees clean termination of the automation lifecycle, preventing stray web driver processes from consuming system resources. In addition, the following should be noted:

  • This method clears internal references by setting playwrightInstance, browserInstance, contextInstances, and currentPage to nil. This allows the garbage collector to reclaim memory allocated to the browser session.

Example:

err := agent.Terminate()

func (*Instance) UploadFile

func (shared *Instance) UploadFile(selector Selector, fileName string, options ...ActionOptions) error

UploadFile is a method which allows you to bind a single local file to a target file input DOM selector. It is a convenience wrapper around UploadFiles for the common one-file case, and behaves identically to calling UploadFiles with a one-element slice.

Example:

err := agent.UploadFile(elementary.Selector{Value: "css=input[type='file']"}, "test-image.jpg", ActionOptions{Timeout: 5 * time.Second})

func (*Instance) UploadFiles

func (shared *Instance) UploadFiles(selector Selector, fileNames []string, options ...ActionOptions) error

UploadFiles is a method which allows you to bind one or more local files to a target file input DOM selector, replacing whatever files the input previously held. This automates multi-part file uploads, labelling each upload with the MIME type inferred from its file name's extension rather than assuming a fixed type. In addition, the following should be noted:

  • An unrecognized or missing extension falls back to "application/octet-stream", the standard generic binary MIME type, rather than mislabelling the upload as a specific type it may not actually be.

  • Only each file's base name is exposed to the page, never its full local path, so uploads do not leak the host's directory layout to the site.

  • The selector is resolved through the instance's default selector engine exactly like every other action, so an unprefixed selector is treated as XPath unless SetDefaultSelectorEngine says otherwise.

  • Selecting more than one file requires the target input to carry the "multiple" attribute; the browser rejects the upload otherwise. An empty fileNames slice returns an error rather than clearing the input.

Example:

err := agent.UploadFiles(elementary.Selector{Value: "css=input[type='file']"}, []string{"front.jpg", "back.jpg"})

func (*Instance) WaitForDownload

func (shared *Instance) WaitForDownload(action func() error, destinationDirectory string, options ...ActionOptions) (string, error)

WaitForDownload is a method which allows you to run action, wait for the download it starts on the active page, and save the finished file into destinationDirectory, returning the saved file's path. action is whatever triggers the download, such as a click. The file keeps the name the site suggests. In addition, the following should be noted:

  • destinationDirectory is created when it does not exist.

  • The suggested name is reduced to a plain file name with illegal characters replaced, so a site cannot write outside destinationDirectory with a name such as "../../evil". An existing file is never overwritten; a number is added instead, as in "report (1).pdf".

  • The timeout bounds only how long to wait for the download to start, defaulting to the navigation timeout. Once started, the method waits for the download to finish however long it takes.

  • An error is returned if action fails, no download starts in time, or the download fails part way.

Example:

path, err := agent.WaitForDownload(func() error {
    return agent.ClickElement(elementary.Selector{Value: "css=#export", Description: "export button"}, nil)
}, "./downloads")

func (*Instance) WaitForElementCount

func (shared *Instance) WaitForElementCount(selector Selector, parentLocator playwright.Locator, elementInstanceCount int, options ...ActionOptions) error

WaitForElementCount is a method which blocks execution until the matched elements reach a specific count. This is useful for waiting for dynamic additions or AJAX lists to finish rendering. In addition, the following should be noted:

  • This method counts against the full, un-narrowed locator for selector rather than a .First()-scoped one, so it can correctly wait for counts greater than 1. Reusing GetElement here would silently cap every wait at a maximum observable count of 1, since GetElement narrows its returned locator to the first match.

Example:

err := agent.WaitForElementCount(elementary.Selector{Value: "css=tr.table-row"}, nil, 10, ActionOptions{Timeout: 4 * time.Second})

func (*Instance) WaitForElementExistenceStatus

func (shared *Instance) WaitForElementExistenceStatus(selector Selector, parentLocator playwright.Locator, isExistStatus bool, options ...ActionOptions) error

WaitForElementExistenceStatus is a method which blocks until an element's existence status matches the target value. This is useful for waiting for loading overlays to detach or target panels to attach to the tree.

Example:

err := agent.WaitForElementExistenceStatus(elementary.Selector{Value: "css=div#spinner"}, nil, false, ActionOptions{Timeout: 5 * time.Second})

func (*Instance) WaitForElementVisibleStatus

func (shared *Instance) WaitForElementVisibleStatus(selector Selector, element playwright.ElementHandle, isVisibleStatus bool, options ...ActionOptions) error

WaitForElementVisibleStatus is a method which blocks execution until the element matches the target visibility status. This is useful for waiting for visual fades or transition stages to resolve before interaction.

Example:

err := agent.WaitForElementVisibleStatus(elementary.Selector{Value: "//div[@id='modal']"}, nil, true, ActionOptions{Timeout: 3 * time.Second})

func (*Instance) WaitForPageToBeReady

func (shared *Instance) WaitForPageToBeReady() error

WaitForPageToBeReady is a method which blocks execution until the page reaches the DOMContentLoaded state. This secures a parsed page model before executing actions, without waiting on NetworkIdle, which can stall well past DOM readiness on pages with persistent connections (ads, analytics beacons, websockets).

Example:

err := agent.WaitForPageToBeReady()

func (*Instance) WaitForPageToChange

func (shared *Instance) WaitForPageToChange(continueIfUrlContains string, options ...ActionOptions) error

WaitForPageToChange is a method which allows you to block execution until the active tab registers a DOM content loaded event, then poll until the page URL contains continueIfUrlContains (when non-empty). This is useful for waiting for simple document updates or page transition boundaries. It returns an error if no page is active, if the DOM content loaded event does not arrive in time, or if the URL never comes to contain continueIfUrlContains before the timeout.

Example:

err := agent.WaitForPageToChange("/dashboard", ActionOptions{Timeout: 5 * time.Second})

type ProxyOptions

type ProxyOptions struct {
	// Server is the proxy address, for example "http://myproxy.com:3128" or "socks5://myproxy.com:3128". A form
	// without a scheme such as "myproxy.com:3128" is treated as an HTTP proxy. Required.
	Server string

	// Bypass is an optional comma-separated list of domains that connect directly instead of through the proxy, for
	// example ".example.com, internal.local".
	Bypass string

	// Username and Password are optional credentials for an HTTP proxy that requires authentication.
	Username string
	Password string
}

ProxyOptions is a structure which describes the proxy server BrowserOptions.Proxy routes browser traffic through.

type ScreenshotOptions

type ScreenshotOptions struct {
	// Directory is the target directory where automated task screenshots are saved. Automated
	// capture (BeforeAction, AfterAction, OnFailure) is disabled entirely while this is empty,
	// regardless of those flags. When ArchiveFilename is also set, this is where the archive
	// itself is created rather than where loose screenshot files are written.
	Directory string

	// BeforeAction enables automatic screenshot capture right before any state-changing action.
	BeforeAction bool

	// AfterAction enables automatic screenshot capture right after any state-changing action.
	AfterAction bool

	// OnFailure enables automatic screenshot capture whenever an action fails.
	OnFailure bool

	// ArchiveFilename, when set, routes every saved screenshot into a TAR archive of this name
	// created inside Directory, instead of writing loose PNG files. Empty disables archiving.
	//
	// Each screenshot is appended directly to the working ".tar" file as it is captured, so it
	// survives an ungraceful shutdown (crash, panic, killed process) intact. Unlike a ZIP archive,
	// TAR has no central index that must be finalized for prior entries to remain readable. On a
	// graceful shutdown (SetScreenshotOptions called again, or the instance closed), the archive is
	// gzip-compressed into "<ArchiveFilename>.gz" and the intermediate plain TAR file is removed.
	ArchiveFilename string
}

ScreenshotOptions is a structure which bundles all automated screenshot behavior into a single configuration unit, covering where captures are saved, which action stages trigger a capture, and whether captures are collected into a TAR archive rather than written as loose files.

type Selector

type Selector struct {
	Value       string
	Description string

	// Timeout overrides the instance's default element timeout for every action performed
	// against this selector. The zero value means "not specified," in which case the caller's
	// per-call ActionOptions.Timeout (if any) or the instance default applies instead — the same
	// zero-means-unset convention already used by ActionOptions.Timeout.
	Timeout time.Duration
}

Selector is a structure which pairs a Playwright-style selector string with a human-readable description of the element it targets. Every action method that locates an element by selector accepts one of these instead of a bare string, so that reusable, named selectors (declared once, referenced everywhere) automatically carry a meaningful label into logs, screenshots, and error messages instead of a raw CSS/XPath expression. Named Selector rather than Locator since several methods already take a resolved playwright.Locator alongside it, and reusing "Locator" for both would make those signatures ambiguous.

Example:

var OkButtonSelector = elementary.Selector{Value: "//button[1]", Description: "OK button"}
var SlowWidgetSelector = elementary.Selector{Value: "#slow-widget", Timeout: 15 * time.Second}

func (Selector) String

func (selector Selector) String() string

String is a method that returns the Selector's Description when set, falling back to Value otherwise. Because Selector implements fmt.Stringer, every existing %s-formatted log and error message resolves to this automatically.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL