feat: add advanced context actions and optional translation
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { initializeShortcut } from "../options/shortcut.js";
|
||||
|
||||
function setup(commands) {
|
||||
const elements = Object.fromEntries([
|
||||
"shortcut-intro", "shortcut-hint", "shortcut-current", "change-shortcut",
|
||||
].map((id) => [id, Object.assign(new EventTarget(), { textContent: "", hidden: true })]));
|
||||
const document = Object.assign(new EventTarget(), {
|
||||
visibilityState: "visible",
|
||||
getElementById: (id) => elements[id],
|
||||
});
|
||||
const window = new EventTarget();
|
||||
const ready = initializeShortcut({ commands, document, window });
|
||||
return { elements, document, window, ready };
|
||||
}
|
||||
|
||||
const flush = () => new Promise((resolve) => setImmediate(resolve));
|
||||
const command = (shortcut) => ({ name: "ask-chatgpt", description: "Ask ChatGPT", shortcut });
|
||||
|
||||
test("shows the configured command rather than another command or the default", async () => {
|
||||
const { elements, ready } = setup({ getAll: async () => [
|
||||
{ name: "other", description: "Other", shortcut: "Alt+O" }, command("Ctrl+Shift+Y"),
|
||||
] });
|
||||
await ready;
|
||||
for (const id of ["shortcut-intro", "shortcut-hint", "shortcut-current"]) {
|
||||
assert.match(elements[id].textContent, /Ctrl\+Shift\+Y/);
|
||||
assert.doesNotMatch(elements[id].textContent, /Alt\+Shift\+G|Alt\+O/);
|
||||
}
|
||||
});
|
||||
|
||||
test("updates an open page when the shortcut is removed", async () => {
|
||||
let changed;
|
||||
let shortcut = "Alt+Shift+G";
|
||||
const { elements, ready } = setup({
|
||||
getAll: async () => [command(shortcut)],
|
||||
onChanged: { addListener: (listener) => { changed = listener; } },
|
||||
});
|
||||
await ready;
|
||||
shortcut = "";
|
||||
changed({ name: "ask-chatgpt", newShortcut: "", oldShortcut: "Alt+Shift+G" });
|
||||
await flush();
|
||||
assert.match(elements["shortcut-current"].textContent, /No keyboard shortcut assigned/);
|
||||
assert.doesNotMatch(elements["shortcut-intro"].textContent, /press|Alt\+Shift\+G/i);
|
||||
});
|
||||
|
||||
test("refreshes on focus and visibility without the change event API", async () => {
|
||||
let shortcut = "Alt+Shift+G";
|
||||
const { elements, window, document, ready } = setup({ getAll: async () => [command(shortcut)] });
|
||||
await ready;
|
||||
shortcut = "Ctrl+Shift+Y";
|
||||
window.dispatchEvent(new Event("focus"));
|
||||
await flush();
|
||||
assert.match(elements["shortcut-current"].textContent, /Ctrl\+Shift\+Y/);
|
||||
shortcut = "Alt+J";
|
||||
document.dispatchEvent(new Event("visibilitychange"));
|
||||
await flush();
|
||||
assert.match(elements["shortcut-current"].textContent, /Alt\+J/);
|
||||
});
|
||||
|
||||
test("missing commands and failed reads never claim the default is assigned", async () => {
|
||||
for (const commands of [undefined, { getAll: async () => [] }, {
|
||||
getAll: async () => { throw new Error("Unavailable"); },
|
||||
}]) {
|
||||
const { elements, ready } = setup(commands);
|
||||
await ready;
|
||||
assert.doesNotMatch(elements["shortcut-current"].textContent, /Alt\+Shift\+G/);
|
||||
assert.equal(elements["change-shortcut"].hidden, true);
|
||||
}
|
||||
});
|
||||
|
||||
test("shortcut editor failure displays manual recovery instructions", async () => {
|
||||
const { elements, ready } = setup({
|
||||
getAll: async () => [command("Alt+J")],
|
||||
openShortcutSettings: async () => { throw new Error("Unavailable"); },
|
||||
});
|
||||
await ready;
|
||||
assert.equal(elements["change-shortcut"].hidden, false);
|
||||
elements["change-shortcut"].dispatchEvent(new Event("click"));
|
||||
await flush();
|
||||
assert.match(elements["shortcut-current"].textContent, /Manage Extension Shortcuts/);
|
||||
});
|
||||
Reference in New Issue
Block a user