// Synthetic contract tests only. This test must never navigate to an official // platform or expose an origin override in the production execution profile. import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import {fileURLToPath} from 'node:url'; import {createServer} from 'node:http'; import {ActionInputError} from './action-contract.mjs'; const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'../..'); await fs.mkdir(path.join(root,'.tmp'),{recursive:true}); const output=await fs.mkdtemp(path.join(root,'.tmp','native-ui-profile-')); process.env.ASSISTANT_LEARNING_HOME=path.join(output,'worker-learning'); process.env.ASSISTANT_BROWSER_HEADLESS='1'; process.env.ASSISTANT_BROWSER_CHANNEL=process.platform==='win32' ? 'msedge' : 'chromium'; const results=[]; let assertions=0; let browserFixture=null; const eq=(actual,expected,message)=>{assert.deepEqual(actual,expected,message);assertions+=1;}; const ok=(value,message)=>{assert.ok(value,message);assertions+=1;}; const throws=(fn,predicate,message)=>{assert.throws(fn,predicate,message);assertions+=1;}; const report=async(extra={})=>fs.writeFile(path.join(output,'report.json'),JSON.stringify({ result:'passed',passed:results.length,assertions,results, environment:'synthetic execution-profile, action, and private request-capability helpers', official_browser_navigation:false,live_platform_requests:0,application_api_calls:0,model_calls:0, browser_fixture:browserFixture || 'not executed; no production origin or network bypass is introduced',...extra, },null,2)); const group=async(name,run)=>{ const start=assertions; try{const details=await run();results.push({name,assertions:assertions-start,...details});await report();} catch(error){await report({result:'failed',failed_group:name,error:{name:error.name,message:error.message,code:error.code}});throw error;} }; const official='https://www.xiaohongshu.com'; const noteId='a'.repeat(24),otherNoteId='b'.repeat(24); const noteUrl=`${official}/explore/${noteId}?xsec_token=LOCAL_NATIVE_FIXTURE_TOKEN`; const profile=await import('./execution-profile.mjs'); const {NATIVE_UI_PROFILE,NATIVE_UI_CONTRACT,resolveExecutionProfile,validNativePage,nativeNoteId, nativeSearchKeyword,nativeReadRootsValid,assertNativeUiAction,assertNativeUiResultLocation, executionContractMatches,executionMetadata}=profile; await group('exact versioned profile and immutable execution contract',()=>{ eq(NATIVE_UI_PROFILE,'playwright-xhs-native-ui-v1'); eq(NATIVE_UI_CONTRACT,{engine:'playwright',action_policy:'xhs-bounded-readonly-v1',network_policy:'xhs-page-native-v1'}); eq(Object.isFrozen(NATIVE_UI_CONTRACT),true); eq(resolveExecutionProfile(undefined),null,'only an omitted profile selects legacy'); eq(resolveExecutionProfile(NATIVE_UI_PROFILE),NATIVE_UI_CONTRACT); eq(executionMetadata(undefined),{},'legacy omits the new contract fields'); eq(executionContractMatches({...NATIVE_UI_CONTRACT}),true); for(const value of [null,undefined,[],{},NATIVE_UI_PROFILE, {...NATIVE_UI_CONTRACT,engine:'browser-use'}, {...NATIVE_UI_CONTRACT,action_policy:'legacy'}, {...NATIVE_UI_CONTRACT,network_policy:'unknown'}, {...NATIVE_UI_CONTRACT,extra:'fixture'}, {engine:'playwright',action_policy:'xhs-bounded-readonly-v1'}, Object.create(NATIVE_UI_CONTRACT)]) eq(executionContractMatches(value),false); const metadata=executionMetadata(NATIVE_UI_PROFILE); eq(metadata,{execution_profile:NATIVE_UI_PROFILE,execution_contract:NATIVE_UI_CONTRACT}); metadata.execution_contract.engine='LOCAL_FIXTURE_MUTATION'; eq(executionMetadata(NATIVE_UI_PROFILE).execution_contract.engine,'playwright','returned DTOs cannot mutate the shared descriptor'); for(const value of [null,false,true,0,1,'','legacy','playwright-xhs-native-ui-v2',NATIVE_UI_PROFILE+' ', ' '+NATIVE_UI_PROFILE,NATIVE_UI_PROFILE.toUpperCase(),[],{},NATIVE_UI_CONTRACT]){ throws(()=>resolveExecutionProfile(value),error=>error instanceof ActionInputError,'unknown or object-valued profiles never silently downgrade'); } }); await group('official page shape uses HTTPS exact host and declared paths',()=>{ for(const url of [official+'/explore',official+'/search_result',official+'/search_result_ai', official+'/search_result?keyword=%E8%A3%85%E4%BF%AE',official+'/search_result_ai?keyword=fixture', noteUrl,`${official}/search_result/${otherNoteId}`]) eq(validNativePage(url),true,url); for(const url of [null,undefined,{},'', 'not a url','http://www.xiaohongshu.com/explore', 'https://xiaohongshu.com/explore','https://www.xiaohongshu.com.evil.invalid/explore', 'https://evilxiaohongshu.com/explore','https://www.xiaohongshu.com:8443/explore', 'https://user:pass@www.xiaohongshu.com/explore','https://www.xiaohongshu.com@evil.invalid/explore', 'https://so.xiaohongshu.com/explore','http://127.0.0.1/explore',official+'/',official+'/explore/', official+'/message',official+'/notification',official+'/user/profile/'+noteId, official+'/api/sns/web/v2/comment/post',official+'/search_result_ai/'+noteId, official+'/explore/'+noteId+'/',official+'/explore/'+noteId.slice(1), official+'/explore/'+'g'.repeat(24),official+'/explore/%2f'+noteId]) eq(validNativePage(url),false,String(url)); }); await group('public note identity and bounded decoding preserve the selected search',()=>{ eq(nativeNoteId(noteUrl),noteId); eq(nativeNoteId(`${official}/search_result/${otherNoteId.toUpperCase()}?from=fixture`),otherNoteId); for(const value of [official+'/search_result_ai/'+noteId,official+'/explore/'+noteId+'/', 'https://evil.invalid/explore/'+noteId,'https://u:p@www.xiaohongshu.com/explore/'+noteId, official+'/user/profile/'+noteId,null,undefined]) eq(nativeNoteId(value),null); const keyword='装修 案例'; eq(nativeSearchKeyword(official+'/search_result?keyword='+encodeURIComponent(keyword)),keyword); eq(nativeSearchKeyword(official+'/search_result_ai?keyword='+encodeURIComponent(encodeURIComponent(keyword))),keyword); eq(nativeSearchKeyword(official+'/search_result?keyword=fixture%20value'),'fixture value'); for(const value of [official+'/explore?keyword=fixture',official+'/search_result', official+'/search_result?keyword=fixture&keyword=other', official+'/search_result?keyword=%25E0%25A4%25A','https://evil.invalid/search_result?keyword=fixture']) eq(nativeSearchKeyword(value),null); const threeTimes=encodeURIComponent(encodeURIComponent(encodeURIComponent(keyword))); ok(nativeSearchKeyword(official+'/search_result?keyword='+threeTimes)!==keyword,'the helper never repeatedly decodes until a desired keyword happens to match'); }); const searchObserved={kind:'fill',tag:'input',unique:true,search_input:true,sensitive:false,stable_label:'Search'}; const searchActual={tag:'input',search_input:true,sensitive:false,visible:true,in_viewport:true,unobscured:true, native_context:{search_input:true,note_link:false,read_root:false}}; const searchAction={kind:'fill',pageUrl:official+'/explore',selector:'#search-input-in-feeds', observed:searchObserved,actualRoots:[searchActual],matchCount:1,keyword:'装修案例'}; const rejectsAction=(context,code='WRITE_ACTION_BLOCKED')=>{ const snapshot=JSON.stringify(context); throws(()=>assertNativeUiAction(context),error=>error instanceof ActionInputError && error.code===code); eq(JSON.stringify(context),snapshot,'rejected action metadata stays unchanged'); }; await group('only observed usable exact search controls accept fill and Enter',()=>{ const snapshot=JSON.stringify(searchAction); for(const selector of ['#search-input-in-feeds','#search-input-ai']){ eq(assertNativeUiAction({...searchAction,selector}),true); eq(assertNativeUiAction({...searchAction,selector,kind:'press',key:'Enter'}),true); } eq(JSON.stringify(searchAction),snapshot); for(const patch of [ {selector:'#generic-search'},{selector:'#comment-input'},{selector:'input[type=search]'}, {matchCount:0},{matchCount:2},{actualRoots:[]},{actualRoots:[searchActual,searchActual]}, {observed:null},{observed:{...searchObserved,kind:'read'}},{observed:{...searchObserved,unique:false}}, {observed:{...searchObserved,search_input:false}},{observed:{...searchObserved,sensitive:true}}, {actualRoots:[{...searchActual,tag:'button'}]},{actualRoots:[{...searchActual,search_input:false}]}, {actualRoots:[{...searchActual,native_context:{...searchActual.native_context,search_input:false}}]}, {actualRoots:[{...searchActual,native_context:undefined}]},{actualRoots:[{...searchActual,sensitive:true}]}, {actualRoots:[{...searchActual,visible:false}]},{actualRoots:[{...searchActual,in_viewport:false}]}, {actualRoots:[{...searchActual,unobscured:false}]},{kind:'press',key:'Tab'}, {kind:'press',key:'Control+Enter'},{kind:'press'}, ]) rejectsAction({...searchAction,...patch}); for(const keyword of [undefined,null,'',' ','x'.repeat(2001),'手机号 13800138000','验证码:123456','password:fixture']){ rejectsAction({...searchAction,keyword},'SENSITIVE_INPUT'); } rejectsAction({...searchAction,pageUrl:official+'/message'},'SCOPE_BLOCKED'); }); const noteObserved={kind:'click',tag:'a',unique:true,sensitive:false}; const noteActual={tag:'a',href:noteUrl,sensitive:false,visible:true,in_viewport:true,unobscured:true, native_context:{search_input:false,note_link:true,read_root:false}}; const noteAction={kind:'click',pageUrl:official+'/search_result?keyword=fixture',selector:'#global a.title', observed:noteObserved,actualRoots:[noteActual],matchCount:1,href:noteUrl,noteId}; await group('clicks require a fixed actual standard note link and selected identity',()=>{ const snapshot=JSON.stringify(noteAction); eq(assertNativeUiAction(noteAction),true); eq(assertNativeUiAction({...noteAction,observed:{...noteObserved,unique:false}}),true,'the worker may supply a uniquely resolved collection member'); eq(JSON.stringify(noteAction),snapshot); for(const patch of [ {kind:'click',observed:null},{matchCount:0},{matchCount:2},{actualRoots:[]}, {observed:{...noteObserved,kind:'read'}},{observed:{...noteObserved,tag:'button'}}, {observed:{...noteObserved,sensitive:true}}, {actualRoots:[{...noteActual,tag:'button',href:''}]}, {actualRoots:[{...noteActual,native_context:{...noteActual.native_context,note_link:false}}]}, {actualRoots:[{...noteActual,native_context:undefined}]}, {actualRoots:[{...noteActual,sensitive:true}]},{actualRoots:[{...noteActual,visible:false}]}, {actualRoots:[{...noteActual,in_viewport:false}]},{actualRoots:[{...noteActual,unobscured:false}]}, {actualRoots:[{...noteActual,href:`${official}/explore/${otherNoteId}`}]}, {noteId:otherNoteId}, ]) rejectsAction({...noteAction,...patch}); for(const href of [official+'/message',official+'/explore',official+'/user/profile/'+noteId, official+'/explore/not-a-note',official+'/explore/'+noteId+'/', official+'/api/sns/web/v2/comment/post','https://evil.invalid/explore/'+noteId, 'javascript:void(0)','data:text/html,fixture','']){ rejectsAction({...noteAction,href,actualRoots:[{...noteActual,href}]}); } }); const readRoot={tag:'section',readonly_root:true,sensitive:false,forbidden:false, native_context:{read_root:true,note_link:false,search_input:false}}; await group('read wait extract and bounded scroll require fixed ordinary roots',()=>{ for(const kind of ['read','wait','extract','scroll']) eq(assertNativeUiAction({kind,pageUrl:noteUrl,actualRoots:[readRoot]}),true); eq(nativeReadRootsValid([readRoot]),true); eq(nativeReadRootsValid(Array.from({length:500},()=>readRoot)),true); for(const actualRoots of [null,undefined,[],[null],[readRoot,null],Array.from({length:501},()=>readRoot), [{...readRoot,readonly_root:false}],[{...readRoot,sensitive:true}],[{...readRoot,forbidden:true}], [{...readRoot,native_context:undefined}],[{...readRoot,native_context:{...readRoot.native_context,read_root:false}}]]){ eq(nativeReadRootsValid(actualRoots),false); rejectsAction({kind:'read',pageUrl:noteUrl,actualRoots},'SENSITIVE_OUTPUT'); } for(const kind of ['evaluate','fetch','request','goto','send_message','follow','comment','arbitrary_js']){ rejectsAction({kind,pageUrl:noteUrl,actualRoots:[readRoot]},'SENSITIVE_OUTPUT'); } }); await group('completed actions require the actual expected final source rather than only permitted in-flight traffic',()=>{ const failLocation=(context,pageUrl,code)=>throws(()=>assertNativeUiResultLocation(context,pageUrl), error=>error instanceof ActionInputError && error.code===code); const press={...searchAction,kind:'press',key:'Enter'}; for(const path of ['/search_result','/search_result_ai']){ eq(assertNativeUiResultLocation(press,official+path+'?keyword='+encodeURIComponent(press.keyword)),true); } failLocation(press,press.pageUrl,'SEARCH_TRANSITION_NOT_READY'); failLocation(press,official+'/search_result?keyword=other','SEARCH_TRANSITION_NOT_READY'); failLocation(press,official+'/search_result?keyword='+encodeURIComponent(press.keyword)+'&keyword=other','SEARCH_TRANSITION_NOT_READY'); failLocation(press,official+'/message','SOURCE_CHANGED'); eq(assertNativeUiResultLocation(noteAction,noteUrl),true); eq(assertNativeUiResultLocation(noteAction,official+'/search_result/'+noteId),true); failLocation(noteAction,noteAction.pageUrl,'NOTE_BINDING_MISMATCH'); failLocation(noteAction,official+'/explore/'+otherNoteId,'NOTE_BINDING_MISMATCH'); failLocation(noteAction,'https://evil.invalid/explore/'+noteId,'SOURCE_CHANGED'); for(const kind of ['fill','read','extract','wait','scroll']){ const context={kind,pageUrl:searchAction.pageUrl}; eq(assertNativeUiResultLocation(context,context.pageUrl),true); failLocation(context,context.pageUrl+'?fixture=changed','SOURCE_CHANGED'); failLocation(context,context.pageUrl+'#changed','SOURCE_CHANGED'); failLocation(context,noteUrl,'SOURCE_CHANGED'); } }); const {beginNativeUiRequestPolicy,evaluatePlatformRequest,matchPlatformRequest,endPlatformRequestPolicy, NATIVE_UI_POLICY_VERSION}=await import('./platform-policy.mjs'); const policyContext={...searchAction,sessionOrigin:official,now:10000}; const nativeRequest={automating:true,sessionOrigin:official,pageUrl:searchAction.pageUrl,activeMainFrame:true, method:'POST',resourceType:'xhr',url:'https://as.xiaohongshu.com/api/sec/v1/fixture',now:10001}; const allowed={allowed:true,policy_version:'xhs-page-native-v1',policy_rule:'native_page_traffic'}; const nativePolicies=new Set(); const mint=context=>{ const snapshot=JSON.stringify(context),policy=beginNativeUiRequestPolicy(context); eq(JSON.stringify(context),snapshot,'minting never changes action evidence'); ok(policy,'a permitted finite UI action can mint its private request policy'); nativePolicies.add(policy);return policy; }; const denied=(request,reason)=>{ const actual=evaluatePlatformRequest(request); eq(actual.allowed,false); if(reason!==undefined) eq(actual.reason,reason); eq(matchPlatformRequest(request),null,'the public matcher uses the same rejection'); }; await group('only valid exact native actions mint private fifteen-second capabilities',()=>{ eq(NATIVE_UI_POLICY_VERSION,'xhs-page-native-v1'); const policy=mint(policyContext); eq(policy,{version:NATIVE_UI_POLICY_VERSION,scope:'native_ui',expiresAt:25000}); eq(Object.isFrozen(policy),true); for(const patch of [ {sessionOrigin:'https://xiaohongshu.com'},{sessionOrigin:'http://127.0.0.1'}, {pageUrl:'https://evil.invalid/explore'},{pageUrl:official+'/message'}, {now:NaN},{now:Infinity},{now:'10000'},{kind:'evaluate'}, {selector:'#comment-input'},{actualRoots:[]},{observed:null}, {actualRoots:[{...searchActual,native_context:{search_input:false}}]}, ]) eq(beginNativeUiRequestPolicy({...policyContext,...patch}),null); eq(evaluatePlatformRequest({...nativeRequest,policy}),allowed); denied({...nativeRequest,policy:{...policy}},'inactive_policy'); denied({...nativeRequest,policy:null},'missing_policy'); endPlatformRequestPolicy(policy); denied({...nativeRequest,policy},'inactive_policy'); }); await group('native page POST permits only exact first-party HTTPS main-frame xhr or fetch',()=>{ const policy=mint(policyContext); const start=assertions; for(const host of ['www.xiaohongshu.com','xiaohongshu.com','as.xiaohongshu.com', 'apm-fe.xiaohongshu.com','so.xiaohongshu.com','nested.fixture.xiaohongshu.com']){ for(const resourceType of ['xhr','fetch']){ const request={...nativeRequest,policy,resourceType,url:`https://${host}/unknown-native-page-traffic?fixture=1`}; eq(evaluatePlatformRequest(request),allowed); eq(matchPlatformRequest(request),{policy_version:NATIVE_UI_POLICY_VERSION,policy_rule:'native_page_traffic'}); } } for(const url of ['http://as.xiaohongshu.com/native','https://u:p@as.xiaohongshu.com/native', 'https://as.xiaohongshu.com:8443/native','https://as.xiaohongshu.com.evil.invalid/native', 'https://evilxiaohongshu.com/native','https://evil.invalid/xiaohongshu.com/native', 'https://xiaohongshu.com@evil.invalid/native','https://xiaohongshu.com./native', 'http://127.0.0.1/native','https://127.0.0.1/native','file:///fixture','data:text/plain,fixture','invalid']){ denied({...nativeRequest,policy,url}); } for(const resourceType of ['document','script','stylesheet','image','font','media','websocket','eventsource','other','',null]){ const request={...nativeRequest,policy,resourceType}; denied(request,'resource_type_not_allowed'); eq(evaluatePlatformRequest(request).expected_resource_types,['xhr','fetch']); } for(const method of ['GET','HEAD','OPTIONS','PUT','PATCH','DELETE','CONNECT','TRACE','post','',null]){ denied({...nativeRequest,policy,method},'method_not_allowed'); } denied({...nativeRequest,policy,activeMainFrame:false},'not_main_frame'); denied({...nativeRequest,policy,automating:false},'automation_inactive'); denied({...nativeRequest,policy,sessionOrigin:'https://evil.invalid'},'session_out_of_scope'); denied({...nativeRequest,policy,pageUrl:'https://evil.invalid/search_result'},'page_out_of_scope'); return {request_boundary_assertions:assertions-start, scope:'POST policy only; ordinary GET/HEAD/OPTIONS routing is not represented as an issued native permission', http_side_effect_free_claim:false}; }); await group('native capabilities reject early exact-expiry late invalid and revoked use',()=>{ const policy=mint(policyContext); eq(evaluatePlatformRequest({...nativeRequest,policy,now:10000}),allowed); eq(evaluatePlatformRequest({...nativeRequest,policy,now:24999}),allowed); denied({...nativeRequest,policy,now:9999},'policy_not_started'); denied({...nativeRequest,policy,now:25000},'policy_expired'); denied({...nativeRequest,policy,now:25001},'policy_expired'); for(const now of [NaN,Infinity,-Infinity,'10001',null]) denied({...nativeRequest,policy,now},'invalid_time'); endPlatformRequestPolicy(policy); denied({...nativeRequest,policy,now:10001},'inactive_policy'); }); await group('fill and ordinary reads cannot borrow page-transition authority',()=>{ const fillPolicy=mint(policyContext); for(const pageUrl of [official+'/search_result?keyword='+encodeURIComponent(searchAction.keyword), official+'/explore?other=1',official+'/explore#changed',noteUrl]){ denied({...nativeRequest,policy:fillPolicy,pageUrl},'page_changed'); } for(const kind of ['read','wait','extract','scroll']){ const pageUrl=official+'/search_result?keyword=fixture'; const policy=mint({kind,pageUrl,actualRoots:[readRoot],sessionOrigin:official,now:10000}); eq(evaluatePlatformRequest({...nativeRequest,policy,pageUrl}),allowed); for(const changed of [pageUrl+'&page=2',pageUrl+'#changed',official+'/search_result_ai?keyword=fixture',noteUrl]){ denied({...nativeRequest,policy,pageUrl:changed},'page_changed'); } } }); await group('Enter allows only the selected keyword search-result transition',()=>{ const keyword='装修 案例'; const policy=mint({...policyContext,kind:'press',key:'Enter',keyword}); eq(evaluatePlatformRequest({...nativeRequest,policy}),allowed); for(const pathname of ['/search_result','/search_result_ai']){ for(const encoded of [encodeURIComponent(keyword),encodeURIComponent(encodeURIComponent(keyword))]){ eq(evaluatePlatformRequest({...nativeRequest,policy,pageUrl:official+pathname+'?keyword='+encoded}),allowed); } } for(const pageUrl of [official+'/search_result?keyword=other',official+'/search_result', official+'/search_result?keyword='+encodeURIComponent(keyword)+'&keyword=other', official+'/explore?keyword='+encodeURIComponent(keyword),noteUrl,official+'/message', 'https://www.xiaohongshu.com.evil.invalid/search_result?keyword='+encodeURIComponent(keyword)]){ denied({...nativeRequest,policy,pageUrl}); } denied({...nativeRequest,policy,pageUrl:official+'/search_result?keyword='+encodeURIComponent(keyword),now:25000},'policy_expired'); }); await group('note click permits only its bound public note identity transition',()=>{ const policy=mint({...noteAction,sessionOrigin:official,now:10000}); eq(evaluatePlatformRequest({...nativeRequest,policy,pageUrl:noteAction.pageUrl}),allowed); for(const pageUrl of [noteUrl,official+'/search_result/'+noteId,official+'/explore/'+noteId+'?from=fixture']){ eq(evaluatePlatformRequest({...nativeRequest,policy,pageUrl}),allowed); } for(const pageUrl of [official+'/explore/'+otherNoteId,official+'/search_result/'+otherNoteId, noteAction.pageUrl+'&changed=1',official+'/search_result?keyword=other',official+'/explore', official+'/user/profile/'+noteId,official+'/search_result_ai/'+noteId]){ denied({...nativeRequest,policy,pageUrl},'page_changed'); } }); await group('issued policy stores immutable source facts and never accepts fabricated contracts',()=>{ const context=structuredClone(policyContext),policy=mint(context); context.pageUrl=official+'/search_result?keyword=other'; context.keyword='other';context.actualRoots[0].native_context.search_input=false; eq(evaluatePlatformRequest({...nativeRequest,policy}),allowed); denied({...nativeRequest,policy,pageUrl:context.pageUrl},'page_changed'); for(const fake of [{...policy},{version:NATIVE_UI_POLICY_VERSION,scope:'native_ui',expiresAt:25000}, {version:NATIVE_UI_POLICY_VERSION,scope:'search',expiresAt:25000}, {execution_profile:NATIVE_UI_PROFILE,execution_contract:NATIVE_UI_CONTRACT}]){ denied({...nativeRequest,policy:fake},'inactive_policy'); } }); await group('real loopback Edge DOM produces restricted search link and ordinary-root facts',async()=>{ const {inspectElements}=await import('./browser-worker.mjs'); const {chromium}=await import('playwright'); let browser,fixtureRequests=0,unexpectedNetwork=0; const observations=[]; const server=createServer((request,response)=>{ fixtureRequests+=1; if(request.method!=='GET' || request.url!=='/') {response.writeHead(404).end();return;} response.writeHead(200,{'content-type':'text/html; charset=utf-8'}).end('Local native UI DOM fixture

