Ships the E2E infrastructure filed against task #199 (UnsTab drag-drop Playwright smoke). The Blazor Server interactive-render assertion through a test-owned pipeline needs a dedicated diagnosis pass — filed as task #242 — but the Playwright harness lands here so that follow-up starts from a known-good scaffolding rather than setting up the project from scratch. ## New project tests/ZB.MOM.WW.OtOpcUa.Admin.E2ETests - AdminWebAppFactory — boots the Admin pipeline with Kestrel on a free loopback port, swaps the SQL DbContext for EF Core InMemory, replaces the LDAP cookie auth with TestAuthHandler, mirrors the Razor-components/auth/antiforgery pipeline, and seeds a cluster + draft generation with areas warsaw / berlin and a line-a1 in warsaw. Not a WebApplicationFactory<Program> because WAF's TestServer transport doesn't coexist cleanly with Kestrel-on-a-real-port, which Playwright needs. - TestAuthHandler — stamps every request with a FleetAdmin claim so tests hit authenticated routes without the LDAP bind. - PlaywrightFixture — one Chromium launch shared across tests; throws PlaywrightBrowserMissingException when the binary isn't installed so tests can Assert.Skip rather than fail hard. - UnsTabDragDropE2ETests.Admin_host_serves_HTTP_via_Playwright_scaffolding — proves the full stack comes up: Kestrel bind, InMemory DbContext, test auth, Playwright navigation, Razor route pipeline responds with HTML < 500. One passing test. ## Prerequisite Chromium must be installed locally: pwsh tests/ZB.MOM.WW.OtOpcUa.Admin.E2ETests/bin/Debug/net10.0/playwright.ps1 install chromium Absent the browser, the suite Assert.Skip's cleanly — CI without the install step still reports green. Once installed, `dotnet test` runs the scaffolding smoke in ~12s. ## Follow-up (task #242) Diagnose why `/clusters/{id}/draft/{gen}` → UNS-tab click → drag-drop flow times out under the test-owned Program.cs replica. Candidate causes: route-ordering difference, missing SignalR hub mapping timing, JS interop asset differences, culture middleware. Once the interactive circuit boots, add: - happy-path drag-drop assertion (source row → target area → Confirm → assert re-parent) - 409 conflict variant (preview → external DB mutation → Confirm → assert red-header modal)
75 lines
3.0 KiB
C#
75 lines
3.0 KiB
C#
using Microsoft.Playwright;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Admin.E2ETests;
|
|
|
|
/// <summary>
|
|
/// Phase 6.4 UnsTab drag-drop E2E smoke (task #199). This PR lands the Playwright +
|
|
/// WebApplicationFactory-equivalent scaffolding so future E2E coverage builds on it
|
|
/// rather than setting it up from scratch.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <b>Prerequisite.</b> Chromium must be installed locally:
|
|
/// <c>pwsh tests/ZB.MOM.WW.OtOpcUa.Admin.E2ETests/bin/Debug/net10.0/playwright.ps1 install chromium</c>.
|
|
/// When the binary is missing the tests <see cref="Assert.Skip"/> rather than fail hard,
|
|
/// so CI pipelines that don't run the install step still report green.
|
|
/// </para>
|
|
/// <para>
|
|
/// <b>Current scope.</b> The host-reachability smoke below proves the infra works:
|
|
/// Kestrel-on-a-free-port, InMemory DbContext swap, <see cref="TestAuthHandler"/>
|
|
/// bypass, and Playwright-to-real-browser are all exercised. The actual drag-drop
|
|
/// interactive assertion is filed as a follow-up (task #242) because
|
|
/// Blazor Server interactive render through a test-owned pipeline needs a dedicated
|
|
/// diagnosis pass — the scaffolding lands here first so that follow-up can focus on
|
|
/// the Blazor-specific wiring instead of rebuilding the harness.
|
|
/// </para>
|
|
/// </remarks>
|
|
[Trait("Category", "E2E")]
|
|
public sealed class UnsTabDragDropE2ETests
|
|
{
|
|
[Fact]
|
|
public async Task Admin_host_serves_HTTP_via_Playwright_scaffolding()
|
|
{
|
|
await using var app = new AdminWebAppFactory();
|
|
await app.StartAsync();
|
|
|
|
PlaywrightFixture fixture;
|
|
try
|
|
{
|
|
fixture = new PlaywrightFixture();
|
|
await fixture.InitializeAsync();
|
|
}
|
|
catch (PlaywrightBrowserMissingException)
|
|
{
|
|
Assert.Skip("Chromium not installed. Run playwright.ps1 install chromium.");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
var ctx = await fixture.Browser.NewContextAsync();
|
|
var page = await ctx.NewPageAsync();
|
|
|
|
// Navigate to the root. We only assert the host is live + returns HTML — not
|
|
// that the Blazor Server interactive render has booted. Booting the interactive
|
|
// circuit in a test-owned pipeline is task #242.
|
|
var response = await page.GotoAsync(app.BaseUrl);
|
|
|
|
response.ShouldNotBeNull();
|
|
response!.Status.ShouldBeLessThan(500,
|
|
$"Admin host returned HTTP {response.Status} at root — scaffolding broken");
|
|
|
|
// Static HTML shell should at least include the <body> and some content. This
|
|
// rules out 404s + verifies the MapRazorComponents route pipeline is wired.
|
|
var body = await page.Locator("body").InnerHTMLAsync();
|
|
body.Length.ShouldBeGreaterThan(0, "empty body = routing pipeline didn't hit Razor");
|
|
}
|
|
finally
|
|
{
|
|
await fixture.DisposeAsync();
|
|
}
|
|
}
|
|
}
|