Skip to content

Migrate CLI and Deployment E2E tests to Hex1bTerminalAutomator API#15244

Merged
mitchdenny merged 12 commits intorelease/13.2from
e2e-automator-migration
Mar 16, 2026
Merged

Migrate CLI and Deployment E2E tests to Hex1bTerminalAutomator API#15244
mitchdenny merged 12 commits intorelease/13.2from
e2e-automator-migration

Conversation

@mitchdenny
Copy link
Member

@mitchdenny mitchdenny commented Mar 14, 2026

Description

Migrates all CLI E2E and Deployment E2E tests from the Hex1bTerminalInputSequenceBuilder fluent builder API to the Hex1bTerminalAutomator async/await imperative API.

This builds on the foundation laid in #15206 (Hex1b 0.116.0, shared helpers, WaitCommandTests reference migration).

Closes #15241

Changes

CLI E2E Tests (26 files, 52 test methods)

All test files migrated, including:

  • SmokeTests, StartStopTests, StopNonInteractiveTests, EmptyAppHostTemplateTests
  • JsReactTemplateTests, PythonReactTemplateTests, TypeScriptStarterTemplateTests, BundleSmokeTests
  • DescribeCommandTests, PsCommandTests, LogsCommandTests, MultipleAppHostTests
  • CentralPackageManagementTests, SecretDotNetAppHostTests, SecretTypeScriptAppHostTests
  • AgentCommandTests, PlaywrightCliInstallTests, DoctorCommandTests, BannerTests, CertificatesCommandTests
  • DockerDeploymentTests, KubernetesPublishTests, StagingChannelTests
  • TypeScriptCodegenValidationTests, TypeScriptPolyglotTests, ProjectReferenceTests

Not migrated (no Hex1b usage): McpDocsE2ETests (MCP SDK), AuthenticationTests (static validation)

Deployment E2E Tests (26 files, 26 test methods)

All deployment test files migrated, including:

  • ACA: Starter, CompactNaming, CompactNamingUpgrade, CustomRegistry, ExistingRegistry, DeploymentErrorOutput
  • AKS: Starter, StarterWithRedis
  • App Service: Python, React
  • Azure services: AppConfig, ContainerRegistry, EventHubs, KeyVault, LogAnalytics, ServiceBus, Storage
  • VNet: KeyVault (Connectivity/Infra), SqlServer (Connectivity/Infra), StorageBlob (Connectivity/Infra)
  • ACR: PurgeTask
  • Polyglot: PythonFastApi, TypeScriptExpress

Not migrated (no Hex1b usage): AuthenticationTests (static validation)

New Helpers Created

  • ClearScreenAsync in CliE2EAutomatorHelpers.cs
  • PrepareEnvironmentAsync, InstallAspireCliFromPullRequestAsync, InstallAspireCliReleaseAsync, SourceAspireCliEnvironmentAsync in DeploymentE2EAutomatorHelpers.cs
  • AspireInitAsync in shared Hex1bAutomatorTestHelpers.cs
  • Hex1bAutomatorTestHelpers.cs linked to deployment test project

Skill Documents Updated

  • .github/skills/cli-e2e-testing/SKILL.md — updated with automator API patterns
  • .github/skills/deployment-e2e-testing/SKILL.md — updated with deployment automator patterns

Migration Pattern

Old (Builder/Fluent):

var sequenceBuilder = new Hex1bTerminalInputSequenceBuilder();
sequenceBuilder.PrepareDockerEnvironment(counter, workspace);
sequenceBuilder.Type("aspire run").Enter()
    .WaitUntil(s => pattern.Search(s).Count > 0, timeout)
    .Ctrl().Key(Hex1bKey.C)
    .WaitForSuccessPrompt(counter);
await sequenceBuilder.Build().ApplyAsync(terminal, ct);

New (Automator/Async):

var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500));
await auto.PrepareDockerEnvironmentAsync(counter, workspace);
await auto.TypeAsync("aspire run");
await auto.EnterAsync();
await auto.WaitUntilAsync(s => pattern.Search(s).Count > 0, timeout: timeout, description: "...");
await auto.Ctrl().KeyAsync(Hex1bKey.C);
await auto.WaitForSuccessPromptAsync(counter);

Benefits

  • Better error reporting: Immediate fail-fast with meaningful stack traces instead of opaque timeout failures
  • Improved readability: async/await is more natural than fluent chains
  • Easier debugging: Each step produces a clear stack trace on failure

Testing

  • All migrated tests build with 0 errors, 0 warnings (both CLI and Deployment projects)
  • No old API references remain in test files
  • Behavioral logic, assertions, and test coverage preserved exactly

Copilot AI review requested due to automatic review settings March 14, 2026 04:37
@github-actions
Copy link
Contributor

github-actions bot commented Mar 14, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15244

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 15244"

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Migrates Aspire CLI end-to-end tests from the Hex1bTerminalInputSequenceBuilder fluent/batched API to the Hex1bTerminalAutomator imperative async/await API to improve debuggability and step-level failure reporting.

Changes:

  • Converted a broad set of CLI E2E tests to Hex1bTerminalAutomator (TypeAsync, EnterAsync, WaitUntilAsync, prompt helpers, etc.).
  • Replaced builder callbacks with direct file operations and explicit awaits around terminal steps.
  • Added a new ClearScreenAsync automator helper for consistent screen clearing + prompt synchronization.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptStarterTemplateTests.cs Migrates TypeScript starter template flow to automator API.
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptPolyglotTests.cs Migrates interactive aspire init TypeScript selection + run/stop to automator.
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptCodegenValidationTests.cs Migrates TypeScript restore/codegen validation scenarios to automator, including CI bundle install flow.
tests/Aspire.Cli.EndToEnd.Tests/StopNonInteractiveTests.cs Migrates non-interactive stop scenarios, using new ClearScreenAsync.
tests/Aspire.Cli.EndToEnd.Tests/StartStopTests.cs Migrates start/stop and package-add-while-detached scenarios to automator.
tests/Aspire.Cli.EndToEnd.Tests/StagingChannelTests.cs Migrates config set/get/delete channel flow to automator.
tests/Aspire.Cli.EndToEnd.Tests/SmokeTests.cs Migrates smoke run + regression prompt detection to automator and fail-fast checks.
tests/Aspire.Cli.EndToEnd.Tests/SecretTypeScriptAppHostTests.cs Migrates secret CRUD against TS AppHost to automator.
tests/Aspire.Cli.EndToEnd.Tests/SecretDotNetAppHostTests.cs Migrates secret CRUD against .NET AppHost to automator.
tests/Aspire.Cli.EndToEnd.Tests/PythonReactTemplateTests.cs Migrates Python React template run/stop flow to automator.
tests/Aspire.Cli.EndToEnd.Tests/PsCommandTests.cs Migrates aspire ps table/json validation to automator.
tests/Aspire.Cli.EndToEnd.Tests/ProjectReferenceTests.cs Migrates TypeScript project-reference/codegen scenario to automator.
tests/Aspire.Cli.EndToEnd.Tests/PlaywrightCliInstallTests.cs Migrates agent-init Playwright CLI install + skill file checks to automator.
tests/Aspire.Cli.EndToEnd.Tests/MultipleAppHostTests.cs Migrates detach/json validation scenario to automator.
tests/Aspire.Cli.EndToEnd.Tests/LogsCommandTests.cs Migrates aspire logs file output and JSON validation to automator.
tests/Aspire.Cli.EndToEnd.Tests/KubernetesPublishTests.cs Migrates KinD/Helm publish/deploy workflow to automator while preserving cleanup semantics.
tests/Aspire.Cli.EndToEnd.Tests/JsReactTemplateTests.cs Migrates JS React template run + regression prompt detection to automator.
tests/Aspire.Cli.EndToEnd.Tests/Helpers/CliE2EAutomatorHelpers.cs Adds ClearScreenAsync helper for prompt-synchronized screen clearing.
tests/Aspire.Cli.EndToEnd.Tests/EmptyAppHostTemplateTests.cs Migrates Empty AppHost template creation to automator.
tests/Aspire.Cli.EndToEnd.Tests/DoctorCommandTests.cs Migrates doctor SSL_CERT_DIR trust detection scenarios to automator.
tests/Aspire.Cli.EndToEnd.Tests/DockerDeploymentTests.cs Migrates Docker Compose deploy workflows to automator, including CI install/version verification.
tests/Aspire.Cli.EndToEnd.Tests/DescribeCommandTests.cs Migrates aspire describe scenarios (table/json + replicas) to automator.
tests/Aspire.Cli.EndToEnd.Tests/CertificatesCommandTests.cs Migrates cert trust/clean flows to automator.
tests/Aspire.Cli.EndToEnd.Tests/CentralPackageManagementTests.cs Migrates CPM update/add workflows to automator with direct file validation.
tests/Aspire.Cli.EndToEnd.Tests/BundleSmokeTests.cs Migrates bundle smoke test (detach JSON + curl) to automator.
tests/Aspire.Cli.EndToEnd.Tests/BannerTests.cs Migrates banner tests (sentinel manipulation + pattern assertions) to automator.
tests/Aspire.Cli.EndToEnd.Tests/AgentCommandTests.cs Migrates agent command help/init/doctor tests to automator, replacing builder file helpers with direct IO.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +39 to +48
// PrepareEnvironment
await auto.WaitUntilAsync(s => new CellPatternSearcher().Find("b").RightUntil("$").Right(' ').Right(' ').Search(s).Count > 0, timeout: TimeSpan.FromSeconds(10), description: "waiting for input prompt");
await auto.WaitAsync(500);
const string promptSetup = "CMDCOUNT=0; PROMPT_COMMAND='s=$?;((CMDCOUNT++));PS1=\"[$CMDCOUNT $([ $s -eq 0 ] && echo OK || echo ERR:$s)] \\$ \"'";
await auto.TypeAsync(promptSetup);
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
await auto.TypeAsync($"cd {workspace.WorkspaceRoot.FullName}");
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
Comment on lines +53 to +62
// Prepare environment
await auto.WaitUntilAsync(s => new CellPatternSearcher().Find("b").RightUntil("$").Right(' ').Right(' ').Search(s).Count > 0, timeout: TimeSpan.FromSeconds(10), description: "waiting for input prompt");
await auto.WaitAsync(500);
const string promptSetup = "CMDCOUNT=0; PROMPT_COMMAND='s=$?;((CMDCOUNT++));PS1=\"[$CMDCOUNT $([ $s -eq 0 ] && echo OK || echo ERR:$s)] \\$ \"'";
await auto.TypeAsync(promptSetup);
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
await auto.TypeAsync($"cd {workspace.WorkspaceRoot.FullName}");
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
Comment on lines 139 to 148
await auto.WaitUntilAsync(s => new CellPatternSearcher().Find("b").RightUntil("$").Right(' ').Right(' ').Search(s).Count > 0, timeout: TimeSpan.FromSeconds(10), description: "waiting for input prompt");
await auto.WaitAsync(500);
const string promptSetup = "CMDCOUNT=0; PROMPT_COMMAND='s=$?;((CMDCOUNT++));PS1=\"[$CMDCOUNT $([ $s -eq 0 ] && echo OK || echo ERR:$s)] \\$ \"'";
await auto.TypeAsync(promptSetup);
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
await auto.TypeAsync($"cd {workspace.WorkspaceRoot.FullName}");
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);

