Task #242 finish — UnsTab drag-drop interactive Playwright E2E tests un-skip + pass
Closes the scope-out left by the #242 partial. Root cause of the blazor.web.js zero-byte response turned out to be two co-operating harness bugs: 1) The static-asset manifest was discoverable but the runtime needs UseStaticWebAssets to be called so the StaticWebAssetsLoader composes a PhysicalFileProvider per ContentRoot declared in staticwebassets.development.json (Admin source wwwroot + obj/compressed + the framework NuGet cache). Without that call MapStaticAssets resolves the route but has no ContentRoot map — so every asset serves zero bytes. 2) The EF InMemory DB name was being re-generated on every DbContext construction (the lambda body called Guid.NewGuid() inline), so the seed scope, Blazor circuit scope, and test-assertion scopes all got separate stores. Capturing the name as a stable string per fixture instance fixes the "cluster not found → page stays at Loading…" symptom. Fixes: - AdminWebAppFactory: * ApplicationName set on WebApplicationOptions so UseStaticWebAssets discovers the manifest. * builder.WebHost.UseStaticWebAssets() wired explicitly (matches what `dotnet run` does via MSBuild targets). * dbName captured once per fixture; the options lambda reads the captured string instead of re-rolling a Guid. - UnsTabDragDropE2ETests: the two [Fact(Skip=...)] tests un-skip. Suite state: 3 passed, 0 skipped, 0 failed. Task #242 closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,18 +47,25 @@ public sealed class AdminWebAppFactory : IAsyncDisposable
|
||||
var port = GetFreeTcpPort();
|
||||
BaseUrl = $"http://127.0.0.1:{port}";
|
||||
|
||||
// Point the content root at the Admin project's build output so wwwroot/ (app.css,
|
||||
// site CSS, icons) + the Blazor framework assets served from the Admin assembly
|
||||
// resolve. Without this the default content root is the test project's bin dir and
|
||||
// blazor.web.js + app.css return 404, which keeps the interactive circuit from
|
||||
// booting at all.
|
||||
// Point the content root at the Admin project's build output so the Admin
|
||||
// assembly + its sibling staticwebassets manifest are discoverable. The manifest
|
||||
// maps /_framework/* to the framework NuGet cache + /app.css to the Admin source
|
||||
// wwwroot; StaticWebAssetsLoader.UseStaticWebAssets reads it and wires a composite
|
||||
// file provider automatically.
|
||||
var adminAssemblyDir = System.IO.Path.GetDirectoryName(
|
||||
typeof(Admin.Components.App).Assembly.Location)!;
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
ContentRootPath = adminAssemblyDir,
|
||||
ApplicationName = typeof(Admin.Components.App).Assembly.GetName().Name,
|
||||
});
|
||||
builder.WebHost.UseUrls(BaseUrl);
|
||||
// UseStaticWebAssets reads {ApplicationName}.staticwebassets.runtime.json (or the
|
||||
// development variant via the ASPNETCORE_HOSTINGSTARTUPASSEMBLIES convention) and
|
||||
// composes a PhysicalFileProvider per declared ContentRoot. This is what
|
||||
// `dotnet run` does automatically via the MSBuild targets — we replicate it
|
||||
// explicitly for the test-owned pipeline.
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
// E2E host runs in Development so unhandled exceptions during Blazor render surface
|
||||
// as visible 500s with stacks the test can capture — prod-style generic errors make
|
||||
// diagnosis of circuit / DI misconfig effectively impossible.
|
||||
@@ -78,8 +85,13 @@ public sealed class AdminWebAppFactory : IAsyncDisposable
|
||||
.AddPolicy("CanPublish", p => p.RequireRole(Admin.Services.AdminRoles.FleetAdmin));
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
|
||||
// One InMemory database name per fixture — the lambda below runs on every DbContext
|
||||
// construction, so capturing a stable string (not calling Guid.NewGuid() inline) is
|
||||
// critical: every scope (seed, Blazor circuit, test assertions) must share the same
|
||||
// backing store or rows written in one scope disappear in the next.
|
||||
var dbName = $"e2e-{Guid.NewGuid():N}";
|
||||
builder.Services.AddDbContext<OtOpcUaConfigDbContext>(opt =>
|
||||
opt.UseInMemoryDatabase($"e2e-{Guid.NewGuid():N}"));
|
||||
opt.UseInMemoryDatabase(dbName));
|
||||
|
||||
builder.Services.AddScoped<Admin.Services.ClusterService>();
|
||||
builder.Services.AddScoped<Admin.Services.GenerationService>();
|
||||
|
||||
Reference in New Issue
Block a user