Rivet keeps UI tests native for the same reason it keeps production UI native: the platform accessibility and interaction stacks are part of the product. The reference Taskboard is exercised through UI Automation on Windows, AXUIElement on macOS, and AT-SPI on Linux. No shared widget DSL or synthetic Rivet view tree sits between the test and WinUI 3, SwiftUI/AppKit, or GTK4.
The Native UI End-to-End workflow packages the application before testing it
and requires each platform driver to prove all of the following:
- a real native window can be discovered and activated;
- stable semantic names/identifiers and roles are exposed;
- invoking
new-taskcrosses the generated client and RVT1 boundary and the resulting State reaches the native list; - invoking
generate-demomakes anoperation-progressEvent visible through the native accessibility surface; - the final 1,000-row State reaches the UI; and
- native window close or
SIGTERMcompletes the orderly backend shutdown.
Every run uploads the bounded interaction trace and accessibility snapshots.
It also captures a screen image when the runner supports the platform capture
API, plus application/compositor logs on Linux. The evidence is uploaded with
if: always() so a failed assertion remains diagnosable.
Product applications own their views, so they also own the identifiers and scenario vocabulary. Keep those identifiers in native source:
- WinUI:
AutomationProperties.AutomationIdandAutomationProperties.Name; - SwiftUI/AppKit:
.accessibilityIdentifier, labels, and native roles; and - GTK4:
GtkAccessibleproperties and meaningful widget roles.
Copy the matching driver under tests/native-ui/, replace the reference
identifiers and actions with one product-critical scenario, and add the driver
to a packaging job. A useful minimum scenario has one RPC-driven mutation, one
Event, a stable accessibility-tree assertion, and orderly close. Test-only
protocol messages and a cross-platform selector language are deliberately not
extension points.
Keep snapshots small: cap recursion depth, record semantic fields rather than platform object dumps, and never include user data or secret values. Failure artifacts should be retained only as long as the repository's normal CI logs.