Gua.Testing 0.15.0

dotnet add package Gua.Testing --version 0.15.0
                    
NuGet\Install-Package Gua.Testing -Version 0.15.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="Gua.Testing" Version="0.15.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gua.Testing" Version="0.15.0" />
                    
Directory.Packages.props
<PackageReference Include="Gua.Testing" />
                    
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 Gua.Testing --version 0.15.0
                    
#r "nuget: Gua.Testing, 0.15.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 Gua.Testing@0.15.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=Gua.Testing&version=0.15.0
                    
Install as a Cake Addin
#tool nuget:?package=Gua.Testing&version=0.15.0
                    
Install as a Cake Tool

Gua.Testing

Gua.Testing adds locator, assertion, wait, and test-host helpers on top of Gua.Core.

The package targets both net10.0 and netstandard2.1. The latter is intended for Unity 6's .NET Standard 2.1 API Compatibility Level; the initial verified native configuration is the Windows x64 Editor described in the Unity smoke guide.

using var ui = new GuaContext();
var host = new GuaTestHost(ui);
var loading = false;

host.Frame("title", frame =>
{
    if (frame.Button("start", "Start Game", new GuaBounds(0, 0, 200, 40)))
    {
        loading = true;
    }
});

GuaAssertions.GetByRole(ui, "button", "Start Game").Click();

host.Frame("title", frame =>
{
    if (frame.Button("start", "Start Game", new GuaBounds(0, 0, 200, 40)))
    {
        loading = true;
    }
});

host.Frame("loading", frame =>
{
    if (loading)
    {
        frame.Text("loading", "Loading...", new GuaBounds(0, 48, 200, 24));
    }
});

GuaAssertions.WaitForText(ui, "Loading...").ToBeVisible();

Click() enqueues a click request. A real adapter or GuaTestHost must consume that request and emit the click event while advancing frames.

For real .NET tests, use NUnit, xUnit, or MSTest as the test runner and use Gua.Testing inside each test. The repository's recommended sample is NUnit:

using var _ = GuaAssertionScope.UseNUnit(Assert.Fail);

GuaAssertions.GetById(ui, "start").ToBeVisible();

See examples/dotnet-nunit for a complete NUnit project with multiple [Test] methods in one file.

Async condition waits are the primary synchronization API. They use a monotonic timeout, honor cancellation, and work with both local GuaContext and remote GuaRemoteContext snapshot polling:

await GuaAssertions.WaitForVisibleAsync(ui, "status", cancellationToken: token);
await GuaAssertions.WaitForTextAsync(ui, "status", "Ready", pollInterval: TimeSpan.FromMilliseconds(20));
await GuaAssertions.WaitForValueAsync(ui, "progress", "100");
await GuaAssertions.WaitForStableSnapshotAsync(ui, stableFrames: 3);

Stable snapshot waiting counts only distinct frameSequence values whose revision remains unchanged; repeatedly polling one stopped frame never satisfies the wait. Hidden waiting succeeds for either visible=false or a removed node. Timeout messages include the condition, last node state, frame, and revision. Sync wrappers remain available for compatibility.

WaitForStateAsync(context, id, predicate) polls fresh snapshots for detailed state such as caret/selection, scroll offsets, range bounds, and selected index. Action completion includes session/frame/revision metadata, but remains distinct from observing the requested state; chain a state wait when the UI result matters.

Use GuaTestSession as the explicit process-reuse boundary. The default reset clears semantic nodes, requests, events, and retained history while preserving logs and screenshots. Strict teardown detects leaked requests/events without discarding them:

var session = new GuaTestSession(context);
session.Reset(); // setup; starts a new session epoch
// ...test...
session.Reset(new GuaResetOptions(Strict: true)); // teardown; throws if dirty

For high-level isolation, construct GuaTestSession with lifecycle options. GuaTestSessionOptions.Strict enables strict startup and teardown reset. Policies can also be selected independently with GuaResetPolicy.Disabled, NonStrict, or Strict; their default targets are nodes, requests, events, and retained history. Logs and screenshots remain preserved unless selected.

using var session = new GuaTestSession(context, new GuaTestSessionOptions
{
    StartupReset = GuaResetPolicy.Strict,
    TeardownReset = GuaResetPolicy.Strict,
    CaptureDiagnosticsBeforeTeardown = true,
    CleanupAfterLeakReport = true,
    DiagnosticsSession = diagnostics,
});

session.Run(() => RunTestBody());

Run rethrows the original test-body exception with its type and stack trace. A teardown failure is attached as GuaTeardownFailure, and a typed diagnostic result as GuaDiagnosticsResult. Leak inspection reports epoch, counts, request ID, action/event type, and node ID without action payload values. Cleanup runs only after diagnostics were attempted and only when enabled. Clean completion creates no artifact, and Dispose is idempotent.

