feat(web): persist workspace presentation across browser hosts — #205

This commit is contained in:
2026-08-15 01:24:23 +02:00
parent 723e2987ef
commit 3b8ce66e33
6 changed files with 542 additions and 13 deletions

View File

@ -7,7 +7,7 @@
* that selecting an entry routes the main surface without ever crashing on a
* desktop-only action.
*/
import { describe, it, expect, vi } from "vitest";
import { beforeEach, describe, it, expect, vi } from "vitest";
import { fireEvent, render, screen, within } from "@testing-library/react";
import type { Gateways } from "@/ports";
@ -34,6 +34,11 @@ const okFetch: FetchLike = async () => ({
text: async () => "{}",
});
beforeEach(() => {
window.localStorage.clear();
vi.restoreAllMocks();
});
async function seededGateways(): Promise<Gateways> {
const gateways = createMockGateways();
await gateways.project.createProject("Demo", "/srv/demo");
@ -89,6 +94,24 @@ describe("WebWorkspace « Panneaux » menu (#90)", () => {
open.mockRestore();
});
it("restores the #205 presentation state per project", async () => {
const gateways = await seededGateways();
const first = renderPairedWebApp(gateways);
fireEvent.click(await screen.findByText("Demo"));
fireEvent.click(await screen.findByRole("button", { name: "Surface Tickets" }));
fireEvent.click(screen.getByRole("button", { name: "Rail gauche" }));
fireEvent.click(screen.getByRole("button", { name: "Rail droit" }));
first.unmount();
renderPairedWebApp(gateways);
fireEvent.click(await screen.findByText("Demo"));
expect(await screen.findByText("Surface Tickets")).toBeTruthy();
expect(screen.getByRole("button", { name: "Rail gauche" }).getAttribute("aria-pressed")).toBe("false");
expect(screen.getByRole("button", { name: "Rail droit" }).getAttribute("aria-pressed")).toBe("false");
});
it("only enables Projets while no project is open, with a help note", async () => {
renderPairedWebApp(await seededGateways());