diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/AppHostTestFixture.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/AppHostTestFixture.cs index c98f0ddf56..9046fd1b33 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/AppHostTestFixture.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/AppHostTestFixture.cs @@ -10,15 +10,19 @@ public async Task ConfigureAsync( string[]? args = null, Action? configureBuilder = null) where TEntryPoint : class { + if (App is not null) + { + return App; + } + var builder = await DistributedApplicationTestingBuilder.CreateAsync( args: args ?? [], configureBuilder: static (options, _) => { options.DisableDashboard = false; + options.AllowUnsecuredTransport = true; }); - builder.Configuration["ASPIRE_ALLOW_UNSECURED_TRANSPORT"] = "true"; - configureBuilder?.Invoke(builder); App = await builder.BuildAsync(); diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/CaptureImages.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/CaptureImages.cs index 013a0bee57..c1e458f864 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/CaptureImages.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/CaptureImages.cs @@ -186,23 +186,25 @@ await InteractWithPageAsync(async page => // Login to the dashboard await page.LoginAndWaitForRunningResourcesAsync(DashboardLoginToken); - var apiEllipsisButton = FluentDataGridSelector.Grid.Body.Row(3).Cell(6) - .Descendant("fluent-button:nth-of-type(3)"); - await page.ClickAsync(apiEllipsisButton); + await page.ClickAsync(FluentDataGridSelector.Grid.Body.Row(3).Cell(6) + .Descendant("fluent-button:nth-of-type(3)")); await page.HighlightElementAsync("fluent-anchored-region"); await page.SaveExploreScreenshotAsync("resource-actions.png"); await page.ClickAsync(DashboardSelectors.ResourcePage.ViewDetailsOption); - await page.ClickAsync(DashboardSelectors.ResourcePage.SplitPanel); + //await page.ClickAsync(DashboardSelectors.ResourcePage.SplitPanel); - await page.AdjustSplitPanelsGridTemplateAsync(); - await page.ClickAndDragShadowRootElementAsync( - DashboardSelectors.SplitPanels, DashboardSelectors.MedianId, (0, 20)); + //await page.AdjustSplitPanelsGridTemplateAsync(); + //await page.ClickAndDragShadowRootElementAsync( + // DashboardSelectors.SplitPanels, DashboardSelectors.MedianId, (0, 20)); await page.RedactElementTextAsync(DashboardSelectors.ResourcePage.ResourceDetailsProjectPath); - await page.ClickAsync(apiEllipsisButton); + var apiEllipsisButton = FluentDataGridSelector.Grid.Body.Row(3).Cell(4) + .Descendant("fluent-button"); + + await page.ClickAsync(apiEllipsisButton, new() { Force = true }); await page.HoverAsync(DashboardSelectors.ResourcePage.ViewDetailsOption); await page.HighlightElementAsync(DashboardSelectors.ResourcePage.ViewDetailsOption); @@ -258,7 +260,7 @@ await InteractWithPageAsync(async page => [Fact, Trait("Capture", "resource-errors")] public async Task CaptureResourcesWithErrorsImages() { - await ConfigureAsync([ "API_THROWS_EXCEPTION=true" ]); + await ConfigureAsync(["API_THROWS_EXCEPTION=true"]); await InteractWithPageAsync(async page => { @@ -447,7 +449,7 @@ await InteractWithPageAsync(async page => // Delay beyond output cache, and invalidate then reload. await Task.Delay(2_250); - await webPage.ReloadAsync(); + await webPage.ReloadAsync(new() { WaitUntil = WaitUntilState.NetworkIdle }); await page.BringToFrontAsync(); diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/DashboardSelectors.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/DashboardSelectors.cs index 3ca209b51e..ee9fdee2af 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/DashboardSelectors.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/DashboardSelectors.cs @@ -64,6 +64,6 @@ internal static class ResourcePage public const string StartResource = """fluent-button[title="Start resource"]"""; public const string SplitPanel = """fluent-button[title="Split horizontal"]"""; - public const string ResourceDetailsProjectPath = """fluent-accordion-item [title^="C:"]:last-of-type"""; + public const string ResourceDetailsProjectPath = """fluent-accordion-item [title^="C:"]:last-of-type, fluent-accordion-item [title^="E:"]:last-of-type"""; } } diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/Extensions/PageExtensions.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/Extensions/PageExtensions.cs index d55bb44824..dda8796e9f 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/Extensions/PageExtensions.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/Extensions/PageExtensions.cs @@ -147,7 +147,8 @@ await page.EvaluateAsync($$""" public static async Task LoginAsync(this IPage page, string token) { - var response = await page.GotoAsync($"/login?t={token}"); + var response = await page.GotoAsync( + $"/login?t={token}", new() { WaitUntil = WaitUntilState.NetworkIdle }); Assert.NotNull(response); Assert.True(response.Ok, $"Failed to navigate to login page: {response.Status}"); diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/FluentDataGridSelector.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/FluentDataGridSelector.cs index 0832a70f64..b8482d68db 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/FluentDataGridSelector.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/FluentDataGridSelector.cs @@ -1,5 +1,7 @@ -namespace Aspire.Dashboard.ScreenCapture; + +namespace Aspire.Dashboard.ScreenCapture; +[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")] public class FluentDataGridSelector(string initialSelector) { private readonly StringBuilder _selector = new(initialSelector); @@ -46,4 +48,6 @@ public FluentDataGridSelector Descendant(string selector) public static implicit operator string(FluentDataGridSelector fluentDataGridSelector) => fluentDataGridSelector.ToString(); + + private string GetDebuggerDisplay() => ToString(); } diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightFixture.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightFixture.cs index 7d17db62cb..191d0e90e9 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightFixture.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightFixture.cs @@ -11,7 +11,7 @@ public class PlaywrightFixture : IAsyncLifetime public async Task InitializeAsync() { - Assertions.SetDefaultExpectTimeout(10_000); + Assertions.SetDefaultExpectTimeout(30_000); _playwright = await Playwright.CreateAsync(); diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightTestsBase.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightTestsBase.cs index e598998daf..39484cadc1 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightTestsBase.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/Aspire.Dashboard.ScreenCapture/PlaywrightTestsBase.cs @@ -1,4 +1,9 @@ -namespace Aspire.Dashboard.ScreenCapture; +using Aspire.Hosting.ApplicationModel; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.Extensions.DependencyInjection; + +namespace Aspire.Dashboard.ScreenCapture; public class PlaywrightTestsBase(AppHostTestFixture appHostTestFixture) : IClassFixture, IAsyncDisposable @@ -6,25 +11,44 @@ public class PlaywrightTestsBase(AppHostTestFixture app { public AppHostTestFixture AppHostTestFixture { get; } = appHostTestFixture; public PlaywrightFixture PlaywrightFixture { get; } = appHostTestFixture.PlaywrightFixture; - public string? DashboardUrl { get; private set; } + public string? DashboardUrl { get; internal set; } public string DashboardLoginToken { get; private set; } = ""; private IBrowserContext? _context; - public Task ConfigureAsync( + public async Task ConfigureAsync( string[]? args = null, - Action? configureBuilder = null) where TEntryPoint : class => - AppHostTestFixture.ConfigureAsync(args, builder => + Action? configureBuilder = null) where TEntryPoint : class + { + var app = await AppHostTestFixture.ConfigureAsync(args, builder => { - var aspNetCoreUrls = builder.Configuration["ASPNETCORE_URLS"]; - var urls = aspNetCoreUrls is not null ? aspNetCoreUrls.Split(";") : []; - - DashboardUrl = urls.FirstOrDefault(); DashboardLoginToken = builder.Configuration["AppHost:BrowserToken"] ?? ""; + builder.Eventing.Subscribe((@event, _) => + { + if (@event.Resource.TryGetUrls(out var urls)) + { + DashboardUrl = urls.FirstOrDefault()?.ToString() ?? ""; + } + + return Task.CompletedTask; + }); + configureBuilder?.Invoke(builder); }); + var server = app.Services.GetRequiredService(); + var addresses = server.Features.Get()?.Addresses; + if (addresses is not null) + { + + } + var hostUrl = app.GetEndpoint("aspire-dashboard"); + DashboardUrl = hostUrl.ToString(); + + return app; + } + public async Task InteractWithPageAsync(Func test, ViewportSize? size = null) { var page = await CreateNewPageAsync(size); @@ -33,6 +57,12 @@ public async Task InteractWithPageAsync(Func test, ViewportSize? si { await test(page); } + catch (Exception ex) + { + Console.Error.WriteLine($"Error during test interaction: {ex.Message}"); + + throw; + } finally { await page.CloseAsync(); diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.ApiService/Program.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.ApiService/Program.cs index 1b1c2c80d4..c9ff78986e 100644 --- a/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.ApiService/Program.cs +++ b/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.ApiService/Program.cs @@ -23,7 +23,7 @@ app.MapGet("/weatherforecast", () => { - if (builder.Configuration.GetValue("THROW_EXCEPTION")) + if (builder.Configuration.GetValue("THROW_EXCEPTION", false)) { throw new ApplicationException("Error processing request"); } diff --git a/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.AppHost/Program.cs b/docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.AppHost/AppHost.cs similarity index 100% rename from docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.AppHost/Program.cs rename to docs/fundamentals/dashboard/automation/aspire-dashboard/AspireSample/AspireSample.AppHost/AppHost.cs diff --git a/docs/fundamentals/dashboard/media/explore/dashboard-help.png b/docs/fundamentals/dashboard/media/explore/dashboard-help.png index 15667fb95a..729d6a4e65 100644 Binary files a/docs/fundamentals/dashboard/media/explore/dashboard-help.png and b/docs/fundamentals/dashboard/media/explore/dashboard-help.png differ diff --git a/docs/fundamentals/dashboard/media/explore/project-graphs.png b/docs/fundamentals/dashboard/media/explore/project-graphs.png index 481f71a309..72a2503de8 100644 Binary files a/docs/fundamentals/dashboard/media/explore/project-graphs.png and b/docs/fundamentals/dashboard/media/explore/project-graphs.png differ diff --git a/docs/fundamentals/dashboard/media/explore/project-logs-error.png b/docs/fundamentals/dashboard/media/explore/project-logs-error.png index 15f75686e2..e9c1b4e5b6 100644 Binary files a/docs/fundamentals/dashboard/media/explore/project-logs-error.png and b/docs/fundamentals/dashboard/media/explore/project-logs-error.png differ diff --git a/docs/fundamentals/dashboard/media/explore/projects.png b/docs/fundamentals/dashboard/media/explore/projects.png index 7ff84fef8e..7aa0247653 100644 Binary files a/docs/fundamentals/dashboard/media/explore/projects.png and b/docs/fundamentals/dashboard/media/explore/projects.png differ diff --git a/docs/fundamentals/dashboard/media/explore/resource-actions.png b/docs/fundamentals/dashboard/media/explore/resource-actions.png index 6d95930dc6..b6f8b65c00 100644 Binary files a/docs/fundamentals/dashboard/media/explore/resource-actions.png and b/docs/fundamentals/dashboard/media/explore/resource-actions.png differ diff --git a/docs/fundamentals/dashboard/media/explore/resource-details.png b/docs/fundamentals/dashboard/media/explore/resource-details.png index 1e20d3a409..b5ecfb7b2c 100644 Binary files a/docs/fundamentals/dashboard/media/explore/resource-details.png and b/docs/fundamentals/dashboard/media/explore/resource-details.png differ diff --git a/docs/fundamentals/dashboard/media/explore/resource-started-action.png b/docs/fundamentals/dashboard/media/explore/resource-started-action.png index 1f62d0718a..b547b3e6c0 100644 Binary files a/docs/fundamentals/dashboard/media/explore/resource-started-action.png and b/docs/fundamentals/dashboard/media/explore/resource-started-action.png differ diff --git a/docs/fundamentals/dashboard/media/explore/resource-stop-action.png b/docs/fundamentals/dashboard/media/explore/resource-stop-action.png index 0f0cdf24dc..5e3e90c400 100644 Binary files a/docs/fundamentals/dashboard/media/explore/resource-stop-action.png and b/docs/fundamentals/dashboard/media/explore/resource-stop-action.png differ diff --git a/docs/fundamentals/dashboard/media/explore/resource-stopped-action.png b/docs/fundamentals/dashboard/media/explore/resource-stopped-action.png index 588418adfd..f5286cdf5d 100644 Binary files a/docs/fundamentals/dashboard/media/explore/resource-stopped-action.png and b/docs/fundamentals/dashboard/media/explore/resource-stopped-action.png differ diff --git a/docs/fundamentals/dashboard/media/explore/select-resource-type.png b/docs/fundamentals/dashboard/media/explore/select-resource-type.png index 7a4fedc3e3..8c006daa94 100644 Binary files a/docs/fundamentals/dashboard/media/explore/select-resource-type.png and b/docs/fundamentals/dashboard/media/explore/select-resource-type.png differ diff --git a/docs/fundamentals/dashboard/media/explore/structured-logs-filtered.png b/docs/fundamentals/dashboard/media/explore/structured-logs-filtered.png index f089742495..459c899682 100644 Binary files a/docs/fundamentals/dashboard/media/explore/structured-logs-filtered.png and b/docs/fundamentals/dashboard/media/explore/structured-logs-filtered.png differ diff --git a/docs/fundamentals/dashboard/media/explore/text-visualizer-resources.png b/docs/fundamentals/dashboard/media/explore/text-visualizer-resources.png index 74c7ae25e4..de723dd07e 100644 Binary files a/docs/fundamentals/dashboard/media/explore/text-visualizer-resources.png and b/docs/fundamentals/dashboard/media/explore/text-visualizer-resources.png differ diff --git a/docs/fundamentals/dashboard/media/explore/text-visualizer-selection-menu.png b/docs/fundamentals/dashboard/media/explore/text-visualizer-selection-menu.png index 13ddf05ea4..9a1731b560 100644 Binary files a/docs/fundamentals/dashboard/media/explore/text-visualizer-selection-menu.png and b/docs/fundamentals/dashboard/media/explore/text-visualizer-selection-menu.png differ diff --git a/docs/fundamentals/dashboard/media/explore/theme-selection-light.png b/docs/fundamentals/dashboard/media/explore/theme-selection-light.png index 8f0e253cc1..99fa3e2d81 100644 Binary files a/docs/fundamentals/dashboard/media/explore/theme-selection-light.png and b/docs/fundamentals/dashboard/media/explore/theme-selection-light.png differ diff --git a/docs/fundamentals/dashboard/media/explore/theme-selection.png b/docs/fundamentals/dashboard/media/explore/theme-selection.png index 281084ec17..59e3a53bac 100644 Binary files a/docs/fundamentals/dashboard/media/explore/theme-selection.png and b/docs/fundamentals/dashboard/media/explore/theme-selection.png differ