@@ -20,7 +20,7 @@ public sealed class E2ETestContext : IAsyncDisposable
2020
2121 public string HomeDir { get ; }
2222 public string WorkDir { get ; }
23- public string ProxyUrl { get ; }
23+ public string ProxyUrl { get ; private set ; }
2424 internal static bool UsesInProcessTransport => IsInProcess ( null ) ;
2525
2626 /// <summary>Optional logger injected by tests; applied to all clients created via <see cref="CreateClient"/>.</summary>
@@ -47,7 +47,12 @@ private E2ETestContext(string homeDir, string workDir, string proxyUrl, ReplayPr
4747 _legacyCliPath = GetCachedCliPath ( repoRoot , "--print-legacy-path" ) ;
4848 }
4949
50- public static async Task < E2ETestContext > CreateAsync ( )
50+ public static Task < E2ETestContext > CreateAsync ( ) => CreateAsync (
51+ new ReplayProxy ( ) ,
52+ Path . Combine ( Path . GetTempPath ( ) , $ "copilot-test-config-{ Guid . NewGuid ( ) } ") ,
53+ Path . Combine ( Path . GetTempPath ( ) , $ "copilot-test-work-{ Guid . NewGuid ( ) } ") ) ;
54+
55+ internal static async Task < E2ETestContext > CreateAsync ( ReplayProxy proxy , string homeDir , string workDir )
5156 {
5257 // A previous in-process context may have left this process's cwd inside a work
5358 // directory that has since been deleted. getcwd() then fails, which breaks
@@ -57,33 +62,45 @@ public static async Task<E2ETestContext> CreateAsync()
5762
5863 var repoRoot = FindRepoRoot ( ) ;
5964
60- var homeDir = Path . Combine ( Path . GetTempPath ( ) , $ "copilot-test-config-{ Guid . NewGuid ( ) } ") ;
61- var workDir = Path . Combine ( Path . GetTempPath ( ) , $ "copilot-test-work-{ Guid . NewGuid ( ) } ") ;
62-
63- Directory . CreateDirectory ( homeDir ) ;
64- Directory . CreateDirectory ( workDir ) ;
65-
6665 // Resolve symlinks (e.g., macOS /var -> /private/var) so paths
6766 // match what spawned subprocesses see when they resolve their cwd.
6867 homeDir = ResolveSymlinks ( homeDir ) ;
6968 workDir = ResolveSymlinks ( workDir ) ;
7069
71- var proxy = new ReplayProxy ( ) ;
72- var proxyUrl = await proxy . StartAsync ( ) ;
73- // Creating an in-process fixture applies this URL before its first
74- // test-specific configuration is posted, so early runtime requests need
75- // an empty but valid replay state.
76- await proxy . ConfigureAsync (
77- Path . Combine ( workDir , "__unconfigured__.yaml" ) ,
78- workDir ,
79- "capi" ) ;
80- await proxy . SetCopilotUserByTokenAsync ( DefaultGitHubToken , new CopilotUserConfig (
81- Login : "e2e-test-user" ,
82- CopilotPlan : "individual_pro" ,
83- Endpoints : new CopilotUserEndpoints ( Api : proxyUrl , Telemetry : "https://localhost:1/telemetry" ) ,
84- AnalyticsTrackingId : "e2e-test-tracking-id" , Id : 12345 ) ) ;
85-
86- return new E2ETestContext ( homeDir , workDir , proxyUrl , proxy , repoRoot ) ;
70+ var context = new E2ETestContext ( homeDir , workDir , string . Empty , proxy , repoRoot ) ;
71+ try
72+ {
73+ Directory . CreateDirectory ( homeDir ) ;
74+ Directory . CreateDirectory ( workDir ) ;
75+
76+ context . ProxyUrl = await proxy . StartAsync ( ) ;
77+ // Creating an in-process fixture applies this URL before its first
78+ // test-specific configuration is posted, so early runtime requests need
79+ // an empty but valid replay state.
80+ await proxy . ConfigureAsync (
81+ Path . Combine ( workDir , "__unconfigured__.yaml" ) ,
82+ workDir ,
83+ "capi" ) ;
84+ await proxy . SetCopilotUserByTokenAsync ( DefaultGitHubToken , new CopilotUserConfig (
85+ Login : "e2e-test-user" ,
86+ CopilotPlan : "individual_pro" ,
87+ Endpoints : new CopilotUserEndpoints ( Api : context . ProxyUrl , Telemetry : "https://localhost:1/telemetry" ) ,
88+ AnalyticsTrackingId : "e2e-test-tracking-id" , Id : 12345 ) ) ;
89+
90+ return context ;
91+ }
92+ catch ( Exception startupError )
93+ {
94+ try
95+ {
96+ await context . DisposeAsync ( ) ;
97+ }
98+ catch ( Exception cleanupError )
99+ {
100+ throw new AggregateException ( startupError , cleanupError ) ;
101+ }
102+ throw ;
103+ }
87104 }
88105
89106 /// <summary>
0 commit comments