// @vitest-environment happy-dom import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { keyCaps, publishedCommands } from "./commands.js"; import { closeHelp, groupedCommands, installHelpKeybind, isHelpOpen, openHelp } from "./help.js"; beforeEach(() => { installHelpKeybind(); }); afterEach(() => { closeHelp(); document.body.replaceChildren(); }); function press(key: string, init: KeyboardEventInit = {}): void { window.dispatchEvent(new KeyboardEvent("keydown", { key, bubbles: true, ...init })); } function rows(): string[] { return [...document.querySelectorAll(".help-row")].map((r) => [...r.querySelectorAll("kbd")].map((k) => k.textContent).join(" "), ); } describe("help overlay", () => { it("renders exactly the commands the registry has bound, grouped", () => { openHelp(); const groups = groupedCommands(); expect([...document.querySelectorAll(".help-group-title")].map((h) => h.textContent)).toEqual( groups.map((g) => g.title), ); expect(rows()).toEqual( groups.flatMap((g) => g.items.map((c) => keyCaps(c.keys[0]).join(" "))), ); expect([...document.querySelectorAll(".help-desc")].map((d) => d.textContent)).toEqual( groups.flatMap((g) => g.items.map((c) => c.label)), ); }); it("names each row by its command id, so a row can't drift from its command", () => { openHelp(); expect([...document.querySelectorAll(".help-row")].map((r) => r.dataset.commandId)) .toEqual(publishedCommands().map((c) => c.id)); }); it("opens on ? and closes on a second ?", () => { press("?", { shiftKey: true }); expect(isHelpOpen()).toBe(true); press("?", { shiftKey: true }); expect(isHelpOpen()).toBe(false); }); it("closes on Escape, on the close button, and on a click outside the panel", () => { openHelp(); press("Escape"); expect(isHelpOpen()).toBe(false); openHelp(); (document.querySelector(".help-close") as HTMLButtonElement).click(); expect(isHelpOpen()).toBe(false); openHelp(); (document.querySelector(".help-overlay") as HTMLElement).dispatchEvent( new MouseEvent("click", { bubbles: true }), ); expect(isHelpOpen()).toBe(false); }); it("stays open for a click inside the panel", () => { openHelp(); (document.querySelector(".help-panel") as HTMLElement).dispatchEvent( new MouseEvent("click", { bubbles: true }), ); expect(isHelpOpen()).toBe(true); }); it("opening twice leaves one overlay", () => { openHelp(); openHelp(); expect(document.querySelectorAll(".help-overlay")).toHaveLength(1); }); it("ignores ? while typing and when a non-shift modifier is held", () => { const input = document.createElement("input"); document.body.appendChild(input); input.dispatchEvent(new KeyboardEvent("keydown", { key: "?", bubbles: true, shiftKey: true })); expect(isHelpOpen()).toBe(false); press("?", { ctrlKey: true }); expect(isHelpOpen()).toBe(false); }); it("installing the keybind twice still toggles once", () => { installHelpKeybind(); press("?", { shiftKey: true }); expect(isHelpOpen()).toBe(true); expect(document.querySelectorAll(".help-overlay")).toHaveLength(1); }); });