Compare commits

...
Author SHA1 Message Date
jaap-jan f43436218a Tests: wait for a dropped session's forwards to stop, not just for the tab to go dead
ci / build and test (pull_request) Successful in 2m42s
ci / desktop nightly (pull_request) Skipped
ci / api image (pull_request) Successful in 7s
ci / deploy ssh.dodotech.cloud (pull_request) Skipped
ci / android head (pull_request) Successful in 3m42s
WhenTheSessionEnds_ItsForwardsSayTheyWentWithIt failed once under a full run. Ended clears IsLive
and then tells each forward its session is over, in one call. The app's dispatcher never splits that,
but the harness's post runs it on the fake shell's thread, so the test's poll on !IsLive could return
between the two and find the forwards still listening.

The test now also waits until every forward says "Stopped with the session.", the last thing
SessionEnded sets. A 300 ms sleep injected between the two steps fails the old test and passes the new
one; the full App.Tests suite passed three runs in a row.
2026-10-16 13:17:01 +02:00
@@ -114,6 +114,13 @@ public sealed partial class ShellFlowTests
await EventuallyAsync(() => !tab.IsLive, "the dropped shell should have ended the session");
// Waited for in its own right rather than taken as read from IsLive. Ended clears IsLive and then
// ends the forwards in the same dispatcher turn, which the app's UI thread never splits — but this
// harness's post runs the ending on the fake shell's thread, so a poll from here can land between.
await EventuallyAsync(
() => tab.Forwards.All(row => row.Detail == "Stopped with the session."),
"the session's end should have reached its forwards");
tab.Forwards.ShouldAllBe(row => row.State == PortForwardState.Stopped);
tab.Forwards.ShouldAllBe(row => row.Detail == "Stopped with the session.");
tab.Forwards.ShouldAllBe(row => !row.CanToggle);