Troubleshooting
Solutions to common problems in Windows UI automation.
Application Launch Issues
TimeoutException: "Could not get main window"
Symptoms:
System.TimeoutException: Could not get main window after 15000ms (PID: 38092)
Cause: The framework cannot find the application window.
For UWP Apps (Windows Store Apps)
✅ Solution 1: Increase timeout to 15-20 seconds
{
"AppPath": "YourUwpApp.exe",
"DefaultTimeout": 20000 // 20 seconds
}
✅ Solution 2: Check logs to see which search mode was used
# Search in logs/test-*.log
[00:05.000] ⚠️ Switching to relaxed search mode (by window title)
[00:05.500] ✓ Window found: 'MyUwpApp' (PID: 38124, Mode: Relaxed)
If you see Mode: Relaxed, it means the window is in a child process (normal for UWP).
✅ Solution 3: Verify app doesn't require admin permissions
# Run as normal user (NOT as admin)
dotnet test
For Classic Win32 Apps (Notepad, Paint, legacy apps)
✅ Solution: Timeout of 5-10 seconds is sufficient
{
"AppPath": "notepad.exe",
"DefaultTimeout": 5000 // 5 seconds
}
If it fails, verify the app isn't blocked or requires manual interaction.
Cursor/VS Code Closes When Running Tests
Symptom: When running dotnet test, the IDE closes unexpectedly.
Cause: Old framework version that searched for windows without filtering by PID.
✅ Solution: Update to latest version which includes:
- Strict search by ProcessId in first 5 seconds
- Exclusion list for IDEs (Cursor, VS Code, Visual Studio)
Verify you have the latest version:
// In AppLauncher.cs should have:
var excludedTitles = new[] {
"Barra de tareas", "Taskbar", "Program Manager",
"Cursor", "Visual Studio", "Visual Studio Code"
};
Element Issues
Element Not Found / TimeoutException
Symptoms:
FlaUI.Core.Exceptions.ElementNotAvailableException:
Element with AutomationId 'ButtonId' not found
Causes and Solutions:
1. Incorrect AutomationId
✅ Solution: Use Inspect.exe to verify
# Location (Windows SDK)
C:\Program Files (x86)\Windows Kits\10\bin\<version>\x64\inspect.exe
Steps:
- Open Inspect.exe
- Open your application
- Hover over the element
- Verify "AutomationId" property in right panel
- Copy exact value (case-sensitive)
2. Element Not Ready
✅ Solution: Increase timeout or add specific wait with adaptive polling
// Wait for element to exist with MSAA (recommended: adaptive polling)
WaitHelper.WaitUntilAdaptive(
() => ElementExistsByPath("Parent", "Button"),
timeoutMs: 10000,
conditionDescription: "button exists");
// Or wait for specific condition with adaptive polling
WaitHelper.WaitUntilAdaptive(
() => {
var element = FindElementByPath("Parent", "Button");
return element != null;
},
timeoutMs: 5000,
conditionDescription: "button available");
Note: WaitUntilAdaptive() uses adaptive polling (starts fast, increases gradually) and automatically records response times for adaptive timeouts. This is more efficient than fixed polling.
3. Element in Popup/Modal
✅ Solution: Wait for popup to appear first, then interact with MSAA (using handle from FlaUI)
// Wait for popup window using FlaUI (for window management)
var automation = AppLauncher.Instance.Automation;
var allWindows = automation.GetDesktop().FindAllChildren();
var popup = allWindows.FirstOrDefault(w => w.Name == "Settings");
if (popup != null)
{
var popupHandle = popup.Properties.NativeWindowHandle.Value;
// Get native handle from FlaUI window, then interact with MSAA
var popupHandle = popup.Properties.NativeWindowHandle.Value;
var okButton = MsaaHelper.FindByNamePath(popupHandle, "OkButton");
okButton?.Click();
}
4. Application Uses Non-Standard UI Framework
✅ Solution: Switch to UIA2 (if UIA3 doesn't work)
// Instead of UIA3Automation
var automation = new UIA2Automation();
Flaky Tests (Intermittent)
Symptoms: Tests pass sometimes but fail other times.
Common Causes:
1. Insufficient Waits
❌ Problem:
button.Click();
Thread.Sleep(500); // Hardcoded sleep
var result = GetResult();
✅ Solution:
ClickElement("Parent", "Button");
WaitHelper.WaitUntilAdaptive(
() => ElementExistsByPath("Parent", "ResultLabel"),
timeoutMs: 5000,
conditionDescription: "result label appears");
var result = GetResult();
2. Race Conditions
❌ Problem:
EnterText("user");
EnterPassword("pass");
ClickLogin(); // Click before text is fully entered
✅ Solution:
SetElementText("user", "Parent", "Username");
SetElementText("pass", "Parent", "Password");
WaitHelper.WaitUntilAdaptive(
() => ElementExistsByPath("Parent", "LoginButton"),
timeoutMs: 5000,
conditionDescription: "login button available");
ClickElement("Parent", "LoginButton");
3. Residual State from Previous Test
❌ Problem: Test depends on state left by previous test.
✅ Solution:
[BeforeScenario]
public void BeforeScenario()
{
// TestHooks already launched a clean app session
// Navigate to known initial state
ResetToDefaultState();
}
4. Animation Timing
✅ Solution: Wait for animation to finish using adaptive polling
// Wait for element to be visible AND settled using adaptive polling
WaitHelper.WaitUntilAdaptive(
() => {
var element = FindElementByPath("Parent", "AnimatedElement");
return element != null && ElementExistsByPath("Parent", "AnimatedElement");
},
timeoutMs: 5000,
conditionDescription: "element visible and rendered");
Note: The framework no longer uses Thread.Sleep(). All waits use explicit conditions with adaptive polling for better performance and reliability.
Permission Issues
Application Requires Admin Permissions
Symptoms:
- App doesn't launch
- "Access denied"
- UAC prompt appears but tests can't interact
✅ Solutions:
Option 1: Run Test Runner as Admin
# Open terminal as Admin
dotnet test
In IDE:
- Visual Studio: Run VS as Admin
- Rider: Run Rider as Admin
Option 2: Disable UAC for the App
Create manifest for the app specifying required level:
<!-- app.manifest -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
Option 3: Modify UAC Settings (NOT recommended for production)
Only for local testing environment:
- Win + R →
UserAccountControlSettings - Lower slider to "Never notify"
- Restart
Session Issues
Tests Fail in CI (Session Lock)
Symptoms:
- Tests pass locally
- Fail in CI with timeout
- Error: "Window not available"
✅ Solution: See CI/CD Guide - "Interactive Session" section
Summary:
- Use self-hosted runner
- Configure auto-login
- Run runner in interactive session (not as service)
Lock Screen Interrupts Tests
✅ Solution: Disable lock screen
# PowerShell as Admin
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" `
-Name "InactivityTimeoutSecs" -Value 0 -PropertyType DWORD -Force
# Disable screensaver
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name ScreenSaveActive -Value 0
Resolution/DPI Issues
Tests Fail with Different Resolution
Symptoms:
- Click on incorrect coordinates
- Screenshots show cut-off elements
- BoundingRectangle doesn't match
✅ Solution 1: Don't use coordinates, use AutomationIds
❌ Don't do this:
Mouse.Click(new Point(100, 200)); // Absolute coordinates
✅ Do this:
ClickElement("Parent", "ButtonId"); // Click using MSAA (via FlaUI window handle)
✅ Solution 2: Configure fixed resolution in CI
# PowerShell on runner
Set-DisplayResolution -Width 1920 -Height 1080 -Force
✅ Solution 3: DPI Awareness
If your app is DPI-aware, ensure tests are too:
<!-- app.manifest -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
FlaUI and MSAA Issues
Note: The framework uses FlaUI (UIA3) for window management (launching applications, managing windows) and MSAA (Microsoft Active Accessibility) accessed through FlaUI window handles for UI element interactions. Most interaction issues are related to MSAA, while window management issues are related to FlaUI.
UIA3 vs UIA2 (Window Management)
When to use UIA2 instead of UIA3 for window management?
Use UIA2 if:
- ❌ Legacy app (Win32, old WinForms) that FlaUI UIA3 cannot detect
- ❌ UIA3 doesn't find the application window
- ❌ App uses custom windowing that UIA3 doesn't support
Note: Changing UIA3 to UIA2 only affects window management (launching and finding windows). MSAA interactions remain the same regardless of UIA version, as MSAA uses native window handles provided by FlaUI.
// Change in AppLauncher.cs
// From:
_automation = new UIA3Automation();
// To:
_automation = new UIA2Automation();
Important Differences (Window Management Only)
| Aspect | UIA3 | UIA2 |
|---|---|---|
| Performance | ✅ Faster | ❌ Slower |
| Compatibility | ✅ Modern apps | ✅ Legacy apps |
| Maintenance | ✅ Active | ⚠️ Legacy |
| Features | ✅ More complete | ❌ Limited |
Performance Issues
Tests Very Slow
Causes:
1. Timeouts Too Long
✅ Solution: Adjust timeouts appropriately
// appsettings.json
{
"DefaultTimeout": 3000 // Reduce from 5000 to 3000 if app is fast
}
2. Unnecessary Waits
❌ Problem:
Thread.Sleep(5000); // Always waits 5 seconds
✅ Solution:
WaitHelper.WaitUntilAdaptive(
() => ElementExistsByPath("Parent", "ButtonId"),
timeoutMs: 5000,
conditionDescription: "button found");
// Returns immediately when element is found (uses adaptive polling)
Additional optimization: Enable adaptive timeouts in appsettings.json:
{
"Timeouts": {
"Adaptive": true,
"InitialTimeout": 5000,
"MinTimeout": 2000,
"MaxTimeout": 30000
}
}
This automatically adjusts timeouts based on actual app performance, making tests faster when the app is fast and more robust when it's slow.
3. App Launches Slowly
✅ Solution: Increase launch timeout
{
"DefaultTimeout": 10000
}
var window = launcher.LaunchApp(appPath, timeoutMs: 15000);
4. Excessive Logging
✅ Solution: Reduce log level
{
"Serilog": {
"MinimumLevel": "Information" // Change from Debug to Information
}
}
Reporting Issues
ExtentReports Not Generated
Symptoms:
- Report file doesn't exist
- Report is empty
✅ Solutions:
1. Verify reports directory exists
ls src/Hipos.Tests/bin/Debug/net8.0-windows/reports/
# Should have: extent-report.html, cucumber.json
If empty:
- Verify ExtentReports is initialized in
TestHooks - Verify tests ran completely
- Check for exceptions during
AfterTestRun/OneTimeTearDown
2. Verify report is flushed
Check that ExtentReportManager.Flush() is called in:
TestHooks.AfterTestRun(for SpecFlow)TestHooks.AfterTestRun
Screenshots Not Appearing in Report
✅ Solution:
Verify screenshots were saved:
ls src/Hipos.Tests/bin/Debug/net8.0-windows/reports/screenshots/
If empty:
- Test didn't fail (screenshots only on failures)
- Verify write permissions
- Verify
TestHooks.AfterScenarioexecutes
Cucumber JSON Not Generated
✅ Solution:
Verify CucumberJsonReportGenerator is initialized and flushed:
// In TestHooks.cs
[BeforeTestRun]
public static void BeforeTestRun()
{
// ...
var cucumberJsonPath = ConfigManager.Instance.GetValue("Reporting:CucumberJsonPath", "reports/cucumber.json");
CucumberJsonReportGenerator.Initialize(cucumberJsonPath, includeScreenshots: true);
}
[AfterTestRun]
public static void AfterTestRun()
{
// ...
CucumberJsonReportGenerator.GenerateReport();
}
Configuration Issues
appsettings.json Not Read
Symptoms:
AppPathis null or empty- Configuration uses defaults
✅ Solutions:
1. Verify file exists in output
ls src/Hipos.Tests/bin/Debug/net8.0-windows/appsettings.json
If it doesn't exist, verify .csproj:
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
2. Verify valid JSON format
Use online JSON validator or:
# PowerShell
Get-Content appsettings.json | ConvertFrom-Json
Environment Variables Don't Override
# Verify correct syntax
# Windows CMD
set AppPath=C:\path\to\app.exe
echo %AppPath%
# PowerShell
$env:AppPath = "C:\path\to\app.exe"
$env:AppPath
# Bash (Git Bash on Windows)
export AppPath="C:/path/to/app.exe"
echo $AppPath
FAQ / Limitations
Why are my tests flaky?
Answer: 99% of the time it's due to insufficient or incorrect waits.
- ❌ Don't use hardcoded
Thread.Sleep()(the framework no longer uses it) - ✅ Use
WaitHelper.WaitUntilAdaptive()with MSAA conditions (recommended) - ✅ Use
WaitHelper.WaitUntil()with fixed polling if needed - ✅ Wait for specific conditions, not arbitrary times
- ✅ Enable adaptive timeouts for automatic timeout adjustment
Can I run tests in parallel?
Answer: NOT recommended for UI tests.
Reasons:
- Only one app can have focus at a time
- Elements in background windows may not be accessible
- Race conditions between tests
If you want to parallelize:
- Use multiple runners/physical VMs (not on same machine)
- Or run each test in isolated VM/container
Does it work with Remote Desktop applications?
Answer: NOT directly.
UI Automation needs direct access to Windows session. RDP creates a separate session.
Alternatives:
- Run tests ON the remote server (self-hosted runner)
- Use virtualization technologies (Hyper-V, VMware) instead of RDP
Can I test 32-bit apps from 64-bit tests?
Answer: YES, FlaUI handles both architectures for window management. MSAA (accessed through FlaUI handles) also works with both 32-bit and 64-bit applications.
Ensure build configuration is correct:
<PropertyGroup>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
Does it work with Electron/Chromium applications?
Answer: PARTIALLY.
- Standard elements (buttons, textboxes) work
- Custom controls may not be accessible
- Consider Selenium/Playwright for web-based apps
Debug Tools
Inspect.exe (Windows SDK)
- View UI structure
- Identify AutomationIds
- Verify element properties
FlaUI Inspect
# Install
dotnet tool install -g FlaUI.Inspect
# Run
flaui-inspect
Note: FlaUI Inspect is useful for inspecting window structure and properties. For MSAA element inspection, you may also need tools like Inspect.exe (Windows SDK) or AccExplorer to view the MSAA accessibility tree.
Spy++ (Visual Studio)
- Analyze window hierarchy
- View Windows messages
- Debug events
Getting Help
If your problem isn't listed:
- Review logs:
src/Hipos.Tests/bin/Debug/net8.0-windows/logs/ - Manual screenshot capture: During debug, see what's happening
- Use Inspect.exe: Verify elements are accessible
- Simplify: Create minimal test that reproduces the problem
- Search GitHub Issues:
- FlaUI Issues - For window management problems
- MSAA issues are typically related to element accessibility - verify elements support MSAA using Inspect.exe
Next Steps
- Contributing - Contribute to the project
- Framework Guide - Back to guides