Files
star-chart-search-enhancer/tests/favorite-folder-dialog.test.ts
T

171 lines
5.4 KiB
TypeScript

// @vitest-environment jsdom
import { beforeEach, describe, expect, test } from "vitest";
import { promptForFavoriteFolderName } from "../src/content/market/favorite-folder-dialog";
function readDialog(): HTMLElement {
const dialog = document.querySelector(
'[data-sces-favorite-folder-dialog="root"]'
);
if (!(dialog instanceof HTMLElement)) {
throw new Error("Expected favorite folder dialog");
}
return dialog;
}
function readInput(): HTMLInputElement {
const input = document.querySelector(
'[data-sces-favorite-folder-dialog="input"]'
);
if (!(input instanceof HTMLInputElement)) {
throw new Error("Expected favorite folder name input");
}
return input;
}
function readButton(name: "confirm" | "cancel"): HTMLButtonElement {
const button = document.querySelector(
`[data-sces-favorite-folder-dialog="${name}"]`
);
if (!(button instanceof HTMLButtonElement)) {
throw new Error(`Expected ${name} button`);
}
return button;
}
describe("favorite-folder-dialog", () => {
beforeEach(() => {
document.body.innerHTML = "";
});
test("renders the requested title and initial name, then trims a confirmation", async () => {
const result = promptForFavoriteFolderName(document, {
initialValue: " 重点合作 ",
title: "重命名收藏夹"
});
expect(readDialog().getAttribute("role")).toBe("dialog");
expect(readDialog().textContent).toContain("重命名收藏夹");
expect(readInput().value).toBe(" 重点合作 ");
expect(document.activeElement).toBe(readInput());
readButton("confirm").click();
await expect(result).resolves.toBe("重点合作");
expect(
document.querySelector('[data-sces-favorite-folder-dialog="root"]')
).toBeNull();
});
test("keeps an inline error open for blank names and clears it after input", async () => {
const result = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
readInput().value = " ";
readButton("confirm").click();
expect(
document.querySelector('[data-sces-favorite-folder-dialog="error"]')?.textContent
).toBe("请输入收藏夹名称");
expect(readInput().getAttribute("aria-invalid")).toBe("true");
expect(document.activeElement).toBe(readInput());
readInput().value = "重点";
readInput().dispatchEvent(new Event("input", { bubbles: true }));
expect(
document.querySelector('[data-sces-favorite-folder-dialog="error"]')?.textContent
).toBe("");
readButton("cancel").click();
await expect(result).resolves.toBeNull();
});
test("cancels from its cancel button, overlay click, and Escape", async () => {
const fromCancel = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
readButton("cancel").click();
await expect(fromCancel).resolves.toBeNull();
const fromOverlay = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
readDialog().dispatchEvent(new MouseEvent("click", { bubbles: true }));
await expect(fromOverlay).resolves.toBeNull();
const fromEscape = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
document.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
await expect(fromEscape).resolves.toBeNull();
});
test("confirms a valid name with Enter", async () => {
const result = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
readInput().value = "待联系";
document.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" }));
await expect(result).resolves.toBe("待联系");
});
test("reuses and focuses one active dialog per document, then allows a new one after close", async () => {
const first = promptForFavoriteFolderName(document, {
initialValue: "首个值",
title: "新建收藏夹"
});
const input = readInput();
input.blur();
const reused = promptForFavoriteFolderName(document, {
initialValue: "不会替换",
title: "重命名收藏夹"
});
expect(reused).toBe(first);
expect(
document.querySelectorAll('[data-sces-favorite-folder-dialog="root"]')
).toHaveLength(1);
expect(readInput().value).toBe("首个值");
expect(document.activeElement).toBe(input);
readButton("cancel").click();
await expect(first).resolves.toBeNull();
const second = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
expect(
document.querySelectorAll('[data-sces-favorite-folder-dialog="root"]')
).toHaveLength(1);
readButton("cancel").click();
await expect(second).resolves.toBeNull();
});
test("traps Tab within the dialog and restores the opener focus on close", async () => {
const opener = document.createElement("button");
opener.type = "button";
opener.textContent = "打开收藏夹";
document.body.append(opener);
opener.focus();
const result = promptForFavoriteFolderName(document, {
title: "新建收藏夹"
});
readInput().focus();
document.dispatchEvent(new KeyboardEvent("keydown", { key: "Tab", shiftKey: true }));
expect(document.activeElement).toBe(readButton("confirm"));
document.dispatchEvent(new KeyboardEvent("keydown", { key: "Tab" }));
expect(document.activeElement).toBe(readInput());
readButton("cancel").click();
await expect(result).resolves.toBeNull();
expect(document.activeElement).toBe(opener);
});
});