// End-to-end NavRail test: verify that clicks flip the parent's view // state AND the active button class follows. We observe the DOM — // that's what the running Tauri webview shows, and it's what the user // sees. // // Pattern: `let view = $state("home")` in the harness, then the // `on_select` callback updates it (same shape as App.svelte). import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { mount, unmount, tick } from "svelte"; import NavRailHarness from "./NavRailHarness.svelte"; let target: HTMLDivElement; let app: ReturnType | null = null; beforeEach(() => { target = document.createElement("div"); document.body.appendChild(target); }); afterEach(() => { if (app) unmount(app); target.remove(); }); async function mountHarness() { app = mount(NavRailHarness, { target }); await tick(); } describe("NavRail (callback-prop pattern)", () => { it("renders 4 buttons with home active", async () => { await mountHarness(); const btns = target.querySelectorAll("button.rail__btn"); expect(btns.length).toBe(4); expect(btns[0].classList.contains("active")).toBe(true); expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("home"); }); it("flips view + active class on click", async () => { await mountHarness(); const btns = target.querySelectorAll("button.rail__btn"); btns[3].dispatchEvent(new MouseEvent("click", { bubbles: true })); await tick(); expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("search"); expect(btns[3].classList.contains("active")).toBe(true); expect(btns[0].classList.contains("active")).toBe(false); btns[1].dispatchEvent(new MouseEvent("click", { bubbles: true })); await tick(); expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("compose"); expect(btns[1].classList.contains("active")).toBe(true); btns[2].dispatchEvent(new MouseEvent("click", { bubbles: true })); await tick(); expect(target.querySelector('[data-testid="view-value"]')?.textContent).toBe("profile"); expect(btns[2].classList.contains("active")).toBe(true); }); });