or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

automation-patterns.mdcontrol-management.mdcontrol-types.mdindex.mdinput-simulation.mdlogging-debugging.mdscreen-capture.mdwindows-api.md

automation-patterns.mddocs/

0

# Automation Patterns

1

2

Implementation of Windows UI Automation patterns for specialized control operations. Patterns provide standardized interfaces for common control behaviors like invoking buttons, setting values, handling selections, and managing scrollable content.

3

4

## Capabilities

5

6

### Invoke Pattern

7

8

The Invoke pattern enables triggering of controls that perform a single action when activated.

9

10

```python { .api }

11

class InvokePattern:

12

"""Pattern for controls that can be invoked (clicked/activated)."""

13

14

def Invoke(self) -> None:

15

"""

16

Invoke the control (equivalent to clicking).

17

Typically used for buttons, menu items, and hyperlinks.

18

"""

19

```

20

21

### Value Pattern

22

23

The Value pattern provides access to controls that have a string value that can be read or set.

24

25

```python { .api }

26

class ValuePattern:

27

"""Pattern for controls with settable string values."""

28

29

def SetValue(self, value: str) -> None:

30

"""

31

Set the value of the control.

32

33

Args:

34

value: String value to set

35

"""

36

37

def GetValue(self) -> str:

38

"""

39

Get the current value of the control.

40

41

Returns:

42

str: Current string value of the control

43

"""

44

45

@property

46

def IsReadOnly(self) -> bool:

47

"""Whether the control's value is read-only."""

48

```

49

50

### Toggle Pattern

51

52

The Toggle pattern supports controls that can cycle through a set of states.

53

54

```python { .api }

55

class TogglePattern:

56

"""Pattern for controls with toggle states (checkboxes, toggle buttons)."""

57

58

def Toggle(self) -> None:

59

"""Toggle the control to its next state."""

60

61

@property

62

def ToggleState(self) -> int:

63

"""

64

Current toggle state.

65

66

Returns:

67

int: ToggleState constant (Off=0, On=1, Indeterminate=2)

68

"""

69

70

class ToggleState:

71

"""Constants for toggle states."""

72

Off: int = 0

73

On: int = 1

74

Indeterminate: int = 2

75

```

76

77

### Range Value Pattern

78

79

The Range Value pattern provides access to controls that represent a value within a range.

80

81

```python { .api }

82

class RangeValuePattern:

83

"""Pattern for controls with numeric ranges (sliders, progress bars)."""

84

85

def SetValue(self, value: float) -> None:

86

"""

87

Set the numeric value.

88

89

Args:

90

value: Numeric value within the valid range

91

"""

92

93

@property

94

def Value(self) -> float:

95

"""Current numeric value."""

96

97

@property

98

def Minimum(self) -> float:

99

"""Minimum allowed value."""

100

101

@property

102

def Maximum(self) -> float:

103

"""Maximum allowed value."""

104

105

@property

106

def SmallChange(self) -> float:

107

"""Small increment/decrement amount."""

108

109

@property

110

def LargeChange(self) -> float:

111

"""Large increment/decrement amount."""

112

113

@property

114

def IsReadOnly(self) -> bool:

115

"""Whether the value is read-only."""

116

```

117

118

### Selection Pattern

119

120

The Selection pattern supports controls that act as containers for selectable child items.

121

122

```python { .api }

123

class SelectionPattern:

124

"""Pattern for selection containers (lists, combo boxes)."""

125

126

def GetSelection(self) -> list:

127

"""

128

Get currently selected items.

129

130

Returns:

131

list: List of selected control elements

132

"""

133

134

@property

135

def CanSelectMultiple(self) -> bool:

136

"""Whether multiple items can be selected."""

137

138

@property

139

def IsSelectionRequired(self) -> bool:

140

"""Whether at least one item must be selected."""

141

```

142

143

### Selection Item Pattern

144

145

The Selection Item pattern supports individual items that can be selected within a selection container.

