or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

action-chains.mdbrowser-configuration.mdelement-interaction.mdindex.mdwaits-conditions.mdwebdriver-classes.md

element-interaction.mddocs/

0

# Element Finding and Interaction

1

2

This document covers element finding strategies and interaction methods in Python Selenium WebDriver. It includes locator strategies, WebElement methods, and best practices for element interaction.

3

4

## Locator Strategies (By Class)

5

6

The `By` class provides constants for different element locating strategies.

7

8

{ .api }

9

```python

10

from selenium.webdriver.common.by import By

11

12

class By:

13

ID = "id"

14

XPATH = "xpath"

15

LINK_TEXT = "link text"

16

PARTIAL_LINK_TEXT = "partial link text"

17

NAME = "name"

18

TAG_NAME = "tag name"

19

CLASS_NAME = "class name"

20

CSS_SELECTOR = "css selector"

21

```

22

23

**Description**: Set of supported locator strategies for finding elements.

24

25

**Locator Types**:

26

- `ID`: Select element by its ID attribute

27

- `XPATH`: Select element via XPath expression

28

- `LINK_TEXT`: Select link element by exact text content

29

- `PARTIAL_LINK_TEXT`: Select link element by partial text content

30

- `NAME`: Select element by name attribute

31

- `TAG_NAME`: Select element by tag name

32

- `CLASS_NAME`: Select element by class name

33

- `CSS_SELECTOR`: Select element by CSS selector

34

35

**Custom Finders**:

36

37

{ .api }

38

```python

39

@classmethod

40

def register_custom_finder(cls, name: str, strategy: str) -> None

41

```

42

43

**Description**: Register a custom finder strategy.

44

45

**Parameters**:

46

- `name`: Name of the custom finder

47

- `strategy`: Strategy string for the finder

48

49

{ .api }

50

```python

51

@classmethod

52

def get_finder(cls, name: str) -> Optional[str]

53

```

54

55

**Description**: Get a finder strategy by name.

56

57

**Parameters**:

58

- `name`: Name of the finder

59

60

**Returns**: Strategy string or None if not found

61

62

{ .api }

63

```python

64

@classmethod

65

def clear_custom_finders(cls) -> None

66

```

67

68

**Description**: Clear all custom finders.

69

70

## Element Finding Methods

71

72

### Single Element Finding

73

74

{ .api }

75

```python

76

def find_element(self, by: str = By.ID, value: Optional[str] = None) -> WebElement

77

```

78

79

**Description**: Find an element given a By strategy and locator.

80

81

**Parameters**:

82

- `by`: The locating strategy to use (default: By.ID)

83

- `value`: The locator value

84

85

**Returns**: WebElement object

86

87

**Raises**: NoSuchElementException if element is not found

88

89

**Supported locator strategies**:

90

- `By.ID`: Locate by element ID

91

- `By.NAME`: Locate by the `name` attribute

92

- `By.XPATH`: Locate by an XPath expression

93

- `By.CSS_SELECTOR`: Locate by a CSS selector

94

- `By.CLASS_NAME`: Locate by class name

95

- `By.TAG_NAME`: Locate by tag name

96

- `By.LINK_TEXT`: Locate by exact link text

97

- `By.PARTIAL_LINK_TEXT`: Locate by partial link text

98

99

**Examples**:

100

```python

101

from selenium.webdriver.common.by import By

102

103

# Find by ID

104

element = driver.find_element(By.ID, "myElement")

105

106

# Find by XPath

107

element = driver.find_element(By.XPATH, "//div[@class='container']")

108

109

# Find by CSS selector

110

element = driver.find_element(By.CSS_SELECTOR, ".btn.btn-primary")

111

112

# Find by class name

113

element = driver.find_element(By.CLASS_NAME, "header")

114

115

# Find by tag name

116

element = driver.find_element(By.TAG_NAME, "h1")

117

118

# Find by name attribute

119

element = driver.find_element(By.NAME, "username")

120

121

# Find by link text

122

element = driver.find_element(By.LINK_TEXT, "Click Here")

123

124

# Find by partial link text

125

element = driver.find_element(By.PARTIAL_LINK_TEXT, "Click")

126

```

127

128

### Multiple Elements Finding

129

130

{ .api }

131

```python

132

def find_elements(self, by: str = By.ID, value: Optional[str] = None) -> List[WebElement]

133

```

134

135

**Description**: Find elements given a By strategy and locator.

136

137

**Parameters**:

138

- `by`: The locating strategy to use (default: By.ID)

139

- `value`: The locator value

140

141

**Returns**: List of WebElement objects (empty list if no elements found)

142

143

**Examples**:

144

