1import { describe, expect, it } from "vite-plus/test";
2import { recordingKeyLabel, recordingKeysAreSensitive } from "./RecordingInput.ts";
3
4const key = (
5 value: string,
6 modifiers: Partial<{
7 metaKey: boolean;
8 ctrlKey: boolean;
9 altKey: boolean;
10 shiftKey: boolean;
11 }> = {},
12) => ({
13 key: value,
14 metaKey: false,
15 ctrlKey: false,
16 altKey: false,
17 shiftKey: false,
18 ...modifiers,
19});
20
21describe("recording key labels", () => {
22 it("formats macOS and other-platform shortcuts", () => {
23 expect(recordingKeyLabel(key("c", { metaKey: true }), true)).toBe("⌘C");
24 expect(recordingKeyLabel(key("c", { ctrlKey: true }), false)).toBe("Ctrl + C");
25 expect(recordingKeyLabel(key("Tab", { altKey: true, shiftKey: true }), true)).toBe("⌥⇧⇥");
26 });
27 it("shows held modifiers once and labels navigation keys", () => {
28 expect(recordingKeyLabel(key("Meta", { metaKey: true }), true)).toBe("⌘");
29 expect(recordingKeyLabel(key("Shift", { shiftKey: true }), false)).toBe("Shift");
30 expect(recordingKeyLabel(key("ArrowLeft"), true)).toBe("←");
31 expect(recordingKeyLabel(key(" "), false)).toBe("Space");
32 });
33 it.each(["Dead", "Unidentified", "Process", ""])("excludes composition key %s", (value) => {
34 expect(recordingKeyLabel(key(value), true)).toBeNull();
35 });
36});
37
38describe("recording key privacy", () => {
39 const field = (type: string) => ({ tagName: "INPUT", getAttribute: () => type });
40 const sensitive = (activeElement: unknown) =>
41 recordingKeysAreSensitive({ activeElement } as Document);
42 it("excludes password fields and their shadow-root focus", () => {
43 expect(sensitive(field("password"))).toBe(true);
44 expect(sensitive({ shadowRoot: { activeElement: field("password") } })).toBe(true);
45 expect(sensitive(field("text"))).toBe(false);
46 });
47 it("excludes iframe focus whose field cannot be inspected", () => {
48 expect(sensitive({ tagName: "IFRAME" })).toBe(true);
49 expect(sensitive({ tagName: "SECRET-FIELD" })).toBe(true);
50 });
51});