or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-testing.mdbrowser-management.mdelement-handling.mdindex.mdinput-simulation.mdnetwork-control.mdpage-interaction.md

element-handling.mddocs/

0

# Element Handling

1

2

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

3

4

## Capabilities

5

6

### Locator Interface (Recommended)

7

8

Modern element interaction API with built-in waiting, retry logic, and improved reliability for dynamic web applications.

9

10

```typescript { .api }

11

/**

12

* Modern element locator with auto-waiting capabilities

13

*/

14

interface Locator {

15

/** Click the element with auto-waiting */

16

click(options?: LocatorClickOptions): Promise<void>;

17

/** Double-click the element */

18

dblclick(options?: LocatorDblclickOptions): Promise<void>;

19

/** Fill input element with text */

20

fill(value: string, options?: LocatorFillOptions): Promise<void>;

21

/** Type text into element */

22

type(text: string, options?: LocatorTypeOptions): Promise<void>;

23

/** Press a key on the element */

24

press(key: string, options?: LocatorPressOptions): Promise<void>;

25

/** Check checkbox or radio button */

26

check(options?: LocatorCheckOptions): Promise<void>;

27

/** Uncheck checkbox */

28

uncheck(options?: LocatorUncheckOptions): Promise<void>;

29

/** Select options from dropdown */

30

selectOption(values: string | string[] | SelectOption | SelectOption[], options?: LocatorSelectOptionOptions): Promise<string[]>;

31

/** Get text content of element */

32

textContent(options?: LocatorTextContentOptions): Promise<string | null>;

33

/** Get inner text of element */

34

innerText(options?: LocatorInnerTextOptions): Promise<string>;

35

/** Get inner HTML of element */

36

innerHTML(options?: LocatorInnerHTMLOptions): Promise<string>;

37

/** Get attribute value */

38

getAttribute(name: string, options?: LocatorGetAttributeOptions): Promise<string | null>;

39

/** Get input value */

40

inputValue(options?: LocatorInputValueOptions): Promise<string>;

41

/** Check if element is checked */

42

isChecked(options?: LocatorIsCheckedOptions): Promise<boolean>;

43

/** Check if element is disabled */

44

isDisabled(options?: LocatorIsDisabledOptions): Promise<boolean>;

45

/** Check if element is editable */

46

isEditable(options?: LocatorIsEditableOptions): Promise<boolean>;

47

/** Check if element is enabled */

48

isEnabled(options?: LocatorIsEnabledOptions): Promise<boolean>;

49

/** Check if element is hidden */

50

isHidden(options?: LocatorIsHiddenOptions): Promise<boolean>;

51

/** Check if element is visible */

52

isVisible(options?: LocatorIsVisibleOptions): Promise<boolean>;

53

/** Take screenshot of element */

54

screenshot(options?: LocatorScreenshotOptions): Promise<Buffer>;

55

/** Scroll element into view if needed */

56

scrollIntoViewIfNeeded(options?: LocatorScrollIntoViewIfNeededOptions): Promise<void>;

57

/** Wait for element to be in specific state */

58

waitFor(options?: LocatorWaitForOptions): Promise<void>;

59

/** Get count of matching elements */

60

count(): Promise<number>;

61

/** Get first matching element */

62

first(): Locator;

63

/** Get last matching element */

64

last(): Locator;

65

/** Get nth matching element */

66

nth(index: number): Locator;

67

/** Filter locator by text or attribute */

68

filter(options: LocatorFilterOptions): Locator;

69

/** Combine locator with AND logic */

70

and(locator: Locator): Locator;

71

/** Combine locator with OR logic */

72

or(locator: Locator): Locator;

73

/** Find child elements */

74

locator(selector: string): Locator;

75

}

76

```

77

78

**Usage Examples:**

79

80

```typescript

81

// Create locators

82

const submitButton = page.locator('button[type="submit"]');

83

const emailInput = page.locator('input[name="email"]');

84

const items = page.locator('.item');

85

86

// Interact with elements (auto-waiting)

87

await emailInput.fill('user@example.com');

88

await submitButton.click();

89

90

// Check element states

91

const isVisible = await submitButton.isVisible();

92

const isDisabled = await submitButton.isDisabled();

93

const count = await items.count();

94

95

// Filter and chain locators

96

const activeItems = items.filter({ hasText: 'Active' });

97

const firstItem = items.first();

98

const specificItem = items.nth(2);

99

100

// Combine locators

101

const buttons = page.locator('button');

102

const submitButtons = buttons.filter({ hasText: 'Submit' });

103

const primaryOrSecondary = page.locator('.primary').or(page.locator('.secondary'));

104

105

// Child element selection

106

const form = page.locator('form');

107

const formInput = form.locator('input[name="email"]');

108

```

109

110

### ElementHandle Interface

111

112

Direct DOM element references for advanced manipulation and when fine-grained control is needed.

113

114

```typescript { .api }

115

/**

116

* Direct reference to DOM elements

117

*/

118

interface ElementHandle {

119

/** Click the element */

120

click(options?: ElementHandleClickOptions): Promise<void>;

121

/** Double-click the element */

122

dblclick(options?: ElementHandleDblclickOptions): Promise<void>;

123

/** Fill input element */

124

fill(value: string, options?: ElementHandleFillOptions): Promise<void>;

125

/** Type text into element */

126

type(text: string, options?: ElementHandleTypeOptions): Promise<void>;

127

/** Press a key on element */

128

press(key: string, options?: ElementHandlePressOptions): Promise<void>;

129

/** Check checkbox or radio */

130

check(options?: ElementHandleCheckOptions): Promise<void>;

131

/** Uncheck checkbox */

132

uncheck(options?: ElementHandleUncheckOptions): Promise<void>;

133

/** Select options from dropdown */

134

selectOption(values: string | string[] | SelectOption | SelectOption[], options?: ElementHandleSelectOptionOptions): Promise<string[]>;

135

/** Get text content */

136

textContent(): Promise<string | null>;

137

/** Get inner text */

138

innerText(): Promise<string>;

139

/** Get inner HTML */

140

innerHTML(): Promise<string>;

141

/** Get attribute value */

142

getAttribute(name: string): Promise<string | null>;

143

/** Get input value */

144

inputValue(): Promise<string>;

145

/** Check if checked */

146

isChecked(): Promise<boolean>;

147

/** Check if disabled */

148

isDisabled(): Promise<boolean>;

149

/** Check if editable */

150

isEditable(): Promise<boolean>;

151

/** Check if enabled */

152

isEnabled(): Promise<boolean>;

153

/** Check if hidden */

154

isHidden(): Promise<boolean>;

155

/** Check if visible */

156

isVisible(): Promise<boolean>;

157

/** Get bounding box */

158

boundingBox(): Promise<{ x: number; y: number; width: number; height: number; } | null>;

159

/** Take screenshot */

160

screenshot(options?: ElementHandleScreenshotOptions): Promise<Buffer>;

161

/** Scroll into view if needed */

162

scrollIntoViewIfNeeded(options?: ElementHandleScrollIntoViewIfNeededOptions): Promise<void>;

163

/** Wait for element state */

164

waitForElementState(state: 'visible' | 'hidden' | 'stable' | 'enabled' | 'disabled' | 'editable', options?: ElementHandleWaitForElementStateOptions): Promise<void>;

165

/** Wait for child selector */

166

waitForSelector(selector: string, options?: ElementHandleWaitForSelectorOptions): Promise<ElementHandle | null>;

167

/** Query selector within element */

168

querySelector(selector: string): Promise<ElementHandle | null>;

169

/** Query all selectors within element */

170

querySelectorAll(selector: string): Promise<ElementHandle[]>;

171

/** Evaluate function on element */

172

evaluate<R, Arg>(pageFunction: PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<R>;

173

/** Evaluate and return handle */

174

evaluateHandle<R, Arg>(pageFunction: PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<JSHandle<R>>;

175

/** Get owner frame */

176

ownerFrame(): Promise<Frame | null>;

177

/** Convert to JSHandle */

178

asElement(): ElementHandle | null;

179

}

180

```

181

182

**Usage Examples:**

183

184