146

147

```python { .api }

148

class SelectionItemPattern:

149

"""Pattern for selectable items within selection containers."""

150

151

def Select(self) -> None:

152

"""Select this item (deselecting others if single-select)."""

153

154

def AddToSelection(self) -> None:

155

"""Add this item to the selection (multi-select containers)."""

156

157

def RemoveFromSelection(self) -> None:

158

"""Remove this item from the selection."""

159

160

@property

161

def IsSelected(self) -> bool:

162

"""Whether this item is currently selected."""

163

164

@property

165

def SelectionContainer(self):

166

"""The container control that manages selection."""

167

```

168

169

### Scroll Pattern

170

171

The Scroll pattern provides scrolling functionality for controls with scrollable content.

172

173

```python { .api }

174

class ScrollPattern:

175

"""Pattern for scrollable controls."""

176

177

def Scroll(self, horizontalAmount: int, verticalAmount: int) -> None:

178

"""

179

Scroll by specified amounts.

180

181

Args:

182

horizontalAmount: Horizontal scroll amount

183

verticalAmount: Vertical scroll amount

184

"""

185

186

def SetScrollPercent(self, horizontalPercent: float, verticalPercent: float) -> None:

187

"""

188

Set scroll position by percentage.

189

190

Args:

191

horizontalPercent: Horizontal position (0-100)

192

verticalPercent: Vertical position (0-100)

193

"""

194

195

@property

196

def HorizontalScrollPercent(self) -> float:

197

"""Current horizontal scroll percentage."""

198

199

@property

200

def VerticalScrollPercent(self) -> float:

201

"""Current vertical scroll percentage."""

202

203

@property

204

def HorizontalViewSize(self) -> float:

205

"""Horizontal view size as percentage of total."""

206

207

@property

208

def VerticalViewSize(self) -> float:

209

"""Vertical view size as percentage of total."""

210

211

@property

212

def HorizontallyScrollable(self) -> bool:

213

"""Whether horizontal scrolling is available."""

214

215

@property

216

def VerticallyScrollable(self) -> bool:

217

"""Whether vertical scrolling is available."""

218

```

219

220

### Scroll Item Pattern

221

222

The Scroll Item pattern enables individual items to scroll themselves into view.

223

224

```python { .api }

225

class ScrollItemPattern:

226

"""Pattern for items that can scroll themselves into view."""

227

228

def ScrollIntoView(self) -> None:

229

"""Scroll this item into the visible area of its container."""

230

```

231

232

### Expand Collapse Pattern

233

234

The Expand Collapse pattern supports controls that can expand to show more content or collapse to hide content.

235

236

```python { .api }

237

class ExpandCollapsePattern:

238

"""Pattern for expandable/collapsible controls (tree nodes, menus)."""

239

240

def Expand(self) -> None:

241

"""Expand the control to show child items."""

242

243

def Collapse(self) -> None:

244

"""Collapse the control to hide child items."""

245

246

@property

247

def ExpandCollapseState(self) -> int:

248

"""

249

Current expand/collapse state.

250

251

Returns:

252

int: ExpandCollapseState constant

253

"""

254

255

class ExpandCollapseState:

256

"""Constants for expand/collapse states."""

257

Collapsed: int = 0

258

Expanded: int = 1

259

PartiallyExpanded: int = 2

260

LeafNode: int = 3

261

```

262

263

### Grid Pattern

264

265

The Grid pattern provides access to controls that act as containers for a collection of child elements organized in a grid.

266

267

```python { .api }

268

class GridPattern:

269

"""Pattern for grid controls (data grids, tables)."""

270

271

def GetItem(self, row: int, column: int):

272

"""

273

Get the control at the specified grid coordinates.

274

275

Args:

276

row: Zero-based row index

277

column: Zero-based column index

278

279

Returns:

280

Control: The control at the specified position

281

"""

282

283

@property

284

def RowCount(self) -> int:

285

"""Number of rows in the grid."""

286

287

@property

288

def ColumnCount(self) -> int:

289

"""Number of columns in the grid."""

290

```