ResetAsync provides the same contract for remote contexts and honors CancellationToken. Remote reset always includes the inspected session epoch, so a stale client cannot reset a newer shared runtime session. Semantic locators are strict: GetBy* fails when zero or multiple nodes match, while QueryAll() is the explicit multi-result API. String matching is exact by default and can opt into ordinal contains or ECMAScript regex matching:

var save = GuaAssertions.Query(ui)
    .ByRole("button")
    .ByText("^保存", GuaMatchMode.Regex)
    .Within("settings-panel")
    .WhereVisible()
    .WhereEnabled()
    .Get();

GuaAssertions.Query(ui).ByRole("listitem").Within("servers").AssertCount(3);

Within(parentId) searches descendants and excludes the parent itself. Pass directChild: true to limit the query to immediate children. Local and Godot remote contexts send the same selector to the native evaluator.

Node expectations expose Focus, SetValue, SetChecked, Select, Scroll, and PressKey. These methods enqueue requests and return a request ID; WaitForAction waits for the adapter's correlated observed result rather than treating enqueue acceptance as completion.

Failure diagnostics

Configure GuaAssertionOptions.Diagnostics to capture a unique artifact directory automatically when a semantic assertion or wait fails:

using var scope = GuaAssertionScope.Use(new GuaAssertionOptions
{
    Diagnostics = new GuaDiagnosticOptions
    {
        TestName = TestContext.CurrentContext.Test.FullName,
        OutputDirectory = Path.Combine("artifacts", "gua"),
    },
});

For one framework-independent failure path across assertions and completed actions, create a GuaDiagnosticsSession and assign it to GuaAssertionOptions.DiagnosticsSession. Capture preserves the primary exception and returns absolute artifact paths, media types, and secondary capture errors. Directories use the sanitized test name, timestamp, and a unique ID so parallel tests do not collide. Caller metadata, runtime version, and optional text/screenshot providers are evaluated only after a failure; successful tests produce no artifact unless the caller explicitly captures.

GuaDiagnosticOptions.AttachmentSink is framework-neutral. NUnit consumers can pass file => TestContext.AddTestAttachment(file.Path, file.MediaType); other frameworks can use the same typed callback without adding a framework dependency to Gua.Testing. Screenshot files can contain rendered secrets and remain the consumer repository's storage and upload responsibility.

The directory contains the final UI tree, bounded operation/event history, pending requests, logs, environment metadata, and an optional PNG. A wait also writes its initial tree and a deterministic node-id diff. Sensitive action values are redacted before the writer receives them. If capture fails, the original assertion delegate still determines the exception type and a secondary capture error is appended to its message.

Protocol v2 operations have one-step sync and async completion APIs for focus, set value, set checked, select, scroll, and key press. They return the correlated GuaActionEvent; GuaActionException exposes rejection, host failure, timeout, or cancellation together with request/action/node/error and snapshot metadata. GuaAssertions.PressKeyAsync(context, key) targets the adapter's current focus.

Queries can add Within, ByValue, WhereFocused, WhereSelected, WhereChecked, and ByAction. Corresponding async state waits re-fetch the latest UI tree on every poll instead of holding the first snapshot. Wait-returned expectations retain the exact successful node snapshot, including sessionEpoch, frameSequence, and revision, so chained assertions evaluate one completed frame. Call Refresh() or a WaitUntil* method to opt into a newer published frame. A retained snapshot from an older session epoch remains readable evidence but must be refreshed before making current-session decisions.

Locator counts can wait on every selector dimension, including scope, state, value, and action:

await GuaAssertions.Query(context).ByRole("listitem").Within("ServerList")
    .WaitForCountAsync(count => count >= 3, timeout, pollInterval, cancellationToken);
GuaAssertions.Query(context).ByAction("scroll").WaitForCount(1, timeout, pollInterval);

Node expectations expose correlated sync/async action completion for click, focus, set_value, set_checked, select, scroll, and press_key. These helpers wait for the same requestId; unrelated events remain queued.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Gua.Testing:

Package Downloads
Gua.Testing.Godot

Godot process test host for Gua runtime UI automation assertions.

Gua.Testing.Visual

Opt-in PNG baseline comparison for Gua UI automation tests.

Gua.Testing.Recording

Semantic UI operation recording and correlated replay for Gua.

Gua.Testing.Unity

Unity Editor and Player process test host for Gua runtime UI automation.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.15.0 230 7/14/2026
0.14.0 186 7/14/2026
0.13.0 104 7/14/2026
0.12.0 105 7/12/2026
0.11.0 105 7/12/2026
0.10.0 140 7/12/2026
0.9.0 105 7/12/2026
0.8.0 105 7/12/2026
0.7.0 98 7/11/2026
0.6.0 99 7/11/2026
0.5.0 113 7/11/2026
0.4.0 113 7/11/2026
0.3.0 107 7/11/2026
0.2.0 107 7/11/2026
0.1.0 116 7/10/2026