diff --git a/src/Components/Fixture.cs b/src/Components/Fixture.cs index d196ec371..4785235b6 100644 --- a/src/Components/Fixture.cs +++ b/src/Components/Fixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Components; namespace Egil.RazorComponents.Testing @@ -12,8 +13,11 @@ namespace Egil.RazorComponents.Testing public class Fixture : FragmentBase { private Action _setup = NoopTestMethod; + private Func _setupAsync = NoopAsyncTestMethod; private Action _test = NoopTestMethod; + private Func _testAsync = NoopAsyncTestMethod; private IReadOnlyCollection _tests = Array.Empty(); + private IReadOnlyCollection> _testsAsync = Array.Empty>(); /// /// A description or name for the test that will be displayed if the test fails. @@ -21,11 +25,17 @@ public class Fixture : FragmentBase [Parameter] public string? Description { get; set; } /// - /// Gets or sets the setup action to perform before the action - /// and actions are invoked. + /// Gets or sets the setup action to perform before the action, + /// action and and actions are invoked. /// [Parameter] public Action Setup { get => _setup; set => _setup = value ?? NoopTestMethod; } + /// + /// Gets or sets the asynchronous setup action to perform before the action, + /// action and and actions are invoked. + /// + [Parameter] public Func SetupAsync { get => _setupAsync; set => _setupAsync = value ?? NoopAsyncTestMethod; } + /// /// Gets or sets the first test action to invoke, after the action has /// executed (if provided). @@ -35,6 +45,15 @@ public class Fixture : FragmentBase /// [Parameter] public Action Test { get => _test; set => _test = value ?? NoopTestMethod; } + /// + /// Gets or sets the first test action to invoke, after the action has + /// executed (if provided). + /// + /// Use this to assert against the and 's + /// defined in the . + /// + [Parameter] public Func TestAsync { get => _testAsync; set => _testAsync = value ?? NoopAsyncTestMethod; } + /// /// Gets or sets the test actions to invoke, one at the time, in the order they are placed /// into the collection, after the action and the action has @@ -45,6 +64,18 @@ public class Fixture : FragmentBase /// [Parameter] public IReadOnlyCollection Tests { get => _tests; set => _tests = value ?? Array.Empty(); } + /// + /// Gets or sets the test actions to invoke, one at the time, in the order they are placed + /// into the collection, after the action and the action has + /// executed (if provided). + /// + /// Use this to assert against the and 's + /// defined in the . + /// + [Parameter] public IReadOnlyCollection> TestsAsync { get => _testsAsync; set => _testsAsync = value ?? Array.Empty>(); } + private static void NoopTestMethod() { } + + private static Task NoopAsyncTestMethod() => Task.CompletedTask; } } diff --git a/src/Components/TestComponentBase.cs b/src/Components/TestComponentBase.cs index 2969e0031..85e0d70ea 100644 --- a/src/Components/TestComponentBase.cs +++ b/src/Components/TestComponentBase.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text; +using System.Threading.Tasks; using Egil.RazorComponents.Testing.Asserting; using Egil.RazorComponents.Testing.Diffing; using Microsoft.AspNetCore.Components; @@ -52,12 +53,12 @@ public TestComponentBase() /// in the file and runs their associated tests. /// [Fact(DisplayName = "Razor test runner")] - public void RazorTest() + public async Task RazorTest() { var container = new ContainerComponent(_renderer.Value); container.Render(BuildRenderTree); - ExecuteFixtureTests(container); + await ExecuteFixtureTests(container).ConfigureAwait(false); ExecuteSnapshotTests(container); } @@ -92,7 +93,7 @@ public override void WaitForNextRender(Action renderTrigger, TimeSpan? timeout = base.WaitForNextRender(renderTrigger, timeout); } - private void ExecuteFixtureTests(ContainerComponent container) + private async Task ExecuteFixtureTests(ContainerComponent container) { foreach (var (_, fixture) in container.GetComponents()) { @@ -102,13 +103,20 @@ private void ExecuteFixtureTests(ContainerComponent container) _testContextAdapter.ActivateRazorTestContext(testData); InvokeFixtureAction(fixture, fixture.Setup); + await InvokeFixtureAction(fixture, fixture.SetupAsync).ConfigureAwait(false); InvokeFixtureAction(fixture, fixture.Test); + await InvokeFixtureAction(fixture, fixture.TestAsync).ConfigureAwait(false); foreach (var test in fixture.Tests) { InvokeFixtureAction(fixture, test); } + foreach (var test in fixture.TestsAsync) + { + await InvokeFixtureAction(fixture, test).ConfigureAwait(false); + } + _testContextAdapter.DisposeActiveTestContext(); } } @@ -125,6 +133,18 @@ private static void InvokeFixtureAction(Fixture fixture, Action action) } } + private static async Task InvokeFixtureAction(Fixture fixture, Func action) + { + try + { + await action().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new FixtureFailedException(fixture.Description ?? $"{action.Method.Name} failed:", ex); + } + } + private void ExecuteSnapshotTests(ContainerComponent container) { foreach (var (_, snapshot) in container.GetComponents())