--- name: flaui-cookbook description: FlaUI and UI Automation recipes for the recordingtest project — waiting strategies, element finding patterns, pattern invocation, and integration with element-aware recording. Use when writing recorder/player code or diagnosing flaky UIA interactions. --- # FlaUI cookbook ## Dependencies - `FlaUI.Core`, `FlaUI.UIA3` (prefer UIA3 over UIA2) - Target: `net8.0-windows` or higher ## Launching the SUT ```csharp var app = FlaUI.Core.Application.Launch("EG-BIM Modeler/EG-BIM Modeler.exe"); using var automation = new UIA3Automation(); var main = app.GetMainWindow(automation, TimeSpan.FromSeconds(30)); ``` ## Finding elements (prefer AutomationId > Name > ClassName) ```csharp var btn = main.FindFirstDescendant(cf => cf.ByAutomationId("BoxCommand")).AsButton(); ``` ## Waiting — NEVER use fixed sleep ```csharp Retry.WhileNull( () => main.FindFirstDescendant(cf => cf.ByName("Ready")), timeout: TimeSpan.FromSeconds(10), interval: TimeSpan.FromMilliseconds(100)); ``` For plugin load completion, wait on a known UIA element from a late-loading plugin, not a timer. ## Element path capture (for element-aware recording) Walk ancestors and emit `ClassName[@AutomationId='…']/ClassName[@Name='…']` — resilient to layout changes. ## 3D viewport fallback SharpDX D3D11 surface is a UIA dead zone. Record: 1. The hosting element's UIA path 2. A normalized offset `(dx/width, dy/height)` inside that element 3. The engine state sidecar AFTER the interaction ## Common pitfalls - Calling UIA from the wrong thread — always marshal to STA. - Stale cached elements after modal dialogs — re-find after focus change. - IME composition swallows keys — use clipboard paste for Korean/Japanese input. - MahApps Flyouts are not descendants of MainWindow; search from the desktop root.