291

292

### Grid Item Pattern

293

294

The Grid Item pattern provides information about individual items within a grid.

295

296

```python { .api }

297

class GridItemPattern:

298

"""Pattern for individual items within grid controls."""

299

300

@property

301

def Row(self) -> int:

302

"""Zero-based row index of this item."""

303

304

@property

305

def Column(self) -> int:

306

"""Zero-based column index of this item."""

307

308

@property

309

def RowSpan(self) -> int:

310

"""Number of rows spanned by this item."""

311

312

@property

313

def ColumnSpan(self) -> int:

314

"""Number of columns spanned by this item."""

315

316

@property

317

def ContainingGrid(self):

318

"""The grid control containing this item."""

319

```

320

321

### Window Pattern

322

323

The Window pattern provides access to window-specific functionality.

324

325

```python { .api }

326

class WindowPattern:

327

"""Pattern for window controls."""

328

329

def Close(self) -> None:

330

"""Close the window."""

331

332

def SetWindowVisualState(self, state: int) -> None:

333

"""

334

Set the window's visual state.

335

336

Args:

337

state: WindowVisualState constant

338

"""

339

340

def WaitForInputIdle(self, timeout: int) -> bool:

341

"""

342

Wait for the window to be ready for user input.

343

344

Args:

345

timeout: Timeout in milliseconds

346

347

Returns:

348

bool: True if window became ready, False if timeout

349

"""

350

351

@property

352

def WindowVisualState(self) -> int:

353

"""Current window visual state."""

354

355

@property

356

def WindowInteractionState(self) -> int:

357

"""Current window interaction state."""

358

359

@property

360

def IsModal(self) -> bool:

361

"""Whether the window is modal."""

362

363

@property

364

def IsTopmost(self) -> bool:

365

"""Whether the window is topmost."""

366

367

@property

368

def Maximizable(self) -> bool:

369

"""Whether the window can be maximized."""

370

371

@property

372

def Minimizable(self) -> bool:

373

"""Whether the window can be minimized."""

374

375

class WindowVisualState:

376

"""Constants for window visual states."""

377

Normal: int = 0

378

Maximized: int = 1

379

Minimized: int = 2

380

```

381

382

### Text Pattern

383

384

The Text pattern provides access to text content and formatting information.

385

386

```python { .api }

387

class TextPattern:

388

"""Pattern for controls containing text content."""

389

390

def GetText(self, maxLength: int = -1) -> str:

391

"""

392

Get text content.

393

394

Args:

395

maxLength: Maximum length to retrieve (-1 for all)

396

397

Returns:

398

str: Text content

399

"""

400

401

def GetSelection(self) -> list:

402

"""

403

Get selected text ranges.

404

405

Returns:

406

list: List of selected text range objects

407

"""

408

409

def GetVisibleRanges(self) -> list:

410

"""

411

Get visible text ranges.

412

413

Returns:

414

list: List of visible text range objects

415

"""

416

```

417

418

## Usage Examples

419

420

### Using Invoke Pattern

421

422

```python

423

import uiautomation

424

425

# Get button and invoke it using pattern

426

button = uiautomation.ButtonControl(Name='Submit')

427

invoke_pattern = button.GetInvokePattern()

428

if invoke_pattern:

429

invoke_pattern.Invoke()

430

```

431

432

### Using Value Pattern

433

434

```python

435

# Set value in a text box

436

text_box = uiautomation.EditControl(Name='Username')

437

value_pattern = text_box.GetValuePattern()

438

if value_pattern and not value_pattern.IsReadOnly:

439

value_pattern.SetValue('myusername')

440

441

# Get current value

442

current_value = value_pattern.GetValue()

443

print(f"Current value: {current_value}")

444

```

445

446

### Using Selection Patterns

447

448

