feat: add Ask ChatGPT toolbar action
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import vm from 'node:vm';
|
||||
|
||||
test('toolbar asks about the clicked tab selection and opens blank when unavailable', async () => {
|
||||
let click;
|
||||
let frames = [];
|
||||
let restricted = false;
|
||||
let settings = { contextMenuMode: 'off' };
|
||||
const opened = [];
|
||||
const noop = { addListener() {}, removeListener() {} };
|
||||
globalThis.browser = {
|
||||
storage: { sync: { get: async () => settings }, onChanged: noop },
|
||||
runtime: { onConnect: noop },
|
||||
menus: { removeAll: async () => {}, onShown: noop, onHidden: noop, onClicked: noop },
|
||||
commands: { onCommand: noop },
|
||||
browserAction: { onClicked: { addListener: listener => { click = listener; } } },
|
||||
tabs: {
|
||||
// The clicked tab must be used even if another tab becomes active.
|
||||
query: async () => [{ id: 99 }],
|
||||
executeScript: async (id, { code }) => {
|
||||
assert.equal(id, 7);
|
||||
if (restricted) throw new Error('Restricted page');
|
||||
return frames.map(frame => vm.runInNewContext(code, {
|
||||
document: {
|
||||
hasFocus: () => frame.focus,
|
||||
activeElement: { tagName: frame.active ?? 'BODY' },
|
||||
},
|
||||
window: { getSelection: () => ({ toString: () => frame.text }) },
|
||||
}));
|
||||
},
|
||||
create: async options => { opened.push(options); },
|
||||
},
|
||||
windows: { create: async options => { opened.push({ ...options, window: true }); } },
|
||||
};
|
||||
try {
|
||||
await import('../background/background.js');
|
||||
assert.equal(typeof click, 'function', 'toolbar click handler must be registered');
|
||||
for (const [selection, expected] of [
|
||||
[[{ focus: true, text: 'selected $& text' }], 'selected $& text'],
|
||||
[[{ focus: true, active: 'IFRAME', text: 'stale parent' },
|
||||
{ focus: false, text: 'stale sibling' },
|
||||
{ focus: true, text: 'iframe selection' }], 'iframe selection'],
|
||||
[[{ focus: true, text: '' }], null],
|
||||
[[{ focus: false, text: 'stale selection' }], null],
|
||||
]) {
|
||||
frames = selection;
|
||||
await click({ id: 7 });
|
||||
assert.equal(new URL(opened.at(-1).url).searchParams.get('q'), expected);
|
||||
}
|
||||
|
||||
settings = { contextMenuMode: 'off', promptTemplate: 'Explain: {query}', openIn: 'background-tab' };
|
||||
frames = [{ focus: true, text: 'hello' }];
|
||||
await click({ id: 7 });
|
||||
assert.deepEqual(opened.at(-1), { url: 'https://chatgpt.com/?q=Explain%3A+hello', active: false });
|
||||
|
||||
settings = { openIn: 'new-window' };
|
||||
restricted = true;
|
||||
await click({ id: 7 });
|
||||
assert.deepEqual(opened.at(-1), { url: 'https://chatgpt.com/', window: true });
|
||||
} finally {
|
||||
delete globalThis.browser;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user