Make the node breadcrumb a seed picker

- replace the node breadcrumb link with a SeedPicker in the repo, user
  and node views, so the node serving a page can be switched where it
  is named
- remove current node picker from settings panel
- reach the node view through the picker's "Open node view" action
- cover the new breadcrumb picker in the e2e tests
- list the active seed in the seed picker
- the seed serving the page is also rendered in the list with a bookmark
  action instead of a remove one.
This commit is contained in:
Daniel Norman
2026-09-25 10:23:40 +02:00
committed by Rūdolfs Ošiņš
parent b9ba3b7917
commit 00f079d0d9
14 changed files with 206 additions and 123 deletions
-3
View File
@@ -64,9 +64,6 @@ test("seed picker lives in the settings dropdown on explore", async ({
await expect(
page.getByRole("button", { name: "Search seed selector" }),
).toContainText("localhost");
// Explore names no node in its URL, so there's nothing to switch.
await expect(page.getByText("Current node")).toHaveCount(0);
});
test("explore shows an error when no seed can be reached", async ({ page }) => {
+45 -2
View File
@@ -185,10 +185,53 @@ test("node can be switched from a repo the node doesn't have", async ({
await expect(
page.getByRole("button", { name: "Seed selector" }),
).toBeVisible();
});
test("repo page shows the node selector in the header", async ({ page }) => {
await page.goto(`/nodes/localhost/${sourceBrowsingRid}`, {
waitUntil: "networkidle",
});
await page.getByRole("button", { name: "Settings" }).click();
await expect(page.getByText("Current node")).toBeVisible();
await expect(
page.getByRole("button", { name: "Current node selector" }),
).toContainText("localhost");
});
test("breadcrumb picker lists a seed that isn't bookmarked", async ({
page,
}) => {
// Proxy requests to seed.example.tld to the local test api, so the page can
// be served by a seed that is neither bookmarked nor a preferred one.
await page.route(
url => url.hostname === "seed.example.tld",
route =>
route.fulfill({
status: 301,
headers: {
Location: route
.request()
.url()
.replace("seed.example.tld", "localhost"),
},
}),
);
await page.goto(`/nodes/seed.example.tld/${sourceBrowsingRid}`, {
waitUntil: "networkidle",
});
const picker = page.getByRole("button", { name: "Current node selector" });
await expect(picker).toContainText("seed.example.tld");
await picker.click();
// The seed serving the page is listed under the custom seeds, even though
// it was never bookmarked, and its node view is reachable from there.
const item = page
.locator(".item")
.filter({ hasText: "seed.example.tld" })
.first();
await expect(item).toBeVisible();
await item.getByRole("button", { name: "Open node view" }).click();
await expect(page).toHaveURL("/nodes/seed.example.tld");
});
+6 -1
View File
@@ -35,7 +35,12 @@ test("navigation between node and repo pages", async ({ page }) => {
await expectBackAndForwardNavigationWorks("/nodes/localhost", page);
await expectUrlPersistsReload(page);
await page.getByRole("link", { name: "Home" }).click();
// The node breadcrumb is a picker now, so the node page is reached through
// its "Open node view" action.
await page.getByRole("button", { name: "Current node selector" }).click();
await page
.getByRole("button", { name: "Open node view", exact: true })
.click();
await expect(page).toHaveURL("/nodes/localhost");
});