import test from 'node:test'; import assert from 'node:assert/strict'; import vm from 'node:vm'; import {createRequire} from 'node:module'; const require=createRequire(import.meta.url),{fillScript}=require('../apps/browser/password-fill.cjs'); const credential={origin:'https://work.example',username:'employee',password:'fixture-only-generated-password'}; function fixture({url='https://work.example/login',action='https://work.example/signin',method='post',target='',visible=true,frame=false,multiple=false,override,focused=true,visibility='visible'}={}){ class Input{constructor(type){this.type=type;this.name=type==='password'?'password':'username';this.autocomplete='';this.disabled=false;this.readOnly=false;}set value(value){this.stored=value;}get value(){return this.stored;}closest(){return null;}getClientRects(){return visible?[{}]:[];}dispatchEvent(){}} const user=new Input('text'),password=new Input('password'); const form={action,method,target,querySelectorAll:()=>[user,password]};user.form=form;password.form=form; form.elements=override?[user,password,{getAttribute:name=>override[name]??null}]:[user,password]; const window={isSecureContext:true};window.top=frame?{}:window; return {user,password,context:vm.createContext({window,location:{href:url,origin:new URL(url).origin},document:{hasFocus:()=>focused,visibilityState:visibility,querySelectorAll:()=>multiple?[password,new Input('password')]:[password]},getComputedStyle:()=>({display:'block',visibility:'visible',opacity:'1'}),HTMLInputElement:Input,Event:class{},URL})}; } test('explicit fill sets exact-origin visible login fields without submitting',()=>{ const f=fixture();assert.equal(vm.runInContext(fillScript('https://work.example/login',credential),f.context).completed,true);assert.equal(f.user.stored,credential.username);assert.equal(f.password.stored,credential.password); }); test('HTTP, subdomains and alternate ports cannot reuse saved credentials',()=>{ for(const url of ['http://work.example/login','https://other.work.example/login','https://work.example:8443/login'])assert.throws(()=>fillScript(url,credential)); }); test('navigation, frames, cross-origin forms, GET, new-window, hidden and ambiguous targets fail before writing',()=>{ for(const options of [{url:'https://work.example/changed'},{frame:true},{action:'https://evil.example/capture'},{action:'http://work.example/login'},{method:'get'},{target:'_blank'},{visible:false},{multiple:true},{override:{formaction:'https://evil.example/capture'}},{override:{formmethod:'get'}},{override:{formtarget:'_blank'}}]){ const f=fixture(options);assert.throws(()=>vm.runInContext(fillScript('https://work.example/login',credential),f.context));assert.equal(f.user.stored,undefined);assert.equal(f.password.stored,undefined); } }); test('expired policy cannot inject a password',()=>{assert.throws(()=>fillScript('https://work.example/login',credential,Date.now()-1));}); test('queued fill cannot write into a hidden or blurred target document',()=>{ for(const options of [{focused:false},{visibility:'hidden'}]){const f=fixture(options);assert.throws(()=>vm.runInContext(fillScript('https://work.example/login',credential),f.context),/foreground/);assert.equal(f.user.stored,undefined);assert.equal(f.password.stored,undefined);} });