feat: add advanced context actions and optional translation
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import vm from 'node:vm';
|
||||
|
||||
test('shortcut uses focused leaf frame, ignores stale ancestors and opens blank without content focus',async()=>{
|
||||
let command;
|
||||
let frames=[];
|
||||
const opened=[];
|
||||
const noop={addListener(){},removeListener(){}};
|
||||
globalThis.browser={
|
||||
storage:{sync:{get:async()=>({contextMenuMode:'off'})},onChanged:noop},
|
||||
runtime:{onConnect:noop},
|
||||
menus:{removeAll:async()=>{},onShown:noop,onHidden:noop,onClicked:noop},
|
||||
commands:{onCommand:{addListener:f=>command=f}},
|
||||
tabs:{query:async()=>[{id:1}],executeScript:async(id,{code})=>frames.map(frame=>vm.runInNewContext(code,{document:{hasFocus:()=>frame.focus,activeElement:{tagName:frame.active??'BODY'}},window:{getSelection:()=>({toString:()=>frame.text})}})),create:async value=>opened.push(value)},
|
||||
};
|
||||
try {
|
||||
await import('../background/background.js');
|
||||
for (const [value,expected] of [
|
||||
[[{focus:true,text:'top'}],'top'],
|
||||
[[{focus:true,active:'IFRAME',text:'stale top'},{focus:true,text:'frame'}],'frame'],
|
||||
[[{focus:false,text:'stale top'},{focus:false,text:'stale frame'}],null],
|
||||
]) {
|
||||
frames=value;await command('ask-chatgpt');
|
||||
assert.equal(new URL(opened.at(-1).url).searchParams.get('q'),expected);
|
||||
}
|
||||
browser.tabs.executeScript=async()=>{throw Error('restricted');};
|
||||
await command('ask-chatgpt');assert.equal(opened.at(-1).url,'https://chatgpt.com/');
|
||||
} finally {delete globalThis.browser;}
|
||||
});
|
||||
Reference in New Issue
Block a user