Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add MSTest.Windows.UIAutomation for desktop UI tests by Evangelink · Pull Request #10862 · microsoft/testfx · GitHub
Skip to content

Add MSTest.Windows.UIAutomation for desktop UI tests - #10862

Open
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing
Open

Add MSTest.Windows.UIAutomation for desktop UI tests#10862
Amaury Levé (Evangelink) wants to merge 23 commits into
mainfrom
dev/amauryleve/mstest-ui-testing

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

Revives and redesigns the unmerged work from #7810 as a narrowly scoped preview integration.

  • add the MSTest.Windows.UIAutomation package for MSTest-managed application lifecycle and UIA2 window access
  • expose it through MSTest.Sdk with <EnableWindowsUIAutomation>true</EnableWindowsUIAutomation> for MTP and VSTest
  • provide abstract ApplicationTest and WindowTest bases with overridable process launch, window discovery, and shutdown hooks
  • support non-Windows cross-targeted builds while preserving explicit EnableWindowsTargeting values
  • add a Character Map sample plus acceptance coverage for both runners, SDK validation, process cleanup, cancellation, custom discovery, launcher-child handoff, and custom shutdown

Scope

This preview targets unpackaged, full-trust Win32, WinForms, and WPF applications running in an interactive Windows session. It does not provide packaged MSIX/UWP/WinUI activation, elevated-process automation, a headless desktop, locators, automatic waits, screenshots, or a multi-window object model.

Validation

  • build.cmd -pack
  • WindowsUIAutomationSdkTests: 26 passed
  • non-Windows solution-filter pack with OS=Unix

Supersedes #7810.

Revive the MSTest.Windows.AppTesting work from PR #7810 on current main, including SDK integration, package metadata, a deterministic sample, and MTP/VSTest acceptance coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI balanced review requested due to automatic review settings August 29, 2026 08:42
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ADemo sample test; checks non-empty title but not a specific expected value.If a known app title is deterministic, assert the exact expected string.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ADemo sample illustrating WindowTest usage; asserts control type only.Could also assert MainWindow.Current.IsEnabled/IsOffscreen for a stronger visibility check.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AFollows established acceptance-test pattern (mirrors PlaywrightSdkTests); asserts exit code and exact pass/fail/skip counts, correctly gated by OSCondition for Windows-only desktop UI automation.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies both VSTest engine banner and exact passed/failed/skipped summary line for the VSTest path.

Note: Mutation analysis reported N/A for all four tests — the acceptance tests spawn out-of-process test hosts against a Windows-only physical UI (Character Map), and the sample tests are documentation demos, so the production entry points (native app automation) could not be resolved/exercised for pseudo-mutation in this review. All four tests are gated correctly ([OSCondition(OperatingSystems.Windows, ...)] on the acceptance tests) and follow the repo's existing SDK-acceptance-test conventions (TestAssetFixture, DynamicData over TargetFrameworks, AssertOutputContainsSummary/AssertOutputContains) closely, matching sibling files like PlaywrightSdkTests.cs. No high-confidence actionable findings warranted an inline suggestion.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 47.6 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary — MSTest.Windows.AppTesting

Clean PR that adds a new MSTest.Windows.AppTesting package with application lifecycle and Windows UI Automation base classes, wired through MSTest.Sdk. Two inline comments posted; neither is blocking.