Comment on lines +140 to +148
if (!fileContent.Contains("\"mcp\""))
{
throw new InvalidOperationException($"Expected file '{configPath}' to contain '\"mcp\"' but it did not. Content: {fileContent}");
}
fileContent = File.ReadAllText(configPath);
if (!fileContent.Contains("\"start\""))
{
throw new InvalidOperationException($"Expected file '{configPath}' to contain '\"start\"' but it did not. Content: {fileContent}");
}
Comment on lines +194 to +203
// PrepareEnvironment
await auto.WaitUntilAsync(s => new CellPatternSearcher().Find("b").RightUntil("$").Right(' ').Right(' ').Search(s).Count > 0, timeout: TimeSpan.FromSeconds(10), description: "waiting for input prompt");
await auto.WaitAsync(500);
const string promptSetup = "CMDCOUNT=0; PROMPT_COMMAND='s=$?;((CMDCOUNT++));PS1=\"[$CMDCOUNT $([ $s -eq 0 ] && echo OK || echo ERR:$s)] \\$ \"'";
await auto.TypeAsync(promptSetup);
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
await auto.TypeAsync($"cd {workspace.WorkspaceRoot.FullName}");
await auto.EnterAsync();
await auto.WaitForSuccessPromptAsync(counter);
@github-actions
Copy link
Contributor

