Extends Verify (https://github.com/VerifyTests/Verify) to allow Blazor component verification.


Keywords
Blazor, Verify, bunit, snapshot-testing, testing
License
MIT
Install
Install-Package Verify.Blazor -Version 11.0.0

Documentation

Verify.Blazor

Discussions Build status NuGet Status NuGet Status

Support for rendering a Blazor Component to a verified file via bunit or via raw Blazor rendering.

See Milestones for release notes.

Component

The below samples use the following Component:

<div>
    <h1>@Title</h1>
    <p>@Person.Name</p>
    <button>MyButton</button>
</div>

@code {
    [Parameter]
    public string Title { get; set; } = "My Test Component";

    [Parameter]
    public Person Person { get; set; }

    public bool Intitialized;

    protected override Task OnInitializedAsync()
    {
        Intitialized = true;
        return Task.CompletedTask;
    }

}

snippet source | anchor

Verify.Blazor

Verify.Blazor uses the Blazor APIs to take a snapshot (metadata and html) of the current state of a Blazor component. It has fewer dependencies and is a simpler API than Verify.Bunit approach, however it does not provide many of the other features, for example trigger event handlers.

NuGet package

Usage

Render using ParameterView

This test:

[Fact]
public Task PassingParameters()
{
    var parameters = ParameterView.FromDictionary(
        new Dictionary<string, object?>
        {
            { "Title", "The Title" },
            { "Person", new Person { Name = "Sam" } }
        });

    var target = Render.Component<TestComponent>(parameters: parameters);

    return Verify(target);
}

snippet source | anchor

Render using template instance

This test:

[Fact]
public Task PassingTemplateInstance()
{
    var template = new TestComponent
    {
        Title = "The Title",
        Person = new()
        {
            Name = "Sam"
        }
    };

    var target = Render.Component(template: template);

    return Verify(target);
}

snippet source | anchor

Result

Both will produce:

The component rendered as html ...verified.html:

<div>
  <h1>The Title</h1>
  <p>Sam</p>
  <button>MyButton</button>
</div>

snippet source | anchor

And the current model rendered as txt ...verified.txt:

{
  Instance: {
    Intitialized: true,
    Title: The Title,
    Person: {
      Name: Sam
    }
  }
}

snippet source | anchor

Verify.Bunit

Verify.Bunit uses the bUnit APIs to take a snapshot (metadata and html) of the current state of a Blazor component. Since it leverages the bUnit API, snapshots can be on a component that has been manipulated using the full bUnit feature set, for example trigger event handlers.

NuGet package

Usage

Enable at startup:

[ModuleInitializer]
public static void Initialize() =>
    VerifyBunit.Initialize();

snippet source | anchor

This test:

[Fact]
public Task Component()
{
    using var context = new TestContext();
    var component = context.RenderComponent<TestComponent>(
        builder =>
        {
            builder.Add(
                _ => _.Title,
                "New Title");
            builder.Add(
                _ => _.Person,
                new()
                {
                    Name = "Sam"
                });
        });
    return Verify(component);
}

[Fact]
public Task MarkupFormattable_NodeList()
{
    using var context = new TestContext();
    var component = context.RenderComponent<TestComponent>(
        builder =>
        {
            builder.Add(
                _ => _.Title,
                "New Title");
            builder.Add(
                _ => _.Person,
                new()
                {
                    Name = "Sam"
                });
        });
    return Verify(component.Nodes);
}

[Fact]
public Task MarkupFormattable_single_Element()
{
    using var context = new TestContext();
    var component = context.RenderComponent<TestComponent>(
        builder =>
        {
            builder.Add(
                _ => _.Title,
                "New Title");
            builder.Add(
                _ => _.Person,
                new()
                {
                    Name = "Sam"
                });
        });
    return Verify(component.Nodes.First().FirstChild);
}

snippet source | anchor

Will produce:

The component rendered as html ...Component.verified.html:

<div>
  <h1>New Title</h1>
  <p>Sam</p>
  <button>MyButton</button>
</div

snippet source | anchor

And the current model rendered as txt ...Component.verified.txt:

{
  Instance: {
    Intitialized: true,
    Title: New Title,
    Person: {
      Name: Sam
    }
  },
  NodeCount: 9
}

snippet source | anchor

Exclude Component

Rendering of the Component state (Samples.Component.verified.txt from above) can be excluded by using excludeComponent.

[ModuleInitializer]
public static void Initialize() =>
    VerifyBunit.Initialize(excludeComponent: true);

snippet source | anchor

Scrubbing

Integrity check

In Blazor an integrity check is applied to the dotnet.*.js file.

<script src="_framework/dotnet.5.0.2.js" defer="" integrity="sha256-AQfZ6sKmq4EzOxN3pymKJ1nlGQaneN66/2mcbArnIJ8=" crossorigin="anonymous"></script>

This line will change when the dotnet SDK is updated.

Noise in rendered template

Blazor uses <!--!--> to delineate components in the resulting html. Some empty lines can be rendered when components are stitched together.

Resulting scrubbing

// remove some noise from the html snapshot
VerifierSettings.ScrubEmptyLines();
BlazorScrubber.ScrubCommentLines();
VerifierSettings.ScrubLinesWithReplace(s =>
{
    var scrubbed = s.Replace("<!--!-->", "");
    if (string.IsNullOrWhiteSpace(scrubbed))
    {
        return null;
    }

    return scrubbed;
});
HtmlPrettyPrint.All();
VerifierSettings.ScrubLinesContaining("<script src=\"_framework/dotnet.");

snippet source | anchor

Credits

Icon

Helmet designed by Leonidas Ikonomou from The Noun Project.