diff --git a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
index 312e95ec8e..e6f738b965 100644
--- a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
+++ b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
@@ -271,17 +271,19 @@ private async ValueTask LoadLogsAsync()
}
else
{
- Logger.LogDebug("Subscribing to console logs for resource {ResourceName}.", PageViewModel.SelectedResource.Name);
+ var resourceSubscriptionName = PageViewModel.SelectedResource.Name;
+
+ Logger.LogDebug("Subscribing to console logs for resource {ResourceName}.", resourceSubscriptionName);
var cancellationToken = await _logSubscriptionCancellationSeries.NextAsync();
- var subscription = DashboardClient.SubscribeConsoleLogs(PageViewModel.SelectedResource.Name, cancellationToken);
+ var subscription = DashboardClient.SubscribeConsoleLogs(resourceSubscriptionName, cancellationToken);
if (subscription is not null)
{
- var task = _logViewer.SetLogSourceAsync(PageViewModel.SelectedResource.Name, subscription);
+ var task = _logViewer.SetLogSourceAsync(resourceSubscriptionName, subscription);
- _subscriptionResourceName = PageViewModel.SelectedResource.Name;
+ _subscriptionResourceName = resourceSubscriptionName;
PageViewModel.Status = Loc[nameof(Dashboard.Resources.ConsoleLogs.ConsoleLogsWatchingLogs)];
_ = Task.Run(async () =>
@@ -292,6 +294,8 @@ private async ValueTask LoadLogsAsync()
}
finally
{
+ Logger.LogDebug("Finished watching logs for resource {ResourceName}.", resourceSubscriptionName);
+
_subscriptionResourceName = null;
PageViewModel.Status = Loc[nameof(Dashboard.Resources.ConsoleLogs.ConsoleLogsFinishedWatchingLogs)];
}
diff --git a/tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj b/tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj
index cb7824b084..7774f04878 100644
--- a/tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj
+++ b/tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj
@@ -16,6 +16,7 @@
+
diff --git a/tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs b/tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs
index 3a77ca1ad5..b7b617b394 100644
--- a/tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs
+++ b/tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs
@@ -12,15 +12,24 @@
using Google.Protobuf.WellKnownTypes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.FluentUI.AspNetCore.Components;
using Xunit;
+using Xunit.Abstractions;
namespace Aspire.Dashboard.Components.Tests.Pages;
[UseCulture("en-US")]
public partial class ConsoleLogsTests : TestContext
{
+ private readonly ITestOutputHelper _testOutputHelper;
+
+ public ConsoleLogsTests(ITestOutputHelper testOutputHelper)
+ {
+ _testOutputHelper = testOutputHelper;
+ }
+
[Fact]
public void ResourceName_MultiRender_SubscribeConsoleLogsOnce()
{
@@ -51,6 +60,7 @@ public void ResourceName_MultiRender_SubscribeConsoleLogsOnce()
});
var instance = cut.Instance;
+ var logger = Services.GetRequiredService>();
var testResource = CreateResourceViewModel("test-resource", KnownResourceState.Running);
resourceChannel.Writer.TryWrite([
@@ -58,17 +68,16 @@ public void ResourceName_MultiRender_SubscribeConsoleLogsOnce()
]);
// Assert
+ logger.LogInformation("Waiting for selected resource.");
cut.WaitForState(() => instance.PageViewModel.SelectedResource == testResource);
- viewport = new ViewportInformation(IsDesktop: false, IsUltraLowHeight: false, IsUltraLowWidth: false);
- dimensionManager.InvokeOnViewportInformationChanged(viewport);
-
- // Re-invoke
+ // Ensure component is rendered again.
cut.SetParametersAndRender(builder => { });
consoleLogsChannel.Writer.TryWrite([new ResourceLogLine(1, "Test content", IsErrorMessage: false)]);
consoleLogsChannel.Writer.Complete();
+ logger.LogInformation("Waiting for finish message.");
var loc = Services.GetRequiredService>();
cut.WaitForState(() => instance.PageViewModel.Status == loc[nameof(Resources.ConsoleLogs.ConsoleLogsFinishedWatchingLogs)]);
@@ -96,7 +105,10 @@ private void SetupConsoleLogsServices(TestDashboardClient? dashboardClient = nul
JSInterop.SetupVoid("initializeContinuousScroll");
JSInterop.SetupVoid("resetContinuousScrollPosition");
+ var loggerFactory = IntegrationTestHelpers.CreateLoggerFactory(_testOutputHelper);
+
Services.AddLocalization();
+ Services.AddSingleton(loggerFactory);
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton>(Options.Create(new DashboardOptions()));
diff --git a/tests/Aspire.Dashboard.Components.Tests/Shared/IntegrationTestHelpers.cs b/tests/Aspire.Dashboard.Components.Tests/Shared/IntegrationTestHelpers.cs
new file mode 100644
index 0000000000..f4e318bdef
--- /dev/null
+++ b/tests/Aspire.Dashboard.Components.Tests/Shared/IntegrationTestHelpers.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Testing;
+using Xunit.Abstractions;
+
+namespace Aspire.Dashboard.Components.Tests.Shared;
+
+public static class IntegrationTestHelpers
+{
+ public static ILoggerFactory CreateLoggerFactory(ITestOutputHelper testOutputHelper, ITestSink? testSink = null)
+ {
+ return LoggerFactory.Create(builder =>
+ {
+ builder.AddXunit(testOutputHelper, LogLevel.Trace, DateTimeOffset.UtcNow);
+ builder.SetMinimumLevel(LogLevel.Trace);
+ if (testSink != null)
+ {
+ builder.AddProvider(new TestLoggerProvider(testSink));
+ }
+ });
+ }
+}