Basics Done
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Enciphered.Blazor.UIComponents.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Launches the demo Blazor app as a separate process on a random free port.
|
||||
/// Shared across all tests in the assembly via [SetUpFixture].
|
||||
/// </summary>
|
||||
public sealed class DemoServerFixture : IDisposable
|
||||
{
|
||||
private Process? _process;
|
||||
|
||||
public string BaseUrl { get; private set; } = string.Empty;
|
||||
|
||||
public async Task StartAsync()
|
||||
{
|
||||
var port = GetFreePort();
|
||||
BaseUrl = $"http://localhost:{port}";
|
||||
|
||||
// Resolve the demo project directory (navigate up from test bin output)
|
||||
var testDir = AppContext.BaseDirectory; // …Tests/bin/Debug/net9.0
|
||||
var solutionRoot = Path.GetFullPath(Path.Combine(testDir, "..", "..", "..", ".."));
|
||||
var demoProjectDir = Path.Combine(solutionRoot, "Enciphered.Blazor.UIComponents.Demo");
|
||||
|
||||
if (!Directory.Exists(demoProjectDir))
|
||||
throw new DirectoryNotFoundException($"Demo project not found at: {demoProjectDir}");
|
||||
|
||||
_process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "dotnet",
|
||||
Arguments = $"run --no-build --urls {BaseUrl}",
|
||||
WorkingDirectory = demoProjectDir,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
Environment =
|
||||
{
|
||||
["ASPNETCORE_ENVIRONMENT"] = "Development",
|
||||
["DOTNET_NOLOGO"] = "1"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_process.Start();
|
||||
|
||||
// Wait for the server to be ready by polling the URL
|
||||
using var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(2) };
|
||||
var deadline = DateTime.UtcNow.AddSeconds(30);
|
||||
|
||||
while (DateTime.UtcNow < deadline)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await httpClient.GetAsync(BaseUrl);
|
||||
if (response.IsSuccessStatusCode)
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Server not ready yet
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
throw new TimeoutException($"Demo server did not start within 30 seconds at {BaseUrl}");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_process is not null && !_process.HasExited)
|
||||
{
|
||||
_process.Kill(entireProcessTree: true);
|
||||
_process.WaitForExit(5000);
|
||||
_process.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetFreePort()
|
||||
{
|
||||
using var listener = new TcpListener(IPAddress.Loopback, 0);
|
||||
listener.Start();
|
||||
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||
listener.Stop();
|
||||
return port;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user