| File: LaunchProfileTests.cs | Web Access |
| Project: src\tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj (Aspire.Cli.EndToEnd.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json; using Aspire.Cli.EndToEnd.Tests.Helpers; using Hex1b.Automation; using Hex1b.Input; using Xunit; namespace Aspire.Cli.EndToEnd.Tests; /// <summary> /// End-to-end coverage for selecting .NET AppHost launch profiles through the Aspire CLI. /// </summary> public sealed class LaunchProfileTests(ITestOutputHelper output) { [CaptureWorkspaceOnFailure] [Fact] public async Task RunStartsAppHostWithSelectedLaunchProfile() { var repoRoot = CliE2ETestHelpers.GetRepoRoot(); var strategy = CliInstallStrategy.Detect(output.WriteLine); var workspace = TemporaryWorkspace.Create(output); // A solution file makes `aspire init` create a project-based AppHost with // Properties/launchSettings.json instead of a single-file AppHost. File.WriteAllText(Path.Combine(workspace.WorkspaceRoot.FullName, "LaunchProfile.sln"), "Fake solution file"); using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal(repoRoot, strategy, output, workspace: workspace); var counter = new SequenceCounter(); var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500)); await using var terminalRun = CliE2ETestHelpers.StartRun(terminal, workspace, auto, counter, output, TestContext.Current.CancellationToken); await auto.PrepareDockerEnvironmentAsync(counter, workspace); await auto.InstallAspireCliAsync(strategy, counter); await auto.AspireInitAsync(counter); var appHostDirectory = Path.Combine(workspace.WorkspaceRoot.FullName, "LaunchProfile.AppHost"); var appHostSourcePath = Path.Combine(appHostDirectory, "AppHost.cs"); var launchSettingsPath = Path.Combine(appHostDirectory, "Properties", "launchSettings.json"); var profileOutputPath = Path.Combine(appHostDirectory, "selected-profile.txt"); var containerProfileOutputPath = CliE2ETestHelpers.ToContainerPath(profileOutputPath, workspace); Assert.True(File.Exists(appHostSourcePath), $"Expected AppHost source file to exist at: {appHostSourcePath}"); Assert.True(File.Exists(launchSettingsPath), $"Expected launch settings to exist at: {launchSettingsPath}"); File.WriteAllText( appHostSourcePath, $$""" File.WriteAllText( {{JsonSerializer.Serialize(containerProfileOutputPath)}}, $"{Environment.GetEnvironmentVariable("SELECTED_PROFILE")}|{Environment.GetEnvironmentVariable("DOTNET_LAUNCH_PROFILE")}|{string.Join("|", args)}"); var builder = DistributedApplication.CreateBuilder(args); builder.Build().Run(); """); // The profiles deliberately carry different environment variables and arguments so the // assertion covers System.CommandLine parsing, CLI propagation, and direct AppHost launch. File.WriteAllText( launchSettingsPath, """ { "profiles": { "default": { "commandName": "Project", "commandLineArgs": "--profile-argument default", "environmentVariables": { "SELECTED_PROFILE": "default" } }, "E2E": { "commandName": "Project", "commandLineArgs": "--profile-argument selected-profile", "environmentVariables": { "SELECTED_PROFILE": "selected-profile" } } } } """); await auto.RunCommandAsync("cd LaunchProfile.AppHost", counter); await auto.TypeAsync(CliE2EAutomatorHelpers.GetAspireRunCommand("--launch-profile E2E")); await auto.EnterAsync(); await auto.WaitUntilAsync( s => s.ContainsText("Press CTRL+C to stop the AppHost and exit."), timeout: CliE2EAutomatorHelpers.AspireRunReadyTimeout, description: "Press CTRL+C message from AppHost using selected launch profile"); await auto.Ctrl().KeyAsync(Hex1bKey.C); await auto.WaitForSuccessPromptAsync(counter); Assert.True(File.Exists(profileOutputPath), $"Expected AppHost to write selected profile details to: {profileOutputPath}"); Assert.Equal("selected-profile|E2E|--profile-argument|selected-profile", File.ReadAllText(profileOutputPath)); } }