- Fix arrow selection line count calculation (overcounted by 1 due to trailing newline, causing progressive line truncation on each redraw) - Replace sync Loreline bridge with queue-based async pattern to avoid "Cannot wait on monitors" WASM deadlock - Add bounded input buffer (8 keys, DropOldest) to prevent held-key accumulation - Set Spectre.Console Profile.Height on all AnsiConsole.Create calls to prevent PlatformNotSupportedException on Console.WindowHeight - Add explicit Loreline.dll reference + TrimmerRootAssembly for WASM - Use MSBuild CopyGameContent target instead of Content/Link for static file serving in Blazor WASM - Add WASM guards for file I/O in ContentRegistry, LocalizationManager, AdventureEngine - Enforce min 120x30 terminal dimensions in xterm.js - Add Playwright E2E tests (6 tests: page load, language selection, full flow, multi-box progression, extended play, adventure)
82 lines
2.6 KiB
C#
82 lines
2.6 KiB
C#
using System.Diagnostics;
|
|
using Microsoft.Playwright;
|
|
|
|
namespace OpenTheBox.Web.Tests;
|
|
|
|
/// <summary>
|
|
/// Shared fixture that starts the Blazor WASM dev server and Playwright browser once per test collection.
|
|
/// </summary>
|
|
public class WebAppFixture : IAsyncLifetime
|
|
{
|
|
private Process? _serverProcess;
|
|
public IBrowser Browser { get; private set; } = null!;
|
|
public IPlaywright Playwright { get; private set; } = null!;
|
|
public string BaseUrl { get; private set; } = "http://localhost:5280";
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
// Start the Blazor WASM dev server
|
|
_serverProcess = new Process
|
|
{
|
|
StartInfo = new ProcessStartInfo
|
|
{
|
|
FileName = "dotnet",
|
|
Arguments = $"run --project src/OpenTheBox.Web --urls {BaseUrl}",
|
|
WorkingDirectory = FindSolutionRoot(),
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true
|
|
}
|
|
};
|
|
_serverProcess.Start();
|
|
|
|
// Wait for the server to be ready (try connecting)
|
|
using var httpClient = new HttpClient();
|
|
for (int i = 0; i < 120; i++) // up to 2 minutes for WASM compilation
|
|
{
|
|
try
|
|
{
|
|
var response = await httpClient.GetAsync(BaseUrl);
|
|
if (response.IsSuccessStatusCode) break;
|
|
}
|
|
catch { }
|
|
await Task.Delay(1000);
|
|
}
|
|
|
|
// Initialize Playwright
|
|
Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
|
|
Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
|
|
{
|
|
Headless = true,
|
|
Args = ["--window-size=1400,900"]
|
|
});
|
|
}
|
|
|
|
public async Task DisposeAsync()
|
|
{
|
|
await Browser.DisposeAsync();
|
|
Playwright.Dispose();
|
|
|
|
if (_serverProcess is { HasExited: false })
|
|
{
|
|
_serverProcess.Kill(entireProcessTree: true);
|
|
_serverProcess.Dispose();
|
|
}
|
|
}
|
|
|
|
private static string FindSolutionRoot()
|
|
{
|
|
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (dir != null)
|
|
{
|
|
if (dir.GetFiles("OpenTheBox.slnx").Length > 0)
|
|
return dir.FullName;
|
|
dir = dir.Parent;
|
|
}
|
|
throw new InvalidOperationException("Could not find solution root (OpenTheBox.slnx)");
|
|
}
|
|
}
|
|
|
|
[CollectionDefinition("WebApp")]
|
|
public class WebAppCollection : ICollectionFixture<WebAppFixture>;
|