You’ve written your FlaUI tests. They pass locally. You push to GitHub. The build fails.
Welcome to the world of UI automation in CI/CD.
Running desktop UI tests in a cloud environment like GitHub Actions is notoriously difficult. Unlike unit tests, which just need a CPU and memory, UI tests need a Desktop Session.
In this post, we’ll tackle the challenges of running FlaUI tests on GitHub Actions windows-latest runners and how to make them reliable.
The Environment: What is windows-latest?#
When you spin up a GitHub Action with runs-on: windows-latest, you are getting a Virtual Machine. Crucially, this VM does have a desktop session, but it is “headless” (no physical monitor connected).
The default resolution is typically 1024x768.
If your application requires a 1080p screen to render all buttons, your tests will fail because elements might be scrolled out of view or collapsed into a “hamburger” menu that your test doesn’t expect.
Step 1: The Workflow YAML#
Here is a baseline workflow for running .NET tests.
| |
This might work if your app is simple. But when it fails, you’ll have no idea why.
Step 2: The “Black Box” Problem (Screenshots)#
When a test fails locally, you watch it happen. In CI, you just get a stack trace saying ElementNotFoundException.
To fix this, you must configure your tests to take a screenshot on failure. FlaUI makes this easy, but you need to hook it into your test framework (e.g., NUnit TearDown).
| |
Step 3: Uploading Artifacts#
Now that you’re saving screenshots, you need to tell GitHub Actions to save them so you can download them after the run.
Update your YAML to include an upload-artifact step that runs even if tests fail.
| |
Step 4: Handling Screen Resolution#
If 1024x768 is breaking your app, you have two options:
- Design for Responsiveness: Make your app (and tests) handle small screens. This is the “correct” software engineering answer.
- Change the Resolution: You can try to use tools to change the VM resolution, but on GitHub hosted runners, this is often locked or unreliable.
A better hack is to ensure your Application.Launch code maximizes the window, or sets a specific size that fits within 1024x768.
| |
Step 5: The “Active Session” Myth#
You might read online that you need a “Self-Hosted Runner” with an active RDP session to run UI tests.
For FlaUI (UIA3), this is not strictly true. UIA3 works fine in the non-interactive session provided by GitHub Actions for standard controls.
However, if you use:
Mouse.Move()(Hardware cursor simulation)Keyboard.Type()(Hardware input simulation)
These might fail or behave erratically if the session is locked.
Best Practice: Prefer Pattern methods over Input simulation.
- Don’t use:
btn.Click()(which moves mouse and clicks). - Use:
btn.Invoke()(which uses the UIA InvokePattern).
Invoke() works programmatically and doesn’t care if the mouse cursor is actually working or if the screen is locked.
Summary#
Running FlaUI on GitHub Actions is possible and powerful.
- Use
windows-latest. - Always capture screenshots on failure.
- Upload those screenshots as Artifacts.
- Prefer
Invoke()patterns over physical mouse clicks to avoid session issues.
Now your CI pipeline isn’t just compiling code—it’s proving your app actually works.
Further Reading#
- FlaUI on GitHub - Official FlaUI repository
- GitHub Actions Windows Runners - Documentation for Windows runners
- Upload Artifacts Action - Official action for artifact uploads
- UI Automation Patterns - Understanding invoke patterns