The transient CI rerun workflow requested reruns for the following jobs after analyzing the failed attempt.
GitHub's job rerun API also reruns dependent jobs, so the retry is being tracked in the rerun attempt.
The job links below point to the failed attempt that matched the retry-safe transient failure rules.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 14, 2026

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit e00a48e:

Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndPublishToKubernetes ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ❌ Upload failed
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ❌ Upload failed
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ❌ Upload failed
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ❌ Upload failed
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RunWithMissingAwaitShowsHelpfulError ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #23133411978

@mitchdenny mitchdenny changed the title Migrate CLI E2E tests to Hex1bTerminalAutomator API Migrate CLI and Deployment E2E tests to Hex1bTerminalAutomator API Mar 14, 2026
@github-actions
Copy link
Contributor

The transient CI rerun workflow requested reruns for the following jobs after analyzing the failed attempt.
GitHub's job rerun API also reruns dependent jobs, so the retry is being tracked in the rerun attempt.
The job links below point to the failed attempt that matched the retry-safe transient failure rules.

@mitchdenny
Copy link
Member Author

Addressed all 5 review comments in commit 66afe30:

  1. PrepareEnvironment duplication (4 comments): Added PrepareEnvironmentAsync, InstallAspireCliFromPullRequestAsync, SourceAspireCliEnvironmentAsync, VerifyAspireCliVersionAsync, InstallAspireBundleFromPullRequestAsync, and SourceAspireBundleEnvironmentAsync to CliE2EAutomatorHelpers. Refactored DockerDeploymentTests, KubernetesPublishTests, and TypeScriptCodegenValidationTests to use these shared helpers.

  2. Assert pattern in AgentCommandTests (1 comment): Replaced File.ReadAllText + throw InvalidOperationException with Assert.Contains / Assert.DoesNotContain.

@github-actions
Copy link
Contributor

The transient CI rerun workflow requested reruns for the following jobs after analyzing the failed attempt.
GitHub's job rerun API also reruns dependent jobs, so the retry is being tracked in the rerun attempt.
The job links below point to the failed attempt that matched the retry-safe transient failure rules.

Mitch Denny and others added 11 commits March 16, 2026 14:56
Convert CreateAndRunAspireStarterProject from Hex1bTerminalInputSequenceBuilder
(fluent builder) to Hex1bTerminalAutomator (async/await imperative) API.

Preserves all test behavior including:
- Regression check for #13971 (unexpected apphost selection prompt)
- Ctrl+C to stop aspire run
- Fail-fast on duplicate apphost detection

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Convert all 4 test methods from Hex1bTerminalInputSequenceBuilder
(fluent builder) to Hex1bTerminalAutomator (async/await imperative) API:
- CreateStartAndStopAspireProject
- StopWithNoRunningAppHostExitsSuccessfully
- AddPackageWhileAppHostRunningDetached
- AddPackageInteractiveWhileAppHostRunningDetached

Key migration notes:
- IncrementSequence(counter) replaced with WaitForAnyPromptAsync(counter)
  for the cleanup stop command where exit code may vary
- All pattern searchers and behavioral logic preserved

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…to automator API

Migrated test files:
- StopNonInteractiveTests (4 methods)
- EmptyAppHostTemplateTests (1 method)
- JsReactTemplateTests (1 method)
- PythonReactTemplateTests (1 method)

Added ClearScreenAsync helper to CliE2EAutomatorHelpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrated test files:
- TypeScriptStarterTemplateTests (1 method) - replaced ExecuteCallback with
  inline assertions (natural in async/await flow)
