Testing Examples
Common testing patterns for Hermes applications.
Basic Window Tests
Testing Window Configuration
csharp
[Fact]
public void Window_AppliesConfiguration()
{
using var testWindow = new TestableHermesWindow()
.SetTitle("My Application")
.SetSize(1280, 720)
.SetPosition(100, 100)
.SetResizable(true);
testWindow.Show();
HermesAssert.HasTitle(testWindow.Backend, "My Application");
HermesAssert.HasSize(testWindow.Backend, 1280, 720);
HermesAssert.HasPosition(testWindow.Backend, 100, 100);
HermesAssert.WasShown(testWindow.Backend);
}Testing Window Lifecycle
csharp
[Fact]
public void Window_LifecycleEventsFireCorrectly()
{
var closingCalled = false;
using var testWindow = new TestableHermesWindow()
.OnClosing(() => closingCalled = true);
testWindow.Show();
testWindow.Close();
Assert.True(closingCalled);
HermesAssert.WasClosed(testWindow.Backend);
}Event Handler Tests
Testing Maximize/Restore
csharp
[Fact]
public void Window_MaximizeRestoreCycle()
{
var events = new List<string>();
using var testWindow = new TestableHermesWindow()
.OnMaximized(() => events.Add("maximized"))
.OnRestored(() => events.Add("restored"));
testWindow.Show();
testWindow.SimulateMaximize();
Assert.True(testWindow.Backend.IsMaximized);
testWindow.SimulateRestore();
Assert.False(testWindow.Backend.IsMaximized);
Assert.Equal(["maximized", "restored"], events);
}Testing Resize Handler
csharp
[Fact]
public void Window_TracksResizeEvents()
{
var resizeHistory = new List<(int W, int H)>();
using var testWindow = new TestableHermesWindow()
.SetSize(800, 600)
.OnResized((w, h) => resizeHistory.Add((w, h)));
testWindow.Show();
testWindow.SimulateResize(1024, 768);
testWindow.SimulateResize(1920, 1080);
Assert.Equal([(1024, 768), (1920, 1080)], resizeHistory);
HermesAssert.HasSize(testWindow.Backend, 1920, 1080);
}WebView Communication Tests
Testing Message Receipt
csharp
[Fact]
public void Window_ProcessesWebMessages()
{
var processedCommands = new List<string>();
using var testWindow = new TestableHermesWindow()
.OnWebMessage(msg =>
{
var json = JsonDocument.Parse(msg);
var type = json.RootElement.GetProperty("type").GetString();
processedCommands.Add(type!);
});
testWindow.Show();
testWindow.SimulateWebMessage("""{"type":"save"}""");
testWindow.SimulateWebMessage("""{"type":"load"}""");
Assert.Equal(["save", "load"], processedCommands);
}Testing Bidirectional Communication
csharp
[Fact]
public void Window_SendsResponseToWebView()
{
using var testWindow = new TestableHermesWindow()
.OnWebMessage(msg =>
{
if (msg.Contains("ping"))
{
testWindow.Window.SendWebMessage("""{"type":"pong"}""");
}
});
testWindow.Show();
testWindow.SimulateWebMessage("""{"type":"ping"}""");
HermesAssert.SentWebMessageMatching(testWindow.Recording, "pong");
}Custom Titlebar Tests
Testing Drag Region Detection
csharp
[Fact]
public void CustomTitlebar_DetectsDragRegions()
{
using var testWindow = new TestableHermesWindow()
.SetCustomTitleBar(true)
.SetChromeless(true);
testWindow.Show();
// User clicks on draggable titlebar area
testWindow.SimulateDragRegionClick();
HermesAssert.DetectedDragRegionClick(testWindow.Recording);
testWindow.Recording.Clear();
// User clicks on a button in the titlebar
testWindow.SimulateNonDragRegionClick();
HermesAssert.DetectedNonDragRegionClick(testWindow.Recording);
}Testing Double-Click to Maximize
csharp
[Fact]
public void CustomTitlebar_DoubleClickMaximizes()
{
var maximizeCalled = false;
using var testWindow = new TestableHermesWindow()
.SetCustomTitleBar(true)
.OnMaximized(() => maximizeCalled = true);
testWindow.Show();
testWindow.SimulateDragRegionDoubleClick();
HermesAssert.DetectedDragRegionDoubleClick(testWindow.Recording);
// Note: The actual maximize behavior depends on your app's handler
}Navigation Tests
Testing URL Loading
csharp
[Fact]
public void Window_NavigatesToUrl()
{
using var testWindow = new TestableHermesWindow()
.Load("https://app.example.com/dashboard");
testWindow.Show();
HermesAssert.NavigatedTo(testWindow.Recording, "https://app.example.com/dashboard");
}Testing Navigation Sequence
csharp
[Fact]
public void Window_TracksNavigationHistory()
{
using var testWindow = new TestableHermesWindow();
testWindow.Load("https://example.com/page1");
testWindow.Show();
// Simulate navigation via web message
testWindow.Window.Load("https://example.com/page2");
Assert.Contains("page1", testWindow.Recording.Navigations);
Assert.Contains("page2", testWindow.Recording.Navigations);
}Custom Scheme Tests
csharp
[Fact]
public void Window_RegistersCustomScheme()
{
using var testWindow = new TestableHermesWindow();
testWindow.Window.RegisterCustomScheme("myapp", url =>
{
if (url.EndsWith(".css"))
{
var css = "body { background: #fff; }";
return (new MemoryStream(Encoding.UTF8.GetBytes(css)), "text/css");
}
return (null, null);
});
HermesAssert.CustomSchemeRegistered(testWindow.Backend, "myapp");
// Test the handler
var result = testWindow.Backend.TestCustomScheme("myapp", "myapp://styles/main.css");
Assert.NotNull(result);
Assert.Equal("text/css", result.Value.ContentType);
}Platform-Specific Tests
csharp
[Theory]
[InlineData(HermesPlatform.Windows)]
[InlineData(HermesPlatform.macOS)]
[InlineData(HermesPlatform.Linux)]
public void Window_BehavesCorrectlyOnPlatform(HermesPlatform platform)
{
var backend = new RecordingWindowBackend { Platform = platform };
using var testWindow = new TestableHermesWindow(backend);
testWindow.Show();
// Test platform-specific behavior
Assert.Equal(platform, testWindow.Backend.Platform);
}Testing with Recording Queries
csharp
[Fact]
public void Recording_QueriesWorkCorrectly()
{
using var testWindow = new TestableHermesWindow();
testWindow.Show();
testWindow.SimulateWebMessage("""{"action":"test"}""");
var recording = testWindow.Recording;
// Query methods
Assert.True(recording.MethodWasCalled("Show"));
Assert.True(recording.ReceivedWebMessageMatching("action"));
Assert.True(recording.EventWasRaised("WebMessageReceived"));
// Direct collection access
Assert.Single(recording.WebMessagesReceived);
Assert.NotEmpty(recording.MethodCalls);
}Clearing Between Test Phases
csharp
[Fact]
public void Window_MultiPhaseTest()
{
using var testWindow = new TestableHermesWindow();
testWindow.Show();
// Phase 1: Initial setup
testWindow.SimulateWebMessage("""{"phase":1}""");
HermesAssert.ReceivedWebMessageMatching(testWindow.Recording, "phase\":1");
// Clear recordings for phase 2
testWindow.Recording.Clear();
// Phase 2: Different behavior
testWindow.SimulateWebMessage("""{"phase":2}""");
// Only phase 2 messages are recorded
Assert.Single(testWindow.Recording.WebMessagesReceived);
HermesAssert.ReceivedWebMessageMatching(testWindow.Recording, "phase\":2");
}