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

logging-debugging.mddocs/

0

# Logging and Debugging

1

2

Comprehensive logging system with color support and control tree enumeration for debugging automation scripts and understanding application structure. These tools help developers troubleshoot automation issues and analyze UI hierarchies.

3

4

## Capabilities

5

6

### Logger Class

7

8

Main logging class providing various output methods with color support.

9

10

```python { .api }

11

class Logger:

12

"""Comprehensive logging system for automation debugging."""

13

14

def Write(self, text: str) -> None:

15

"""

16

Write text to log without newline.

17

18

Args:

19

text: Text to write

20

"""

21

22

def WriteLine(self, text: str) -> None:

23

"""

24

Write text to log with newline.

25

26

Args:

27

text: Text to write

28

"""

29

30

def ColorfulWrite(self, text: str, color: int) -> None:

31

"""

32

Write colored text to log without newline.

33

34

Args:

35

text: Text to write

36

color: Console color constant

37

"""

38

39

def ColorfulWriteLine(self, text: str, color: int) -> None:

40

"""

41

Write colored text to log with newline.

42

43

Args:

44

text: Text to write

45

color: Console color constant

46

"""

47

48

def Log(self, message: str) -> None:

49

"""

50

Log message with timestamp.

51

52

Args:

53

message: Message to log

54

"""

55

56

def ColorfulLog(self, message: str, color: int) -> None:

57

"""

58

Log colored message with timestamp.

59

60

Args:

61

message: Message to log

62

color: Console color constant

63

"""

64

65

def SetLogFile(self, filename: str) -> None:

66

"""

67

Set output log file.

68

69

Args:

70

filename: Path to log file

71

"""

72

73

def Close(self) -> None:

74

"""Close log file."""

75

```

76

77

### Console Colors

78

79

```python { .api }

80

class ConsoleColor:

81

"""Console color constants for colored logging."""

82

83

# Standard colors

84

Black: int = 0

85

DarkBlue: int = 1

86

DarkGreen: int = 2

87

DarkCyan: int = 3

88

DarkRed: int = 4

89

DarkMagenta: int = 5

90

DarkYellow: int = 6

91

Gray: int = 7

92

DarkGray: int = 8

93

Blue: int = 9

94

Green: int = 10

95

Cyan: int = 11

96

Red: int = 12

97

Magenta: int = 13

98

Yellow: int = 14

99

White: int = 15

100

101

class Logger:

102

# Color name to value mapping

103

ColorName2Value: dict = {

104

'Black': 0,

105

'DarkBlue': 1,

106

'DarkGreen': 2,

107

'DarkCyan': 3,

108

'DarkRed': 4,

109

'DarkMagenta': 5,

110

'DarkYellow': 6,

111

'Gray': 7,

112

'DarkGray': 8,

113

'Blue': 9,

114

'Green': 10,

115

'Cyan': 11,

116

'Red': 12,

117

'Magenta': 13,

118

'Yellow': 14,

119

'White': 15

120

}

121

```

122

123

### Control Logging Functions

124

125

Global functions for logging control information and hierarchies.

126

127

```python { .api }

128

def LogControl(control: Control) -> None:

129

"""

130

Log detailed information about a control.

131

132

Args:

133

control: Control to log information for

134

"""

135

136

def EnumAndLogControl(control: Control, depth: int = 1, showAllControls: bool = True) -> None:

137

"""

138

Enumerate and log control hierarchy.

139

140

Args:

141

control: Root control to start enumeration from

142

depth: Maximum depth to enumerate (-1 for unlimited)

143

showAllControls: Whether to show all controls or just visible ones

144

"""

145

146

def EnumAndLogControlAncestors(control: Control) -> None:

147

"""

148

Log all ancestor controls of the given control.

149

150

Args:

151

control: Control to log ancestors for

152

"""

153

```

154

155

### System Utilities

156

157

```python { .api }

158

def ShowDesktop(waitTime: float = 1) -> None:

159

"""

160

Show the desktop (minimize all windows).

161

162

Args:

163

waitTime: Time to wait after showing desktop

164

"""

165

166

def RunWithHotKey(func: callable, hotkey: str) -> None:

167

"""

168

Run a function when a hotkey is pressed.

169

170

Args:

171

func: Function to execute

172

hotkey: Hotkey combination (e.g., 'ctrl+f1')

173

"""

174

175

def WaitHotKeyReleased(hotkey: str, timeout: float = 15) -> bool:

176

"""

177

Wait for a hotkey to be released.

178

179

Args:

180

hotkey: Hotkey combination

181

timeout: Maximum wait time in seconds

182

183

Returns:

184

bool: True if hotkey was released, False if timeout

185

"""

186

```

187

188

### Debug Configuration

189

190

Global debug settings for controlling logging behavior.

191

192

