[Windows] Border: Add automation peer and keyboard tap support#27713
[Windows] Border: Add automation peer and keyboard tap support#27713Tamilarasan-Paranthaman wants to merge 9 commits intodotnet:mainfrom
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Copilot reviewed 4 out of 5 changed files in this pull request and generated no comments.
Files not reviewed (1)
- src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt: Language not supported
Comments suppressed due to low confidence (2)
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27627.cs:7
- [nitpick] The class name Issue27627 is not descriptive. Consider renaming it to BorderAutomationPeerTests.
public class Issue27627 : _IssuesUITest
src/Controls/tests/TestCases.HostApp/Issues/Issue27627.cs:19
- The test case does not verify the functionality of the MauiBorderAutomationPeer. It only waits for the element with the AutomationId 'TestBorder'. Add a more comprehensive test to verify the functionality of the automation peer.
App.WaitForElement("TestBorder");
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
mattleibow
left a comment
There was a problem hiding this comment.
Just the typical "we can;t do cool new things in .NET 9".
But, I am super out pf the a11y loop here, so can you just update the PR description with info on what your reasonoing is with the 4 methods in the peer? The Get*Core methods. I see the other 2 peers we have in maui do not have these.
Also, just for confirmation, can you still select elements inside the border via the various a11y nav options - like keyboard and such?
| [Category(UITestCategories.Border)] | ||
| public void VerifyBorderAutomationPeer() | ||
| { | ||
| App.WaitForElement("TestBorder"); |
There was a problem hiding this comment.
Before you set the automation peer, is this not possible? I mean, this test appears to be looking for a element with this ID, so I just want to check if the test would fail without this new peer.
@mattleibow, I have updated the PR description with the relevant details. Regarding accessibility navigation, yes, it still allows navigating to the child elements within the Border. For example, if an Entry is placed inside the Border, pressing the Tab key will move focus to the Entry as expected. |
6402596 to
fd4179b
Compare
PureWeen
left a comment
There was a problem hiding this comment.
The automation peer needs to only activate when a gesture is attached to it.
Similar to how android and ios work where we change the accessibility features.
fd4179b to
ef45d50
Compare
da60565 to
d61c0e9
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
#34575) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds Windows platform support to the `maui-copilot` CI pipeline (AzDO definition 27723), enabling Copilot PR reviews on Windows-targeted PRs. ### Changes **`eng/pipelines/ci-copilot.yml`** - Add `catalyst` and `windows` to Platform parameter values - Add per-platform pool selection (`androidPool`, `iosPool`, `macPool`, `windowsPool`) - Skip Xcode, Android SDK, simulator setup for Windows/Catalyst - Add Windows-specific "Set screen resolution" step (1920x1080) - Add MacCatalyst-specific "Disable Notification Center" step - Fix `sed` command for `Directory.Build.Override.props` on Windows (Git Bash uses GNU sed) - Handle Copilot CLI PATH detection on Windows vs Unix - Change `script:` steps to `bash:` for cross-platform consistency **`.github/scripts/Review-PR.ps1`** - Add `catalyst` to ValidateSet for Platform parameter **`.github/scripts/BuildAndRunHostApp.ps1`** - Add Windows test assembly directory for artifact collection **`.github/scripts/post-ai-summary-comment.ps1` / `post-pr-finalize-comment.ps1`** - Various improvements for cross-platform comment posting ### Validation Successfully ran the pipeline with `Platform=windows` on multiple Windows-specific PRs: - PR #27713 — ✅ Succeeded - PR #34337 — ✅ Succeeded - PR #26217, #27609, #27880, #28617, #29927, #30068 — Triggered and running --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kubaflo Based on the AI summary, I have made the following changes:
It also mentioned that the gate phase is failing due to device tests. I verified this locally—the device tests pass with the fix and fail without it.
|
🚦 Gate - Test Before and After Fix📊 Expand Full Gate —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 BorderTests (ContentPanelIsTabStopReflectsTapGestureRecognizer) Category=Border |
✅ FAIL — 89s | ❌ FAIL — 18s |
🖥️ Issue27627 Issue27627 |
✅ FAIL — 558s | ✅ PASS — 442s |
🔴 Without fix — 📱 BorderTests (ContentPanelIsTabStopReflectsTapGestureRecognizer): FAIL ✅ · 89s
Determining projects to restore...
Restored D:\a\1\s\src\Core\src\Core.csproj (in 1.06 min).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 2.56 sec).
Restored D:\a\1\s\src\Controls\src\Xaml.Design\Controls.Xaml.Design.csproj (in 20 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 180 ms).
Restored D:\a\1\s\src\Controls\src\Core.Design\Controls.Core.Design.csproj (in 13 ms).
Restored D:\a\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj (in 1.11 min).
Restored D:\a\1\s\src\Controls\src\BindingSourceGen\Controls.BindingSourceGen.csproj (in 64 ms).
Restored D:\a\1\s\src\TestUtils\src\DeviceTests\TestUtils.DeviceTests.csproj (in 101 ms).
Restored D:\a\1\s\src\TestUtils\src\DeviceTests.Runners\TestUtils.DeviceTests.Runners.csproj (in 440 ms).
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 996 ms).
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 18 ms).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 42 ms).
Restored D:\a\1\s\src\Core\tests\DeviceTests.Shared\Core.DeviceTests.Shared.csproj (in 41 ms).
Restored D:\a\1\s\src\TestUtils\src\DeviceTests.Runners.SourceGen\TestUtils.DeviceTests.Runners.SourceGen.csproj (in 3.73 sec).
C:\Users\VssAdministrator\.nuget\packages\microsoft.windowsappsdk.base\1.8.250831001\buildTransitive\Microsoft.WindowsAppSDK.SelfContained.targets(75,9): error : WindowsAppSDKSelfContained requires a supported Windows architecture. [D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Build FAILED.
C:\Users\VssAdministrator\.nuget\packages\microsoft.windowsappsdk.base\1.8.250831001\buildTransitive\Microsoft.WindowsAppSDK.SelfContained.targets(75,9): error : WindowsAppSDKSelfContained requires a supported Windows architecture. [D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj::TargetFramework=net10.0-windows10.0.19041.0]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:07.51
🟢 With fix — 📱 BorderTests (ContentPanelIsTabStopReflectsTapGestureRecognizer): FAIL ❌ · 18s
Determining projects to restore...
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 591 ms).
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 611 ms).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 267 ms).
Restored D:\a\1\s\src\Core\src\Core.csproj (in 546 ms).
Restored D:\a\1\s\src\Controls\src\Xaml.Design\Controls.Xaml.Design.csproj (in 27 ms).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 350 ms).
Restored D:\a\1\s\src\Controls\src\Core.Design\Controls.Core.Design.csproj (in 16 ms).
Restored D:\a\1\s\src\Controls\src\BindingSourceGen\Controls.BindingSourceGen.csproj (in 59 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 227 ms).
5 of 14 projects are up-to-date for restore.
C:\Users\VssAdministrator\.nuget\packages\microsoft.windowsappsdk.base\1.8.250831001\buildTransitive\Microsoft.WindowsAppSDK.SelfContained.targets(75,9): error : WindowsAppSDKSelfContained requires a supported Windows architecture. [D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Build FAILED.
C:\Users\VssAdministrator\.nuget\packages\microsoft.windowsappsdk.base\1.8.250831001\buildTransitive\Microsoft.WindowsAppSDK.SelfContained.targets(75,9): error : WindowsAppSDKSelfContained requires a supported Windows architecture. [D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj::TargetFramework=net10.0-windows10.0.19041.0]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:07.59
🔴 Without fix — 🖥️ Issue27627: FAIL ✅ · 558s
Determining projects to restore...
Restored D:\a\1\s\src\Controls\src\Xaml.Design\Controls.Xaml.Design.csproj (in 696 ms).
Restored D:\a\1\s\src\Controls\src\Core.Design\Controls.Core.Design.csproj (in 4 ms).
Restored D:\a\1\s\src\Controls\src\BindingSourceGen\Controls.BindingSourceGen.csproj (in 45 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 934 ms).
Restored D:\a\1\s\src\Controls\Foldable\src\Controls.Foldable.csproj (in 514 ms).
Restored D:\a\1\s\src\Controls\Maps\src\Controls.Maps.csproj (in 1.49 sec).
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 39 ms).
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 9 ms).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 29 ms).
Restored D:\a\1\s\src\Core\src\Core.csproj (in 77 ms).
Restored D:\a\1\s\src\Core\maps\src\Maps.csproj (in 43 ms).
Restored D:\a\1\s\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 2.76 sec).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 57 ms).
Restored D:\a\1\s\src\Controls\tests\TestCases.HostApp\Controls.TestCases.HostApp.csproj (in 2.36 sec).
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:05:53.54
Determining projects to restore...
Restored D:\a\1\s\src\Controls\tests\CustomAttributes\Controls.CustomAttributes.csproj (in 621 ms).
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils\VisualTestUtils.csproj (in 3 ms).
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils.MagickNet\VisualTestUtils.MagickNet.csproj (in 5.71 sec).
Restored D:\a\1\s\src\Controls\tests\TestCases.WinUI.Tests\Controls.TestCases.WinUI.Tests.csproj (in 6.68 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.Core\UITest.Core.csproj (in 2 ms).
Restored D:\a\1\s\src\TestUtils\src\UITest.Appium\UITest.Appium.csproj (in 2 ms).
Restored D:\a\1\s\src\TestUtils\src\UITest.NUnit\UITest.NUnit.csproj (in 1.56 sec).
Retrying 'FindPackagesByIdAsync' for source 'https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/4828dfac-e9f8-49bc-acb6-319be99331fc/nuget/v3/flat2/system.io.pipelines/index.json'.
An error occurred while sending the request.
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
An existing connection was forcibly closed by the remote host.
Restored D:\a\1\s\src\TestUtils\src\UITest.Analyzers\UITest.Analyzers.csproj (in 41.1 sec).
7 of 15 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/5/2026 11:30:29 AM FixtureSetup for Issue27627(Windows)
>>>>> 4/5/2026 11:30:36 AM VerifyBorderAutomationPeer Start
>>>>> 4/5/2026 11:30:52 AM VerifyBorderAutomationPeer Stop
>>>>> 4/5/2026 11:30:52 AM Log types:
Failed VerifyBorderAutomationPeer [16 s]
Error Message:
System.TimeoutException : Timed out waiting for element...
Stack Trace:
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests.Issues.Issue27627.VerifyBorderAutomationPeer() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27627.cs:line 20
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.08] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.36] Discovered: Controls.TestCases.WinUI.Tests
Total tests: 1
Failed: 1
Test Run Failed.
Total time: 43.5322 Seconds
🟢 With fix — 🖥️ Issue27627: PASS ✅ · 442s
Determining projects to restore...
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 727 ms).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 764 ms).
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 17 ms).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 48 ms).
Restored D:\a\1\s\src\Controls\src\Xaml.Design\Controls.Xaml.Design.csproj (in 11 ms).
Restored D:\a\1\s\src\Core\src\Core.csproj (in 111 ms).
Restored D:\a\1\s\src\Controls\src\Core.Design\Controls.Core.Design.csproj (in 3 ms).
Restored D:\a\1\s\src\Controls\src\BindingSourceGen\Controls.BindingSourceGen.csproj (in 23 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 58 ms).
5 of 14 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:05:34.80
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13749525
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/5/2026 11:38:27 AM FixtureSetup for Issue27627(Windows)
>>>>> 4/5/2026 11:38:33 AM VerifyBorderAutomationPeer Start
>>>>> 4/5/2026 11:38:34 AM VerifyBorderAutomationPeer Stop
Passed VerifyBorderAutomationPeer [971 ms]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.09] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.29] Discovered: Controls.TestCases.WinUI.Tests
Test Run Successful.
Total tests: 1
Passed: 1
Total time: 20.0236 Seconds
⚠️ Issues found
- ❌ BorderTests (ContentPanelIsTabStopReflectsTapGestureRecognizer) FAILED with fix (should pass)
📁 Fix files reverted (4 files)
eng/pipelines/ci-copilot.ymlsrc/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cssrc/Core/src/Platform/Windows/ContentPanel.cssrc/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
New files (not reverted):
src/Core/src/Platform/Windows/MauiBorderAutomationPeer.cs
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #27713 | Add MauiBorderAutomationPeer, wire ContentPanel.OnCreateAutomationPeer(), make Border keyboard-focusable when tap gestures present; gate IsControlElementCore/IsContentElementCore on IsInteractiveOrNamed() |
❌ Gate FAILED | ContentPanel.cs, MauiBorderAutomationPeer.cs, GesturePlatformManager.Windows.cs, PublicAPI.Unshipped.txt, 2 test files |
Test may not actually verify the regression |
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Always-expose peer (IsControlElementCore/IsContentElementCore = true); test asserts ClassName == "Panel" |
PASS | 5 files | Selected best fix simplest implementation, strongest test |
| 2 | try-fix (claude-sonnet-4.6) | AutomationId-only gating; test asserts LocalizedControlType == "pane" |
PASS | 5 files | Cleaner gating than PR |
| 3 | try-fix (gpt-5.3-codex) | IInvokeProvider for tappable borders; test asserts IsInvokePatternAvailable |
PASS | 6 files | Richer semantics, more complex |
| 4 | try-fix (gpt-5.4) | Keep PR's IsInteractiveOrNamed() gating; test asserts ControlType = "pane" |
PASS | 1 file (test only) | Minimal change, preserves PR design |
| PR | PR #27713 | MauiBorderAutomationPeer + IsInteractiveOrNamed() + WaitForElement-only test |
Gate FAILED | 6 files | Test too weak passes without fix |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 2 | Yes | Override GetNameCore() to read from SemanticProperties.Description/Hint |
| gpt-5.3-codex | 2 | Yes | Raise UIA property-changed events when IsTabStop/AutomationId changes at runtime |
| gpt-5.4 | 2 | Yes | Gate on SemanticProperties instead of AutomationId alone |
Exhausted: Yes
Selected Fix: Candidate #1 Simplest passing alternative. Removes fragile IsInteractiveOrNamed() conditional, unconditionally exposes all Borders in automation tree, and strengthens test to assert ClassName == "Panel" which is ONLY returned by the custom peer. Root cause of gate failure: default FrameworkElementAutomationPeer already makes elements with AutomationId discoverable, so WaitForElement alone cannot prove the custom peer is active.
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Windows-only Border accessibility PR with 5 implementation files, 2 test files |
| Gate | ❌ FAILED | Test passes without fix — default FrameworkElementAutomationPeer already exposes named elements |
| Try-Fix | ✅ COMPLETE | 4 attempts, all 4 passing; Candidate #1 selected |
| Report | ✅ COMPLETE |
Summary
The PR correctly identifies that Windows Border controls need a custom AutomationPeer for accessibility and keyboard support. The implementation approach is sound, and the keyboard tap activation logic in GesturePlatformManager.Windows.cs is well-designed. However, the gate failed because the UI test (WaitForElement by AutomationId) passes even on the unmodified main branch — the default WinUI FrameworkElementAutomationPeer already exposes named elements to the automation tree. The test therefore cannot distinguish "fixed" from "unfixed" states.
A previous agent review (s/agent-changes-requested) requested that IsControlElementCore/IsContentElementCore be conditional. The PR author implemented IsInteractiveOrNamed() (gates on IsTabStop || AutomationId). While this is more nuanced than always-exposing borders, it introduced the gating logic that made the test ambiguous — and the IsInteractiveOrNamed() AutomationId path relying on AutomationProperties.GetAutomationId() may not be reliable at the time UIA queries the peer.
Root Cause
The UI test VerifyBorderAutomationPeer only calls App.WaitForElement() by AutomationId. This passes without the PR fix because WinUI's default FrameworkElementAutomationPeer (for Panel) keeps elements discoverable when AutomationProperties.AutomationId is set. The test cannot gate on peer presence alone.
Fix Quality
A better fix (Candidate #1 from try-fix) was found:
- Remove
IsInteractiveOrNamed()— makeIsControlElementCore()andIsContentElementCore()always returntrue. Every Border with a custom peer is fully visible in the automation tree. This is simpler, avoids the fragile AutomationId sync issue, and is consistent with the issue's request that borders be universally accessible. - Strengthen the test — assert
GetAttribute<string>("ClassName") == "Panel"(the value onlyMauiBorderAutomationPeer.GetClassNameCore()returns). This test FAILS on unmodified main (the default peer doesn't return "Panel") and PASSES with the fix. - Keep
IsKeyboardFocusableCore()conditional onIsTabStop— interactive borders (with TapGestureRecognizers) should be keyboard focusable; non-interactive borders should not.
The keyboard tap support in GesturePlatformManager.Windows.cs is correct and should be kept as-is.
Specific Changes Needed
-
src/Core/src/Platform/Windows/MauiBorderAutomationPeer.cs- Remove
IsInteractiveOrNamed()method entirely - Change
IsControlElementCore()to returntrueunconditionally - Change
IsContentElementCore()to returntrueunconditionally - Keep
IsKeyboardFocusableCore()gated on(Owner as ContentPanel)?.IsTabStop == true
- Remove
-
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27627.cs- After
App.WaitForElement("TestBorder"), assertGetAttribute<string>("ClassName") == "Panel" - After
App.WaitForElement("NestedBorder"), assert the same - This makes the test fail without the fix and pass with it
- After
-
All other files (
ContentPanel.cs,GesturePlatformManager.Windows.cs,PublicAPI.Unshipped.txt) can remain as-is.




Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description of Change
Implemented AutomationPeer support for the Windows Border control.
Added keyboard accessibility by invoking the TapGestureRecognizer when the Enter or Space key is pressed, if a TapGestureRecognizer is attached to the Border.
The Border can now receive focus (IsTabStop = true) only when a TapGestureRecognizer is added, ensuring it behaves like an interactive element.
Accessibility support is implemented using a custom MauiBorderAutomationPeer, derived from FrameworkElementAutomationPeer.
This peer is introduced to support accessibility for the custom MauiBorder implementation, which is built using a Panel. Since Panel does not provide a default AutomationPeer, we explicitly define one (MauiBorderAutomationPeer).
Screenshots
Note: In the following video:
The first Border (containing the CheckBox) does not have a TapGestureRecognizer, so it does not receive focus during keyboard navigation.
The second Border (containing the Label) initially has a TapGestureRecognizer attached. It receives focus as expected, and the Tapped event is correctly fired when pressing the Space or Enter key.
The TapGestureRecognizer is then removed at runtime using the “Remove TapGestureRecognizer” button and added again using the “Add TapGestureRecognizer” button.
After removing it at runtime, the second Border no longer receives focus. Once it is added back, the focus behavior and keyboard interaction work as expected again.
Screen.Recording.mp4
Overridden Core Methods and their Purpose
1. GetAutomationControlTypeCore()
2. GetClassNameCore()
Panelto reflect the underlying native element.3. IsControlElementCore()
4. IsContentElementCore()
Issues Fixed
Fixes #27627