or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-management.mddevice-management.mdimage-processing.mdindex.mdscreen-input.mdui-interaction.mdwatchers-automation.mdxpath-selection.md

ui-interaction.mddocs/

0

# UI Element Selection and Interaction

1

2

Comprehensive UI element selection using UiAutomator selectors, coordinate-based targeting, and gesture operations. Supports clicking, text input, gestures, and element property inspection.

3

4

## Capabilities

5

6

### Element Selection

7

8

Select UI elements using UiAutomator selector attributes.

9

10

```python { .api }

11

class Device:

12

def __call__(self, **kwargs) -> UiObject:

13

"""

14

Create UI element selector.

15

16

Parameters:

17

- text: Exact text match

18

- textContains: Partial text match

19

- textMatches: Regular expression text match

20

- textStartsWith: Text prefix match

21

- className: UI element class name

22

- classNameMatches: Regular expression class name match

23

- description: Content description match

24

- descriptionContains: Partial description match

25

- descriptionMatches: Regular expression description match

26

- descriptionStartsWith: Description prefix match

27

- resourceId: Resource ID match

28

- resourceIdMatches: Regular expression resource ID match

29

- packageName: Package name match

30

- packageNameMatches: Regular expression package name match

31

- checkable: Boolean checkable state

32

- checked: Boolean checked state

33

- clickable: Boolean clickable state

34

- longClickable: Boolean long clickable state

35

- scrollable: Boolean scrollable state

36

- enabled: Boolean enabled state

37

- focusable: Boolean focusable state

38

- focused: Boolean focused state

39

- selected: Boolean selected state

40

- index: Element index within parent

41

- instance: Element instance number

42

43

Returns:

44

UiObject for interaction

45

"""

46

47

def exists(self, **kwargs) -> bool:

48

"""Check if UI element exists using selector attributes"""

49

```

50

51

Usage examples:

52

53

```python

54

d = u2.connect()

55

56

# Select by text

57

button = d(text="OK")

58

login_btn = d(textContains="Login")

59

submit_btn = d(textMatches=r"Submit|Send")

60

61

# Select by resource ID

62

username_field = d(resourceId="com.example:id/username")

63

password_field = d(resourceId="com.example:id/password")

64

65

# Select by class and attributes

66

text_view = d(className="android.widget.TextView", clickable=True)

67

edit_text = d(className="android.widget.EditText", enabled=True)

68

69

# Select by index

70

first_item = d(className="android.widget.LinearLayout", index=0)

71

72

# Check existence

73

if d(text="Settings").exists:

74

print("Settings button found")

75

```

76

77

### Element Properties and Information

78

79

Access UI element properties and attributes.

80

81

```python { .api }

82

class UiObject:

83

@property

84

def exists(self) -> bool:

85

"""Check if element exists in current UI"""

86

87

@property

88

def info(self) -> Dict[str, Any]:

89

"""Get element attributes including bounds, text, className, etc."""

90

91

def screenshot(self, display_id: Optional[int] = None) -> Image.Image:

92

"""Take screenshot of element bounds"""

93

```

94

95

Usage examples:

96

97

```python

98

d = u2.connect()

99

100

# Get element info

101

element = d(resourceId="com.example:id/title")

102

if element.exists:

103

info = element.info

104

print(f"Text: {info['text']}")

105

print(f"Bounds: {info['bounds']}")

106

print(f"Class: {info['className']}")

107

print(f"Clickable: {info['clickable']}")

108

109

# Screenshot element

110

element_image = element.screenshot()

111

element_image.save("element.png")

112

```

113

114

### Coordinate-based Interaction

115

116

Direct interaction using screen coordinates.

117

118

```python { .api }

119

class Device:

120

def click(self, x: Union[float, int], y: Union[float, int]):

121

"""

122

Click at coordinates.

123

124

Parameters:

125

- x: X coordinate (absolute pixels or relative 0-1)

126

- y: Y coordinate (absolute pixels or relative 0-1)

127

"""

128

129

def double_click(self, x, y, duration=0.1):

130

"""

131

Double click at coordinates.

132

133

Parameters:

134

- x, y: Coordinates

135

- duration: Delay between clicks in seconds

136

"""

137

138

def long_click(self, x, y, duration: float = 0.5):

139

"""

140

Long click at coordinates.

141

142

Parameters:

143

- x, y: Coordinates

144

- duration: Press duration in seconds

145

"""

146

147

@property

148

def pos_rel2abs(self):

149

"""Function to convert relative (0-1) to absolute pixel coordinates"""

150

```

151

152

Usage examples:

153

154

```python

155

d = u2.connect()

156

157

# Absolute coordinates

158

d.click(100, 200)

159

d.double_click(300, 400)

160

d.long_click(500, 600, duration=2.0)

161

162

# Relative coordinates (0-1 range)

163

d.click(0.5, 0.3) # Center horizontally, 30% from top

164

d.click(0.1, 0.9) # Near bottom-left corner

165

166

# Convert relative to absolute

167

convert = d.pos_rel2abs

168

abs_x, abs_y = convert(0.5, 0.5) # Get center coordinates

169

```

170

171

### Gesture Operations

172

173

Swipe, drag, and multi-touch gestures.

174

175

```python { .api }

176

class Device:

177

def swipe(self, fx, fy, tx, ty, duration: Optional[float] = None, steps: Optional[int] = None):

178

"""

179

Swipe from one point to another.

180

181

Parameters:

182

- fx, fy: From coordinates

183

- tx, ty: To coordinates

184

- duration: Swipe duration in seconds

185

- steps: Number of interpolation steps (overrides duration)

186

"""

187

188

def swipe_points(self, points: List[Tuple[int, int]], duration: float = 0.5):

189

"""

190

Multi-point swipe gesture.

191

192

Parameters:

193

- points: List of (x, y) coordinate tuples

194

- duration: Total gesture duration

195

"""

196

197

def drag(self, sx, sy, ex, ey, duration=0.5):

198

"""

199

Drag from start to end coordinates.

200

201

Parameters:

202

- sx, sy: Start coordinates

203

- ex, ey: End coordinates

204

- duration: Drag duration in seconds

205

"""

206

207

@property

208

def touch(self) -> TouchActions:

209

"""Touch gesture builder for complex multi-touch operations"""

210

```

211

212

Usage examples:

213

214

```python

215

d = u2.connect()

216

217

# Basic swipe gestures

218

d.swipe(100, 500, 100, 100) # Swipe up

219

d.swipe(500, 300, 100, 300) # Swipe left

220

d.swipe(100, 100, 500, 500, duration=2.0) # Slow diagonal swipe

221

222

# Multi-point swipe

223

points = [(100, 100), (200, 150), (300, 100), (400, 200)]

224

d.swipe_points(points, duration=1.5)

225

226

# Drag operation

227

d.drag(100, 100, 500, 500, duration=1.0)

228

229

# Complex touch gestures

230

d.touch.down(100, 100).move(200, 200).sleep(0.5).up(200, 200)

231

```

232

233

### Advanced Gesture Support

234

235

Extended swipe functionality for common UI patterns.

236

237

```python { .api }

238

class Device:

239

@cached_property

240

def swipe_ext(self) -> SwipeExt:

241

"""Extended swipe gestures for common UI patterns"""

242

243

class SwipeExt:

244

def up(self, scale: float = 0.8):

245

"""Swipe up gesture"""

246

247

def down(self, scale: float = 0.8):

248

"""Swipe down gesture"""

249

250

def left(self, scale: float = 0.8):

251

"""Swipe left gesture"""

252

253

def right(self, scale: float = 0.8):

254

"""Swipe right gesture"""

255

```

256

257

Usage examples:

258

259

```python

260

d = u2.connect()

261

262

# Extended swipe gestures

263

d.swipe_ext.up(scale=0.9) # Swipe up 90% of screen

264

d.swipe_ext.down() # Swipe down default 80%

265

d.swipe_ext.left(scale=0.7) # Swipe left 70% of screen

266

d.swipe_ext.right() # Swipe right default 80%

267

```

268

269

### Element Interaction

270

271

Direct interaction with selected UI elements.

272

273

```python { .api }

274

class UiObject:

275

def click(self, timeout: Optional[float] = None):

276

"""Click the UI element"""

277

278

def long_click(self, duration: float = 0.5):

279

"""Long click the UI element"""

280

281

def set_text(self, text: str):

282

"""Set text content of element"""

283

284

def clear_text(self):

285

"""Clear text content of element"""

286

287

def wait(self, timeout: Optional[float] = None) -> bool:

288

"""Wait for element to appear"""

289

290

def wait_gone(self, timeout: Optional[float] = None) -> bool:

291

"""Wait for element to disappear"""

292

293

def click_exists(self, timeout=0) -> bool:

294

"""Click element if it exists within timeout"""

295

296

def click_gone(self, maxretry=10, interval=1.0):

297

"""Click element repeatedly until it disappears"""

298

299

def bounds(self) -> Tuple[int, int, int, int]:

300

"""Get element bounds (left, top, right, bottom)"""

301

302

def center(self, offset=(0.5, 0.5)) -> Tuple[int, int]:

303

"""Get element center coordinates with optional offset"""

304

305

def drag_to(self, **kwargs):

306

"""Drag element to another element or coordinates"""

307

```

308

309

Usage examples:

310

311

```python

312

d = u2.connect()

313

314

# Element interaction

315

button = d(text="Submit")

316

button.click()

317

318

# Text input

319

username = d(resourceId="com.example:id/username")

320

username.clear_text()

321

username.set_text("john_doe")

322

323

# Wait for elements

324

loading = d(text="Loading...")

325

loading.wait(timeout=10) # Wait up to 10 seconds

326

loading.wait_gone(timeout=30) # Wait for loading to disappear

327

328

# Advanced element interaction

329

button = d(text="Optional Button")

330

if button.click_exists(timeout=5): # Click if exists within 5 seconds

331

print("Button clicked")

332

333

# Remove popup by clicking repeatedly

334

popup_close = d(resourceId="close_popup")

335

popup_close.click_gone(maxretry=5, interval=0.5) # Click until gone

336

337

# Get element position and size

338

element = d(resourceId="target_element")

339

bounds = element.bounds() # (left, top, right, bottom)

340

print(f"Element bounds: {bounds}")

341

342

center_x, center_y = element.center() # Get center point

343

print(f"Element center: ({center_x}, {center_y})")

344

345

# Get center with offset (0.8, 0.2 means 80% right, 20% down within element)

346

offset_point = element.center(offset=(0.8, 0.2))

347

348

# Drag element to another location

349

source = d(text="Drag Me")

350

target = d(text="Drop Here")

351

source.drag_to(target) # Drag to another element

352

source.drag_to(x=500, y=300) # Drag to coordinates

353

```

354

355

### Element Navigation and Hierarchy

356

357

Navigate through UI hierarchy using parent-child relationships.

358

359

```python { .api }

360

class UiObject:

361

def child(self, **kwargs) -> UiObject:

362

"""Find child element using selector attributes"""

363

364

def sibling(self, **kwargs) -> UiObject:

365

"""Find sibling element using selector attributes"""

366

367

def child_by_text(self, txt: str, **kwargs) -> UiObject:

368

"""Find child element by text match"""

369

370

def child_by_description(self, txt: str, **kwargs) -> UiObject:

371

"""Find child element by description match"""

372

373

def child_by_instance(self, inst: int, **kwargs) -> UiObject:

374

"""Find child element by instance number"""

375

```

376

377

Usage examples:

378

379

```python

380

d = u2.connect()

381

382

# Navigate through hierarchy

383

container = d(resourceId="container")

384

submit_button = container.child(text="Submit")

385

submit_button.click()

386

387

# Find specific child by text

388

menu = d(className="android.widget.LinearLayout")

389

settings_item = menu.child_by_text("Settings")

390

settings_item.click()

391

392

# Find sibling elements

393

current_item = d(text="Current Item")

394

next_item = current_item.sibling(text="Next Item")

395

next_item.click()

396

```

397

398

### Relative Positioning

399

400

Find elements relative to other elements on screen.

401

402

```python { .api }

403

class UiObject:

404

def right(self, **kwargs) -> UiObject:

405

"""Find element to the right of current element"""

406

407

def left(self, **kwargs) -> UiObject:

408

"""Find element to the left of current element"""

409

410

def up(self, **kwargs) -> UiObject:

411

"""Find element above current element"""

412

413

def down(self, **kwargs) -> UiObject:

414

"""Find element below current element"""

415

```

416

417

Usage examples:

418

419

```python

420

d = u2.connect()

421

422

# Relative positioning

423

username_field = d(resourceId="username")

424

password_field = username_field.down(resourceId="password")

425

password_field.set_text("secret123")

426

427

# Find button to the right of a label

428

price_label = d(text="Price:")

429

edit_button = price_label.right(text="Edit")

430

edit_button.click()

431

```

432

433

### Scrolling and Flinging

434

435

Scroll elements within containers with precise control.

436

437

```python { .api }

438

class UiObject:

439

@property

440

def scroll(self):

441

"""Scroll gesture builder for element"""

442

443

@property

444

def fling(self):

445

"""Fling gesture builder for element"""

446

447

class ScrollBuilder:

448

def forward(self, steps: int = 10): """Scroll forward (up/left)"""

449

def backward(self, steps: int = 10): """Scroll backward (down/right)"""

450

def toBeginning(self, steps: int = 10): """Scroll to beginning"""

451

def toEnd(self, steps: int = 10): """Scroll to end"""

452

def to(self, **kwargs): """Scroll until element is visible"""

453

454

class FlingBuilder:

455

def forward(self): """Fling forward quickly"""

456

def backward(self): """Fling backward quickly"""

457

def toBeginning(self): """Fling to beginning"""

458

def toEnd(self): """Fling to end"""

459

```

460

461

Usage examples:

462

463

```python

464

d = u2.connect()

465

466

# Scroll within a list or container

467

scrollable_list = d(scrollable=True)

468

scrollable_list.scroll.forward(steps=5) # Scroll up 5 steps

469

scrollable_list.scroll.backward(steps=10) # Scroll down 10 steps

470

scrollable_list.scroll.toBeginning() # Scroll to top

471

scrollable_list.scroll.toEnd() # Scroll to bottom

472

473

# Scroll until specific element is visible

474

scrollable_list.scroll.to(text="Target Item")

475

476

# Fast fling gestures

477

scrollable_list.fling.forward() # Quick fling up

478

scrollable_list.fling.toEnd() # Quick fling to bottom

479

```

480

481

### Advanced Gestures

482

483

Multi-finger gestures for complex interactions.

484

485

```python { .api }

486

class UiObject:

487

def gesture(self, start1: Tuple[float, float], start2: Tuple[float, float],

488

end1: Tuple[float, float], end2: Tuple[float, float], steps: int = 100):

489

"""Two-finger gesture between specified points"""

490

491

def pinch_in(self, percent: int = 100, steps: int = 50):

492

"""Pinch in gesture (zoom out)"""

493

494

def pinch_out(self, percent: int = 100, steps: int = 50):

495

"""Pinch out gesture (zoom in)"""

496

```

497

498

Usage examples:

499

500

```python

501

d = u2.connect()

502

503

# Pinch gestures on image or map

504

image_view = d(className="ImageView")

505

image_view.pinch_out(percent=200, steps=30) # Zoom in 200%

506

image_view.pinch_in(percent=50, steps=30) # Zoom out 50%

507

508

# Custom two-finger gesture

509

map_view = d(resourceId="map_view")

510

# Two-finger drag from corners to center

511

map_view.gesture(start1=(0.1, 0.1), start2=(0.9, 0.9),

512

end1=(0.4, 0.4), end2=(0.6, 0.6), steps=50)

513

```

514

515

### Element Indexing and Iteration

516

517

Work with multiple matching elements using indexing and iteration.

518

519

```python { .api }

520

class UiObject:

521

def __getitem__(self, index: int) -> UiObject:

522

"""Get element by index when multiple matches exist"""

523

524

def __len__(self) -> int:

525

"""Get count of matching elements"""

526

527

def __iter__(self):

528

"""Iterate over all matching elements"""

529

530

@property

531

def count(self) -> int:

532

"""Get count of matching elements"""

533

```

534

535

Usage examples:

536

537

```python

538

d = u2.connect()

539

540

# Work with multiple matching elements

541

buttons = d(className="android.widget.Button")

542

print(f"Found {len(buttons)} buttons") # Get count

543

print(f"Found {buttons.count} buttons") # Alternative count

544

545

# Access specific element by index

546

first_button = buttons[0] # First button

547

last_button = buttons[-1] # Last button

548

first_button.click()

549

550

# Iterate over all matching elements

551

for i, button in enumerate(buttons):

552

print(f"Button {i}: {button.get_text()}")

553

if button.get_text() == "Submit":

554

button.click()

555

break

556

```