diff --git a/tests/PalladiumWallet.Tests/App/HeadlessSetup.cs b/tests/PalladiumWallet.Tests/App/HeadlessSetup.cs index 628979f..02349bc 100644 --- a/tests/PalladiumWallet.Tests/App/HeadlessSetup.cs +++ b/tests/PalladiumWallet.Tests/App/HeadlessSetup.cs @@ -22,7 +22,23 @@ internal static class UiSession private static readonly Lazy Session = new(() => HeadlessUnitTestSession.StartNew(typeof(TestAppBuilder))); - public static Task Run(Func body) => Session.Value.Dispatch(body, CancellationToken.None); + // Avalonia's Dispatch(Func) returns as soon as the body reaches its first real await: + // everything after it (including the assertions) would silently never run and the test would + // pass vacuously. So the async body is driven to completion here, pumping the dispatcher on + // the UI thread (the continuations of its awaits are posted there), with a hard time limit. + public static Task Run(Func body) => Session.Value.Dispatch(() => + { + var task = body(); + var deadline = DateTime.UtcNow + TimeSpan.FromMinutes(2); + while (!task.IsCompleted) + { + if (DateTime.UtcNow > deadline) + throw new TimeoutException("Async UI test body did not complete within 2 minutes."); + Avalonia.Threading.Dispatcher.UIThread.RunJobs(); + Thread.Sleep(1); + } + task.GetAwaiter().GetResult(); + }, CancellationToken.None); public static Task Run(Action body) => Session.Value.Dispatch(() => { body(); return Task.CompletedTask; }, CancellationToken.None); diff --git a/tests/PalladiumWallet.Tests/App/VmTestBase.cs b/tests/PalladiumWallet.Tests/App/VmTestBase.cs index 9c131c2..a78a30d 100644 --- a/tests/PalladiumWallet.Tests/App/VmTestBase.cs +++ b/tests/PalladiumWallet.Tests/App/VmTestBase.cs @@ -34,7 +34,10 @@ public abstract class VmTestBase : IDisposable MainWindowViewModel.UpdateCheck = _ => Task.FromResult(null); // No bootstrap servers: the only reachable server is the in-process fake, so the // VM's connect/reconnect loops can never touch a real indexing server. - MainWindowViewModel.ProfileOverride = ChainProfiles.Mainnet with { BootstrapServers = [] }; + // No checkpoints either: the fake chains use tiny heights, and with the real mainnet checkpoints + // every proof would have to be anchored up to height 20,000 (ADR 0040), which the fake + // server does not serve. Tests that care about anchoring set their own profile. + MainWindowViewModel.ProfileOverride = ChainProfiles.Mainnet with { BootstrapServers = [], Checkpoints = [] }; new AppConfig { LastServerHost = _server.Host, LastServerPort = _server.Port, LastServerUseSsl = false } .Save(AppPaths.ConfigPath()); }