or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdapi-testing.mdassertions.mdbrowser-management.mdelement-location.mdindex.mdmobile-testing.mdnetwork-interception.mdpage-interaction.md

element-location.mddocs/

0

# Element Location

1

2

Modern element location and interaction using the Locator API with built-in auto-waiting, retry logic, and robust element interaction methods. The Locator API is the recommended approach for element interaction in Playwright.

3

4

## Capabilities

5

6

### Locator Creation

7

8

Create locators using various strategies including CSS selectors, text content, ARIA roles, and semantic attributes.

9

10

```python { .api }

11

class Page:

12

def locator(self, selector: str) -> Locator:

13

"""

14

Create locator for elements matching selector.

15

16

Args:

17

selector: CSS selector, text selector, or XPath

18

19

Returns:

20

Locator: Element locator with auto-waiting

21

"""

22

23

def get_by_role(

24

self,

25

role: str,

26

checked: Optional[bool] = None,

27

disabled: Optional[bool] = None,

28

expanded: Optional[bool] = None,

29

include_hidden: Optional[bool] = None,

30

level: Optional[int] = None,

31

name: Union[str, Pattern, None] = None,

32

pressed: Optional[bool] = None,

33

selected: Optional[bool] = None,

34

exact: Optional[bool] = None

35

) -> Locator:

36

"""

37

Create locator by ARIA role.

38

39

Args:

40

role: ARIA role (button, textbox, heading, etc.)

41

checked: Checkbox/radio checked state

42

disabled: Element disabled state

43

expanded: Element expanded state

44

include_hidden: Include hidden elements

45

level: Heading level for heading role

46

name: Accessible name pattern

47

pressed: Button pressed state

48

selected: Option selected state

49

exact: Exact name match

50

51

Returns:

52

Locator: Role-based locator

53

"""

54

55

def get_by_text(

56

self,

57

text: Union[str, Pattern],

58

exact: Optional[bool] = None

59

) -> Locator:

60

"""

61

Create locator by text content.

62

63

Args:

64

text: Text content or pattern

65

exact: Exact text match

66

67

Returns:

68

Locator: Text-based locator

69

"""

70

71

def get_by_label(

72

self,

73

text: Union[str, Pattern],

74

exact: Optional[bool] = None

75

) -> Locator:

76

"""

77

Create locator by associated label text.

78

79

Args:

80

text: Label text or pattern

81

exact: Exact text match

82

83

Returns:

84

Locator: Label-based locator

85

"""

86

87

def get_by_placeholder(

88

self,

89

text: Union[str, Pattern],

90

exact: Optional[bool] = None

91

) -> Locator:

92

"""

93

Create locator by placeholder text.

94

95

Args:

96

text: Placeholder text or pattern

97

exact: Exact text match

98

99

Returns:

100

Locator: Placeholder-based locator

101

"""

102

103

def get_by_alt_text(

104

self,

105

text: Union[str, Pattern],

106

exact: Optional[bool] = None

107

) -> Locator:

108

"""

109

Create locator by alt text attribute.

110

111

Args:

112

text: Alt text or pattern

113

exact: Exact text match

114

115

Returns:

116

Locator: Alt text-based locator

117

"""

118

119

def get_by_title(

120

self,

121

text: Union[str, Pattern],

122

exact: Optional[bool] = None

123

) -> Locator:

124

"""

125

Create locator by title attribute.

126

127

Args:

128

text: Title text or pattern

129

exact: Exact text match

130

131

Returns:

132

Locator: Title-based locator

133

"""

134

135

def get_by_test_id(self, test_id: str) -> Locator:

136

"""

137

Create locator by test ID attribute.

138

139

Args:

140

test_id: Test identifier value

141

142

Returns:

143

Locator: Test ID-based locator

144

"""

145

146

def frame_locator(self, selector: str) -> FrameLocator:

147

"""

148

Create frame locator for iframe elements.

149

150

Args:

151

selector: Frame selector

152

153

Returns:

154

FrameLocator: Frame locator

155

"""

156

```

157

158

### Locator Operations

159

160

Interact with elements through locators with automatic waiting and retry logic.

161

162

