// @vitest-environment jsdom import { beforeEach, describe, expect, it, vi } from "vitest"; import { fillFields } from "./fill"; describe("content fill", () => { beforeEach(() => { document.body.innerHTML = ""; }); function makeVisibleInput(type: string): HTMLInputElement { const input = document.createElement("input"); input.type = type; Object.defineProperty(input, "getBoundingClientRect", { configurable: true, value: () => ({ width: 100, height: 20, top: 0, left: 0, right: 100, bottom: 20, x: 0, y: 0, toJSON: () => ({}), }), }); document.body.appendChild(input); return input; } it("fillFields writes username and password into matching inputs", () => { const username = makeVisibleInput("text"); const password = makeVisibleInput("password"); fillFields(username, password, "june", "hunter2"); expect(username.value).toBe("june"); expect(password.value).toBe("hunter2"); }); it("fillFields refuses to fill when the form action domain does not match", () => { const form = document.createElement("form"); form.action = "https://evil.com/login"; const username = makeVisibleInput("text"); const password = makeVisibleInput("password"); form.append(username, password); document.body.appendChild(form); fillFields(username, password, "june", "hunter2", form, "github.com"); expect(username.value).toBe(""); expect(password.value).toBe(""); }); it("fillFields still fills the username when the username field is hidden", () => { const username = makeVisibleInput("text"); const password = makeVisibleInput("password"); Object.defineProperty(username, "getBoundingClientRect", { value: () => ({ width: 0, height: 0, top: 0, left: 0, right: 0, bottom: 0, x: 0, y: 0, toJSON: () => ({}), }), }); fillFields(username, password, "june", "hunter2"); expect(username.value).toBe("june"); expect(password.value).toBe("hunter2"); }); it("fillFields dispatches standard input/change events rather than custom password events", () => { const username = makeVisibleInput("text"); const password = makeVisibleInput("password"); const usernameDispatch = vi.spyOn(username, "dispatchEvent"); const passwordDispatch = vi.spyOn(password, "dispatchEvent"); fillFields(username, password, "june", "hunter2"); expect(usernameDispatch.mock.calls.map(([event]) => event.type)).toEqual(["input", "change"]); expect(passwordDispatch.mock.calls.map(([event]) => event.type)).toEqual(["input", "change"]); expect(passwordDispatch.mock.calls.every(([event]) => !(event instanceof CustomEvent))).toBe(true); }); });