A high-level API to automate Chromium
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Modern element interaction API providing both traditional ElementHandle references and the new Locator interface with auto-waiting capabilities and comprehensive element state checking.
Modern element interaction API with built-in waiting, retry logic, and improved reliability for dynamic web applications.
/**
* Modern element locator with auto-waiting capabilities
*/
interface Locator {
/** Click the element with auto-waiting */
click(options?: LocatorClickOptions): Promise<void>;
/** Double-click the element */
dblclick(options?: LocatorDblclickOptions): Promise<void>;
/** Fill input element with text */
fill(value: string, options?: LocatorFillOptions): Promise<void>;
/** Type text into element */
type(text: string, options?: LocatorTypeOptions): Promise<void>;
/** Press a key on the element */
press(key: string, options?: LocatorPressOptions): Promise<void>;
/** Check checkbox or radio button */
check(options?: LocatorCheckOptions): Promise<void>;
/** Uncheck checkbox */
uncheck(options?: LocatorUncheckOptions): Promise<void>;
/** Select options from dropdown */
selectOption(values: string | string[] | SelectOption | SelectOption[], options?: LocatorSelectOptionOptions): Promise<string[]>;
/** Get text content of element */
textContent(options?: LocatorTextContentOptions): Promise<string | null>;
/** Get inner text of element */
innerText(options?: LocatorInnerTextOptions): Promise<string>;
/** Get inner HTML of element */
innerHTML(options?: LocatorInnerHTMLOptions): Promise<string>;
/** Get attribute value */
getAttribute(name: string, options?: LocatorGetAttributeOptions): Promise<string | null>;
/** Get input value */
inputValue(options?: LocatorInputValueOptions): Promise<string>;
/** Check if element is checked */
isChecked(options?: LocatorIsCheckedOptions): Promise<boolean>;
/** Check if element is disabled */
isDisabled(options?: LocatorIsDisabledOptions): Promise<boolean>;
/** Check if element is editable */
isEditable(options?: LocatorIsEditableOptions): Promise<boolean>;
/** Check if element is enabled */
isEnabled(options?: LocatorIsEnabledOptions): Promise<boolean>;
/** Check if element is hidden */
isHidden(options?: LocatorIsHiddenOptions): Promise<boolean>;
/** Check if element is visible */
isVisible(options?: LocatorIsVisibleOptions): Promise<boolean>;
/** Take screenshot of element */
screenshot(options?: LocatorScreenshotOptions): Promise<Buffer>;
/** Scroll element into view if needed */
scrollIntoViewIfNeeded(options?: LocatorScrollIntoViewIfNeededOptions): Promise<void>;
/** Wait for element to be in specific state */
waitFor(options?: LocatorWaitForOptions): Promise<void>;
/** Get count of matching elements */
count(): Promise<number>;
/** Get first matching element */
first(): Locator;
/** Get last matching element */
last(): Locator;
/** Get nth matching element */
nth(index: number): Locator;
/** Filter locator by text or attribute */
filter(options: LocatorFilterOptions): Locator;
/** Combine locator with AND logic */
and(locator: Locator): Locator;
/** Combine locator with OR logic */
or(locator: Locator): Locator;
/** Find child elements */
locator(selector: string): Locator;
}Usage Examples:
// Create locators
const submitButton = page.locator('button[type="submit"]');
const emailInput = page.locator('input[name="email"]');
const items = page.locator('.item');
// Interact with elements (auto-waiting)
await emailInput.fill('user@example.com');
await submitButton.click();
// Check element states
const isVisible = await submitButton.isVisible();
const isDisabled = await submitButton.isDisabled();
const count = await items.count();
// Filter and chain locators
const activeItems = items.filter({ hasText: 'Active' });
const firstItem = items.first();
const specificItem = items.nth(2);
// Combine locators
const buttons = page.locator('button');
const submitButtons = buttons.filter({ hasText: 'Submit' });
const primaryOrSecondary = page.locator('.primary').or(page.locator('.secondary'));
// Child element selection
const form = page.locator('form');
const formInput = form.locator('input[name="email"]');Direct DOM element references for advanced manipulation and when fine-grained control is needed.
/**
* Direct reference to DOM elements
*/
interface ElementHandle {
/** Click the element */
click(options?: ElementHandleClickOptions): Promise<void>;
/** Double-click the element */
dblclick(options?: ElementHandleDblclickOptions): Promise<void>;
/** Fill input element */
fill(value: string, options?: ElementHandleFillOptions): Promise<void>;
/** Type text into element */
type(text: string, options?: ElementHandleTypeOptions): Promise<void>;
/** Press a key on element */
press(key: string, options?: ElementHandlePressOptions): Promise<void>;
/** Check checkbox or radio */
check(options?: ElementHandleCheckOptions): Promise<void>;
/** Uncheck checkbox */
uncheck(options?: ElementHandleUncheckOptions): Promise<void>;
/** Select options from dropdown */
selectOption(values: string | string[] | SelectOption | SelectOption[], options?: ElementHandleSelectOptionOptions): Promise<string[]>;
/** Get text content */
textContent(): Promise<string | null>;
/** Get inner text */
innerText(): Promise<string>;
/** Get inner HTML */
innerHTML(): Promise<string>;
/** Get attribute value */
getAttribute(name: string): Promise<string | null>;
/** Get input value */
inputValue(): Promise<string>;
/** Check if checked */
isChecked(): Promise<boolean>;
/** Check if disabled */
isDisabled(): Promise<boolean>;
/** Check if editable */
isEditable(): Promise<boolean>;
/** Check if enabled */
isEnabled(): Promise<boolean>;
/** Check if hidden */
isHidden(): Promise<boolean>;
/** Check if visible */
isVisible(): Promise<boolean>;
/** Get bounding box */
boundingBox(): Promise<{ x: number; y: number; width: number; height: number; } | null>;
/** Take screenshot */
screenshot(options?: ElementHandleScreenshotOptions): Promise<Buffer>;
/** Scroll into view if needed */
scrollIntoViewIfNeeded(options?: ElementHandleScrollIntoViewIfNeededOptions): Promise<void>;
/** Wait for element state */
waitForElementState(state: 'visible' | 'hidden' | 'stable' | 'enabled' | 'disabled' | 'editable', options?: ElementHandleWaitForElementStateOptions): Promise<void>;
/** Wait for child selector */
waitForSelector(selector: string, options?: ElementHandleWaitForSelectorOptions): Promise<ElementHandle | null>;
/** Query selector within element */
querySelector(selector: string): Promise<ElementHandle | null>;
/** Query all selectors within element */
querySelectorAll(selector: string): Promise<ElementHandle[]>;
/** Evaluate function on element */
evaluate<R, Arg>(pageFunction: PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<R>;
/** Evaluate and return handle */
evaluateHandle<R, Arg>(pageFunction: PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<JSHandle<R>>;
/** Get owner frame */
ownerFrame(): Promise<Frame | null>;
/** Convert to JSHandle */
asElement(): ElementHandle | null;
}Usage Examples:
// Get element handles
const button = await page.$('button.submit');
const inputs = await page.$$('input[type="text"]');
// Direct element manipulation
if (button) {
await button.click();
const text = await button.textContent();
const box = await button.boundingBox();
if (box) {
console.log(`Button at: ${box.x}, ${box.y}`);
}
}
// Element queries
const form = await page.$('form');
if (form) {
const emailInput = await form.querySelector('input[name="email"]');
const allInputs = await form.querySelectorAll('input');
}
// Evaluate on element
const value = await button?.evaluate(el => el.dataset.value);References to JavaScript objects in the page context, including DOM elements and other objects.
/**
* Reference to JavaScript objects in page context
*/
interface JSHandle<T = any> {
/** Evaluate function with this handle */
evaluate<R, Arg>(pageFunction: PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<R>;
/** Evaluate and return new handle */
evaluateHandle<R, Arg>(pageFunction: PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<JSHandle<R>>;
/** Get object property */
getProperty(propertyName: string): Promise<JSHandle>;
/** Get all properties */
getProperties(): Promise<Map<string, JSHandle>>;
/** Serialize to JSON */
jsonValue(): Promise<T>;
/** Convert to ElementHandle if possible */
asElement(): ElementHandle | null;
/** Release the handle */
dispose(): Promise<void>;
}Usage Examples:
// Get window object
const windowHandle = await page.evaluateHandle(() => window);
// Access properties
const location = await windowHandle.getProperty('location');
const href = await location.getProperty('href');
const url = await href.jsonValue();
// Get all properties
const props = await windowHandle.getProperties();
for (const [name, handle] of props) {
console.log(`Property: ${name}`);
}
// Cleanup
await windowHandle.dispose();/**
* Find element by selector (returns first match)
* @param selector - CSS selector
* @returns ElementHandle or null
*/
$(selector: string): Promise<ElementHandle | null>;
/**
* Find all elements by selector
* @param selector - CSS selector
* @returns Array of ElementHandles
*/
$$(selector: string): Promise<ElementHandle[]>;
/**
* Create a locator for element(s)
* @param selector - CSS selector
* @returns Locator instance
*/
locator(selector: string): Locator;
/**
* Get element by text content
* @param text - Text to search for
* @param options - Text search options
* @returns Locator instance
*/
getByText(text: string | RegExp, options?: LocatorGetByTextOptions): Locator;
/**
* Get element by label text
* @param text - Label text
* @param options - Label search options
* @returns Locator instance
*/
getByLabel(text: string | RegExp, options?: LocatorGetByLabelOptions): Locator;
/**
* Get element by placeholder text
* @param text - Placeholder text
* @param options - Placeholder search options
* @returns Locator instance
*/
getByPlaceholder(text: string | RegExp, options?: LocatorGetByPlaceholderOptions): Locator;
/**
* Get element by alt text
* @param text - Alt text
* @param options - Alt text search options
* @returns Locator instance
*/
getByAltText(text: string | RegExp, options?: LocatorGetByAltTextOptions): Locator;
/**
* Get element by title attribute
* @param text - Title text
* @param options - Title search options
* @returns Locator instance
*/
getByTitle(text: string | RegExp, options?: LocatorGetByTitleOptions): Locator;
/**
* Get element by test ID
* @param testId - Test ID value
* @returns Locator instance
*/
getByTestId(testId: string | RegExp): Locator;
/**
* Get element by role
* @param role - ARIA role
* @param options - Role search options
* @returns Locator instance
*/
getByRole(role: AriaRole, options?: LocatorGetByRoleOptions): Locator;Usage Examples:
// Different selection methods
const button = page.locator('button.submit');
const textElement = page.getByText('Click me');
const input = page.getByLabel('Email address');
const image = page.getByAltText('Company logo');
const testElement = page.getByTestId('submit-button');
const roleElement = page.getByRole('button', { name: 'Submit' });
// Traditional element handles
const handle = await page.$('button');
const handles = await page.$$('input');interface LocatorClickOptions {
/** Which button to click */
button?: 'left' | 'right' | 'middle';
/** Number of clicks */
clickCount?: number;
/** Delay between mousedown and mouseup */
delay?: number;
/** Position relative to element */
position?: { x: number; y: number; };
/** Modifier keys */
modifiers?: Array<'Alt' | 'Control' | 'Meta' | 'Shift'>;
/** Bypass actionability checks */
force?: boolean;
/** No action, just perform checks */
trial?: boolean;
/** Wait timeout */
timeout?: number;
}
interface LocatorFillOptions {
/** Bypass actionability checks */
force?: boolean;
/** No action, just perform checks */
trial?: boolean;
/** Wait timeout */
timeout?: number;
}
interface LocatorWaitForOptions {
/** Element state to wait for */
state?: 'attached' | 'detached' | 'visible' | 'hidden';
/** Wait timeout */
timeout?: number;
}
interface LocatorFilterOptions {
/** Filter by text content */
hasText?: string | RegExp;
/** Filter by child element */
has?: Locator;
/** Filter by not having text */
hasNotText?: string | RegExp;
/** Filter by not having child */
hasNot?: Locator;
}interface LocatorGetByTextOptions {
/** Exact text match */
exact?: boolean;
}
interface LocatorGetByLabelOptions {
/** Exact label match */
exact?: boolean;
}
interface LocatorGetByRoleOptions {
/** Accessible name */
name?: string | RegExp;
/** Exact name match */
exact?: boolean;
/** Checked state */
checked?: boolean;
/** Disabled state */
disabled?: boolean;
/** Expanded state */
expanded?: boolean;
/** Include hidden elements */
includeHidden?: boolean;
/** Selected state */
selected?: boolean;
/** Pressed state */
pressed?: boolean;
}type ElementState = 'attached' | 'detached' | 'visible' | 'hidden' | 'stable' | 'enabled' | 'disabled' | 'editable';
interface SelectOption {
/** Option value */
value?: string;
/** Option label */
label?: string;
/** Option index */
index?: number;
}
type AriaRole =
| 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'blockquote'
| 'button' | 'caption' | 'cell' | 'checkbox' | 'code' | 'columnheader'
| 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'deletion'
| 'dialog' | 'directory' | 'document' | 'emphasis' | 'feed' | 'figure'
| 'form' | 'generic' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img'
| 'insertion' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main'
| 'marquee' | 'math' | 'meter' | 'menu' | 'menubar' | 'menuitem'
| 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note'
| 'option' | 'paragraph' | 'presentation' | 'progressbar' | 'radio'
| 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar'
| 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status'
| 'strong' | 'subscript' | 'superscript' | 'switch' | 'tab' | 'table'
| 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'time' | 'timer'
| 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';Install with Tessl CLI
npx tessl i tessl/npm-playwright-chromium