#DimensionVerdict
1Algorithmic Correctness✅ OK — startup loop handles edge cases (process exit, timeout) correctly
2Threading & Concurrency⚠️ Minor — AutomationTest uses [TestClass] (MTA) while subclasses use [STATestClass]; see inline comment
3Security & IPC✅ N/A
4Public API & Binary Compat✅ OK — all public API in PublicAPI.Unshipped.txt, no init accessors, types unsealed by design (base-class hierarchy), XML docs present
5Performance & Allocations✅ OK — not a hot path
6Cross-TFM Compatibility✅ OK — targets net8.0-windows / net9.0-windows only, validated in .targets
7Resource & IDisposable✅ OK — Process disposed in finally; CloseMainWindowKill cascade is correct
8Defensive Coding✅ OK — boundary checks for process exit, null handle, and timeout present
9Naming & Code Style✅ OK
10Logging & Observability✅ N/A
11Error Messages & UX✅ OK — clear exception messages with variable names
12Tests & Test Quality✅ OK — acceptance tests cover MTP and VSTest, OS-gated
13Documentation✅ OK — PACKAGE.md present, XML docs thorough
14Localization✅ N/A — no user-facing resx strings
15Backward Compatibility✅ N/A — new package
16Build & Pack Integration✅ OK — verify-nupkgs.ps1 updated, MSBuild integration mirrors Aspire/Playwright patterns
17Serialization✅ N/A
18Tracing & Telemetry✅ N/A
19Nullability✅ OK — null! used for lifecycle-initialized properties, consistent with rest of codebase
20TODOs & Leftovers✅ None found
21Scope Discipline✅ Single concern
22Script & Tooling Hygiene✅ OK — PowerShell hash table update is correct

Overall: Looks good. The two inline comments are non-blocking suggestions for future hardening.

Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/AutomationTest.cs Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 2 Medium severity · 2 Low severity

New issues introduced by this change (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because…
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a…
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that…
What changed in this PR

Adds Windows desktop UI automation support to MSTest through a new package, SDK integration, sample, and acceptance coverage.

Changes:

  • Adds application lifecycle and UI Automation base classes.
  • Integrates the package into MSTest.Sdk for MTP and VSTest.
  • Adds Character Map samples, acceptance tests, and package verification.
FileDescription
TestFx.slnxIncludes the new package project.
WindowsAppTestingSdkTests.csTests MTP and VSTest integration.
WindowTest.csExposes the main UI Automation window.
TestFramework.Windows.AppTesting.csprojDefines the Windows package.
PublicAPI.Unshipped.txtTracks new public APIs.
PublicAPI.Shipped.txtInitializes the shipped baseline.
PACKAGE.mdDocuments package usage.
GlobalUsings.csImports MSTest APIs globally.
AutomationTest.csAdds the hierarchy root.
ApplicationTest.csManages application lifecycle.
VSTest.targetsEnables the feature under VSTest.
Sdk.props.templateDefines feature and version properties.
NativeAOT.targetsRejects unsupported NativeAOT usage.
ClassicEngine.targetsEnables the feature under MTP.
WindowsAppTesting.targetsAdds validation, package reference, and using.
MSTest.Sdk.csprojPacks and versions the feature target.
ProjectUsingWindowsAppTesting.csprojAdds the SDK sample configuration.
CharacterMapTests.csDemonstrates desktop UI tests.
verify-nupkgs.ps1Verifies package contents.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Comment threadsrc/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs Outdated
Run the base hierarchy on STA threads, honor cooperative cancellation during app startup, include the package in MSTest.slnf, and make package verification detect missing outputs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed 4 new test methods introduced by this PR across the new TestFramework.Windows.AppTesting sample and its acceptance test. All four are focused, single-behavior tests with meaningful equality/non-empty assertions on the exercised contract (ControlType, window Name, process exit code, and MSTest/VSTest summary counts), correctly awaited async work, and no anti-pattern findings. No high-confidence actionable issues were found, so no inline suggestions were posted.

GradeTestMutationNotesHow to improve
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
0/0 (no meaningful points)Single meaningful equality assertion on ControlType; behavior is thin OS-automation plumbing with no internal branch logic to mutate.
A (90–100)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
0/0 (no meaningful points)Clear non-empty-title assertion with a descriptive failure message.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AEnd-to-end acceptance test asserting exit code and exact pass/fail/skip summary against a generated real project.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/AVerifies exit code and VSTest-specific summary output; async call correctly awaited.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 66.8 AIC · ⌖ 1.12 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 3 Medium severity · 3 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain…
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.…
Pre-existing issues (4)
SeverityFinding
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View comment
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View comment
Suppressed comments (3)

samples/public/DemoMSTestSdk/ProjectUsingWindowsAppTesting/ProjectUsingWindowsAppTesting.csproj:1

  • This public sample is not included in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. eng/build-samples.ps1:60-64 builds discovered solutions rather than standalone projects, so the new sample is currently omitted from sample CI and can silently break. Add the project and its Debug/Release configurations to that solution.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets:11

  • The added acceptance asset always targets *-windows, and no other test exercises this validation message, so removing or breaking this target would leave all current tests green. Add a non-Windows-target build case that enables the feature and asserts this diagnostic.
 <Target Name="_ValidateWindowsAppTestingPlatform" BeforeTargets="Restore;Build"
Condition=" '$(TargetFramework)' != '' and '$(_IsWindowsTfm)' != 'true' ">
<Error Text="MSTest.Windows.AppTesting requires a Windows target framework (e.g. net8.0-windows). Current TargetFramework: '$(TargetFramework)'." />

src/TestFramework/TestFramework.Windows.AppTesting/ApplicationTest.cs:124

  • The Character Map acceptance path closes normally and does not assert that cleanup terminated the process, so this forced-kill branch is untested; a regression here can leave desktop processes running after the suite. Add a test application that ignores CloseMainWindow and verify that cleanup terminates its process tree.
 _ = appProcess.CloseMainWindow();
if (!appProcess.WaitForExit(5000))
{
appProcess.Kill(entireProcessTree: true);
_ = appProcess.WaitForExit(5000);

Comment threadsrc/Package/MSTest.Sdk/Sdk/Sdk.props.template Outdated
Cover invalid target frameworks, early process exit, startup timeout, and forced cleanup while correcting the standalone sample package version.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 10:45
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers…
Pre-existing issues (2)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View comment
Issues resolved since last review (4)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.AppTesting/​ApplicationTest.cs — The acceptance tests exercise only a responsive Character Map process. Add coverage for an app that… View resolved comment
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — No test exercises this validation path: every generated acceptance TFM appends -windows. Add a… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — The non-SDK example cannot restore as written: MSTestWindowsAppTestingVersion is only defined by… View resolved comment
Medium severitysamples/​public/​DemoMSTestSdk/​ProjectUsingWindowsAppTesting/​ProjectUsingWindowsAppTesting.csproj — This project is not listed in samples/public/DemoMSTestSdk/DemoMSTestSdk.sln. Because… View resolved comment
Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.AppTesting/PACKAGE.md:12

  • This standalone getting-started snippet does not pin MSTest.Sdk, and the README does not provide a global.json pin, so users copying it from the NuGet package page cannot resolve the project SDK. Include an SDK version here, consistent with src/Package/MSTest.Sdk/PACKAGE.md:9-16.
<Project Sdk="MSTest.Sdk">

src/Package/MSTest.Sdk/Sdk/Sdk.props.template:45

  • The repository's complete MSTest.Sdk property reference in docs/glossary.md:312-343 still lists only Aspire and Playwright and omits both new controls. Add an EnableWindowsAppTesting compatibility row (including its NativeAOT error and VSTest support) and document MSTestWindowsAppTestingVersion, otherwise the advertised complete reference is stale as soon as this feature ships.
 <EnableWindowsAppTesting Condition=" '$(EnableWindowsAppTesting)' == '' ">false</EnableWindowsAppTesting>
<EnablePlaywright Condition=" '$(EnablePlaywright)' == '' ">false</EnablePlaywright>
<AspireHostingTestingVersion Condition=" '$(AspireHostingTestingVersion)' == '' ">${AspireHostingTestingVersion}</AspireHostingTestingVersion>
<MicrosoftNETTestSdkVersion Condition=" '$(MicrosoftNETTestSdkVersion)' == '' ">${MicrosoftNETTestSdkVersion}</MicrosoftNETTestSdkVersion>
<MSTestWindowsAppTestingVersion Condition=" '$(MSTestWindowsAppTestingVersion)' == '' ">${MSTestWindowsAppTestingVersion}</MSTestWindowsAppTestingVersion>

Comment threadsrc/Package/MSTest.Sdk/Sdk/Features/WindowsAppTesting.targets Outdated
Apply desktop runtime roll-forward consistently to the VSTest acceptance leg and document the feature and version override properties.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

The pre-step's extract data (test-file/line-range TSV) was unavailable in this run, so this review was derived directly from the PR's file diffs. Two new test files were added: a sample demo (CharacterMapTests.cs) and an acceptance-test suite (WindowsAppTestingSdkTests.cs) for the new EnableWindowsAppTesting MSTest.Sdk feature.

GradeTestMutationNotesHow to improve
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
N/ASample/demo asset; single ControlType assertion, adequate for illustrating the API.
B (80–89)new CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
N/ASample/demo asset; only checks the title is non-empty, not a specific expected value.
B (80–89)new WindowsAppTestingSdkTests.
ApplicationTearDown_
WhenApplicationNeverCreatesWindow_
TerminatesProcess
N/ASolid scenario, but the hardcoded 1s `WaitForExit` and silent `catch (ArgumentException)` could mask a slow-terminate flake under CI load.Add an explicit fail message covering the not-yet-exited case and consider a longer/backoff wait.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingMSTestRunner_
RunsDesktopTests
N/AExercises the real MSTest runner path end-to-end and asserts exit code plus exact pass/fail/skip summary.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenUsingVSTest_
RunsDesktopTests
N/ACovers the VSTest bridge path with deterministic exit-code and output assertions.
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
N/AVerifies the build-time guard with the exact expected error message.
A (90–100)new WindowsAppTestingSdkTests.
ApplicationSetup_
WhenApplicationExitsBeforeCreatingWindow_
ReportsClearFailure
N/AAsserts the specific failure exit code and diagnostic message for the early-exit scenario.

Note on mutation column: production code for the new TestFramework.Windows.AppTesting classes (WindowTest, ApplicationTest, AutomationTest) is Windows-only and process/UI-Automation driven, so meaningful pseudo-mutation execution could not be resolved in this sandbox; marked N/A throughout rather than guessed.

No inline suggestions were posted — findings above are minor reliability/coverage notes rather than concrete, safely-anchorable mechanical fixes.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 54.2 AIC · ⌖ 1 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity

Pre-existing issues (1)
SeverityFinding
High severitysrc/​Package/​MSTest.Sdk/​Sdk/​Features/​WindowsAppTesting.targets — This check is case-sensitive, although the SDK accepts target framework monikers… View comment
Issues resolved since last review (2)
SeverityFinding
Low severitysrc/​Package/​MSTest.Sdk/​Sdk/​Sdk.props.template — These new user-facing SDK properties are missing from the SDK documentation tables.… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsAppTestingSdkTests.cs — This VSTest leg omits the roll-forward setting used by the MTP leg above. The repo-local toolchain… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsAppTestingSdkTests.cs:150

  • The generated asset imports Microsoft.MSTest.Windows.AppTesting explicitly, so these acceptance tests do not exercise the implicit Using added by WindowsAppTesting.targets. Since the public sample relies on that implicit import and is intentionally excluded from sample CI, removing this using is needed to make a regression in the SDK feature fail automated coverage.
using Microsoft.MSTest.Windows.AppTesting;

@github-actions

This comment has been minimized.

Use MSBuild's target-platform parser, cover uppercase target framework monikers, and pin the package README SDK example.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 29, 2026 11:31
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
A (90–100)new WindowsAppTestingSdkTests.
EnableWindowsAppTesting_
WhenTargetFrameworkUsesUppercase_
IsAccepted
1/1 killedDirectly exercises the case-insensitive TargetPlatformIdentifier fix; reverting it fails the build.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 48.8 AIC · ⌖ 0.905 AIC · ⊞ 16.9K · [◷]( · )

@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 High severity · 2 Medium severity

New issues introduced by this change (3)
SeverityFinding
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts…
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplication
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing…
Issues resolved since last review (1)
SeverityFinding
Low severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​PACKAGE.md — The getting-started example does not compile when copied into the shown SDK project because… View resolved comment

Comment threadsrc/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs Outdated
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

GradeTestMutationNotesHow to improve
C (70–79)new CharacterMapTests.
CharacterMap_
MainWindow_
HasExpectedTitle
1/2 killedOnly checks title is non-empty; a wrong/garbled window title still passes.Assert the title contains the expected app name, e.g. "Character Map".
C (70–79)new sample CharacterMapTests.
CharacterMap_
MainWindow_
HasTitle
1/2 killedOnly checks title is non-empty; a wrong window title still passes (same gap as the acceptance-test twin).Assert the title contains "Character Map" or a similar expected substring.
B (80–89)CharacterMapTests.
CharacterMap_
MainWindow_
IsVisible
(both copies)
2/2 killedClear, focused assertion on ControlType protects the primary discovery contract.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/4 killedValidates exit code and PID file end-to-end; relies on shared fixture/env var protocol without asserting it explicitly.Assert stdout mentions the passed test names to catch silent early exits.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
3/4 killedMirrors the MSTest-runner test for VSTest path; same shallow output verification.Assert the VSTest trx/output confirms the expected test count ran.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
3/3 killedAsserts non-zero exit and a specific, clear error message for the misconfiguration case.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedCovers a real case-sensitivity boundary in TFM/property matching with a clear success assertion.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/3 killedVerifies the build succeeds but doesn't check the Windows TFM's automation feature is actually enabled in output.Assert the build log/output confirms UI automation support for the windows TFM specifically.
B (80–89)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
2/2 killedProtects the "explicit false is preserved" contract with a targeted assertion.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts both failure exit code and a diagnostic message naming the early-exit cause.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedUses AssertProcessExitedAsync to actively confirm process termination, not just a passing exit code.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedConfirms the custom FindWindow override path actually executed, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
2/2 killedConfirms the custom shutdown override ran, protecting the extensibility contract.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedVerifies process termination via AssertProcessExitedAsync after cancellation, a strong isolation-relevant assertion.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedConfirms guaranteed disposal even when derived cleanup throws — the core regression this PR fixes.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K · [◷]( · )

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 189.7 AIC · ⌖ 2.72 AIC · ⊞ 16.9K ·

Let custom discovery continue after the launcher exits, add launcher-child lifecycle coverage, and remove asynchronous PID publication races from cleanup tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 11:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (3)
SeverityFinding
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — This cleanup-failure case has the same PID race: the empty test proceeds directly to failing… View resolved comment
Medium severitytest/​IntegrationTests/​MSTest.Acceptance.IntegrationTests/​WindowsUIAutomationSdkTests.cs — The child writes its PID asynchronously, but this empty test can finish and enter StopApplicationView resolved comment
High severitysrc/​TestFramework/​TestFramework.Windows.UIAutomation/​WindowTest.csFindWindow is documented as supporting launcher processes, but this unconditional check aborts… View resolved comment
Suppressed comments (2)

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:479

  • The cancellation timer can fire and cleanup can kill PowerShell before its asynchronous command creates the PID file. The outer test unconditionally reads that file, so slow scheduling turns this cleanup check into a FileNotFoundException. Write applicationProcess.Id synchronously before scheduling cancellation instead of relying on the child command.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:417

  • This PID is written asynchronously by the child, but cleanup starts after a fixed three-second discovery timeout and can terminate PowerShell before it ever executes Set-Content on a heavily loaded worker. AssertProcessExitedAsync then fails with a missing file instead of checking cleanup. Record applicationProcess.Id synchronously from FindWindow before polling, as the other cleanup cases do.
 "-NoProfile -NonInteractive -Command \"$PID | Set-Content -LiteralPath $env:MSTEST_UI_AUTOMATION_PID_FILE; Start-Sleep -Seconds 30\"");

@github-actions

This comment has been minimized.

Rename Character Map title tests to reflect their locale-independent non-empty-title assertion.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 12:07
Record timeout and cancellation process IDs synchronously during window discovery instead of relying on child PowerShell scheduling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:50

  • ApplicationShutdownTimeout is first validated during disposal, after the process has been launched. If an override returns a negative value (or one above Int32.MaxValue milliseconds), cleanup throws before CloseMainWindow/Kill; Dispose then clears and disposes the Process object while leaving the application running. Validate the timeout before Process.Start so an invalid configuration cannot leak a process.
 ProcessStartInfo startInfo = CreateProcessStartInfo();

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:88

  • AutomationElement.FromHandle also throws ArgumentException when the HWND is no longer valid. A window can be destroyed or replaced between reading MainWindowHandle and this call (especially during splash-screen transitions), so that transient race currently fails initialization instead of continuing discovery. Treat ArgumentException like ElementNotAvailableException and retry.
 : AutomationElement.FromHandle(mainWindowHandle);

src/TestFramework/TestFramework.Windows.UIAutomation/ApplicationTest.cs:96

  • CloseMainWindow() returns false when no close message was sent (for example, a windowless process or a disabled main window), but the code still waits the full shutdown timeout before killing. This adds the default five-second delay to cleanup paths where graceful shutdown was never requested. Use the return value to proceed directly to Kill when it is false.
 _ = applicationProcess.CloseMainWindow();
if (!applicationProcess.WaitForExit(shutdownTimeoutMilliseconds))

CopilotAI review requested due to automatic review settings August 31, 2026 12:22
@github-actions

This comment has been minimized.

Validate shutdown timeout before launch, retry stale window handles, skip unnecessary graceful waits, and cover invalid configuration without process creation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/TestFramework/TestFramework.Windows.UIAutomation/WindowTest.cs:112

  • An override returning Timeout.InfiniteTimeSpan is treated as already expired here, and any other negative value produces a misleading application timeout instead of rejecting invalid configuration. Since this is a public customization point, validate the value once and either support infinite polling explicitly or reject it with ArgumentOutOfRangeException, consistent with ApplicationShutdownTimeout.
 MainWindow = window;
return;

src/TestFramework/TestFramework.Windows.UIAutomation/TestFramework.Windows.UIAutomation.csproj:5

  • This assignment overwrites an EnableWindowsTargeting value supplied earlier (for example from Directory.Build.props) on every non-Windows evaluation. That breaks the PR's value-preservation contract and differs from the conditional fallback in the SDK target and sample; only default it when the property is unset.
 <EnableWindowsTargeting Condition=" '$(OS)' != 'Windows_NT' ">true</EnableWindowsTargeting>

CopilotAI review requested due to automatic review settings August 31, 2026 12:36
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

Support infinite window discovery, reject invalid negative values, preserve explicit Windows-targeting settings, and cover invalid configuration cleanup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 006cf5a8-6525-4ecb-829f-e83a99c4de05
CopilotAI review requested due to automatic review settings August 31, 2026 13:02
@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10862

Parallelization — one row per test assembly audited:

Test assemblyScopeWorkersAnalyzer coverage
MSTest.Acceptance.IntegrationTestsMethodLevel (assembly-level [assembly: Parallelize(Scope = MethodLevel, Workers = 0)] in Program.cs, pre-existing, unchanged by this PR)CPU countcoverable once MSTEST0074–0077 ship (attribute-based opt-in)

Findings: A (global-state) 0 · B (paths) 0 · C (declaration) 0 · D (over-serialization) 1 — by severity: Critical 0 · High 0 · Warning 0 · Info 1.

This PR's only changed test file is a brand-new class,
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs
(714 added lines), decorated [TestClass] [DoNotParallelize]. All other files this PR touches
(Program.cs, AssemblyCleanupTests.cs, etc. carrying [assembly: Parallelize]) are pre-existing
and unmodified here, so scope resolution is context, not a live config change from this PR.

Top actions:

  1. Nothing blocking — the class-level [DoNotParallelize] is an appropriate, deliberate choice for tests that launch real Windows desktop processes and drive UI automation; no changes recommended.

Info

  • [D · High confidence]test/IntegrationTests/MSTest.Acceptance.IntegrationTests/WindowsUIAutomationSdkTests.cs:11 — new class-level [DoNotParallelize] defers all ~17 test methods in this class to run sequentially after the assembly's MethodLevel parallel set drains — a genuine category-D throughput cost, since this assembly otherwise runs with Workers = 0 (CPU count). Not recommended to narrow to [ResourceLock]: the tests spawn real child processes that open OS-level desktop windows and assert on window discovery/PID termination (CharacterMapTests, EarlyExitTests, StartupTimeoutTests, ...) — the actual point of contention is the OS window manager/desktop session, not a single named in-process resource a lock could scope. Sequential execution here is the safer, deliberate tradeoff; no fix needed.
  • [B · High confidence, no finding] All per-test artifact paths (pidFile, shutdownMarker, childPidFile, launchMarker) are built with Path.Combine(AssetFixture.ProjectPath, $"{Guid.NewGuid():N}.<ext>") — unique per invocation, so no cross-test collision even though the base AssetFixture.ProjectPath directory is shared across all methods in the class. Confirmed safe; not reported as a finding, noted for completeness since the class-level [DoNotParallelize] means it wouldn't matter today regardless.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 72.7 AIC · ⌖ 3.97 AIC · ⊞ 24.8K · [◷]( · )

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10862

Reviewed the 15 new acceptance-test methods in WindowsUIAutomationSdkTests.cs covering the new EnableWindowsUIAutomation MSBuild feature and the ApplicationTest/WindowTest base classes (src/TestFramework/TestFramework.Windows.UIAutomation). Test classes embedded inside the fixture's SourceCode string literal (e.g. CharacterMapTests, StartupTimeoutTests, CustomWindowDiscoveryTests, ...) are test assets generated on disk, not compiled methods in this file, so they were not graded separately — their behavior is exercised indirectly through the outer acceptance-test assertions (exit code, summary, process-exit checks).

GradeTestMutationNotesHow to improve
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingMSTestRunner_
RunsDesktopTests
3/3 killedVerifies exit code, exact pass/fail summary counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenUsingVSTest_
RunsDesktopTests
4/4 killedCross-checks VSTest output text, exact pass counts, and process termination.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkIsNotWindows_
FailsWithClearError
2/2 killedAsserts both build failure and the exact diagnostic message text.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenTargetFrameworkUsesUppercase_
IsAccepted
2/2 killedConfirms success exit code and absence of the case-sensitivity error message.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenCrossTargetingFromNonWindows_
BuildsSuccessfully
2/2 killedChecks resolved MSBuild property value separately from build success.
A (90–100)WindowsUIAutomationSdkTests.
EnableWindowsUIAutomation_
WhenWindowsTargetingIsExplicitlyDisabled_
PreservesValue
1/1 killedNarrow, focused check on the opt-out property value.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenApplicationExitsBeforeDiscovery_
ReportsClearFailure
2/2 killedAsserts the exact failure exit-code path and diagnostic wording for an early-exit process.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTearDown_
WhenApplicationNeverExposesWindow_
TerminatesProcess
3/3 killedVerifies the timeout message, failure exit code, and that the stuck process is still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenWindowDiscoveryIsCustomized_
UsesOverride
2/2 killedSuccess summary depends on the fixture's own invocation-count assertion, giving indirect but real coverage of the override hook.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenShutdownIsCustomized_
UsesOverride
3/3 killedConfirms the custom shutdown hook ran (marker file) and the process was still terminated.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenTestIsCanceled_
StopsDiscoveryAndTerminatesProcess
3/3 killedCovers cooperative cancellation during discovery plus process cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationTest_
WhenDerivedCleanupFails_
StillTerminatesProcess
3/3 killedTargets the specific guarantee that Dispose still runs after a derived [TestCleanup] throws.
A (90–100)WindowsUIAutomationSdkTests.
WindowTest_
WhenLauncherExitsBeforeChildWindow_
DiscoversAndStopsChild
3/3 killedExercises the launcher/child-process discovery override end to end, including child cleanup.
A (90–100)WindowsUIAutomationSdkTests.
ApplicationSetup_
WhenShutdownTimeoutIsInvalid_
DoesNotLaunchProcess
3/3 killedVerifies the process is never launched, catching any reordering of the timeout-validation step.
A (90–100)WindowsUIAutomationSdkTests.
WindowSetup_
WhenDiscoveryTimeoutIsInvalid_
FailsAndTerminatesProcess
3/3 killedConfirms the exact validation message and that the already-launched process is still cleaned up.

No high-confidence actionable inline findings were identified; assertions consistently match the exact wording and control flow of the production code in ApplicationTest.cs / WindowTest.cs, and process/resource cleanup is verified for every scenario that launches a process. The class is correctly marked [DoNotParallelize] given its shared use of environment-variable-based marker files across process-spawning tests.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 105.5 AIC · ⌖ 2.67 AIC · ⊞ 16.9K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: None

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Evangelink