```typescript

185

// Get element handles

186

const button = await page.$('button.submit');

187

const inputs = await page.$$('input[type="text"]');

188

189

// Direct element manipulation

190

if (button) {

191

await button.click();

192

const text = await button.textContent();

193

const box = await button.boundingBox();

194

195

if (box) {

196

console.log(`Button at: ${box.x}, ${box.y}`);

197

}

198

}

199

200

// Element queries

201

const form = await page.$('form');

202

if (form) {

203

const emailInput = await form.querySelector('input[name="email"]');

204

const allInputs = await form.querySelectorAll('input');

205

}

206

207

// Evaluate on element

208

const value = await button?.evaluate(el => el.dataset.value);

209

```

210

211

### JSHandle Interface

212

213

References to JavaScript objects in the page context, including DOM elements and other objects.

214

215

```typescript { .api }

216

/**

217

* Reference to JavaScript objects in page context

218

*/

219

interface JSHandle<T = any> {

220

/** Evaluate function with this handle */

221

evaluate<R, Arg>(pageFunction: PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<R>;

222

/** Evaluate and return new handle */

223

evaluateHandle<R, Arg>(pageFunction: PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<JSHandle<R>>;

224

/** Get object property */

225

getProperty(propertyName: string): Promise<JSHandle>;

226

/** Get all properties */

227

getProperties(): Promise<Map<string, JSHandle>>;

228

/** Serialize to JSON */

229

jsonValue(): Promise<T>;

230

/** Convert to ElementHandle if possible */

231

asElement(): ElementHandle | null;

232

/** Release the handle */

233

dispose(): Promise<void>;

234

}

235

```

236

237

**Usage Examples:**

238

239

```typescript

240

// Get window object

241

const windowHandle = await page.evaluateHandle(() => window);

242

243

// Access properties

244

const location = await windowHandle.getProperty('location');

245

const href = await location.getProperty('href');

246

const url = await href.jsonValue();

247

248

// Get all properties

249

const props = await windowHandle.getProperties();

250

for (const [name, handle] of props) {

251

console.log(`Property: ${name}`);

252

}

253

254

// Cleanup

255

await windowHandle.dispose();

256

```

257

258

## Element Selection Methods

259

260

### Page-level Selection

261

262

```typescript { .api }

263

/**

264

* Find element by selector (returns first match)

265

* @param selector - CSS selector

266

* @returns ElementHandle or null

267

*/

268

$(selector: string): Promise<ElementHandle | null>;

269

270

/**

271

* Find all elements by selector

272

* @param selector - CSS selector

273

* @returns Array of ElementHandles

274

*/

275

$$(selector: string): Promise<ElementHandle[]>;

276

277

/**

278

* Create a locator for element(s)

279

* @param selector - CSS selector

280

* @returns Locator instance

281

*/

282

locator(selector: string): Locator;

283

284

/**

285

* Get element by text content

286

* @param text - Text to search for

287

* @param options - Text search options

288

* @returns Locator instance

289

*/

290

getByText(text: string | RegExp, options?: LocatorGetByTextOptions): Locator;

291

292

/**

293

* Get element by label text

294

* @param text - Label text

295

* @param options - Label search options

296

* @returns Locator instance

297

*/

298

getByLabel(text: string | RegExp, options?: LocatorGetByLabelOptions): Locator;

299

300

/**

301

* Get element by placeholder text

302

* @param text - Placeholder text

303

* @param options - Placeholder search options

304

* @returns Locator instance

305

*/

306

getByPlaceholder(text: string | RegExp, options?: LocatorGetByPlaceholderOptions): Locator;

307

308

/**

309

* Get element by alt text

310

* @param text - Alt text

311

* @param options - Alt text search options

312

* @returns Locator instance

313

*/

314

getByAltText(text: string | RegExp, options?: LocatorGetByAltTextOptions): Locator;

315

316

/**

317

* Get element by title attribute

318

* @param text - Title text

319

* @param options - Title search options

320

* @returns Locator instance

321

*/

322

getByTitle(text: string | RegExp, options?: LocatorGetByTitleOptions): Locator;

323

324

/**

325

* Get element by test ID

326

* @param testId - Test ID value

327

* @returns Locator instance

328

*/

329

getByTestId(testId: string | RegExp): Locator;

330

331

/**

332

* Get element by role

333

* @param role - ARIA role

334

* @param options - Role search options

335

* @returns Locator instance

336

*/

337

getByRole(role: AriaRole, options?: LocatorGetByRoleOptions): Locator;

338

```

