Aspire Resource for Aspire–part 3–usage


AspireExtensionsResource

This package provides Aspire as a Resource in the Aspire Host Dashboard, making it easier to test and manage Aspire dashboards.
You can download the solution at https://github.com/ignatandrei/aspireExtensions/tree/main/src/AspireResourceExtensions in order to see the tests.

Installation

Install via NuGet:

  dotnet add package AspireExtensionsResource
  

Usage

  1. Add the Aspire resource to your distributed application builder:
  using AspireResourceExtensionsAspire;

  var aspire = builder.AddAspireResource();
  
  1. Use the resource to add environment variables to other resources:
  aspire.Resource.AddEnvironmentVariablesTo(otherResource);
  

(see below integration with Playwright tests for .NET and NodeJS)

  1. Start parsing Aspire dashboard URLs:

Instead of

  builder.Build().Run();
  

write this:

  var result = aspire.Resource.StartParsing(app);
  await Task.WhenAll(app.RunAsync(), result);
  

Features

  • Adds Aspire dashboard as a resource for testing
  • Exposes login and base URLs as environment variables
  • Designed for .NET Aspire distributed applications

Integrations

Playwright NodeJS

Suppose that you have a NodeJS playwright app that you want to test your ASPIRE dashboard. You can integrate this way: In AppHost.cs

  var npmTests = builder.AddNpmApp("GenerateVideo", "../GenerateTest")
      .WaitFor(aspire)
      .WithExplicitStart()
      ;

  aspire.Resource.AddEnvironmentVariablesTo(tests,npmTests);
  

In the test you can write

  const DEFAULT_BASE_URL = process.env.ASPIRE_BASE_URL ??"";
  const DEFAULT_LOGIN_URL = process.env.ASPIRE_LOGIN_URL??""; 
  const RESOURCE_URL = `${DEFAULT_BASE_URL}`;

  test.describe('Test group', () => {
    test.use({ ignoreHTTPSErrors: true });

    test.beforeEach(async ({ page }) => {
      await page.goto(DEFAULT_LOGIN_URL);
      await page.waitForLoadState('networkidle');
    });
  });
  

Playwright .NET

Suppose that you have a NodeJS playwright app that you want to test your ASPIRE dashboard. You can integrate this way:

In AppHost.cs

  var tests= builder.AddTestProject<Projects.AspireResourceExtensions_Tests>("MyTests",
      "test --filter Category=Integration"
      )
      .WaitFor(aspire)
      .WithExplicitStart()
      ;
  aspire.Resource.AddEnvironmentVariablesTo(tests);
  

In the Playwright test you will obtain the ASPIRE Dashboard url:

  private (string ASPIRE_LOGIN_URL, string ASPIRE_BASE_URL) Endpoints = (
      Environment.GetEnvironmentVariable("ASPIRE_LOGIN_URL") ?? throw new ArgumentException("Should run from aspire"),
      Environment.GetEnvironmentVariable("ASPIRE_BASE_URL") ?? throw new ArgumentException("Should run from aspire")
  );
  

Examples

Screenshot of ASPIRE graph

Test code to obtain the screenshot of aspire

      var (loginUrl, baseUrl) = Endpoints; //see above definition of Endpoints
      playwright = await Playwright.CreateAsync();
      browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = false });
      page = await browser.NewPageAsync();
      await page.GotoAsync(loginUrl);
      await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
      await page.GotoAsync(baseUrl);
      await page.WaitForLoadStateAsync(LoadState.NetworkIdle);    
      await page.GetByRole(AriaRole.Tab,new() { Name = "Graph" ,Exact=false} ).ClickAsync();
      await Task.Delay(5000);
      await page.GetByRole(AriaRole.Button, new() { Name = "Zoom Out", Exact = false }).ClickAsync();
      await Task.Delay(5000);
      await page.ScreenshotAsync(new PageScreenshotOptions { Path = "AspireResourceGraph.png" });
  

This is the result

Graph

Video of Aspire Dashboard

  const actionsButton = page.getByRole('button', { name: 'Actions' }).nth(1);
      await flashAndClick(actionsButton);
      await flashAndClick(page.getByRole('menuitem', { name: 'View details' }));
      const urlTables = page.locator('table');
      await expect(urlTables).toHaveCount(7);

      const urlTable = urlTables.nth(2); // Assuming the URLs table is the second table on the page
      urlTable.scrollIntoViewIfNeeded();
      await flashAndClick(urlTable);
      const rows = urlTable.locator('tbody tr');
      await expect(rows).toHaveCount(2);

      // First row assertions
      const firstRow = rows.nth(0);
      await expect(firstRow.locator('a', { hasText: `${DEFAULT_BASE_URL}` })).toBeVisible();
      await expect(firstRow).toContainText('BaseUrl');
      await expect(firstRow).toContainText('ASPIRE_BASE_URL');
      await firstRow.highlight();
      // Second row assertions
      const secondRow = rows.nth(1);
      await expect(secondRow.locator('a', { hasText: `${DEFAULT_LOGIN_URL}` })).toBeVisible();
      await expect(secondRow).toContainText('LoginUrl');
      await expect(secondRow).toContainText('ASPIRE_LOGIN_URL');
      await secondRow.highlight();
  

And this is the video generated

ShowUrl


Posted

in

, , ,

by

Tags: