DOM
DOM API
Section titled “DOM API”getElementById(id)querySelector(selector)querySelectorAll(selector)getFrame(selector)getFrameElement(selector)getByRole(role, options?)getByText(text, options?)getByLabel(label, options?)getByPlaceholder(text, options?)getByAltText(text, options?)getByTitle(text, options?)getByDataAttribute(name, value, options?)getByXPath(xpath)querySelectorWithin(parent, selector)querySelectorAllWithin(parent, selector)getAttribute(handle, name)disposeElement(handle)waitForElement(selector, options?)getElementBounds(selectorOrHandle, timeoutMs?)getElementCenter(selectorOrHandle, options?)findEditableClickTarget()clickEditableTarget()getActiveElementState()
Element handle workflow
Section titled “Element handle workflow”ElementHandle lets you resolve an element once and reuse it for nested queries and actions.
querySelector(selector) is your CSS locator.
getByXPath(xpath) is the XPath locator.
getFrame(selector) returns a chainable frame locator with the same lookup methods as view.
getFrameElement(selector) returns the underlying frame or iframe element handle when you need a raw reference.
Open shadow roots and same-origin iframe documents are traversed by the built-in locator methods.
const loginButton = await view.getByRole("button", { name: "Sign in" });const username = await view.getByLabel("Username");const email = await view.getByPlaceholder("Email address");const logo = await view.getByAltText("Company logo");const title = await view.getByTitle("More info");const note = await view.getByDataAttribute("testid", "notice");const xpathNode = await view.getByXPath("//button[@id='submit']");const frame = await view.getFrame("iframe#payment-frame");const frameButton = await frame?.getByRole("button", { name: "Pay now" });const frameNote = await frame?.getByText("Payment note", { exact: true });const section = await view.getElementById("profile");if (!section) throw new Error("section not found");
const saveButton = await view.querySelectorWithin(section, "button.save");if (!saveButton) throw new Error("save button not found");
const todoItems = await view.querySelectorAllWithin(section, ".todo");for (const item of todoItems) { await view.getAttribute(item, "data-id");}
const role = await view.getAttribute(saveButton, "data-role");const bounds = await view.getElementBounds(saveButton);
await view.click(saveButton);
await view.disposeElement(saveButton);for (const item of todoItems) { await view.disposeElement(item);}await view.disposeElement(section);Locator notes
Section titled “Locator notes”getByRole()uses a best-effort accessible role and accessible-name match.getByText()matches visible text content.getByLabel()resolves form controls by associated label text,aria-label, oraria-labelledby.getByPlaceholder()matches placeholder text on inputs and textareas.getByAltText()matchesalttext on image-like elements.getByTitle()matches thetitleattribute.getByDataAttribute()matchesdata-*attributes by name and value.getByXPath()uses the browser XPath engine and returns the first matched element.querySelector()andquerySelectorAll()remain the CSS locator primitives.- Locator searches recurse through open shadow roots and same-origin iframe documents.
Wait strategies
Section titled “Wait strategies”observer: MutationObserver-based detection.poll: repeated DOM checks on a timer.