CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-playwright-chromium

A high-level API to automate Chromium

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

element-handling.mddocs/

Element Handling

Modern element interaction API providing both traditional ElementHandle references and the new Locator interface with auto-waiting capabilities and comprehensive element state checking.

Capabilities

Locator Interface (Recommended)

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"]');

ElementHandle Interface

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);

JSHandle Interface

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();

Element Selection Methods

Page-level Selection

/**
 * 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');

Configuration Types

Locator Options

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;
}

Selection Options

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;
}

Element State Types

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

docs

api-testing.md

browser-management.md

element-handling.md

index.md

input-simulation.md

network-control.md

page-interaction.md

tile.json