```python { .api }

163

class Locator:

164

page: Page

165

first: Locator

166

last: Locator

167

168

def click(

169

self,

170

modifiers: Optional[List[str]] = None,

171

position: Optional[Position] = None,

172

delay: Optional[float] = None,

173

button: Optional[str] = None,

174

click_count: Optional[int] = None,

175

timeout: Optional[float] = None,

176

force: Optional[bool] = None,

177

no_wait_after: Optional[bool] = None,

178

trial: Optional[bool] = None

179

) -> None:

180

"""

181

Click element.

182

183

Args:

184

modifiers: Modifier keys ('Alt', 'Control', 'Meta', 'Shift')

185

position: Click position relative to element

186

delay: Delay between mousedown and mouseup

187

button: Mouse button ('left', 'right', 'middle')

188

click_count: Number of clicks

189

timeout: Action timeout in milliseconds

190

force: Skip actionability checks

191

no_wait_after: Don't wait for navigation

192

trial: Perform checks without action

193

"""

194

195

def dblclick(

196

self,

197

modifiers: Optional[List[str]] = None,

198

position: Optional[Position] = None,

199

delay: Optional[float] = None,

200

button: Optional[str] = None,

201

timeout: Optional[float] = None,

202

force: Optional[bool] = None,

203

no_wait_after: Optional[bool] = None,

204

trial: Optional[bool] = None

205

) -> None:

206

"""Double-click element."""

207

208

def fill(

209

self,

210

value: str,

211

timeout: Optional[float] = None,

212

no_wait_after: Optional[bool] = None,

213

force: Optional[bool] = None

214

) -> None:

215

"""

216

Fill input element with value.

217

218

Args:

219

value: Value to fill

220

timeout: Action timeout in milliseconds

221

no_wait_after: Don't wait for navigation

222

force: Skip actionability checks

223

"""

224

225

def type(

226

self,

227

text: str,

228

delay: Optional[float] = None,

229

timeout: Optional[float] = None,

230

no_wait_after: Optional[bool] = None

231

) -> None:

232

"""

233

Type text character by character.

234

235

Args:

236

text: Text to type

237

delay: Delay between keystrokes

238

timeout: Action timeout in milliseconds

239

no_wait_after: Don't wait for navigation

240

"""

241

242

def press(

243

self,

244

key: str,

245

delay: Optional[float] = None,

246

timeout: Optional[float] = None,

247

no_wait_after: Optional[bool] = None

248

) -> None:

249

"""

250

Press key on element.

251

252

Args:

253

key: Key to press ('Enter', 'Escape', etc.)

254

delay: Delay between keydown and keyup

255

timeout: Action timeout in milliseconds

256

no_wait_after: Don't wait for navigation

257

"""

258

259

def check(

260

self,

261

timeout: Optional[float] = None,

262

force: Optional[bool] = None,

263

no_wait_after: Optional[bool] = None,

264

trial: Optional[bool] = None

265

) -> None:

266

"""Check checkbox or radio button."""

267

268

def uncheck(

269

self,

270

timeout: Optional[float] = None,

271

force: Optional[bool] = None,

272

no_wait_after: Optional[bool] = None,

273

trial: Optional[bool] = None

274

) -> None:

275

"""Uncheck checkbox."""

276

277

def select_option(

278

self,

279

value: Union[str, List[str], None] = None,

280

index: Union[int, List[int], None] = None,

281

label: Union[str, List[str], None] = None,

282

element: Union[ElementHandle, List[ElementHandle], None] = None,

283

timeout: Optional[float] = None,

284

force: Optional[bool] = None,

285

no_wait_after: Optional[bool] = None

286

) -> List[str]:

287

"""

288

Select option(s) in select element.

289

290

Returns:

291

List[str]: Selected option values

292

"""

293

294

def set_input_files(

295

self,

296

files: Union[str, List[str], FilePayload, List[FilePayload]],

297

timeout: Optional[float] = None,

298

no_wait_after: Optional[bool] = None

299

) -> None:

300

"""Set files for file input element."""

301

302

def hover(

303

self,

304

modifiers: Optional[List[str]] = None,

305

position: Optional[Position] = None,

306

timeout: Optional[float] = None,

307

force: Optional[bool] = None,

308

trial: Optional[bool] = None

309

) -> None:

310

"""Hover over element."""

311

312

def focus(

313

self,

314

timeout: Optional[float] = None

315

) -> None:

316

"""Focus element."""

317

318

def clear(

319

self,

320

timeout: Optional[float] = None,

321

no_wait_after: Optional[bool] = None,

322

force: Optional[bool] = None

323

) -> None:

324

"""Clear input element."""

325

326

def scroll_into_view_if_needed(

327

self,

328

timeout: Optional[float] = None

329

) -> None:

330

"""Scroll element into view if needed."""

331

```

332

333

### Locator Filtering and Chaining

334

335

Refine and combine locators for precise element targeting.

336

337

