/** Isolated preview integration: real Runtime/Router/Store/UI, recording wire port. */ export async function verifyTaskNetworkPreview(){ const e=await System.import('cc'),modules=Array.from(System.entries()).map(([,m])=>m); const exported=name=>{const m=modules.find(m=>m[name]);if(!m)throw Error(`Missing ${name}`);return m[name];}; const source=e.director.getScene().getChildByName('PlatformServices').getComponent('PlatformStartup'); const config=source.config,assets=source.getComponent('LobbyAssets'); source.unsubscribe?.();source.runtime?.stop();source.panel?.dispose();source.panel=null; await new Promise((resolve,reject)=>e.director.loadScene('PlatformLobby',err=>err?reject(err):resolve())); const sent=[],tips=[],checks=[];let receive,panel; const assert=(ok,message)=>{if(!ok)throw Error(message);checks.push(message);}; const runtime=new (exported('PlatformRuntime'))({ gameEntry:exported('createLoginStageGameEntry')(config.identity.gameid,()=>{}), resolveRuntimeConfig:async()=>config, createWireClient:()=>({subscribe:cb=>{receive=cb;return ()=>{};},start:()=>{},stop:()=>{},send:packet=>sent.push(packet),switchServer:()=>{},reconnectCurrent:()=>{}}), scene:{showLoading:()=>{},showLogin:()=>{},showLobby:()=>{},showRoom:()=>{},showReconnect:()=>{},showKicked:()=>{},showServerDenial:()=>{},showFatal:err=>{throw err;}, showTips:(msg,time,kind)=>{if(kind==='show_message')panel?.cancelTaskRequest();tips.push(msg);}}, loadResources:async()=>{},waitForMinimumDisplay:async()=>{},getLoginDeviceSnapshot:()=>{throw Error('Test uses inbound login fixture');}, }); await runtime.start();receive({type:'open',server:config.servers[0]}); const packet=(rpc,data)=>receive({type:'message',message:{route:'agent',rpc,data}}); packet('player_login',{state:0,playerid:7,nickname:'任务接线验证',avatar:'',sex:0,bean:0,roomcard:3,taskstate:1,score:0,sign:null,ip:'127.0.0.1'}); const canvas=e.director.getScene().getChildByName('Canvas'),popup=new e.Node('TaskNetworkTestPopup');popup.parent=canvas;popup.layer=canvas.layer;popup.addComponent(e.UITransform).setContentSize(1600,720); const remote=exported('createRemoteConfig')({gameNoticeShow:-1,agentmode:1,hideTaskBtn:0},config.identity); panel=new (exported('LobbyPanel'))(canvas,popup,assets,config,exported('resolveLobbyPolicy')(remote),runtime.state,msg=>tips.push(msg),()=>{},()=>null,()=>{}, exported('resolveLobbyMenuConfig')(remote),{versionState:0,launchMode:0},action=>{if(action==='tasks')runtime.getPlayerTasks();else tips.push(action);},id=>runtime.claimTask(id)); popup.setSiblingIndex(canvas.children.length-1); const off=runtime.subscribeState(state=>panel.render(state),err=>{throw err;}); const clickTask=()=>panel.menuNodes.get(17).emit(e.Button.EventType.CLICK); clickTask();clickTask(); assert(sent.length===1&&sent[0].rpc==='get_player_task','task button sends one request while pending'); assert(JSON.stringify(sent[0].data)===JSON.stringify({agentid:config.identity.agentid,playerid:7,gameid:config.identity.gameid}),'request identity comes from config and authenticated store'); packet('update_roomcard',{roomcard:4,text:'余额更新'}); assert(panel.taskPending==='list','balance notification preserves pending list'); packet('get_player_task',{tasks:[{taskid:9,title:'今日登录奖励',award:2,finish:1,total:1,state:1}]}); assert(panel.modalKind==='tasks','list response opens authored task prefab'); const view=panel.modal.getComponent('TaskListView'),claim=view.scrollView.content.children[0].getComponent('TaskItemView').claimButton; claim.node.emit(e.Button.EventType.CLICK);claim.node.emit(e.Button.EventType.CLICK); assert(sent.length===2&&sent[1].rpc==='get_task_award','claim sends one award request'); assert(JSON.stringify(sent[1].data)===JSON.stringify({agentid:config.identity.agentid,playerid:7,taskid:9}),'award packet preserves legacy fields'); packet('update_roomcard',{roomcard:6,text:'奖励到账'}); assert(panel.taskPending==='award','balance notification preserves duplicate claim guard'); packet('get_task_award',{taskid:9,taskstate:0}); assert(!panel.taskTip.active,'award response clears red dot'); assert(view.scrollView.content.children[0].getComponent('TaskItemView').claimedMark.active,'award response renders claimed mark'); panel.modal.getChildByPath('group-10/Spirit115').emit(e.Button.EventType.CLICK); assert(panel.modal===null,'close button closes task list'); clickTask();packet('show_message',{msg:'任务暂不可用',time:0});assert(panel.taskPending===null,'server message releases request guard'); clickTask();receive({type:'slow'});assert(panel.taskPending===null,'reconnect cancels pending request'); const count=sent.length;clickTask();assert(sent.length===count,'reconnect blocks task sends'); await new Promise(resolve=>e.director.once(e.Director.EVENT_AFTER_DRAW,resolve)); assert(!document.body.innerText.includes('TypeError:'),'no deferred UI lifecycle errors'); off();panel.dispose();runtime.stop();popup.destroy(); return {checks,sent:sent.map(({rpc,data})=>({rpc,fields:Object.keys(data)}))}; }