Home

Awesome

<!-- GENERATED FILE - DO NOT EDIT This file was generated by [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets). Source File: /readme.source.md To change this file edit the source file and then run MarkdownSnippets. -->

<img src="/src/icon.png" height="30px"> Verify.Bunit

Discussions Build status NuGet Status

Support for rendering a Blazor Component to a verified file via 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.

See Milestones for release notes.

Component

The below samples use the following Component:

<!-- snippet: BlazorApp/TestComponent.razor -->

<a id='snippet-BlazorApp/TestComponent.razor'></a>

<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;
    }

}

<sup><a href='/src/BlazorApp/TestComponent.razor#L1-L23' title='Snippet source file'>snippet source</a> | <a href='#snippet-BlazorApp/TestComponent.razor' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

NuGet package

Usage

Enable at startup:

<!-- snippet: BunitEnable -->

<a id='snippet-BunitEnable'></a>

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

<sup><a href='/src/Tests/ModuleInitializer.cs#L5-L11' title='Snippet source file'>snippet source</a> | <a href='#snippet-BunitEnable' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

This test:

<!-- snippet: BunitComponentTest -->

<a id='snippet-BunitComponentTest'></a>

[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);
}

<sup><a href='/src/Tests/Samples.cs#L3-L66' title='Snippet source file'>snippet source</a> | <a href='#snippet-BunitComponentTest' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Will produce:

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

<!-- snippet: Tests/Samples.Component.verified.html -->

<a id='snippet-Tests/Samples.Component.verified.html'></a>

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

<sup><a href='/src/Tests/Samples.Component.verified.html#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-Tests/Samples.Component.verified.html' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

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

<!-- snippet: Tests/Samples.Component.verified.txt -->

<a id='snippet-Tests/Samples.Component.verified.txt'></a>

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

<sup><a href='/src/Tests/Samples.Component.verified.txt#L1-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-Tests/Samples.Component.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Exclude Component

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

<!-- snippet: BunitEnableExcludeComponent -->

<a id='snippet-BunitEnableExcludeComponent'></a>

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

<sup><a href='/src/ExcludeComponentTests/ModuleInitializer.cs#L3-L9' title='Snippet source file'>snippet source</a> | <a href='#snippet-BunitEnableExcludeComponent' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

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

<!-- snippet: scrubbers -->

<a id='snippet-scrubbers'></a>

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

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

<sup><a href='/src/Tests/ModuleInitializer.cs#L16-L35' title='Snippet source file'>snippet source</a> | <a href='#snippet-scrubbers' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Icon

Helmet designed by Leonidas Ikonomou from The Noun Project.