Merge pull request 'Start port forwards on the phone, listed in a sheet off its terminal' (#20) from claude/dazzling-moser-641acd into main
ci / build and test (push) Successful in 3m57s
ci / desktop nightly (push) Successful in 1m28s
ci / api image (push) Failing after 13s
ci / android head (push) Successful in 5m32s

Reviewed-on: #20
This commit was merged in pull request #20.
This commit is contained in:
jaap-jan committed 2026-09-28 19:06:37 +00:00
commit d7d002c972
13 files changed
+415 -56

No files matched your search

@@ -157,6 +157,78 @@ public sealed partial class ShellFlowTests
ssh.Forwards.ShouldBeEmpty();
}
// ---- The phone's sheet ----
/// <remarks>
/// The phone lists a tab's forwards in a sheet over the terminal, so it obeys the connect sheet's rules:
/// it collapses the renderer while it is up, and leaving the terminal lowers it however it is left.
/// </remarks>
[Fact]
public async Task TheForwardsSheet_HidesTheRenderer_AndLeavingTheTerminalLowersIt()
{
await ConnectedHostWithForwardsAsync();
shell.SelectedTab.ShouldNotBeNull().HasForwards.ShouldBeTrue();
shell.OpenForwardsSheetCommand.Execute(null);
shell.IsForwardsSheetOpen.ShouldBeTrue();
shell.IsTerminalShowing.ShouldBeFalse("the sheet draws over the renderer's rectangle");
shell.IsTerminalSurface.ShouldBeTrue("the bar the sheet was raised from is on that surface");
shell.CloseForwardsSheetCommand.Execute(null);
shell.IsTerminalShowing.ShouldBeTrue();
shell.OpenForwardsSheetCommand.Execute(null);
shell.ShowScreenCommand.Execute(ShellScreen.Keychain);
shell.IsForwardsSheetOpen.ShouldBeFalse("a sheet left up over a page would hold the renderer blank");
shell.OpenForwardsSheetCommand.Execute(null);
shell.IsForwardsSheetOpen.ShouldBeFalse("it must not open over a page either");
}
/// <remarks>
/// What the phone's bar button and its keep-alive notification read: whether a tab has forwards, whether
/// one failed, and how many listen across every tab — with an event each time any of that moves.
/// </remarks>
[Fact]
public async Task TheCountsAPhoneShows_FollowEveryForwardsState()
{
ssh.ForwardFailure = spec => spec.BindPort == 5432 ? "Port 5432 on this machine is already in use." : null;
var changes = 0;
shell.ForwardsChanged += (_, _) => changes++;
await ConnectedHostWithForwardsAsync();
var tab = shell.Tabs.ShouldHaveSingleItem();
await EventuallyAsync(() => tab.Forwards.All(row => row.State is not PortForwardState.Starting), "both should settle");
tab.HasForwards.ShouldBeTrue();
tab.HasFailedForward.ShouldBeTrue();
tab.HasListeningForward.ShouldBeTrue();
shell.ListeningForwardCount.ShouldBe(1);
changes.ShouldBeGreaterThan(0);
var before = changes;
ssh.ForwardFailure = null;
await tab.Forwards[0].ToggleCommand.ExecuteAsync(null);
tab.HasFailedForward.ShouldBeFalse();
shell.ListeningForwardCount.ShouldBe(2);
changes.ShouldBeGreaterThan(before, "a retry that listens is a change the notification has to hear");
ssh.Shells.ShouldHaveSingleItem().Drop("An established connection was aborted by the server.");
await EventuallyAsync(() => !tab.IsLive, "the dropped shell should have ended the session");
shell.ListeningForwardCount.ShouldBe(0);
tab.HasListeningForward.ShouldBeFalse();
tab.HasForwards.ShouldBeTrue("the rows stay, saying they went with the session");
}
// ---- The editor ----
[Fact]