Loopback only

'); }); await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve)); const loopback=`http://127.0.0.1:${server.address().port}`; try{ browser=await chromium.launch({channel:process.platform==='win32' ? 'msedge' : 'chromium',headless:true}); const context=await browser.newContext({viewport:{width:1280,height:840},serviceWorkers:'block'}); await context.route('**/*',async route=>{ const url=new URL(route.request().url()); if(url.origin!==loopback){unexpectedNetwork+=1;await route.abort();return;} await route.continue(); }); const page=await context.newPage(); await page.goto(loopback+'/',{waitUntil:'domcontentloaded'}); const render=body=>page.setContent(`Local native UI contract fixture

Local native UI DOM fixture

Only metadata is inspected; no search or link is activated.

${body}`); const inspect=async(selector,nativeProfile=true)=>{ const facts=await page.locator(selector).evaluate(inspectElements,{origin:official,nativeProfile}); eq(facts.length,1);return facts[0]; }; const remember=(name,state,accepted)=>observations.push({name,accepted, tag:state.tag,sensitive:state.sensitive,search_input:state.search_input, readonly_root:state.readonly_root,native_context:state.native_context}); const searchFixtures=[ ['known-feed-search','','#search-input-in-feeds',true], ['known-ai-search','','#search-input-ai',true], ['generic-search-name','','#generic-search',false], ['comment-input','','#comment-input',false], ['post-form-search','
','#search-input-in-feeds',false], ['editable-search','
','#search-input-in-feeds',false], ['button-role-search','','#search-input-in-feeds',false], ['checkbox-role-search','','#search-input-in-feeds',false], ['button-ancestor-search','
','#search-input-in-feeds',false], ['searchbox-role-search','','#search-input-in-feeds',true], ]; for(const [name,html,selector,accepted] of searchFixtures){ await render(html);const state=await inspect(selector); eq(state.native_context.search_input,accepted,name); const action={...searchAction,selector,actualRoots:[state]}; if(accepted){eq(assertNativeUiAction(action),true);eq(assertNativeUiAction({...action,kind:'press',key:'Enter'}),true);} else rejectsAction(action); remember(name,state,accepted); } const linkFixtures=[ ['standard-note',`Synthetic note`,true], ['self-target-note',`Synthetic note`,true], ['download-note',`Synthetic note`,false], ['blank-target-note',`Synthetic note`,false], ['named-target-note',`Synthetic note`,false], ['editable-note',`Synthetic note`,false], ['plaintext-editable-note',`
Synthetic note
`,false], ['form-note',`
Synthetic note
`,false], ['button-role-note',`Synthetic note`,false], ['checkbox-role-note',`Synthetic note`,false], ['switch-role-note',`Synthetic note`,false], ['menuitem-role-note',`Synthetic note`,false], ['button-ancestor-note',`
Synthetic note
`,false], ['checkbox-ancestor-note',`
Synthetic note
`,false], ['link-role-note',`Synthetic note`,true], ]; for(const [name,html,accepted] of linkFixtures){ await render(html);const state=await inspect('#fixture'); eq(state.native_context.note_link,accepted,name); const action={...noteAction,selector:'#fixture',actualRoots:[state]}; if(accepted) eq(assertNativeUiAction(action),true);else rejectsAction(action); remember(name,state,accepted); } const rootFixtures=[ ['ordinary-section','
Plain result text
',true], ['editable-section','
Plain result text
',false], ['plaintext-editable-section','
Plain result text
',false], ['inherited-editable-section','
Plain result text
',false], ['button-root','',false], ['button-role-root','
Plain result text
',false], ['checkbox-role-root','',false], ['button-ancestor-root','
Plain result text
',false], ['checkbox-ancestor-root','
Plain result text
',false], ['form-root','
Plain result text
',false], ['anchor-root',`Synthetic note`,false], ]; for(const [name,html,accepted] of rootFixtures){ await render(html);const state=await inspect('#fixture'); eq(state.native_context.read_root,accepted,name); const action={kind:'read',pageUrl:noteUrl,selector:'#fixture',actualRoots:[state]}; if(accepted) eq(assertNativeUiAction(action),true);else rejectsAction(action,'SENSITIVE_OUTPUT'); remember(name,state,accepted); } await render('
Plain result text
'); eq(Object.hasOwn(await inspect('#fixture',false),'native_context'),false,'legacy inspection omits the new metadata'); const screenshot=path.join(output,'loopback-native-dom.png'); await page.screenshot({path:screenshot,fullPage:true}); const png=await fs.readFile(screenshot);eq(png.subarray(1,4).toString(),'PNG'); eq(unexpectedNetwork,0,'synthetic links are never navigated or fetched'); browserFixture={browser:process.platform==='win32' ? 'Edge' : 'Chromium',origin:'loopback only', inspected_cases:observations.length,fixture_requests:fixtureRequests,unexpected_network_attempts:unexpectedNetwork, actual_png:true,screenshot,worker_native_profile_end_to_end:false}; await fs.writeFile(path.join(output,'loopback-dom-observations.json'),JSON.stringify(observations,null,2)); return browserFixture; }finally{ if(browser) await browser.close(); await new Promise(resolve=>server.close(resolve)); } }); await group('real legacy worker DTOs omit native fields and reject profile overrides before navigation',async()=>{ const {dispatch}=await import('./browser-worker.mjs'); const task='native-ui-profile-legacy-shape'; let requests=0,opened=false; const server=createServer((request,response)=>{ requests+=1; response.writeHead(200,{'content-type':'text/html; charset=utf-8'}).end('Local legacy shape fixture
Loopback only
'); }); await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve)); const entry=`http://127.0.0.1:${server.address().port}/`; const omitted=value=>{ eq(Object.hasOwn(value,'execution_profile'),false); eq(Object.hasOwn(value,'execution_contract'),false); }; const rejectedAsync=async(run,code)=>{ await assert.rejects(run,error=>error.code===code);assertions+=1; }; try{ await rejectedAsync(()=>dispatch('open',{task_id:task,account_key:'isolated-native-profile-shape',entry_url:entry, execution_profile:NATIVE_UI_PROFILE}),'EXECUTION_PROFILE_INVALID'); eq(requests,0,'native mode never introduces a loopback origin override'); const initial=await dispatch('open',{task_id:task,account_key:'isolated-native-profile-shape',entry_url:entry});opened=true; omitted(initial); omitted(await dispatch('ready',{task_id:task,identity_label:'Local legacy shape'})); omitted(await dispatch('status',{task_id:task})); const capture=await dispatch('capture',{task_id:task});omitted(capture); eq(capture.elements.some(element=>element.selector==='#local-read'),true); const action=await dispatch('action',{task_id:task,kind:'read',selector:'#local-read'}); omitted(action);omitted(action.before);omitted(action.after); const verifyParams={task_id:task,schema_version:2,entry_url:entry, steps:[{kind:'read',selector:'#local-read',output_name:'note'}],parameters:{},expected_outputs:{note:'Loopback only'}}; const previous=requests; await rejectedAsync(()=>dispatch('verify',{...verifyParams,execution_profile:NATIVE_UI_PROFILE, execution_contract:{...NATIVE_UI_CONTRACT}}),'EXECUTION_PROFILE_MISMATCH'); await rejectedAsync(()=>dispatch('verify',{...verifyParams,execution_contract:{...NATIVE_UI_CONTRACT}}),'EXECUTION_PROFILE_MISMATCH'); await rejectedAsync(()=>dispatch('verify',{...verifyParams,execution_profile:'unknown-mode'}),'EXECUTION_PROFILE_INVALID'); eq(requests,previous,'profile failures cannot navigate or replay the legacy session'); const verified=await dispatch('verify',verifyParams); eq(verified.passed,true);omitted(verified); ok(verified.evidence.length>0);for(const evidence of verified.evidence) omitted(evidence); return {fixture_requests:requests,legacy_worker_native_fields_absent:true, mismatched_or_unknown_profile_before_navigation:true,native_loopback_override:false}; }finally{ if(opened) await dispatch('close',{task_id:task}).catch(()=>{}); await new Promise(resolve=>server.close(resolve)); } }); for(const policy of nativePolicies) endPlatformRequestPolicy(policy); await report({status:'pure profile/action/request contract checks complete; worker wiring and platform execution are separate'}); console.log(JSON.stringify({passed:results.length,assertions,output, official_browser_navigation:false,live_platform_requests:0,application_api_calls:0,model_calls:0}));