inject.keyguard.test.ts

2.5 KB · raw

1// @vitest-environment jsdom23import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";45// PCH-01-007: the three document-level keydown handlers inside the inline6// selector must ignore page-synthesised KeyboardEvents (isTrusted === false),7// so a host page cannot script selection + fill without a real keypress.89describe("PCH-01-007 — inject keydown handlers gate on e.isTrusted", () => {10  let showAutofillSelector: typeof import("./inject").showAutofillSelector;11  let cleanup: (() => void) | null = null;1213  beforeEach(async () => {14    vi.resetModules();15    (globalThis as unknown as { chrome: unknown }).chrome = {16      runtime: { sendMessage: vi.fn(), getURL: (p: string) => p },17    };18    class NoopObserver {19      observe() {}20      unobserve() {}21      disconnect() {}22    }23    (globalThis as unknown as { ResizeObserver: unknown }).ResizeObserver = NoopObserver;24    (globalThis as unknown as { IntersectionObserver: unknown }).IntersectionObserver = NoopObserver;25    ({ showAutofillSelector } = await import("./inject"));26  });2728  afterEach(() => {29    cleanup?.();30    cleanup = null;31    document.body.innerHTML = "";32  });3334  it("ignores untrusted ArrowDown/Enter — no fill without user intent", () => {35    const input = document.createElement("input");36    document.body.appendChild(input);37    const onSelect = vi.fn();38    cleanup = showAutofillSelector(39      input,40      [41        { id: "1", title: "GitHub", username: "june", url: "https://github.com" },42        { id: "2", title: "GitLab", username: "june", url: "https://gitlab.com" },43      ],44      onSelect,45      { domain: "github.com" },46    );4748    // Synthetic events have isTrusted === false in jsdom → handlers no-op.49    document.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowDown", bubbles: true }));50    document.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));5152    expect(onSelect).not.toHaveBeenCalled();53  });5455  it("ignores untrusted single-character keys (type-to-search handlers no-op)", () => {56    const input = document.createElement("input");57    document.body.appendChild(input);58    const onSelect = vi.fn();59    cleanup = showAutofillSelector(60      input,61      [{ id: "1", title: "GitHub", username: "june", url: "https://github.com" }],62      onSelect,63      { domain: "github.com" },64    );6566    // A page-dispatched printable key must not drive selection/fill.67    document.dispatchEvent(new KeyboardEvent("keydown", { key: "a", bubbles: true }));68    expect(onSelect).not.toHaveBeenCalled();69  });70});