```python

449

# Work with a list box

450

list_box = uiautomation.ListControl(Name='Items')

451

selection_pattern = list_box.GetSelectionPattern()

452

453

# Get current selection

454

selected_items = selection_pattern.GetSelection()

455

for item in selected_items:

456

print(f"Selected: {item.Name}")

457

458

# Select an item

459

list_item = list_box.ListItemControl(Name='Item 3')

460

selection_item_pattern = list_item.GetSelectionItemPattern()

461

if selection_item_pattern:

462

selection_item_pattern.Select()

463

```

464

465

### Using Toggle Pattern

466

467

```python

468

# Toggle a checkbox

469

checkbox = uiautomation.CheckBoxControl(Name='Enable notifications')

470

toggle_pattern = checkbox.GetTogglePattern()

471

if toggle_pattern:

472

current_state = toggle_pattern.ToggleState

473

if current_state == uiautomation.ToggleState.Off:

474

toggle_pattern.Toggle() # Turn on

475

```

476

477

### Using Range Value Pattern

478

479

```python

480

# Set slider value

481

slider = uiautomation.SliderControl(Name='Volume')

482

range_pattern = slider.GetRangeValuePattern()

483

if range_pattern and not range_pattern.IsReadOnly:

484

# Set to 75% of the range

485

range_size = range_pattern.Maximum - range_pattern.Minimum

486

target_value = range_pattern.Minimum + (range_size * 0.75)

487

range_pattern.SetValue(target_value)

488

```

489

490

### Using Scroll Pattern

491

492

```python

493

# Scroll in a scrollable area

494

text_area = uiautomation.EditControl(Name='Content')

495

scroll_pattern = text_area.GetScrollPattern()

496

if scroll_pattern and scroll_pattern.VerticallyScrollable:

497

# Scroll to bottom

498

scroll_pattern.SetScrollPercent(-1, 100) # -1 means no change for horizontal

499

```

500

501

### Using Expand Collapse Pattern

502

503

```python

504

# Expand a tree node

505

tree = uiautomation.TreeControl(Name='Directory')

506

folder_node = tree.TreeItemControl(Name='Documents')

507

expand_pattern = folder_node.GetExpandCollapsePattern()

508

if expand_pattern:

509

if expand_pattern.ExpandCollapseState == uiautomation.ExpandCollapseState.Collapsed:

510

expand_pattern.Expand()

511

```

512

513

### Using Grid Pattern

514

515

```python

516

# Access grid data

517

data_grid = uiautomation.DataGridControl(Name='Results')

518

grid_pattern = data_grid.GetGridPattern()

519

if grid_pattern:

520

# Get cell at row 2, column 1

521

cell = grid_pattern.GetItem(2, 1)

522

if cell:

523

print(f"Cell value: {cell.Name}")

524

525

print(f"Grid size: {grid_pattern.RowCount} x {grid_pattern.ColumnCount}")

526

```

527

528

### Using Window Pattern

529

530

```python

531

# Manage window state

532

window = uiautomation.WindowControl(Name='My Application')

533

window_pattern = window.GetWindowPattern()

534

if window_pattern:

535

# Maximize the window

536

window_pattern.SetWindowVisualState(uiautomation.WindowVisualState.Maximized)

537

538

# Wait for window to be ready

539

ready = window_pattern.WaitForInputIdle(5000) # 5 second timeout

540

if ready:

541

print("Window is ready for input")

542

```

543

544

### Pattern Availability Checking

545

546

```python

547

def safe_invoke_button(button_name):

548

"""Safely invoke a button using pattern if available."""

549

button = uiautomation.ButtonControl(Name=button_name)

550

if not button.Exists():

551

print(f"Button '{button_name}' not found")

552

return False

553

554

# Try using invoke pattern first

555

invoke_pattern = button.GetInvokePattern()

556

if invoke_pattern:

557

invoke_pattern.Invoke()

558

return True

559

560

# Fall back to regular click

561

button.Click()

562

return True

563

```