E2E for .NET

Write the goal.
Check the screen.

Describe a goal in plain language, let an agent drive the app, then check the result with locators. The same test API runs on the web, on iOS and Android, on .NET MAUI, and on Windows.

A community port of the e2e framework. Not an official TesterArmy product.

dotnet add package E2E && dotnet add package E2E.NUnit

Or E2E.XUnit.V3 instead ofE2E.NUnit. The packages target net10.0.E2E on NuGet.

C#BillingTestsREADME sample
using E2E;
using E2E.NUnit;
using NUnit.Framework;

public sealed class BillingTests : E2ETest
{
    protected override IAgentModel? CreateModel() =>
        new OpenAiCompatibleModel(
            new OpenAiCompatibleModelOptions
            {
                Model = "gpt-4.1-mini",
            });

    [Test]
    public async Task Member_upgrades_to_Pro()
    {
        await App.OpenAsync("/settings/billing");
        await Agent.ActAsync(
            "upgrade the workspace to the Pro plan");
        await Agent.AssertAsync(
            "the invoice preview shows a prorated amount");
        await Expect.That(Screen.GetByRole("status"))
            .ToContainTextAsync("Pro");
    }
}
Passing run records the actNext run replays it

Web

Browser

Chrome, Firefox, and WebKit

Mobile

iOS and Android

Simulators and emulators

Windows

UI Automation

Windows 10 and 11

License

Apache-2.0

Free for commercial use

Why E2E

The test describes the task. The checks stay exact.

  • A goal, not a script

    Agent.ActAsync takes one goal. The agent works out the steps. Give it one atomic action per call.

    Write a test
  • Checks that skip the model

    Expect.That and Screen.GetByRole assert an exact value. No model call. Pair each agent step with one.

    Locator checks
  • Replay on the next run

    A verified act is recorded. The next run replays it with no model call until the screen no longer matches.

    Rerun while you fix
  • One API, four platforms

    App, Agent, Screen, and Expect on WebEngine, MobileEngine, and WinAppEngine. WebEngine runs Chrome, Firefox, and WebKit.

    Pick a platform

Get started

From an empty project to a running test, in three steps.

Install the packages, point at the app, and write a test. Each step links to the page that has the rest.

Read the getting-started guide
  1. Install the packages

    Add the library and the NUnit fixture. For xUnit v3, add E2E.XUnit.V3 instead of E2E.NUnit.

    dotnet add package E2E
    dotnet add package E2E.NUnit
    Create the test project
  2. Point at your app

    An e2e.config.json names the target, the model, and the replay cache. Every key is optional.

    {
      "targets": [{ "name": "web", "platform": "web", "app": { "url": "http://localhost:3000" } }],
      "actionTimeout": 15000,
      "assertionTimeout": 10000,
      "agents": { "default": { "provider": "copilot", "model": "claude-sonnet-5.5" } },
      "cache": { "dir": ".e2e/cache" }
    }
    The config file
  3. Write a test and run

    Derive from E2ETest. The first passing ActAsync is recorded, and the next run replays it.

    dotnet test --project .
    Write a test