Back closes what is open
On a phone the Back button left the page under an open menu, sheet or dialog. An open overlay now says so (new IDOverlayHost, cascaded by MainLayout; OverlayService keeps them newest last): DModal and DDropdown through the cascade, so the D components stay free of app services, and the nav menu, PhoneSheet and the full-screen globe through the service. MainLayout's location-changing handler lets Back close the newest overlay instead of leaving the page; a link followed or the app's own navigation (signing out after its question, say) closes them all and goes on. Blazor can't tell Back from the app's navigation, so a capture-phase popstate listener in main.js marks Back (AppStatusService.TookBack). No history entries are pushed. Phone flow: Back closes the menu, a card's More sheet, the composer and the full-screen globe one after another without leaving the feed, and with nothing open goes back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
5522fe4fbb
commit
f1ac5eaad2
12 files changed
+290
-17
No files matched your search
@@ -310,6 +310,51 @@ namespace decePubClient.E2E.Mobile
|
||||
});
|
||||
}
|
||||
|
||||
// the Back button closes what is open, one at a time, and stays on the page
|
||||
[Fact]
|
||||
public async Task Back_closes_what_is_open()
|
||||
{
|
||||
await using var session = await SignIn.As(browser, Persona(), Phone);
|
||||
await Flow(session, "back", async page =>
|
||||
{
|
||||
var home = page.Url;
|
||||
// a page to go back to, so a Back that isn't held would leave the feed
|
||||
await page.Locator("[data-nav-toggle]").TapAsync();
|
||||
await page.Locator("[data-nav-panel] a[href='explore']").TapAsync();
|
||||
await page.WaitForURLAsync(url => new Uri(url).AbsolutePath == "/explore");
|
||||
await page.Locator("[data-nav-toggle]").TapAsync();
|
||||
await page.Locator("[data-nav-panel] a[href='/']").First.TapAsync();
|
||||
await page.WaitForURLAsync(url => new Uri(url).AbsolutePath == "/");
|
||||
await page.Locator("#feed-scroll article[data-uri]").First.WaitForAsync();
|
||||
|
||||
async Task BackCloses(ILocator open, string what)
|
||||
{
|
||||
await Assertions.Expect(open).ToBeVisibleAsync();
|
||||
await page.GoBackAsync();
|
||||
await Assertions.Expect(open).ToBeHiddenAsync(new() { Timeout = 5000 });
|
||||
Assert.True(new Uri(page.Url).AbsolutePath == "/", $"Back after the {what} left the feed for {page.Url}");
|
||||
}
|
||||
|
||||
await page.Locator("[data-nav-toggle]").TapAsync();
|
||||
await BackCloses(page.Locator("[data-nav-panel]"), "menu");
|
||||
|
||||
var card = Card(page, "footer [title='Other']");
|
||||
await card.Locator("footer [title='Other'] > [role=button]").TapAsync();
|
||||
await BackCloses(card.Locator(".dropdown-open > [data-sheet]"), "More sheet");
|
||||
|
||||
await page.Locator("[data-compose-open]").TapAsync();
|
||||
await BackCloses(page.Locator("[data-sheet]:has(textarea[data-compose])"), "composer");
|
||||
|
||||
await page.Locator("button[title='Globe']").TapAsync();
|
||||
await page.Locator("[data-globe-expand]").TapAsync();
|
||||
await BackCloses(page.Locator("aside[role=dialog]"), "full-screen globe");
|
||||
|
||||
// with nothing open, Back leaves the feed as before
|
||||
await page.GoBackAsync();
|
||||
await page.WaitForURLAsync(url => new Uri(url).AbsolutePath == "/explore", new() { Timeout = 10000 });
|
||||
});
|
||||
}
|
||||
|
||||
static async Task<JsonNode> Latest(Pasture.Persona persona) =>
|
||||
(await PersonaApi.Call(persona, $"/api/v1/accounts/{persona.LocalId}/statuses?limit=1"))!.AsArray().FirstOrDefault();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user