Skip to content

Integration test host: clean shutdown and readable output - #323

Open
damyanpetev wants to merge 4 commits into
masterfrom
dpetev/integration-test-logging
Open

Integration test host: clean shutdown and readable output#323
damyanpetev wants to merge 4 commits into
masterfrom
dpetev/integration-test-logging

Conversation

@damyanpetev

Copy link
Copy Markdown
Member

1. Stop the Kestrel host instead of only disposing it

BlazorApplicationFactory.DisposeAsync called host.Dispose() on the Kestrel host. IHost.Dispose() only disposes the service provider — it never calls StopAsync, so ApplicationStopping never fired. That is the event HttpConnectionManager registers CloseConnections on, which is what disconnects live circuits (awaiting each OnDisconnectedAsync) while the container is still alive.

Without it, teardown was a race: closing the browser context returns as soon as the client side is gone, and the server noticed the dead socket whenever it got round to it. If that landed after the provider was disposed, OnDisconnectedAsync failed on a disposed IServiceProvider — the intermittent ObjectDisposedException noise in the logs, which never failed a test because the assertions had already completed.

Teardown now StopAsynces the host before disposing it, and closes the browser context first. BrowserTest closes contexts too, but its TearDown runs after the derived one and only when the test passed, so the close cannot be left to it; CloseAsync is idempotent, so the base closing it again is a no-op.

2. Quieter, test-attributed logging plus per-component coverage

Each test builds two hosts (TestServer + Kestrel) and each logged its full lifetime straight to the console — nine info: lines per test, landing on whichever test the runner was reporting at the time.

  • The host keeps Warning and above only, via PostConfigure<LoggerFilterOptions> (not SetMinimumLevel, which a Default rule in appsettings.json would win over).

  • What survives goes through TestOutputLoggerProvider into the current test's output, with Error and above also written to TestContext.Progress so it surfaces regardless of runner verbosity.

  • The startup details worth having — address, environment, content root — are read off the host and logged once per run.

  • SetComponentType now returns a ComponentRunSummary rather than a bool, so each test reports what it covered:

    [host] listening on http://127.0.0.1:5249/ - environment Development, content root .../IgniteUI.Blazor.Lite.TestBed
    IgbCarousel (igc-carousel): 27 checks - 8 defaults, 11 props, 3 events, 5 methods, 0 server / 0 client templates
    IgbCardContent (igc-card-content): rendered, no members to check
    

The bool that summary replaces was never checked by the test, so a component that never rendered — an unresolvable name, an instance that is not a BaseRendererControl — reported no errors and passed. The summary now carries a Failure string instead, which the test asserts is null, along with a summary having been returned at all. Zero checks is left passing: 13 components are slot-only wrappers (IgbCardContent, IgbNavbar, IgbRipple, the various headers) with no settable API, and the summary line says so.

Copilot AI review requested due to automatic review settings August 7, 2026 14:30
@damyanpetev damyanpetev added the e2e label Aug 7, 2026
Comment thread tests/IgniteUI.Blazor.Lite.IntegrationTests/Infrastructure/BlazorPageTest.cs Dismissed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the Ignite UI Blazor Lite integration test infrastructure by making the test host lifecycle deterministic (clean shutdown of the Kestrel host) and by reducing/attributing host logging to the currently running test. It also enhances component test runs by returning a structured per-component run summary from the TestBed, so tests can report what was exercised and fail when the component didn’t actually render.

Changes:

  • Stop Kestrel via StopAsync during teardown (instead of only disposing) and close the browser context before stopping the host to avoid intermittent SignalR/circuit disposal races.
  • Route host logs into NUnit test output via a custom ILoggerProvider, and describe host startup details once per run.
  • Return a ComponentRunSummary from SetComponentType and surface it through JS + Playwright to report per-component coverage and detect “didn’t render” failures.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/IgniteUI.Blazor.Lite.TestBed/wwwroot/app.js Return the SetComponentType result to the test runner and log it as an object.
tests/IgniteUI.Blazor.Lite.TestBed/Components/Pages/Home.razor Change SetComponentType to return ComponentRunSummary and track counts for exercised members.
tests/IgniteUI.Blazor.Lite.TestBed/Components/Common/ComponentRunSummary.cs New DTO summarizing what a component run checked, including failure reason when it didn’t reach rendering.
tests/IgniteUI.Blazor.Lite.IntegrationTests/Infrastructure/TestOutputLoggerProvider.cs New logger provider to route host logs into per-test output (and progress for errors).
tests/IgniteUI.Blazor.Lite.IntegrationTests/Infrastructure/BlazorPageTest.cs Close browser context earlier in teardown and log host description once per run.
tests/IgniteUI.Blazor.Lite.IntegrationTests/Infrastructure/BlazorApplicationFactory.cs Configure host logging and stop Kestrel host during disposal before disposing services.
tests/IgniteUI.Blazor.Lite.IntegrationTests/ComponentTest.cs Consume and assert ComponentRunSummary, and print a readable per-component summary line.

Comment on lines +57 to +60
if (Context != null)
{
await Context.CloseAsync().ConfigureAwait(false);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope

@damyanpetev
damyanpetev force-pushed the dpetev/integration-test-logging branch from 625fb0b to 15632f1 Compare August 7, 2026 15:03
@damyanpetev
damyanpetev requested a review from MayaKirova August 7, 2026 15:03
@damyanpetev
damyanpetev enabled auto-merge (rebase) August 7, 2026 15:03
damyanpetev and others added 2 commits August 7, 2026 18:14
GetComponentByType prefixed the incoming name with Igb, but the names from
TestUtil already carry it, so every lookup missed and each test bailed out
before rendering anything. Dropping the prefix here rather than stripping it
in TestUtil keeps the componentsConfig.json keys matching.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants