// @vitest-environment happy-dom import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { SHORTCUTS, closeHelp, installHelpKeybind, isHelpOpen, isTypingTarget, 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 every registered shortcut, grouped", () => { openHelp(); const groups = [...document.querySelectorAll(".help-group-title")].map((h) => h.textContent); expect(groups).toEqual(SHORTCUTS.map((g) => g.title)); expect(rows()).toEqual(SHORTCUTS.flatMap((g) => g.items.map((s) => s.keys.join(" ")))); expect(document.querySelectorAll(".help-desc")).toHaveLength( SHORTCUTS.reduce((n, g) => n + g.items.length, 0), ); }); 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); }); }); describe("isTypingTarget", () => { it("is true for form fields and editable nodes, false otherwise", () => { const el = (html: string) => { const d = document.createElement("div"); d.innerHTML = html; return d.firstElementChild as HTMLElement; }; expect(isTypingTarget(el(""))).toBe(true); expect(isTypingTarget(el(""))).toBe(true); expect(isTypingTarget(el(""))).toBe(true); expect(isTypingTarget(el('
'))).toBe(true); expect(isTypingTarget(el(""))).toBe(false); expect(isTypingTarget(null)).toBe(false); }); });