-
Notifications
You must be signed in to change notification settings - Fork 300
Add generic ITestHostLauncher extension point + PackagedApp reference extension #9454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
251f79f
Add generic ITestHostLauncher test host launcher extension point
Evangelink 42a31e4
Add AppDeployment extension and support PID-less test host launchers
Evangelink 6e03c9b
Rename AppDeployment extension to scenario-specific WinUI
Evangelink d33ff64
Rename WinUI extension to Msix to cover both UWP and WinUI
Evangelink d8fc92d
Rename Msix extension to PackagedApp (scenario, not format/tooling)
Evangelink 6195ac4
Address review feedback on ITestHostLauncher implementation
Evangelink cc4662c
Refine ITestHostHandle: drop Exited, replace ProcessId with string Id…
Evangelink e82cb3c
Address code-quality review: non-empty/specific catch handling
Evangelink afaf79d
Merge remote-tracking branch 'origin/main' into evangelink-generic-te…
Evangelink f6d88b1
Fix stale Exited reference in PackagedApp launcher comment
Evangelink 1923692
Add CancellationToken to WaitForExitAsync and make ITestHostHandle ID…
Evangelink 5f09f29
Address launcher review: no shipping breadcrumb, honor cancellation +…
Evangelink 2ecaea0
Merge remote-tracking branch 'origin/main' into evangelink-generic-te…
Evangelink ca2edd8
Make PackagedApp APIs and package version experimental; add MSBuild r…
Evangelink 6380a39
Address review: don't raise synthetic Exited on fault/cancel; determi…
Evangelink 5ee38da
Add PackagedApp to NonWindowsTests/Platform solution filters so the p…
Evangelink a6dff39
Address review: best-effort Kill on cancel; single NoWarn in deployme…
Evangelink b577f63
Merge remote-tracking branch 'origin/main' into evangelink-generic-te…
Evangelink 42cdfbe
Fix forward-compat regression (restore IProcess.WaitForExitAsync()) a…
Evangelink e4855ea
Address review: keep MIT license, localize launcher strings, use buil…
Evangelink File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
src/Platform/Microsoft.Testing.Extensions.PackagedApp/BannedSymbols.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| P:System.DateTime.Now; Use 'IClock' instead | ||
| P:System.DateTime.UtcNow; Use 'IClock' instead | ||
| M:System.Threading.Tasks.Task.Run(System.Action); Use 'ITask' instead | ||
| M:System.Threading.Tasks.Task.WhenAll(System.Threading.Tasks.Task[]); Use 'ITask' instead | ||
| M:System.Threading.Tasks.Task.WhenAll(System.Collections.Generic.IEnumerable{System.Threading.Tasks.Task}); Use 'ITask' instead | ||
| M:System.String.IsNullOrEmpty(System.String); Use 'RoslynString.IsNullOrEmpty' instead | ||
| M:System.String.IsNullOrWhiteSpace(System.String); Use 'RoslynString.IsNullOrWhiteSpace' instead | ||
| M:System.Diagnostics.Debug.Assert(System.Boolean); Use 'RoslynDebug.Assert' instead | ||
| M:System.Diagnostics.Debug.Assert(System.Boolean,System.String); Use 'RoslynDebug.Assert' instead |
56 changes: 56 additions & 0 deletions
56
.../Microsoft.Testing.Extensions.PackagedApp/Microsoft.Testing.Extensions.PackagedApp.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <RootNamespace>Microsoft.Testing.Extensions.PackagedApp</RootNamespace> | ||
| <!-- The packaged-app launcher uses modern Process APIs (ArgumentList, WaitForExitAsync, | ||
| Kill(entireProcessTree)) and targets runtime hosts, so it ships only for .NET. --> | ||
| <TargetFrameworks>$(SupportedNetFrameworks)</TargetFrameworks> | ||
| <GenerateBuildInfo>true</GenerateBuildInfo> | ||
| <BuildInfoTemplateFile>$(RepoRoot)src\Platform\SharedExtensionHelpers\BuildInfo.cs.template</BuildInfoTemplateFile> | ||
| <!-- This extension consumes the experimental ITestHostLauncher extension point. --> | ||
| <NoWarn>$(NoWarn);TPEXP</NoWarn> | ||
| <!-- Early preview/experimental package: keep an experimental (alpha) version even in official builds. --> | ||
| <VersionPrefix>$(MicrosoftTestingExtensionsPackagedAppVersionPrefix)</VersionPrefix> | ||
| <PreReleaseVersionLabel>$(MicrosoftTestingExtensionsPackagedAppPreReleaseVersionLabel)</PreReleaseVersionLabel> | ||
| <SuppressFinalPackageVersion>true</SuppressFinalPackageVersion> | ||
| </PropertyGroup> | ||
|
|
||
| <!-- NuGet properties --> | ||
| <PropertyGroup> | ||
| <PackageDescription> | ||
| <![CDATA[This package provides extensions to Microsoft Testing Platform intended to extend base functionalities. | ||
|
|
||
| This package extends Microsoft Testing Platform to deploy and launch a packaged Windows (UWP/WinUI) test host through a custom mechanism instead of starting it in place.]]> | ||
| </PackageDescription> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <AdditionalFiles Include="BannedSymbols.txt" /> | ||
| <AdditionalFiles Include="PublicAPI/PublicAPI.Shipped.txt" /> | ||
| <AdditionalFiles Include="PublicAPI/PublicAPI.Unshipped.txt" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Compile Include="$(RepoRoot)src/Polyfills/**/*.cs" Link="Polyfills\%(RecursiveDir)%(Filename)%(Extension)" /> | ||
| </ItemGroup> | ||
|
|
||
| <!-- NuGet package layout --> | ||
| <!-- NuGet folders https://learn.microsoft.com/nuget/create-packages/creating-a-package#from-a-convention-based-working-directory --> | ||
| <ItemGroup> | ||
| <Content Include="buildMultiTargeting/**"> | ||
| <Pack>true</Pack> | ||
| <PackagePath>buildMultiTargeting</PackagePath> | ||
| </Content> | ||
| <TfmSpecificPackageFile Include="buildTransitive/**"> | ||
| <PackagePath>buildTransitive/$(TargetFramework)</PackagePath> | ||
| </TfmSpecificPackageFile> | ||
| <TfmSpecificPackageFile Include="build/**"> | ||
| <PackagePath>build/$(TargetFramework)</PackagePath> | ||
| </TfmSpecificPackageFile> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Platform\Microsoft.Testing.Platform.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
34 changes: 34 additions & 0 deletions
34
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PACKAGE.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Microsoft.Testing.Extensions.PackagedApp | ||
|
|
||
| > [!IMPORTANT] | ||
| > This package is experimental and consumes the experimental `ITestHostLauncher` extension point of [Microsoft.Testing.Platform](https://www.nuget.org/packages/Microsoft.Testing.Platform). The API may change or be removed in a future update. | ||
|
|
||
| `Microsoft.Testing.Extensions.PackagedApp` is an extension for [Microsoft.Testing.Platform](https://www.nuget.org/packages/Microsoft.Testing.Platform) that deploys a packaged Windows test host (UWP or packaged WinUI) into an isolated directory and launches it from there, instead of starting the test host in place. | ||
|
|
||
| It is the consumer of the platform's `ITestHostLauncher` extension point for packaged Windows apps. UWP and packaged WinUI ship as MSIX and share the same launch mechanism, which is why VSTest exposes a single `UwpTestHostRuntimeProvider` for both: | ||
|
|
||
| - **Deploy + launch** (implemented): the app's loose layout is deployed to a deployment directory and the produced executable is launched from there. | ||
| - **Packaged AUMID activation** (planned): the loose layout is registered with the `PackageManager` and the app is activated by Application User Model ID (AUMID) via `IApplicationActivationManager` — the scenario behind [#2784](https://github.com/microsoft/testfx/issues/2784). | ||
|
|
||
| Microsoft.Testing.Platform is open source. You can find `Microsoft.Testing.Extensions.PackagedApp` code in the [microsoft/testfx](https://github.com/microsoft/testfx) GitHub repository. | ||
|
|
||
| ## Install the package | ||
|
|
||
| ```dotnetcli | ||
| dotnet add package Microsoft.Testing.Extensions.PackagedApp | ||
| ``` | ||
|
|
||
| ## About | ||
|
|
||
| This package extends Microsoft.Testing.Platform with: | ||
|
|
||
| - **Deployment + launch**: stages the packaged Windows (UWP/WinUI) test host payload into an isolated directory and launches the deployed copy. | ||
| - **Mechanism-agnostic monitoring**: returns an `ITestHostHandle` that exposes only the lifecycle the platform needs and no local process id. | ||
|
|
||
| ## Documentation | ||
|
|
||
| For comprehensive documentation, see <https://aka.ms/testingplatform>. | ||
|
|
||
| ## Feedback & contributing | ||
|
|
||
| Microsoft.Testing.Platform is an open source project. Provide feedback or report issues in the [microsoft/testfx](https://github.com/microsoft/testfx/issues) GitHub repository. |
26 changes: 26 additions & 0 deletions
26
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackagedAppExtensions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.Testing.Extensions.PackagedApp; | ||
| using Microsoft.Testing.Platform.Builder; | ||
|
|
||
| namespace Microsoft.Testing.Extensions; | ||
|
|
||
| /// <summary> | ||
| /// Provides extension methods for adding packaged Windows (UWP/WinUI) test host deployment support | ||
| /// to the test application builder. | ||
| /// </summary> | ||
| [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] | ||
| public static class PackagedAppExtensions | ||
| { | ||
| /// <summary> | ||
| /// Registers a test host launcher that deploys the packaged Windows (UWP/WinUI) test host into | ||
| /// an isolated directory and launches it from there. | ||
| /// </summary> | ||
| /// <param name="builder">The test application builder.</param> | ||
| public static void AddPackagedAppDeployment(this ITestApplicationBuilder builder) | ||
| { | ||
| _ = builder ?? throw new System.ArgumentNullException(nameof(builder)); | ||
| builder.TestHostControllers.AddTestHostLauncher(_ => new PackagedAppTestHostLauncher()); | ||
| } | ||
| } |
68 changes: 68 additions & 0 deletions
68
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackagedAppTestHostHandle.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.Testing.Platform.Extensions.TestHostControllers; | ||
|
|
||
| namespace Microsoft.Testing.Extensions.PackagedApp; | ||
|
|
||
| /// <summary> | ||
| /// An <see cref="ITestHostHandle"/> over a deployed packaged Windows (UWP/WinUI) test host process | ||
| /// that deliberately exposes no identifier, modelling a launch where no local, queryable PID is | ||
| /// available. | ||
| /// </summary> | ||
| internal sealed class PackagedAppTestHostHandle : ITestHostHandle | ||
| { | ||
| private readonly Process _process; | ||
| private readonly string _deploymentDirectory; | ||
|
|
||
| public PackagedAppTestHostHandle(Process process, string deploymentDirectory) | ||
| { | ||
| _process = process; | ||
| _deploymentDirectory = deploymentDirectory; | ||
| } | ||
|
|
||
| // Intentionally null: the platform must not depend on any identifier. A packaged UWP/WinUI | ||
| // implementation could surface the AUMID-activated PID (as a string) here instead. | ||
| public string? Identifier => null; | ||
|
|
||
| public int ExitCode => _process.ExitCode; | ||
|
|
||
| public bool HasExited => _process.HasExited; | ||
|
|
||
| public Task WaitForExitAsync(CancellationToken cancellationToken) => _process.WaitForExitAsync(cancellationToken); | ||
|
|
||
| public void Terminate() | ||
| { | ||
| try | ||
| { | ||
| _process.Kill(entireProcessTree: true); | ||
| } | ||
| catch (InvalidOperationException) | ||
| { | ||
| // The process has already exited. | ||
| } | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| _process.Dispose(); | ||
|
|
||
| // The platform disposes the handle once the host has exited, so it is safe to remove the | ||
| // staged deployment now. Best-effort: never let cleanup failures surface as run failures. | ||
| try | ||
| { | ||
| if (Directory.Exists(_deploymentDirectory)) | ||
| { | ||
| Directory.Delete(_deploymentDirectory, recursive: true); | ||
| } | ||
| } | ||
| catch (IOException ex) | ||
| { | ||
| Debug.WriteLine($"Best-effort cleanup of deployment directory '{_deploymentDirectory}' failed: {ex}"); | ||
| } | ||
| catch (UnauthorizedAccessException ex) | ||
| { | ||
| Debug.WriteLine($"Best-effort cleanup of deployment directory '{_deploymentDirectory}' failed: {ex}"); | ||
| } | ||
| } | ||
| } |
110 changes: 110 additions & 0 deletions
110
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackagedAppTestHostLauncher.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.Testing.Extensions.PackagedApp.Resources; | ||
| using Microsoft.Testing.Platform.Extensions.TestHostControllers; | ||
|
|
||
| namespace Microsoft.Testing.Extensions.PackagedApp; | ||
|
|
||
| /// <summary> | ||
| /// An <see cref="ITestHostLauncher"/> for packaged Windows test applications (UWP and packaged | ||
| /// WinUI): it deploys the test host's loose layout into an isolated directory and launches it from | ||
| /// there, instead of starting the test host in place. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// <para> | ||
| /// Packaged Windows apps — produced by both UWP and packaged WinUI projects, and shipped as MSIX — | ||
| /// cannot be started with a plain <c>Process.Start</c> from the build output. They share the same | ||
| /// launch mechanism: the loose layout is registered with the <c>PackageManager</c> and the app is | ||
| /// activated by Application User Model ID (AUMID) via <c>IApplicationActivationManager</c>. That | ||
| /// mechanism is the reason VSTest's <c>UwpTestHostRuntimeProvider</c> exists (it serves both UWP and | ||
| /// WinUI); see https://github.com/microsoft/testfx/issues/2784. | ||
| /// </para> | ||
| /// <para> | ||
| /// This reference implementation performs the deploy-and-launch step (stage the loose layout, then | ||
| /// launch the produced executable from the deployment directory). The packaged AUMID-activation | ||
| /// branch — registering the layout with <c>PackageManager.RegisterPackageByUriAsync</c> and calling | ||
| /// <c>IApplicationActivationManager.ActivateApplication</c> — is a clearly-marked follow-up. | ||
| /// </para> | ||
| /// <para> | ||
| /// In all cases the platform owns argument/environment preparation, the controller-to-host IPC pipe, | ||
| /// the PID handshake, and the lifetime-handler dispatch; this launcher only performs the | ||
| /// deploy-and-create step and returns an <see cref="ITestHostHandle"/> the platform monitors. | ||
| /// </para> | ||
| /// </remarks> | ||
| internal sealed class PackagedAppTestHostLauncher : ITestHostLauncher | ||
| { | ||
| public string Uid => nameof(PackagedAppTestHostLauncher); | ||
|
|
||
| public string Version => ExtensionVersion.DefaultSemVer; | ||
|
|
||
| public string DisplayName => ExtensionResources.PackagedAppExtensionDisplayName; | ||
|
|
||
| public string Description => ExtensionResources.PackagedAppExtensionDescription; | ||
|
|
||
| public Task<bool> IsEnabledAsync() => Task.FromResult(true); | ||
|
|
||
| public Task<ITestHostHandle> LaunchTestHostAsync(TestHostLaunchContext context, CancellationToken cancellationToken) | ||
| { | ||
| // Honor immediate cancellation before doing any (potentially expensive) deployment work. | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
|
|
||
| string sourceDirectory = Path.GetDirectoryName(context.FileName) | ||
| ?? throw new InvalidOperationException($"Unable to determine the source directory of '{context.FileName}'."); | ||
|
|
||
| // 1. Deploy the app's loose layout into an isolated directory. For packaged UWP/WinUI this is | ||
| // also where the layout would be registered via PackageManager.RegisterPackageByUriAsync. | ||
| string deploymentDirectory = Path.Combine(Path.GetTempPath(), "MTPPackagedAppDeployment", Guid.NewGuid().ToString("N")); | ||
| CopyDirectory(sourceDirectory, deploymentDirectory, cancellationToken); | ||
|
|
||
| // 2. Launch the deployed test host, forwarding the platform-prepared arguments and | ||
| // environment (which include the controller IPC pipe name the host connects back on). | ||
| // Packaged UWP/WinUI would instead AUMID-activate here via IApplicationActivationManager | ||
| // and wrap the activated process id. | ||
| string deployedFileName = Path.Combine(deploymentDirectory, Path.GetFileName(context.FileName)); | ||
| var startInfo = new ProcessStartInfo(deployedFileName) | ||
| { | ||
| UseShellExecute = false, | ||
| // Honor an explicitly requested working directory; otherwise run from the deployment dir. | ||
| WorkingDirectory = context.WorkingDirectory ?? deploymentDirectory, | ||
| }; | ||
|
|
||
| foreach (string argument in context.Arguments) | ||
| { | ||
| startInfo.ArgumentList.Add(argument); | ||
| } | ||
|
|
||
| foreach (KeyValuePair<string, string?> environmentVariable in context.EnvironmentVariables) | ||
| { | ||
| startInfo.Environment[environmentVariable.Key] = environmentVariable.Value; | ||
| } | ||
|
|
||
| Process process = Process.Start(startInfo) | ||
| ?? throw new InvalidOperationException($"Failed to start deployed packaged-app test host '{deployedFileName}'."); | ||
|
Evangelink marked this conversation as resolved.
|
||
|
|
||
| // 3. Return a handle that deliberately does NOT surface the underlying process id, validating | ||
| // that the platform relies purely on the lifecycle contract | ||
| // (WaitForExitAsync/ExitCode/HasExited/Terminate) and the IPC PID handshake. This | ||
| // matches launch mechanisms where no local, queryable PID is available (e.g. an | ||
| // AppContainer-sandboxed AUMID activation surfaced through a broker). The handle also owns | ||
| // cleanup of the deployment directory once the host has exited. | ||
| return Task.FromResult<ITestHostHandle>(new PackagedAppTestHostHandle(process, deploymentDirectory)); | ||
| } | ||
|
|
||
| private static void CopyDirectory(string sourceDirectory, string destinationDirectory, CancellationToken cancellationToken) | ||
| { | ||
| Directory.CreateDirectory(destinationDirectory); | ||
|
|
||
| foreach (string file in Directory.EnumerateFiles(sourceDirectory)) | ||
| { | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
| File.Copy(file, Path.Combine(destinationDirectory, Path.GetFileName(file)), overwrite: true); | ||
| } | ||
|
|
||
| foreach (string directory in Directory.EnumerateDirectories(sourceDirectory)) | ||
| { | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
| CopyDirectory(directory, Path.Combine(destinationDirectory, Path.GetFileName(directory)), cancellationToken); | ||
| } | ||
| } | ||
| } | ||
1 change: 1 addition & 0 deletions
1
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PublicAPI/PublicAPI.Shipped.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| #nullable enable |
5 changes: 5 additions & 0 deletions
5
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PublicAPI/PublicAPI.Unshipped.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| #nullable enable | ||
| Microsoft.Testing.Extensions.PackagedApp.TestingPlatformBuilderHook | ||
| [TPEXP]Microsoft.Testing.Extensions.PackagedAppExtensions | ||
| static Microsoft.Testing.Extensions.PackagedApp.TestingPlatformBuilderHook.AddExtensions(Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, string![]! _) -> void | ||
| [TPEXP]static Microsoft.Testing.Extensions.PackagedAppExtensions.AddPackagedAppDeployment(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder) -> void |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.