```python { .api }

338

class Locator:

339

def nth(self, index: int) -> Locator:

340

"""

341

Get nth matching element.

342

343

Args:

344

index: Element index (0-based)

345

346

Returns:

347

Locator: Nth element locator

348

"""

349

350

def filter(

351

self,

352

has_text: Union[str, Pattern, None] = None,

353

has_not_text: Union[str, Pattern, None] = None,

354

has: Optional[Locator] = None,

355

has_not: Optional[Locator] = None

356

) -> Locator:

357

"""

358

Filter locator by additional criteria.

359

360

Args:

361

has_text: Element must contain text

362

has_not_text: Element must not contain text

363

has: Element must contain descendant

364

has_not: Element must not contain descendant

365

366

Returns:

367

Locator: Filtered locator

368

"""

369

370

def and_(self, locator: Locator) -> Locator:

371

"""

372

Logical AND with another locator.

373

374

Args:

375

locator: Locator to combine with AND

376

377

Returns:

378

Locator: Combined locator

379

"""

380

381

def or_(self, locator: Locator) -> Locator:

382

"""

383

Logical OR with another locator.

384

385

Args:

386

locator: Locator to combine with OR

387

388

Returns:

389

Locator: Combined locator

390

"""

391

392

def locator(self, selector: str) -> Locator:

393

"""

394

Find locator relative to this locator.

395

396

Args:

397

selector: Relative selector

398

399

Returns:

400

Locator: Relative locator

401

"""

402

```

403

404

### Element State Queries

405

406

Check element states with automatic waiting and retry.

407

408

```python { .api }

409

class Locator:

410

def is_checked(

411

self,

412

timeout: Optional[float] = None

413

) -> bool:

414

"""

415

Check if element is checked.

416

417

Args:

418

timeout: Query timeout in milliseconds

419

420

Returns:

421

bool: True if checked

422

"""

423

424

def is_disabled(

425

self,

426

timeout: Optional[float] = None

427

) -> bool:

428

"""Check if element is disabled."""

429

430

def is_editable(

431

self,

432

timeout: Optional[float] = None

433

) -> bool:

434

"""Check if element is editable."""

435

436

def is_enabled(

437

self,

438

timeout: Optional[float] = None

439

) -> bool:

440

"""Check if element is enabled."""

441

442

def is_hidden(

443

self,

444

timeout: Optional[float] = None

445

) -> bool:

446

"""Check if element is hidden."""

447

448

def is_visible(

449

self,

450

timeout: Optional[float] = None

451

) -> bool:

452

"""Check if element is visible."""

453

454

def count(self) -> int:

455

"""

456

Get number of matching elements.

457

458

Returns:

459

int: Element count

460

"""

461

```

462

463

### Content Access

464

465

Get element content and attributes.

466

467

```python { .api }

468

class Locator:

469

def text_content(

470

self,

471

timeout: Optional[float] = None

472

) -> Optional[str]:

473

"""

474

Get element text content.

475

476

Args:

477

timeout: Query timeout in milliseconds

478

479

Returns:

480

Optional[str]: Text content

481

"""

482

483

def inner_text(

484

self,

485

timeout: Optional[float] = None

486

) -> str:

487

"""

488

Get element inner text.

489

490

Args:

491

timeout: Query timeout in milliseconds

492

493

Returns:

494

str: Inner text

495

"""

496

497

def inner_html(

498

self,

499

timeout: Optional[float] = None

500

) -> str:

501

"""Get element inner HTML."""

502

503

def input_value(

504

self,

505

timeout: Optional[float] = None

506

) -> str:

507

"""Get input element value."""

508

509

def get_attribute(

510

self,

511

name: str,

512

timeout: Optional[float] = None

513

) -> Optional[str]:

514

"""

515

Get element attribute value.

516

517

Args:

518

name: Attribute name

519

timeout: Query timeout in milliseconds

520

521

Returns:

522

Optional[str]: Attribute value

523

"""

524

525

def all_text_contents(self) -> List[str]:

526

"""

527

Get text content of all matching elements.

528

529

Returns:

530

List[str]: Text contents

531

"""

532

533

def all_inner_texts(self) -> List[str]:

534

"""

535

Get inner text of all matching elements.

536

537

Returns:

538

List[str]: Inner texts

539

"""

540

```

541

542

### Utilities

543

544

Additional locator utilities for waiting and screenshots.

545

546

```python { .api }

547

class Locator:

548

def wait_for(

549

self,

550

state: Optional[str] = None,

551

timeout: Optional[float] = None

552

) -> None:

553

"""

554

Wait for locator to reach state.

555

556

Args:

557

state: Element state ('attached', 'detached', 'visible', 'hidden')

558

timeout: Wait timeout in milliseconds

559

"""

560

561

def bounding_box(

562

self,

563

timeout: Optional[float] = None

564

) -> Optional[FloatRect]:

565

"""

566

Get element bounding box.

567

568

Args:

569

timeout: Query timeout in milliseconds

570

571

Returns:

572

Optional[FloatRect]: Element bounds

573

"""

574

575

def screenshot(

576

self,

577

timeout: Optional[float] = None,

578

type: Optional[str] = None,

579

path: Optional[str] = None,

580

quality: Optional[int] = None,

581

omit_background: Optional[bool] = None,

582

animations: Optional[str] = None,

583

caret: Optional[str] = None,

584

scale: Optional[str] = None,

585

mask: Optional[List[Locator]] = None

586

) -> bytes:

587

"""

588

Take element screenshot.

589

590

Args:

591

timeout: Screenshot timeout in milliseconds

592

type: Image type ('png', 'jpeg')

593

path: File path to save screenshot

594

quality: JPEG quality (0-100)

595

omit_background: Hide default background

596

animations: Handle animations ('disabled', 'allow')

597

caret: Handle text caret ('hide', 'initial')

598

scale: Viewport scale ('css', 'device')

599

mask: Elements to mask in screenshot

600

601

Returns:

602

bytes: Screenshot data

603

"""

604

```

605

606

## Usage Examples

607

608

### Semantic Element Location

609

610

```python

611

from playwright.sync_api import sync_playwright

612

613

with sync_playwright() as p:

614

browser = p.chromium.launch()

615

page = browser.new_page()

616

617

page.goto("https://example.com")

618

619

# Locate by role and name

620

submit_button = page.get_by_role("button", name="Submit")

621

submit_button.click()

622

623

# Locate by text content

624

error_message = page.get_by_text("Please fill required fields")

625

assert error_message.is_visible()

626

627

# Locate by label

628

email_input = page.get_by_label("Email Address")

629

email_input.fill("user@example.com")

630

631

# Locate by placeholder

632

search_input = page.get_by_placeholder("Search...")

633

search_input.type("playwright")

634

635

browser.close()

636

```

637

638

### Locator Filtering and Chaining

639

640

```python

641

with sync_playwright() as p:

642

browser = p.chromium.launch()

643

page = browser.new_page()

644

645

page.goto("https://example.com/products")

646

647

# Filter products by text

648

product_cards = page.locator(".product-card")

649

laptop_cards = product_cards.filter(has_text="Laptop")

650

651

# Get specific product

652

first_laptop = laptop_cards.first

653

first_laptop.click()

654

655

# Combine locators

656

form_inputs = page.locator("form").locator("input")

657

required_inputs = form_inputs.and_(page.locator("[required]"))

658

659

# Fill all required inputs

660

for i in range(required_inputs.count()):

661

input_locator = required_inputs.nth(i)

662

input_locator.fill("test value")

663

664

browser.close()

665

```

666

667

### Complex Element Interaction

668

669

```python

670

with sync_playwright() as p:

671

browser = p.chromium.launch()

672

page = browser.new_page()

673

674

page.goto("https://example.com/app")

675

676

# Multi-step form interaction

677

page.get_by_label("First Name").fill("John")

678

page.get_by_label("Last Name").fill("Doe")

679

680

# Select from dropdown

681

country_select = page.get_by_label("Country")

682

country_select.select_option(label="United States")

683

684

# Check multiple checkboxes

685

interests = ["Technology", "Sports", "Music"]

686

for interest in interests:

687

page.get_by_role("checkbox", name=interest).check()

688

689

# Upload file

690

file_input = page.get_by_label("Profile Picture")

691

file_input.set_input_files("profile.jpg")

692

693

# Submit with confirmation

694

submit_btn = page.get_by_role("button", name="Create Account")

695

696

# Wait for confirmation dialog

697

with page.expect_event("dialog") as dialog_info:

698

submit_btn.click()

699

dialog = dialog_info.value

700

dialog.accept()

701

702

browser.close()

703

```

704

705

### Element State Validation

706

707

```python

708

with sync_playwright() as p:

709

browser = p.chromium.launch()

710

page = browser.new_page()

711

712

page.goto("https://example.com/form")

713

714

# Check initial states

715

submit_btn = page.get_by_role("button", name="Submit")

716

assert submit_btn.is_disabled()

717

718

# Fill required field

719

email_input = page.get_by_label("Email")

720

email_input.fill("test@example.com")

721

722

# Verify button becomes enabled

723

assert submit_btn.is_enabled()

724

725

# Check visibility of elements

726

error_message = page.get_by_text("Email is required")

727

assert error_message.is_hidden()

728

729

# Clear field to trigger validation

730

email_input.clear()

731

assert error_message.is_visible()

732

733

browser.close()

734

```