```python { .api }

193

# Debug flags

194

DEBUG_SEARCH_TIME: bool = False # Log search timing information

195

DEBUG_EXIST_DISAPPEAR: bool = False # Log control existence checking

196

197

# Configuration functions

198

def SetDebugSearchTime(enabled: bool) -> None:

199

"""Enable/disable search time debugging."""

200

201

def SetDebugExistDisappear(enabled: bool) -> None:

202

"""Enable/disable existence checking debugging."""

203

```

204

205

## Usage Examples

206

207

### Basic Logging

208

209

```python

210

import uiautomation

211

212

# Create logger instance

213

logger = uiautomation.Logger()

214

215

# Basic text logging

216

logger.WriteLine("Starting automation script")

217

logger.Write("Processing... ")

218

logger.WriteLine("Done")

219

220

# Colored logging

221

logger.ColorfulWriteLine("Success!", uiautomation.ConsoleColor.Green)

222

logger.ColorfulWriteLine("Warning: Check configuration", uiautomation.ConsoleColor.Yellow)

223

logger.ColorfulWriteLine("Error: Failed to connect", uiautomation.ConsoleColor.Red)

224

225

# Timestamped logging

226

logger.Log("Script execution started")

227

logger.ColorfulLog("Critical error occurred", uiautomation.ConsoleColor.Red)

228

```

229

230

### File Logging

231

232

```python

233

# Set up file logging

234

logger = uiautomation.Logger()

235

logger.SetLogFile("automation_log.txt")

236

237

# Log to file

238

logger.WriteLine("This will be written to the file")

239

logger.ColorfulWriteLine("Colored text in file", uiautomation.ConsoleColor.Blue)

240

241

# Close file when done

242

logger.Close()

243

```

244

245

### Control Information Logging

246

247

```python

248

# Log detailed information about a specific control

249

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

250

if button.Exists():

251

uiautomation.LogControl(button)

252

253

# Log information about the focused control

254

focused = uiautomation.GetFocusedControl()

255

if focused:

256

uiautomation.LogControl(focused)

257

```

258

259

### Control Hierarchy Enumeration

260

261

```python

262

# Enumerate and log entire application window

263

app_window = uiautomation.WindowControl(Name='Calculator')

264

if app_window.Exists():

265

# Log all controls in the window (unlimited depth)

266

uiautomation.EnumAndLogControl(app_window, depth=-1)

267

268

# Enumerate with limited depth

269

desktop = uiautomation.GetRootControl()

270

uiautomation.EnumAndLogControl(desktop, depth=2) # Only 2 levels deep

271

272

# Show only visible controls

273

visible_only = False # Set to True to show only visible controls

274

uiautomation.EnumAndLogControl(app_window, depth=3, showAllControls=visible_only)

275

```

276

277

### Ancestor Logging

278

279

```python

280

# Find a specific control and log its ancestry

281

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

282

if text_field.Exists():

283

uiautomation.EnumAndLogControlAncestors(text_field)

284

# This will show: Desktop -> Window -> Pane -> Group -> EditControl

285

```

286

287

### Debug Mode Configuration

288

289

```python

290

# Enable debug logging for performance analysis

291

uiautomation.SetDebugSearchTime(True)

292

uiautomation.SetDebugExistDisappear(True)

293

294

# Now control searches will log timing information

295

button = uiautomation.ButtonControl(Name='Click Me')

296

button.Click() # This will log search time and existence checks

297

298

# Disable debug logging

299

uiautomation.SetDebugSearchTime(False)

300

uiautomation.SetDebugExistDisappear(False)

301

```

302

303

### Automation Script Debugging

304

305

```python

306

def debug_automation_step(step_name, func, *args, **kwargs):

307

"""Wrapper function to debug automation steps."""

308

logger = uiautomation.Logger()

309

310

logger.ColorfulWriteLine(f"Starting step: {step_name}", uiautomation.ConsoleColor.Cyan)

311

312

try:

313

start_time = time.time()

314

result = func(*args, **kwargs)

315

end_time = time.time()

316

317

logger.ColorfulWriteLine(

318

f"Step completed in {end_time - start_time:.2f}s: {step_name}",

319

uiautomation.ConsoleColor.Green

320

)

321

return result

322

323

except Exception as e:

324

logger.ColorfulWriteLine(

325

f"Step failed: {step_name} - {str(e)}",

326

uiautomation.ConsoleColor.Red

327

)

328

raise

329

330

# Use the debug wrapper

331

def click_submit_button():

332

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

333

button.Click()

334

335

debug_automation_step("Click Submit Button", click_submit_button)

336

```

337

338

### Control Search Debugging

339

340

