Skip to content

Add Windows MAUI integration tests with Appium screenshot verification#3969

Open
mattleibow wants to merge 7 commits into
mainfrom
mattleibow/release-testing-windows
Open

Add Windows MAUI integration tests with Appium screenshot verification#3969
mattleibow wants to merge 7 commits into
mainfrom
mattleibow/release-testing-windows

Conversation

@mattleibow

Copy link
Copy Markdown
Contributor

Summary

Adds Windows MAUI integration tests using Appium + WinAppDriver for screenshot-based verification of SKCanvasView and SKGLView rendering.

Changes

New: Windows MAUI Tests (MauiWindowsTests)

  • Builds and launches a MAUI WinUI app via WinAppDriver
  • Captures screenshots and crops the canvas region
  • Compares against a platform-specific reference image (reference-test-image-windows.png)
  • Uses the commandBar AppBar as a geometric anchor to calculate canvas bounds (WinUI MAUI doesn't expose page content in the UIA tree — the entire content area is a single opaque Custom element)

Fixed: Test Infrastructure

  • XAML template: Moved AutomationId from canvas element to outer Grid wrapper (canvas elements like SwapChainPanel have no UIA automation peers on Windows)
  • MauiTestBase.cs: Removed unnecessary virtual methods (FindCanvasElement, PrepareWindowAsync, GetFullScreenshot) — simplified the test base
  • Linux Docker tests: Updated to .NET 10 SDK image; fixed stdout/stderr deadlock in RunAdbCommand
  • Android adb path: Fixed to use adb.exe extension on Windows
  • Process launching: Use shell prefix pattern (cmd.exe /C on Windows, /bin/bash -c on Unix) for cross-platform process execution

Test Results (verified on this machine)

Test Similarity Status
Windows SKGLView 99.3%
Windows SKCanvasView 100.0%
Android API 26 (both views) 98.3%
Android API 36 (both views) 98.3%

Technical Notes

Why geometric calculation instead of element lookup on Windows?
WinUI MAUI renders all page content as a single opaque Custom element with no children in the UIA accessibility tree. Only MAUI Shell navigation elements (like commandBar) are accessible. The canvas position is calculated geometrically: commandBar.Y + commandBar.Height gives the content top, then the canvas is centered within the remaining space.

mattleibow and others added 7 commits April 28, 2026 17:41
- Add MauiWindowsTests.cs with SKCanvasView and SKGLView test cases
- Add Appium-based screenshot capture with geometric canvas fallback
  (WinUI raw surfaces lack UIA peers, so commandBar y=40+h=60 used as anchor)
- Add AppiumFixture.cs with shell-wrapper for launching Appium on Windows
- Add PlatformTestBase verbose logging and xunit.runner.json with diagnostics
- Add reference-test-image-windows.png from real GPU-rendered app output
- MauiTestBase: virtual hooks PrepareWindowAsync/GetFullScreenshot/GetCanvasBounds
- All tests pass: SKCanvasView 100%, SKGLView 99.3%

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eadlock

- Update Dockerfile base image from dotnet/sdk:8.0 to dotnet/sdk:10.0
  to match the net10.0 target framework of the test projects
- Fix deadlock in PlatformTestBase.Run() where stdout and stderr were
  read sequentially — if the process fills the stderr buffer while we're
  waiting for stdout to close, the process blocks and both sides hang
  Fix: read both streams concurrently with Task.WhenAll, then apply the
  timeout via Task.WhenAny, and use process.Kill(entireProcessTree: true)
- Increase docker build timeout from 180s to 600s to allow dotnet restore
  to download packages from the EAP feed on first run (takes ~3 min)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove duplicate 'Crop region' log line in MauiTestBase.VerifyWithAppium
  (VerifyCanvasScreenshot already logs it)
- Remove unused 'completed' variable from PlatformTestBase.Run()
- Fix RunAdbCommand in MauiAndroidTests to read stderr concurrently with
  stdout, preventing a potential deadlock when adb writes to stderr
- Remove trailing blank line in MauiWindowsTests.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: AutomationId='SkiaCanvas' was on SKCanvasView/SKGLView, which are
WinUI raw rendering surfaces (SwapChainPanel-based) with NO UIA automation peers.
WinAppDriver could never find the element, so a geometric fallback ran instead.
That fallback centered the canvas below the commandBar height offset, but the
MAUI ContentPage centers its content in the full page - so y was ~34px too low,
clipping the top of the canvas and the 'SkiaSharp Test' text.

Fix: move AutomationId='SkiaCanvas' to the wrapping Grid element, which has a
proper WinUI UIA peer (GridAutomationPeer). The Grid also gets explicit
WidthRequest/HeightRequest so its bounds match the canvas exactly. This one
change makes the same accessibility id lookup work on all platforms:
  - Windows:  UIA GridAutomationPeer  -> WinAppDriver finds it
  - Android:  contentDescription set by MAUI -> UIAutomator2 finds it
  - iOS:      accessibilityIdentifier -> XCUITest finds it

Removed:
  - MauiWindowsTests.GetCanvasBounds override (try/catch + geometric fallback)
  - MauiTestBase.FindCanvasElement virtual (unnecessary indirection)
  - MauiTestBase.PrepareWindowAsync virtual (never overridden)
  - MauiTestBase.GetFullScreenshot virtual (never overridden)
  - MauiAndroidTests.FindCanvasElement override (base works for Grid)
  - reference-test-image-windows.png (captured with wrong crop; falls back to
    base CPU reference which is sufficient for GPU similarity >= 95%)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use commandBar as geometric anchor to calculate canvas position since WinUI
MAUI does not expose page content elements in the UIA tree. The entire page
content below the commandBar is a single opaque Custom element with no
accessible children, so element lookup via AutomationId/accessibility id
is not possible on Windows. The commandBar AppBar is the only MAUI Shell
navigation element reliably present in the UIA tree.

Also add reference-test-image-windows.png captured from the GPU-rendered
Windows app (DirectX/ANGLE) as a platform-specific reference to avoid false
failures from CPU vs GPU text rendering differences (~82% similarity without
platform-specific reference vs 99-100% with it).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bring in latest main (37 commits) including CI fixes, new APIs,
and workflow improvements. No conflicts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

📦 Try the packages from this PR

Warning

Do not run these scripts without first reviewing the code in this PR.

Step 1 — Download the packages

bash / macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.sh | bash -s -- 3969

PowerShell / Windows:

iex "& { $(irm https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.ps1) } 3969"

Step 2 — Add the local NuGet source

dotnet nuget add source ~/.skiasharp/hives/pr-3969/packages --name skiasharp-pr-3969
More options
Option Description
--successful-only / -SuccessfulOnly Only use successful builds
--force / -Force Overwrite previously downloaded packages
--list / -List List available artifacts without downloading
--build-id ID / -BuildId ID Download from a specific build

Or download manually from Azure Pipelines — look for the nuget artifact on the build for this PR.

Remove the source when you're done:

dotnet nuget remove source skiasharp-pr-3969

@github-actions

Copy link
Copy Markdown
Contributor

📖 Documentation Preview

The documentation for this PR has been deployed and is available at:

🔗 View Staging Site
🔗 View Staging Docs
🔗 View Staging Gallery (Blazor)
🔗 View Staging Gallery (Uno Platform)
🔗 View Staging SkiaFiddle

This preview will be updated automatically when you push new commits to this PR.


This comment is automatically updated by the documentation staging workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant