using System.Diagnostics; using System.Text.RegularExpressions; namespace Tests.Helpers; public static class LocalServer { private static Process? _process; public static string? BaseUrl { get; private set; } public static async Task StartAsync() { if (_process != null) return; var root = FindProjectRoot(); var webProject = Path.Combine(root, "Web"); Console.WriteLine($"[DEBUG_LOG] Starting local server for project: {webProject}"); _process = new Process { StartInfo = new ProcessStartInfo { FileName = "dotnet", Arguments = $"run --project \"{webProject}\" --urls http://127.0.0.1:0", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = root } }; var tcs = new TaskCompletionSource(); _process.OutputDataReceived += (s, e) => { if (string.IsNullOrEmpty(e.Data)) return; Console.WriteLine($"[SERVER] {e.Data}"); var match = Regex.Match(e.Data, @"Now listening on:\s+(http://127.0.0.1:\d+)"); if (match.Success) tcs.TrySetResult(match.Groups[1].Value); }; _process.ErrorDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) Console.Error.WriteLine($"[SERVER ERROR] {e.Data}"); }; _process.Start(); _process.BeginOutputReadLine(); _process.BeginErrorReadLine(); // Wait for the URL to be parsed from output BaseUrl = await Task.WhenAny(tcs.Task, Task.Delay(30000)) == tcs.Task ? tcs.Task.Result : null; if (BaseUrl == null) { Stop(); throw new Exception("Timeout waiting for local server to start and provide a URL."); } Console.WriteLine($"[DEBUG_LOG] Local server started at: {BaseUrl}"); } public static void Stop() { if (_process != null && !_process.HasExited) { Console.WriteLine("[DEBUG_LOG] Stopping local server..."); _process.Kill(true); _process.Dispose(); _process = null; } } private static string FindProjectRoot() { var current = AppDomain.CurrentDomain.BaseDirectory; while (!string.IsNullOrEmpty(current) && !File.Exists(Path.Combine(current, "IGP.sln"))) { var parent = Path.GetDirectoryName(current); if (parent == current) break; current = parent; } if (string.IsNullOrEmpty(current) || !File.Exists(Path.Combine(current, "IGP.sln"))) { // Fallback to searching up from current directory if BaseDirectory fails current = Directory.GetCurrentDirectory(); while (!string.IsNullOrEmpty(current) && !File.Exists(Path.Combine(current, "IGP.sln"))) { var parent = Path.GetDirectoryName(current); if (parent == current) break; current = parent; } } return current ?? throw new Exception("Could not find project root containing IGP.sln"); } }