XUnitAssured.Playwright.AspNetCore 6.22.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package XUnitAssured.Playwright.AspNetCore --version 6.22.0
                    
NuGet\Install-Package XUnitAssured.Playwright.AspNetCore -Version 6.22.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XUnitAssured.Playwright.AspNetCore" Version="6.22.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XUnitAssured.Playwright.AspNetCore" Version="6.22.0" />
                    
Directory.Packages.props
<PackageReference Include="XUnitAssured.Playwright.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XUnitAssured.Playwright.AspNetCore --version 6.22.0
                    
#r "nuget: XUnitAssured.Playwright.AspNetCore, 6.22.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XUnitAssured.Playwright.AspNetCore@6.22.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XUnitAssured.Playwright.AspNetCore&version=6.22.0
                    
Install as a Cake Addin
#tool nuget:?package=XUnitAssured.Playwright.AspNetCore&version=6.22.0
                    
Install as a Cake Tool

XUnitAssured.Playwright.AspNetCore

Browser tests against your own ASP.NET Core API, with dotnet test alone. BrowserAppFixture<TProgram> hosts the API on a real port with WebApplicationFactory, serves your built front-end on another, and launches the browser — no terminals to start by hand, so the tests run in CI.

Part of XUnitAssured.Net. Requires .NET 10 (WebApplicationFactory.UseKestrel arrived in Microsoft.AspNetCore.Mvc.Testing 10).

Installation

dotnet add package XUnitAssured.Playwright.AspNetCore

Then install the browser once, from the test project's output:

pwsh bin/Debug/net10.0/playwright.ps1 install chromium

Why

The usual WebApplicationFactory hosts the API in memory, where no browser can reach it. Browser tests then need the API, the front-end and the tests started separately, and they stay out of CI. Out of CI they go stale without anyone noticing: in a real consumer suite, the front-end changed how it stores the session and a browser test kept passing while provoking nothing.

Usage

using XUnitAssured.Playwright.AspNetCore;

public sealed class MyApp : BrowserAppFixture<Program>
{
    // The built front-end (the folder with index.html), relative to the test output.
    protected override string? AppDirectory => "../../../../my-app/dist";

    protected override void ConfigureApi(IWebHostBuilder api) =>
        api.UseEnvironment("E2ETesting");
}

public class SessionTests(MyApp app) : IClassFixture<MyApp>
{
    [Fact]
    public async Task Signs_In()
    {
        await using var page = await app.OpenPageAsync();

        await ScenarioDsl.Given(page)
            .NavigateTo("/login")              // relative to app.AppUrl
            .FillByLabel("Email", "user@test.com")
            .ClickByRole(AriaRole.Button, "Sign in")
            .WaitForSelector("[data-testid=dashboard]")
            .ExecuteAsync()
            .AssertUrlContains("/dashboard");
    }
}
Member What it is
ApiUrl The API's address, e.g. http://localhost:5199
AppUrl The front-end's address — the browser's base URL. The API's when there is no front-end
Api The WebApplicationFactory: Api.Services for the API's services, Api.CreateClient() to arrange data over HTTP
ApiPort, AppPort Override to fix a port. 0 (the default) picks a free one
AppDirectory Override to serve a built front-end, with a fallback to index.html for client-side routes
ConfigureApi Override to configure the API host before it starts

Two origins, on purpose

The API and the front-end run on different ports, like an app and its API in production, so SameSite, the cookie Path and CORS with credentials apply as they would for real. The API must allow AppUrl as an origin. If its CORS policy reads the allowed origins from configuration, fix AppPort and set it in ConfigureApi; otherwise add a policy there:

protected override void ConfigureApi(IWebHostBuilder api) =>
    api.ConfigureServices(services => services
        .AddCors()
        .AddTransient<IStartupFilter>(_ => new AllowApp(() => AppUrl)));

sealed class AllowApp(Func<string> origin) : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next) => app =>
    {
        app.UseCors(p => p.SetIsOriginAllowed(o => o == origin()).AllowCredentials().AllowAnyHeader().AllowAnyMethod());
        next(app);
    };
}

If the front-end was built with the API address baked in (VITE_API_URL=http://localhost:5199, for example), fix ApiPort to match.

Fixed ports: one fixture for every class

A fixed port can be bound once, and xUnit starts an IClassFixture per class, in parallel. With fixed ports, share one fixture through a collection — which also starts the API and the front-end once instead of once per class:

[CollectionDefinition("Browser")]
public sealed class BrowserCollection : ICollectionFixture<MyApp>;

[Collection("Browser")]
public class SessionTests(MyApp app) { /* ... */ }

Apps with a service worker (PWA)

Requests a service worker makes for the page bypass InterceptRoute, so an interception answers nothing once the worker controls the page. Block service workers in the settings:

protected override PlaywrightSettings CreateSettings()
{
    var settings = base.CreateSettings();
    settings.BlockServiceWorkers = true;
    return settings;
}
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.30.5 0 10/16/2026
6.30.1 0 10/16/2026
6.27.1 0 10/16/2026
6.27.0 0 10/16/2026
6.22.0 0 10/16/2026
6.21.3 0 10/16/2026
6.19.0 70 10/12/2026
6.18.1 80 10/12/2026
6.18.0 76 10/12/2026
6.17.0 78 10/12/2026
6.16.0 76 10/12/2026
6.15.7 75 10/12/2026
6.15.6 74 10/12/2026
6.15.5 73 10/12/2026
6.15.4 80 10/12/2026
6.15.3 75 10/12/2026
6.15.2 79 10/12/2026
6.15.1 86 10/12/2026
6.15.0 79 10/12/2026
6.14.0 77 10/12/2026
Loading failed

New package XUnitAssured.Camunda: deploy BPMN, start real Camunda 8.10 process instances on a shared cluster and mock the diagram's job workers per instance, with assertions that wait for the cluster. The other packages are unchanged from 6.19.1. Upgrade guide: https://github.com/andrewBezerra/xunit-assured-net/blob/main/UPGRADING.md