```python

145

# Find all elements with a class

146

elements = driver.find_elements(By.CLASS_NAME, "item")

147

148

# Find all links

149

links = driver.find_elements(By.TAG_NAME, "a")

150

151

# Find all elements matching XPath

152

items = driver.find_elements(By.XPATH, "//div[contains(@class, 'product')]")

153

```

154

155

## WebElement Class

156

157

{ .api }

158

```python

159

from selenium.webdriver.remote.webelement import WebElement

160

161

class WebElement(BaseWebElement):

162

def __init__(self, parent, id_: str) -> None

163

```

164

165

**Description**: Represents a DOM element. Generally, all interesting operations that interact with a document will be performed through this interface.

166

167

**Parameters**:

168

- `parent`: The WebDriver instance that found this element

169

- `id_`: The element ID from the WebDriver protocol

170

171

## WebElement Properties

172

173

{ .api }

174

```python

175

@property

176

def tag_name(self) -> str

177

```

178

179

**Description**: This element's tagName property.

180

181

**Returns**: The tag name of the element

182

183

**Example**:

184

```python

185

element = driver.find_element(By.ID, 'foo')

186

print(element.tag_name) # e.g., "div", "input", "a"

187

```

188

189

{ .api }

190

```python

191

@property

192

def text(self) -> str

193

```

194

195

**Description**: The text of the element.

196

197

**Returns**: The visible text of the element

198

199

**Example**:

200

```python

201

element = driver.find_element(By.ID, 'content')

202

print(element.text) # Visible text content

203

```

204

205

{ .api }

206

```python

207

@property

208

def size(self) -> dict

209

```

210

211

**Description**: The size of the element.

212

213

**Returns**: Dictionary with 'width' and 'height' keys

214

215

**Example**:

216

```python

217

element = driver.find_element(By.ID, 'banner')

218

size = element.size

219

print(f"Width: {size['width']}, Height: {size['height']}")

220

```

221

222

{ .api }

223

```python

224

@property

225

def location(self) -> dict

226

```

227

228

**Description**: The location of the element in the renderable canvas.

229

230

**Returns**: Dictionary with 'x' and 'y' keys

231

232

**Example**:

233

```python

234

element = driver.find_element(By.ID, 'button')

235

location = element.location

236

print(f"X: {location['x']}, Y: {location['y']}")

237

```

238

239

{ .api }

240

```python

241

@property

242

def rect(self) -> dict

243

```

244

245

**Description**: A dictionary with the size and location of the element.

246

247

**Returns**: Dictionary with 'x', 'y', 'width', and 'height' keys

248

249

**Example**:

250

```python

251

element = driver.find_element(By.ID, 'modal')

252

rect = element.rect

253

print(f"Position: ({rect['x']}, {rect['y']})")

254

print(f"Size: {rect['width']} x {rect['height']}")

255

```

256

257

## WebElement Interaction Methods

258

259

### Basic Interaction

260

261

{ .api }

262

```python

263

def click(self) -> None

264

```

265

266

**Description**: Clicks the element.

267

268

**Example**:

269

```python

270

button = driver.find_element(By.ID, 'submit-btn')

271

button.click()

272

```

273

274

{ .api }

275

```python

276

def clear(self) -> None

277

```

278

279

**Description**: Clears the text if it's a text entry element.

280

281

**Example**:

282

```python

283

text_field = driver.find_element(By.NAME, 'username')

284

text_field.clear()

285

```

286

287

{ .api }

288

```python

289

def send_keys(self, *value: str) -> None

290

```

291

292

**Description**: Simulates typing into the element.

293

294

**Parameters**:

295

- `*value`: A string to send, or key combinations using Keys class

296

297

**Example**:

298

```python

299

from selenium.webdriver.common.keys import Keys

300

301

text_field = driver.find_element(By.NAME, 'search')

302

text_field.send_keys('Python Selenium')

303

text_field.send_keys(Keys.ENTER)

304

305

# Clear and type new text

306

text_field.send_keys(Keys.CONTROL + 'a') # Select all

307

text_field.send_keys(Keys.DELETE) # Delete

308

text_field.send_keys('New text')

309

```

310

311

{ .api }

312

```python

313

def submit(self) -> None

314

```

315

316

**Description**: Submits a form. If this element is a form, or an element within a form, this will submit that form.

317

318

**Example**:

319

```python

320

form = driver.find_element(By.TAG_NAME, 'form')

321

form.submit()

322

323

# Or submit via any element within the form

324

input_field = driver.find_element(By.NAME, 'username')

325

input_field.submit()

326

```

327

328

### Element State Methods

329

330

{ .api }

331

```python

332

def is_selected(self) -> bool

333

```

334

335

**Description**: Returns whether the element is selected (for checkboxes, radio buttons, and select options).

336

337

**Returns**: True if element is selected, False otherwise

338

339

**Example**:

340

```python

341

checkbox = driver.find_element(By.ID, 'agree-terms')

342

if checkbox.is_selected():

343

print("Checkbox is checked")

344

else:

345

checkbox.click() # Check the checkbox

346

```

347

348

{ .api }

349

```python

350

def is_enabled(self) -> bool

351

```

352

353

**Description**: Returns whether the element is enabled.

354

355

**Returns**: True if element is enabled, False otherwise

356

357

**Example**:

358

```python

359

submit_btn = driver.find_element(By.ID, 'submit')

360

if submit_btn.is_enabled():

361

submit_btn.click()

362

else:

363

print("Submit button is disabled")

364

```

365

366

{ .api }

367

```python

368

def is_displayed(self) -> bool

369

```

370

371

**Description**: Returns whether the element is visible to a user.

372

373

**Returns**: True if element is displayed, False otherwise

374

375

**Example**:

376

```python

377

modal = driver.find_element(By.ID, 'error-modal')

378

if modal.is_displayed():

379

print("Error modal is visible")

380

close_btn = modal.find_element(By.CLASS_NAME, 'close')

381

close_btn.click()

382

```

383

384

### Attribute and Property Methods

385

386

{ .api }

387

```python

388

def get_attribute(self, name: str) -> Optional[str]

389

```

390

391

**Description**: Gets the given attribute or property of the element.

392

393

**Parameters**:

394

- `name`: Name of the attribute/property to retrieve

395

396

**Returns**: The value of the attribute/property, or None if not set

397

398

**Example**:

399

```python

400

link = driver.find_element(By.TAG_NAME, 'a')

401

href = link.get_attribute('href')

402

class_name = link.get_attribute('class')

403

data_value = link.get_attribute('data-value')

404

```

405

406

{ .api }

407

```python

408

def get_dom_attribute(self, name: str) -> str

409

```

410

411

**Description**: Gets the given attribute of the element from the DOM.

412

413

**Parameters**:

414

- `name`: Name of the attribute to retrieve

415

416

**Returns**: The attribute value

417

418

**Example**:

419

```python

420

element = driver.find_element(By.ID, 'custom-element')

421

custom_attr = element.get_dom_attribute('data-custom')

422

```

423

424

{ .api }

425

```python

426

def get_property(self, name: str) -> Union[str, bool, WebElement, dict]

427

```

428

429

**Description**: Gets the given property of the element.

430

431

**Parameters**:

432

- `name`: Name of the property to retrieve

433

434

**Returns**: The property value

435

436

**Example**:

437

```python

438

input_field = driver.find_element(By.NAME, 'email')

439

value = input_field.get_property('value')

440

checked = checkbox.get_property('checked') # Returns boolean

441

```

442

443

{ .api }

444

```python

445

def value_of_css_property(self, property_name: str) -> str

446

```

447

448

**Description**: The value of a CSS property.

449

450

**Parameters**:

451

- `property_name`: CSS property name

452

453

**Returns**: The value of the CSS property

454

455

**Example**:

456

```python

457

element = driver.find_element(By.ID, 'header')

458

color = element.value_of_css_property('color')

459

background = element.value_of_css_property('background-color')

460

font_size = element.value_of_css_property('font-size')

461

```

462

463

### Screenshot Methods

464

465

{ .api }

466

```python

467

def screenshot_as_base64(self) -> str

468

```

469

470

**Description**: Gets the screenshot of the current element as a base64 encoded string.

471

472

**Returns**: Base64 encoded string of the PNG image

473

474

{ .api }

475

```python

476

def screenshot_as_png(self) -> bytes

477

```

478

479

**Description**: Gets the screenshot of the current element as binary data.

480

481

**Returns**: Binary data of the PNG image

482

483

{ .api }

484

```python

485

def screenshot(self, filename: str) -> bool

486

```

487

488

**Description**: Saves a screenshot of the current element to a PNG image file.

489

490

**Parameters**:

491

- `filename`: The full path to save the screenshot

492

493

**Returns**: True if the screenshot was saved successfully, False otherwise

494

495

**Example**:

496

```python

497

element = driver.find_element(By.ID, 'chart')

498

499

# Save screenshot to file

500

element.screenshot('/path/to/element_screenshot.png')

501

502

# Get as binary data

503

png_data = element.screenshot_as_png()

504

505

# Get as base64 string

506

base64_data = element.screenshot_as_base64()

507

```

508

509

### Accessibility Methods

510

511

{ .api }

512

```python

513

def aria_role(self) -> str

514

```

515

516

**Description**: Gets the ARIA role of the current element.

517

518

**Returns**: The ARIA role attribute value

519

520

{ .api }

521

```python

522

def accessible_name(self) -> str

523

```

524

525

**Description**: Gets the accessible name of the current element.

526

527

**Returns**: The accessible name of the element

528

529

**Example**:

530

```python

531

button = driver.find_element(By.ID, 'submit-btn')

532

role = button.aria_role

533

name = button.accessible_name

534

print(f"Button role: {role}, accessible name: {name}")

535

```

536

537

## Element Finding from Elements

538

539

WebElements also support finding child elements:

540

541

{ .api }

542

```python

543

def find_element(self, by: str = By.ID, value: Optional[str] = None) -> WebElement

544

```

545

546

{ .api }

547

```python

548

def find_elements(self, by: str = By.ID, value: Optional[str] = None) -> List[WebElement]

549

```

550

551

**Example**:

552

```python

553

# Find a container element

554

container = driver.find_element(By.ID, 'products')

555

556

# Find child elements within the container

557

products = container.find_elements(By.CLASS_NAME, 'product-item')

558

559

for product in products:

560

title = product.find_element(By.CLASS_NAME, 'product-title')

561

price = product.find_element(By.CLASS_NAME, 'product-price')

562

print(f"{title.text}: {price.text}")

563

```

564

565

## Shadow DOM Support

566

567

{ .api }

568

```python

569

def shadow_root(self) -> ShadowRoot

570

```

571

572

**Description**: Returns a shadow root of the element if there is one, or an error.

573

574

**Returns**: ShadowRoot object

575

576

**Example**:

577

```python

578

# Find element with shadow DOM

579

host_element = driver.find_element(By.ID, 'shadow-host')

580

581

# Access shadow root

582

shadow_root = host_element.shadow_root

583

584

# Find elements within shadow DOM

585

shadow_element = shadow_root.find_element(By.CSS_SELECTOR, '.shadow-content')

586

```

587

588

## Best Practices for Element Interaction

589

590

### 1. Robust Element Finding

591

592

```python

593

from selenium.common.exceptions import NoSuchElementException, TimeoutException

594

from selenium.webdriver.support.ui import WebDriverWait

595

from selenium.webdriver.support import expected_conditions as EC

596

597

def find_element_safely(driver, by, value, timeout=10):

598

"""Safely find element with timeout"""

599

try:

600

element = WebDriverWait(driver, timeout).until(

601

EC.presence_of_element_located((by, value))

602

)

603

return element

604

except TimeoutException:

605

print(f"Element not found: {by}={value}")

606

return None

607

608

# Usage

609

element = find_element_safely(driver, By.ID, 'submit-btn')

610

if element:

611

element.click()

612

```

613

614

### 2. Waiting for Element State

615

616

```python

617

from selenium.webdriver.support import expected_conditions as EC

618

619

# Wait for element to be clickable

620

wait = WebDriverWait(driver, 10)

621

button = wait.until(EC.element_to_be_clickable((By.ID, 'submit-btn')))

622

button.click()

623

624

# Wait for element to be visible

625

element = wait.until(EC.visibility_of_element_located((By.ID, 'result')))

626

print(element.text)

627

```

628

629

### 3. Handling Dynamic Content

630

631

```python

632

def wait_for_text_change(element, old_text, timeout=10):

633

"""Wait for element text to change"""

634

wait = WebDriverWait(driver, timeout)

635

wait.until(lambda d: element.text != old_text)

636

637

# Usage

638

status_element = driver.find_element(By.ID, 'status')

639

old_status = status_element.text

640

# Trigger some action

641

submit_button.click()

642

# Wait for status to update

643

wait_for_text_change(status_element, old_status)

644

```

645

646

### 4. Efficient Element Interaction

647

648

```python

649

def interact_with_form(driver):

650

"""Efficient form interaction pattern"""

651

# Find form container once

652

form = driver.find_element(By.ID, 'user-form')

653

654

# Find all inputs within the form

655

username = form.find_element(By.NAME, 'username')

656

password = form.find_element(By.NAME, 'password')

657

submit_btn = form.find_element(By.TYPE, 'submit')

658

659

# Perform interactions

660

username.clear()

661

username.send_keys('testuser')

662

663

password.clear()

664

password.send_keys('password123')

665

666

# Submit form

667

submit_btn.click()

668

```

669

670

### 5. Error Handling

671

672

```python

673

from selenium.common.exceptions import (

674

NoSuchElementException,

675

ElementNotInteractableException,

676

StaleElementReferenceException

677

)

678

679

def safe_click(element, retries=3):

680

"""Safely click element with retry logic"""

681

for attempt in range(retries):

682

try:

683

element.click()

684

return True

685

except StaleElementReferenceException:

686

# Re-find the element

687

element = driver.find_element(By.ID, element.id)

688

except ElementNotInteractableException:

689

# Wait a bit and try again

690

time.sleep(0.5)

691

return False

692

```