import test from 'node:test'; import assert from 'node:assert/strict'; import {EventEmitter} from 'node:events'; import {createRequire} from 'node:module'; import vm from 'node:vm'; const require=createRequire(import.meta.url); const {attachPageClipboardGuard,guardedScreenshot,disposePageClipboardGuard}=require('../apps/browser/page-clipboard-guard.cjs'); const {capturePNG}=require('../apps/browser/visual-capture.cjs'); function fixture(valid=true){ const api=new EventEmitter(),commands=[];let attached=false,detaches=0,failures=0; api.isAttached=()=>attached;api.attach=version=>{assert.equal(version,'1.3');attached=true;}; api.detach=()=>{attached=false;detaches++;api.emit('detach');}; const png=Buffer.from('Public bounded screenshot fixture'); api.sendCommand=async(method,parameters)=>{commands.push({method,parameters});if(method==='Page.addScriptToEvaluateOnNewDocument')return valid?{identifier:'fixed-guard'}:{};if(method==='Page.captureScreenshot')return {data:png.toString('base64')};return {};}; const contents={debugger:api,isDestroyed:()=>false}; return {api,contents,commands,png,detachCount:()=>detaches,failureCount:()=>failures,initialize:()=>attachPageClipboardGuard(contents,()=>failures++)}; } test('static page guard registers only fixed initialization and shares screenshot without detaching',async()=>{ const f=fixture();await f.initialize();assert.deepEqual(f.commands.map(c=>c.method),['Page.enable','Page.addScriptToEvaluateOnNewDocument']); assert.equal(/require\(|ipcRenderer|process\./.test(f.commands[1].parameters.source),false); assert.deepEqual(await capturePNG(f.contents),f.png);assert.equal(f.commands.at(-1).method,'Page.captureScreenshot');assert.equal(f.detachCount(),0); disposePageClipboardGuard(f.contents);assert.equal(f.detachCount(),1);assert.equal(f.failureCount(),0);assert.equal(guardedScreenshot(f.contents,{}),null); }); test('unknown attachment and invalid initialization cannot gain trusted screenshot ownership',async()=>{ const occupied=fixture();occupied.api.attach('1.3');await assert.rejects(occupied.initialize());assert.equal(occupied.commands.length,0); const invalid=fixture(false);await assert.rejects(invalid.initialize());assert.equal(invalid.detachCount(),1);assert.equal(guardedScreenshot(invalid.contents,{}),null); }); test('unexpected disconnect revokes ownership and reports failure; deliberate disposal is idempotent',async()=>{ const f=fixture();await f.initialize();f.api.detach();assert.equal(f.failureCount(),1);assert.equal(guardedScreenshot(f.contents,{}),null);disposePageClipboardGuard(f.contents);assert.equal(f.detachCount(),1); }); test('new-frame source freezes clipboard and replacement primitives against page tampering',async()=>{ const f=fixture();await f.initialize();const native=[]; class Document{execCommand(command){native.push(command);return true;}open(){return 'opened';}write(){}writeln(){}} const listeners=[],realm={Document,DOMException,window:{addEventListener:(name,handler,capture)=>listeners.push({name,handler,capture})}}; vm.createContext(realm);vm.runInContext(f.commands[1].parameters.source,realm); const doc=new Document();for(const name of ['copy','cut','paste','PasteAndMatchStyle'])assert.equal(doc.execCommand(name),false); assert.equal(doc.execCommand('insertText'),true);assert.deepEqual(native,['insertText']); for(const name of ['open','write','writeln'])assert.throws(()=>doc[name](),error=>error.name==='SecurityError'); vm.runInContext('Reflect.apply=()=>true;RegExp.prototype.test=()=>false;',realm);assert.equal(doc.execCommand('copy'),false); assert.throws(()=>Object.defineProperty(Document.prototype,'execCommand',{value:()=>true})); for(const name of ['copy','cut','paste','dragstart','drop']){let prevented=false,stopped=false;const listener=listeners.find(item=>item.name===name);assert.equal(listener.capture,true);listener.handler({preventDefault:()=>prevented=true,stopImmediatePropagation:()=>stopped=true});assert.equal(prevented&&stopped,true);} disposePageClipboardGuard(f.contents); });