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
```