Files
kra-new/scripts/sw_page_smoke.cjs
T

87 lines
7.3 KiB
JavaScript

// 使用受控身份和接口数据检查实际 Vue 页面,不修改业务库。
const fs = require('node:fs/promises');
const path = require('node:path');
const { chromium } = require(process.env.SW_PLAYWRIGHT_MODULE || 'playwright');
(async () => {
const token = (await fs.readFile(path.join(process.env.TEMP, 'sw-kra-http-test-token'), 'utf8')).trim();
const browser = await chromium.launch({channel:'chrome', headless:true});
const results = [];
try {
for (const level of [0,1,2,3]) {
const context = await browser.newContext({viewport:{width:1440,height:1000}});
await context.addInitScript(value => localStorage.setItem('token',value),token);
const page = await context.newPage();
const pageErrors=[];
page.on('pageerror',e=>pageErrors.push(e.message));
let bindingCalls=0; const channelCalls=[];
await page.route('http://127.0.0.1:8080/api/**', async route => {
const request=route.request();
const uri=new URL(request.url());
const apiPath=uri.pathname.slice(4);
let body;
if(apiPath==='/sw/business/list') body={code:0,msg:'成功',data:{rows:[{userId:79999,userName:'展示测试商务',level:2,parentUserName:'上级商务',realName:'测试姓名',phoneNumber:'',bindCount:0,promoteCount:0,createTime:'2026-11-03 10:00:00',status:'0',authorityId:902}],total:1}};
else if(/^\/sw\/business\/\d+\/promotes$/.test(apiPath)) { channelCalls.push(Object.fromEntries(uri.searchParams)); body={code:0,msg:'成功',data:{rows:[{promoteId:1,promoteName:'渠道测试',sourceDb:'lx',platformName:'龙翔'}],total:1,available:true}}; }
else if(apiPath==='/sw/business/bindPlatform') {
bindingCalls++;
body={code:0,msg:'成功',data:{total:3,rows:['0','2','3'].map((status,i)=>({userId:70000+level,sourceDb:'lx',platformName:'龙翔',platformBusierId:10+i,platformBusierAccount:['正常账号','驳回账号','待审账号'][i],bindUserName:'测试商务',promoteCount:status==='0'?2:0,status,createTime:'2026-11-03 10:00:00',reviewTime:'2026-11-03 11:00:00',reviewAccount:'测试审核人',rejectReason:status==='2'?'测试驳回原因':null}))}};
} else if(/^\/sw\/business\/\d+\/bindPlatform$/.test(apiPath)) body={code:0,msg:'成功',data:[]};
if(body) {await route.fulfill({json:body});return;}
const response=await route.fetch({url:'http://127.0.0.1:18000'+apiPath+uri.search,headers:{...request.headers(),'x-token':token}});
if(apiPath==='/user/getUserInfo') {
body=await response.json();
const info=body.data.userInfo;
Object.assign(info,{ID:70000+level,level,nickName:'页面核对账号',phone:'',email:'',authorityId:level===0?888:900+level});
await route.fulfill({response,json:body});
} else await route.fulfill({response});
});
await page.goto('http://127.0.0.1:8080/#/layout/sw-BusMgmt/BusinessList');
try { await page.getByRole('tab',{name:'商务列表',exact:true}).waitFor({timeout:15000}); } catch (error) { console.log(JSON.stringify({url:page.url(),errors:pageErrors,text:(await page.locator('body').innerText()).slice(0,1800)})); await page.screenshot({path:path.join(process.env.TEMP,'sw-kra-browser-failure.png')}); throw error; }
await page.getByText('展示测试商务',{exact:true}).waitFor();
const tabs=await page.getByRole('tab',{name:'绑定列表',exact:true}).count();
const editButtons=await page.getByRole('button',{name:'编辑',exact:true}).count();
if(tabs!==(level===3?1:0)||editButtons!==0) throw new Error('页面权限或编辑入口不一致 level='+level);
const result={level,bindingTab:tabs===1,editButtons,passed:true};
if(level===1 || level===2) {
await page.getByRole('row').filter({hasText:'展示测试商务'}).getByRole('button',{name:'查看SDK商务绑定详情',exact:true}).click();
await page.getByRole('dialog',{name:'SDK商务绑定详情'}).waitFor();
result.sdkDetailReadonly=(await page.getByRole('dialog',{name:'SDK商务绑定详情'}).getByRole('button',{name:'解绑',exact:true}).count())===0;
if(!result.sdkDetailReadonly)throw new Error('SDK 详情出现写操作');
await page.getByRole('dialog',{name:'SDK商务绑定详情'}).getByRole('button',{name:'关闭此对话框',exact:true}).click();
}
if(level===3) {
await page.getByRole('tab',{name:'绑定列表',exact:true}).click();
await page.getByText('正常账号',{exact:true}).waitFor();
const normal=page.getByRole('row').filter({hasText:'正常账号'});
const rejected=page.getByRole('row').filter({hasText:'驳回账号'});
const pending=page.getByRole('row').filter({hasText:'待审账号'});
result.normalUnbind=await normal.getByRole('button',{name:'解绑',exact:true}).count();
result.rejectedUnbind=await rejected.getByRole('button',{name:'解绑',exact:true}).count();
result.pendingUnbind=await pending.getByRole('button',{name:'解绑',exact:true}).count();
result.rejectedDetail=await rejected.getByRole('button',{name:'查看驳回',exact:true}).count();
if(result.normalUnbind!==1||result.rejectedUnbind||result.pendingUnbind||result.rejectedDetail!==1)throw new Error('绑定状态操作不一致');
result.rejectedChannelsDisabled=await rejected.getByRole('button',{name:'查看旗下渠道',exact:true}).isDisabled();
result.pendingChannelsDisabled=await pending.getByRole('button',{name:'查看旗下渠道',exact:true}).isDisabled();
if(!result.rejectedChannelsDisabled || !result.pendingChannelsDisabled)throw new Error('未通过绑定仍可查看渠道');
await normal.getByRole('button',{name:'查看旗下渠道',exact:true}).click();
await page.getByText('渠道测试',{exact:true}).waitFor();
const channelQuery=channelCalls.at(-1);
if(channelQuery.sourceDb!=='lx'||channelQuery.platformBusierId!=='10')throw new Error('旗下渠道未携带平台和商务筛选');
result.channelFilters=true;
await page.getByRole('dialog',{name:'旗下渠道',exact:true}).getByRole('button',{name:'关闭此对话框',exact:true}).click();
await rejected.getByRole('button',{name:'查看驳回',exact:true}).click();
await page.getByText('测试驳回原因',{exact:true}).waitFor();
const panel=await page.getByRole('dialog',{name:'审核详情',exact:true}).elementHandle();
await page.waitForFunction(el=>{const box=el.getBoundingClientRect();return box.x>=0 && box.right<=innerWidth+1},panel,{timeout:5000});
result.rejectDrawerInViewport=true;
} else if(bindingCalls!==0) throw new Error('非三级加载了绑定列表');
result.bindingCalls=bindingCalls;
result.pageErrors=pageErrors;
await page.screenshot({path:path.join(process.env.TEMP,'sw-kra-business-level-'+level+'.png'),fullPage:true,animations:'disabled'});
results.push(result);
console.log(JSON.stringify(result));
await context.close();
}
await fs.writeFile('docs/sw6-to-kra/business-page-parity-2026-11-03.json',JSON.stringify({method:'真实 Chrome 渲染;受控身份和业务数据,权限页签与状态操作核对',results},null,2));
} finally {await browser.close();}
})().catch(error=>{console.error(error.message);process.exitCode=1});