diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/AcaCompactNamingUpgradeDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/AcaCompactNamingUpgradeDeploymentTests.cs index b992d67c05e..ea7dc249825 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/AcaCompactNamingUpgradeDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/AcaCompactNamingUpgradeDeploymentTests.cs @@ -98,12 +98,107 @@ private async Task UpgradeFromGaToDevDoesNotDuplicateStorageAccountsCore(Cancell // Step 5: Create single-file AppHost with GA CLI output.WriteLine("Step 5: Creating single-file AppHost with GA CLI..."); + var waitingForLanguageSelectionPrompt = new CellPatternSearcher() + .Find("Which language would you like to use?"); + var waitingForTemplateVersionPrompt = new CellPatternSearcher() + .Find("NuGet.config"); + var waitingForAgentInitPrompt = new CellPatternSearcher() + .Find("configure AI agent environments"); + var waitingForSuccessPrompt = new CellPatternSearcher() + .FindPattern(counter.Value.ToString()) + .RightText(" OK] $ "); + await auto.TypeAsync("aspire init"); await auto.EnterAsync(); - await auto.WaitAsync(TimeSpan.FromSeconds(5)); - await auto.EnterAsync(); - await auto.WaitUntilTextAsync("Aspire initialization complete", timeout: TimeSpan.FromMinutes(2)); - await auto.DeclineAgentInitPromptAsync(counter); + + var initState = "success"; + await auto.WaitUntilAsync(s => + { + if (waitingForLanguageSelectionPrompt.Search(s).Count > 0) + { + initState = "language"; + return true; + } + + if (waitingForTemplateVersionPrompt.Search(s).Count > 0) + { + initState = "template-version"; + return true; + } + + if (waitingForAgentInitPrompt.Search(s).Count > 0) + { + initState = "agent-init"; + return true; + } + + if (waitingForSuccessPrompt.Search(s).Count > 0) + { + initState = "success"; + return true; + } + + return false; + }, timeout: TimeSpan.FromMinutes(2), description: "language prompt, template version prompt, agent init prompt, or init success prompt"); + + if (initState == "language") + { + await auto.EnterAsync(); + + await auto.WaitUntilAsync(s => + { + if (waitingForTemplateVersionPrompt.Search(s).Count > 0) + { + initState = "template-version"; + return true; + } + + if (waitingForAgentInitPrompt.Search(s).Count > 0) + { + initState = "agent-init"; + return true; + } + + if (waitingForSuccessPrompt.Search(s).Count > 0) + { + initState = "success"; + return true; + } + + return false; + }, timeout: TimeSpan.FromMinutes(2), description: "template version prompt, agent init prompt, or init success prompt"); + } + + if (initState == "template-version") + { + await auto.EnterAsync(); + + await auto.WaitUntilAsync(s => + { + if (waitingForAgentInitPrompt.Search(s).Count > 0) + { + initState = "agent-init"; + return true; + } + + if (waitingForSuccessPrompt.Search(s).Count > 0) + { + initState = "success"; + return true; + } + + return false; + }, timeout: TimeSpan.FromMinutes(2), description: "agent init prompt or init success prompt"); + } + + if (initState == "agent-init") + { + await auto.DeclineAgentInitPromptAsync(counter); + } + else + { + await auto.WaitForSuccessPromptAsync(counter); + } // Step 6: Add ACA package using GA CLI (uses GA NuGet packages) output.WriteLine("Step 6: Adding Azure Container Apps package (GA)..."); diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/AcaManagedRedisDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/AcaManagedRedisDeploymentTests.cs index 1caee7f4023..ce4c4b2a0fc 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/AcaManagedRedisDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/AcaManagedRedisDeploymentTests.cs @@ -75,7 +75,7 @@ private async Task DeployStarterWithManagedRedisToAzureContainerAppsCore(Cancell .Find($"Enter the project name ({workspace.WorkspaceRoot.Name}): "); var waitingForOutputPathPrompt = new CellPatternSearcher() - .Find("Enter the output path:"); + .Find("Enter the output path"); var waitingForUrlsPrompt = new CellPatternSearcher() .Find("Use *.dev.localhost URLs"); diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/AcrPurgeTaskDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/AcrPurgeTaskDeploymentTests.cs index d8b139cd759..70c3a40f3a3 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/AcrPurgeTaskDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/AcrPurgeTaskDeploymentTests.cs @@ -74,10 +74,17 @@ private async Task DeployPythonStarterWithPurgeTaskCore(CancellationToken cancel await auto.PrepareEnvironmentAsync(workspace, counter); // Step 2: Set up CLI environment (in CI) + // Python apphosts need the full bundle because + // the prebuilt AppHost server is required for aspire new with Python templates. if (DeploymentE2ETestHelpers.IsRunningInCI) { - output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build..."); - await auto.SourceAspireCliEnvironmentAsync(counter); + var prNumber = DeploymentE2ETestHelpers.GetPrNumber(); + if (prNumber > 0) + { + output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}..."); + await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter); + } + await auto.SourceAspireBundleEnvironmentAsync(counter); } // Step 3: Create Python FastAPI project using aspire new @@ -95,7 +102,7 @@ private async Task DeployPythonStarterWithPurgeTaskCore(CancellationToken cancel await auto.TypeAsync("aspire add Aspire.Hosting.Azure.AppContainers"); await auto.EnterAsync(); - if (DeploymentE2ETestHelpers.IsRunningInCI) + if (DeploymentE2ETestHelpers.IsRunningInCI && DeploymentE2ETestHelpers.GetPrNumber() <= 0) { await auto.WaitUntilTextAsync("(based on NuGet.config)", timeout: TimeSpan.FromSeconds(60)); await auto.EnterAsync(); diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/AppServicePythonDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/AppServicePythonDeploymentTests.cs index 1710ee2758f..28b342d20c9 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/AppServicePythonDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/AppServicePythonDeploymentTests.cs @@ -76,10 +76,17 @@ private async Task DeployPythonFastApiTemplateToAzureAppServiceCore(Cancellation await auto.PrepareEnvironmentAsync(workspace, counter); // Step 2: Set up CLI environment (in CI) + // Python apphosts need the full bundle because + // the prebuilt AppHost server is required for aspire new with Python templates. if (DeploymentE2ETestHelpers.IsRunningInCI) { - output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build..."); - await auto.SourceAspireCliEnvironmentAsync(counter); + var prNumber = DeploymentE2ETestHelpers.GetPrNumber(); + if (prNumber > 0) + { + output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}..."); + await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter); + } + await auto.SourceAspireBundleEnvironmentAsync(counter); } // Step 3: Create Python FastAPI project using aspire new with interactive prompts diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/PythonFastApiDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/PythonFastApiDeploymentTests.cs index 870da4f9651..817c7c9362c 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/PythonFastApiDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/PythonFastApiDeploymentTests.cs @@ -76,10 +76,17 @@ private async Task DeployPythonFastApiTemplateToAzureContainerAppsCore(Cancellat await auto.PrepareEnvironmentAsync(workspace, counter); // Step 2: Set up CLI environment (in CI) + // Python apphosts need the full bundle because + // the prebuilt AppHost server is required for aspire new with Python templates. if (DeploymentE2ETestHelpers.IsRunningInCI) { - output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build..."); - await auto.SourceAspireCliEnvironmentAsync(counter); + var prNumber = DeploymentE2ETestHelpers.GetPrNumber(); + if (prNumber > 0) + { + output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}..."); + await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter); + } + await auto.SourceAspireBundleEnvironmentAsync(counter); } // Step 3: Create Python FastAPI project using aspire new with interactive prompts diff --git a/tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptVnetSqlServerInfraDeploymentTests.cs b/tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptVnetSqlServerInfraDeploymentTests.cs index bea38786351..0b6c0be601a 100644 --- a/tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptVnetSqlServerInfraDeploymentTests.cs +++ b/tests/Aspire.Deployment.EndToEnd.Tests/TypeScriptVnetSqlServerInfraDeploymentTests.cs @@ -86,28 +86,60 @@ private async Task DeployTypeScriptVnetSqlServerInfrastructureCore(CancellationT // Step 3: Create TypeScript AppHost using aspire init output.WriteLine("Step 3: Creating TypeScript AppHost with aspire init..."); - var waitingForNuGetConfigPrompt = new CellPatternSearcher() + var waitingForTemplateVersionPrompt = new CellPatternSearcher() .Find("NuGet.config"); - var waitingForInitComplete = new CellPatternSearcher() - .Find("Aspire initialization complete"); + var waitingForAgentInitPrompt = new CellPatternSearcher() + .Find("configure AI agent environments"); + var waitingForSuccessPrompt = new CellPatternSearcher() + .FindPattern(counter.Value.ToString()) + .RightText(" OK] $ "); await auto.TypeAsync("aspire init --language typescript"); await auto.EnterAsync(); - // NuGet.config prompt may or may not appear depending on environment. - await auto.WaitUntilAsync( - s => waitingForNuGetConfigPrompt.Search(s).Count > 0 - || waitingForInitComplete.Search(s).Count > 0, - timeout: TimeSpan.FromMinutes(2), - description: "NuGet.config prompt or init completion"); - await auto.EnterAsync(); // Dismiss NuGet.config prompt if present + var sawTemplateVersionPrompt = false; + var sawAgentInitPrompt = false; + await auto.WaitUntilAsync(s => + { + if (waitingForTemplateVersionPrompt.Search(s).Count > 0) + { + sawTemplateVersionPrompt = true; + return true; + } - await auto.WaitUntilAsync( - s => waitingForInitComplete.Search(s).Count > 0, - timeout: TimeSpan.FromMinutes(2), - description: "aspire initialization complete"); + if (waitingForAgentInitPrompt.Search(s).Count > 0) + { + sawAgentInitPrompt = true; + return true; + } + + return waitingForSuccessPrompt.Search(s).Count > 0; + }, timeout: TimeSpan.FromMinutes(2), description: "template version prompt, agent init prompt, or init success prompt"); + + if (sawTemplateVersionPrompt) + { + await auto.EnterAsync(); - await auto.DeclineAgentInitPromptAsync(counter); + await auto.WaitUntilAsync(s => + { + if (waitingForAgentInitPrompt.Search(s).Count > 0) + { + sawAgentInitPrompt = true; + return true; + } + + return waitingForSuccessPrompt.Search(s).Count > 0; + }, timeout: TimeSpan.FromMinutes(2), description: "agent init prompt or init success prompt"); + } + + if (sawAgentInitPrompt) + { + await auto.DeclineAgentInitPromptAsync(counter); + } + else + { + await auto.WaitForSuccessPromptAsync(counter); + } // Step 4a: Add Aspire.Hosting.Azure.AppContainers output.WriteLine("Step 4a: Adding Azure Container Apps hosting package...");