```python

341

def debug_control_search(control_type, **search_criteria):

342

"""Debug control search operations."""

343

logger = uiautomation.Logger()

344

345

# Log search criteria

346

criteria_str = ", ".join([f"{k}='{v}'" for k, v in search_criteria.items()])

347

logger.ColorfulWriteLine(f"Searching for {control_type.__name__} with {criteria_str}",

348

uiautomation.ConsoleColor.Yellow)

349

350

# Perform search

351

control = control_type(**search_criteria)

352

353

if control.Exists():

354

logger.ColorfulWriteLine("Control found!", uiautomation.ConsoleColor.Green)

355

# Log control details

356

uiautomation.LogControl(control)

357

return control

358

else:

359

logger.ColorfulWriteLine("Control not found!", uiautomation.ConsoleColor.Red)

360

361

# Try to find similar controls for debugging

362

logger.WriteLine("Looking for similar controls...")

363

root = uiautomation.GetRootControl()

364

uiautomation.EnumAndLogControl(root, depth=5, showAllControls=True)

365

return None

366

367

# Debug a control search

368

found_button = debug_control_search(

369

uiautomation.ButtonControl,

370

Name='Submit',

371

ClassName='Button'

372

)

373

```

374

375

### Application Structure Analysis

376

377

```python

378

def analyze_application_structure(app_name):

379

"""Analyze and log the structure of an application."""

380

logger = uiautomation.Logger()

381

logger.SetLogFile(f"{app_name}_structure.log")

382

383

# Find application window

384

app_window = uiautomation.WindowControl(Name=app_name)

385

if not app_window.Exists():

386

logger.ColorfulWriteLine(f"Application '{app_name}' not found", uiautomation.ConsoleColor.Red)

387

return

388

389

logger.ColorfulWriteLine(f"Analyzing structure of '{app_name}'", uiautomation.ConsoleColor.Cyan)

390

391

# Log basic window information

392

logger.WriteLine(f"Window Handle: {app_window.Handle}")

393

logger.WriteLine(f"Process ID: {app_window.ProcessId}")

394

logger.WriteLine(f"Class Name: {app_window.ClassName}")

395

logger.WriteLine(f"Bounds: {app_window.BoundingRectangle}")

396

397

# Enumerate all controls

398

logger.WriteLine("\n=== COMPLETE CONTROL HIERARCHY ===")

399

uiautomation.EnumAndLogControl(app_window, depth=-1)

400

401

logger.Close()

402

logger.WriteLine(f"Structure analysis saved to {app_name}_structure.log")

403

404

# Analyze Calculator application

405

analyze_application_structure("Calculator")

406

```

407

408

### Hotkey Debugging Support

409

410

```python

411

def setup_debug_hotkey():

412

"""Set up hotkey for interactive debugging."""

413

def debug_current_control():

414

logger = uiautomation.Logger()

415

logger.ColorfulWriteLine("=== DEBUG HOTKEY PRESSED ===", uiautomation.ConsoleColor.Magenta)

416

417

# Get control under cursor

418

cursor_control = uiautomation.ControlFromCursor()

419

if cursor_control:

420

logger.WriteLine("Control under cursor:")

421

uiautomation.LogControl(cursor_control)

422

423

logger.WriteLine("\nControl ancestors:")

424

uiautomation.EnumAndLogControlAncestors(cursor_control)

425

else:

426

logger.ColorfulWriteLine("No control found under cursor", uiautomation.ConsoleColor.Red)

427

428

# Set up Ctrl+F12 as debug hotkey

429

uiautomation.RunWithHotKey(debug_current_control, 'ctrl+f12')

430

print("Debug hotkey (Ctrl+F12) is active. Press it while hovering over controls to debug.")

431

432

# Activate debug hotkey

433

setup_debug_hotkey()

434

```

435

436

### Log Analysis Utilities

437

438

```python

439

def parse_automation_log(log_file):

440

"""Parse and analyze automation log files."""

441

logger = uiautomation.Logger()

442

443

try:

444

with open(log_file, 'r') as f:

445

lines = f.readlines()

446

447

logger.ColorfulWriteLine(f"Analyzing log file: {log_file}", uiautomation.ConsoleColor.Cyan)

448

logger.WriteLine(f"Total lines: {len(lines)}")

449

450

# Count different types of entries

451

error_count = sum(1 for line in lines if 'error' in line.lower())

452

warning_count = sum(1 for line in lines if 'warning' in line.lower())

453

454

logger.WriteLine(f"Errors found: {error_count}")

455

logger.WriteLine(f"Warnings found: {warning_count}")

456

457

# Show errors and warnings

458

if error_count > 0:

459

logger.ColorfulWriteLine("\nErrors:", uiautomation.ConsoleColor.Red)

460

for line in lines:

461

if 'error' in line.lower():

462

logger.ColorfulWriteLine(f" {line.strip()}", uiautomation.ConsoleColor.Red)

463

464

if warning_count > 0:

465

logger.ColorfulWriteLine("\nWarnings:", uiautomation.ConsoleColor.Yellow)

466

for line in lines:

467

if 'warning' in line.lower():

468

logger.ColorfulWriteLine(f" {line.strip()}", uiautomation.ConsoleColor.Yellow)

469

470

except FileNotFoundError:

471

logger.ColorfulWriteLine(f"Log file not found: {log_file}", uiautomation.ConsoleColor.Red)

472

473

# Analyze a log file

474

parse_automation_log("automation_log.txt")

475

```