339

340

**Usage Examples:**

341

342

```typescript

343

// Different selection methods

344

const button = page.locator('button.submit');

345

const textElement = page.getByText('Click me');

346

const input = page.getByLabel('Email address');

347

const image = page.getByAltText('Company logo');

348

const testElement = page.getByTestId('submit-button');

349

const roleElement = page.getByRole('button', { name: 'Submit' });

350

351

// Traditional element handles

352

const handle = await page.$('button');

353

const handles = await page.$$('input');

354

```

355

356

## Configuration Types

357

358

### Locator Options

359

360

```typescript { .api }

361

interface LocatorClickOptions {

362

/** Which button to click */

363

button?: 'left' | 'right' | 'middle';

364

/** Number of clicks */

365

clickCount?: number;

366

/** Delay between mousedown and mouseup */

367

delay?: number;

368

/** Position relative to element */

369

position?: { x: number; y: number; };

370

/** Modifier keys */

371

modifiers?: Array<'Alt' | 'Control' | 'Meta' | 'Shift'>;

372

/** Bypass actionability checks */

373

force?: boolean;

374

/** No action, just perform checks */

375

trial?: boolean;

376

/** Wait timeout */

377

timeout?: number;

378

}

379

380

interface LocatorFillOptions {

381

/** Bypass actionability checks */

382

force?: boolean;

383

/** No action, just perform checks */

384

trial?: boolean;

385

/** Wait timeout */

386

timeout?: number;

387

}

388

389

interface LocatorWaitForOptions {

390

/** Element state to wait for */

391

state?: 'attached' | 'detached' | 'visible' | 'hidden';

392

/** Wait timeout */

393

timeout?: number;

394

}

395

396

interface LocatorFilterOptions {

397

/** Filter by text content */

398

hasText?: string | RegExp;

399

/** Filter by child element */

400

has?: Locator;

401

/** Filter by not having text */

402

hasNotText?: string | RegExp;

403

/** Filter by not having child */

404

hasNot?: Locator;

405

}

406

```

407

408

### Selection Options

409

410

```typescript { .api }

411

interface LocatorGetByTextOptions {

412

/** Exact text match */

413

exact?: boolean;

414

}

415

416

interface LocatorGetByLabelOptions {

417

/** Exact label match */

418

exact?: boolean;

419

}

420

421

interface LocatorGetByRoleOptions {

422

/** Accessible name */

423

name?: string | RegExp;

424

/** Exact name match */

425

exact?: boolean;

426

/** Checked state */

427

checked?: boolean;

428

/** Disabled state */

429

disabled?: boolean;

430

/** Expanded state */

431

expanded?: boolean;

432

/** Include hidden elements */

433

includeHidden?: boolean;

434

/** Selected state */

435

selected?: boolean;

436

/** Pressed state */

437

pressed?: boolean;

438

}

439

```

440

441

### Element State Types

442

443

```typescript { .api }

444

type ElementState = 'attached' | 'detached' | 'visible' | 'hidden' | 'stable' | 'enabled' | 'disabled' | 'editable';

445

446

interface SelectOption {

447

/** Option value */

448

value?: string;

449

/** Option label */

450

label?: string;

451

/** Option index */

452

index?: number;

453

}

454

455

type AriaRole =

456

| 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'blockquote'

457

| 'button' | 'caption' | 'cell' | 'checkbox' | 'code' | 'columnheader'

458

| 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'deletion'

459

| 'dialog' | 'directory' | 'document' | 'emphasis' | 'feed' | 'figure'

460

| 'form' | 'generic' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img'

461

| 'insertion' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main'

462

| 'marquee' | 'math' | 'meter' | 'menu' | 'menubar' | 'menuitem'

463

| 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note'

464

| 'option' | 'paragraph' | 'presentation' | 'progressbar' | 'radio'

465

| 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar'

466

| 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status'

467

| 'strong' | 'subscript' | 'superscript' | 'switch' | 'tab' | 'table'

468

| 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'time' | 'timer'

469

| 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';

470

```