diff --git a/.vscode/settings.json b/.vscode/settings.json index 7301fa2..f2aafb8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,6 @@ "Antiforgery", "blazor", "Hsts" - ] + ], + "dotnet.unitTests.runSettingsPath": "./test/Blog.Tests/.runsettings" } \ No newline at end of file diff --git a/src/Blog/Components/Layout/MainLayout.razor b/src/Blog/Components/Layout/MainLayout.razor index 0d3d3af..94f26e9 100644 --- a/src/Blog/Components/Layout/MainLayout.razor +++ b/src/Blog/Components/Layout/MainLayout.razor @@ -1,4 +1,5 @@ @inherits LayoutComponentBase +@rendermode InteractiveServer @Body diff --git a/src/Blog/Program.cs b/src/Blog/Program.cs index a2d5151..bc42976 100644 --- a/src/Blog/Program.cs +++ b/src/Blog/Program.cs @@ -23,4 +23,6 @@ app .MapRazorComponents() .AddInteractiveServerRenderMode(); -app.Run(); \ No newline at end of file +app.Run(); + +public partial class Program {} \ No newline at end of file diff --git a/test/Blog.Tests/.runsettings b/test/Blog.Tests/.runsettings new file mode 100644 index 0000000..d2d9961 --- /dev/null +++ b/test/Blog.Tests/.runsettings @@ -0,0 +1,10 @@ + + + + chromium + + false + msedge + + + \ No newline at end of file diff --git a/test/Blog.Tests/Blog.Tests.csproj b/test/Blog.Tests/Blog.Tests.csproj index 636746e..a885eb3 100644 --- a/test/Blog.Tests/Blog.Tests.csproj +++ b/test/Blog.Tests/Blog.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/test/Blog.Tests/EndToEnd/BlogHostFactory.cs b/test/Blog.Tests/EndToEnd/BlogHostFactory.cs new file mode 100644 index 0000000..cc47aec --- /dev/null +++ b/test/Blog.Tests/EndToEnd/BlogHostFactory.cs @@ -0,0 +1,15 @@ +namespace Blog.Tests.EndToEnd; + +public class BlogHostFactory : WebApplicationFactory where TProgram : class +{ + protected override IHost CreateHost(IHostBuilder builder) + { + var testHost = base.CreateHost(builder); + builder.ConfigureWebHost(webHostBuilder => webHostBuilder.UseKestrel()); + + var kestrelHost = builder.Build(); + kestrelHost.Start(); + + return new CompositeHost(testHost, kestrelHost); + } +} \ No newline at end of file diff --git a/test/Blog.Tests/EndToEnd/BlogPageTest.cs b/test/Blog.Tests/EndToEnd/BlogPageTest.cs new file mode 100644 index 0000000..51a4015 --- /dev/null +++ b/test/Blog.Tests/EndToEnd/BlogPageTest.cs @@ -0,0 +1,19 @@ +namespace Blog.Tests.EndToEnd; + +public class BlogPageTest : PageTest +{ + private readonly BlogHostFactory _factory = new(); + + public override BrowserNewContextOptions ContextOptions() + { + var baseUrl = "http://localhost:5000"; + + _factory + .WithWebHostBuilder(builder => builder.UseUrls(baseUrl)) + .CreateDefaultClient(); + + var options = base.ContextOptions(); + options.BaseURL = baseUrl; + return options; + } +} \ No newline at end of file diff --git a/test/Blog.Tests/EndToEnd/CompositeHost.cs b/test/Blog.Tests/EndToEnd/CompositeHost.cs new file mode 100644 index 0000000..5402072 --- /dev/null +++ b/test/Blog.Tests/EndToEnd/CompositeHost.cs @@ -0,0 +1,28 @@ +namespace Blog.Tests.EndToEnd; + +public class CompositeHost(IHost testHost, IHost kestrelHost) : IHost +{ + private readonly IHost _testHost = testHost; + private readonly IHost _kestrelHost = kestrelHost; + + public IServiceProvider Services => _testHost.Services; + + public void Dispose() + { + _testHost.Dispose(); + _kestrelHost.Dispose(); + GC.SuppressFinalize(this); + } + + public async Task StartAsync(CancellationToken cancellationToken = default) + { + await _testHost.StartAsync(cancellationToken); + await _kestrelHost.StartAsync(cancellationToken); + } + + public async Task StopAsync(CancellationToken cancellationToken = default) + { + await _testHost.StopAsync(cancellationToken); + await _kestrelHost.StopAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/test/Blog.Tests/EndToEnd/IndexTests.cs b/test/Blog.Tests/EndToEnd/IndexTests.cs new file mode 100644 index 0000000..967cefa --- /dev/null +++ b/test/Blog.Tests/EndToEnd/IndexTests.cs @@ -0,0 +1,13 @@ +namespace Blog.Tests.EndToEnd; + +[TestFixture] +public class IndexTests : BlogPageTest +{ + [Test] + public async Task Index_WhenNavigatedTo_ItShouldDisplayMessage() + { + await Page.GotoAsync("/"); + var message = Page.GetByRole(AriaRole.Heading, new () { Name = "Hello, world!" }); + await Expect(message).ToBeVisibleAsync(); + } +} \ No newline at end of file diff --git a/test/Blog.Tests/GlobalUsings.cs b/test/Blog.Tests/GlobalUsings.cs index cefced4..d77345b 100644 --- a/test/Blog.Tests/GlobalUsings.cs +++ b/test/Blog.Tests/GlobalUsings.cs @@ -1 +1,6 @@ -global using NUnit.Framework; \ No newline at end of file +global using NUnit.Framework; +global using Microsoft.AspNetCore.Mvc.Testing; +global using Microsoft.Extensions.Hosting; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.Playwright.NUnit; +global using Microsoft.Playwright; \ No newline at end of file