- BundleSmokeTests (1 method)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrated test files:
- DescribeCommandTests (2 methods)
- PsCommandTests (2 methods)
- LogsCommandTests (1 method)
- MultipleAppHostTests (1 method)
- CentralPackageManagementTests (2 methods)
- SecretDotNetAppHostTests (1 method)
- SecretTypeScriptAppHostTests (1 method)
- AgentCommandTests (4 methods)
- PlaywrightCliInstallTests (1 method)
- DoctorCommandTests (2 methods)
- BannerTests (3 methods)
- CertificatesCommandTests (3 methods)
- DockerDeploymentTests (2 methods)
- KubernetesPublishTests (1 method)
- StagingChannelTests (1 method)
- TypeScriptCodegenValidationTests (2 methods)
- TypeScriptPolyglotTests (1 method)
- ProjectReferenceTests (1 method)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add Hex1bAutomatorTestHelpers.cs link to deployment test project
- Create DeploymentE2EAutomatorHelpers.cs with PrepareEnvironmentAsync,
  InstallAspireCliFromPullRequestAsync, InstallAspireCliReleaseAsync,
  SourceAspireCliEnvironmentAsync
- Migrate AcaStarterDeploymentTests as reference implementation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add PrepareEnvironmentAsync, InstallAspireCliFromPullRequestAsync,
  SourceAspireCliEnvironmentAsync, VerifyAspireCliVersionAsync,
  InstallAspireBundleFromPullRequestAsync, SourceAspireBundleEnvironmentAsync
  to CliE2EAutomatorHelpers
- Replace inlined PrepareEnvironment in DockerDeploymentTests,
  KubernetesPublishTests, TypeScriptCodegenValidationTests with helpers
- Replace File.ReadAllText + throw InvalidOperationException with
  Assert.Contains/Assert.DoesNotContain in AgentCommandTests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…o automator API

Migrated 3 new test files added after the initial migration:
- ConfigHealingTests (1 method)
- ConfigMigrationTests (7 methods, including 1 OuterloopTest)
- TypeScriptPublishTests (1 method)

Added new automator helpers:
- EnablePolyglotSupportAsync (no-op, matching old API)
- InstallAspireCliVersionAsync (downloads specific CLI version)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny mitchdenny force-pushed the e2e-automator-migration branch from 66afe30 to 0df044a Compare March 16, 2026 04:06
Address PR feedback from JamesNK: simplify verbose CellPatternSearcher
patterns by using WaitUntilTextAsync(string) and ContainsText(string)
APIs already available in Hex1b v0.116.0.

Changes across 56 files (30 CLI E2E + 26 Deployment E2E):
- Simple Find patterns: CellPatternSearcher().Find("text") +
  WaitUntilAsync(s => pattern.Search(s).Count > 0) replaced with
  WaitUntilTextAsync("text", timeout)
- Compound predicates: replaced CellPatternSearcher inner expressions
  with s.ContainsText("text") for && and || conditions
- Complex patterns preserved: RightUntil, RightText, FindPattern
  (prompt detection/regex) correctly left unchanged

Net result: -868 lines of boilerplate removed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny
Copy link
Member Author

Addressed James' feedback in e00a48e: replaced all simple CellPatternSearcher().Find() patterns with WaitUntilTextAsync(string text, TimeSpan? timeout) which already exists in Hex1b v0.116.0. Compound predicates now use s.ContainsText() directly. Only kept CellPatternSearcher for ~5 cases needing complex pattern matching (RightUntil, FindPattern).

Net result: -868 lines of boilerplate across 56 files.

@github-actions
Copy link
Contributor

The transient CI rerun workflow requested reruns for the following jobs after analyzing the failed attempt.
GitHub's job rerun API also reruns dependent jobs, so the retry is being tracked in the rerun attempt.
The job links below point to the failed attempt that matched the retry-safe transient failure rules.

@mitchdenny mitchdenny requested a review from JamesNK March 16, 2026 08:19
Copy link
Member

@JamesNK JamesNK left a comment

Choose a reason for hiding this comment

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

If WaitUntilTextAsync creates good error messages on failure then looks good to me.

@mitchdenny mitchdenny merged commit 41b4291 into release/13.2 Mar 16, 2026
500 of 503 checks passed
@mitchdenny mitchdenny deleted the e2e-automator-migration branch March 16, 2026 09:29
@dotnet-policy-service dotnet-policy-service bot added this to the 13.2 milestone Mar 16, 2026
Sign up for free to 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.

3 participants