Files
kefu/deploy/protocol-integration-20260916/review-qa/browser.mjs
T
2026-09-21 10:34:06 +08:00

72 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {createRequire} from 'node:module';
import {readFileSync,writeFileSync} from 'node:fs';
const require=createRequire('C:/kefu/admin-web/package.json');
const {chromium}=require('playwright');
const root='C:/kefu/deploy/protocol-integration-20260916/review-qa';
const fixture=JSON.parse(readFileSync(`${root}/fixture.json`,'utf8'));
const browser=await chromium.launch({executablePath:'C:/Program Files/Google/Chrome/Application/chrome.exe',headless:true,args:['--no-proxy-server']});
const context=await browser.newContext({viewport:{width:1600,height:1100},locale:'zh-CN'});
await context.route('**/*',route=>new URL(route.request().url()).hostname==='127.0.0.1'?route.continue():route.abort());
const page=await context.newPage();page.setDefaultTimeout(20000);
const errors=[],checks=[];page.on('pageerror',e=>errors.push(e.message));
const origin='http://127.0.0.1:18872';
const login=await fetch(`${origin}/api/v2/auth/login`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({username:'admin',password:'KnowledgeQA@2026'})}).then(r=>r.json());
const api=async path=>{const r=await fetch(`${origin}/api/v2/knowledge/${path}`,{headers:{Authorization:`Bearer ${login.access_token}`}});if(!r.ok)throw Error(`${path}: ${r.status}`);return r.json();};
const assert=(ok,message)=>{if(!ok)throw Error(message);};
const modal=page.getByRole('dialog').filter({has:page.getByText('全量审核',{exact:true})});
const account=async name=>{await page.locator('.ant-card-extra .ant-select-selector').click();await page.locator('.ant-select-dropdown:visible').getByText(name,{exact:true}).click();};
const finish=async expected=>{
for(let i=0;i<25;i++){
const jobs=await api('review-tasks');const job=jobs.items[0];
if(job?.status==='completed'){assert(job.approved===expected,JSON.stringify(job));return job;}
await page.waitForTimeout(400);
}throw Error('Review did not complete');
};
try{
await page.goto(`${origin}/#/auth/login`);
await page.getByPlaceholder('用户名',{exact:true}).fill('admin');
await page.getByPlaceholder('密码',{exact:true}).fill('KnowledgeQA@2026');
await page.getByRole('button',{name:'login',exact:true}).click();
await page.waitForURL(url=>!url.hash.includes('/auth/login'));
await page.goto(`${origin}/#/knowledge/center`);
await account('全量验收客服甲(QA001)');
await page.getByRole('button',{name:'一键审核此账号全部草稿',exact:true}).click();
await modal.getByRole('button',{name:'预览全部待审草稿',exact:true}).click();
const firstStart=modal.getByRole('button',{name:'一键审核 35 条并进入待发布',exact:true});
await firstStart.waitFor();
assert(!(await firstStart.isEnabled()),'Missing explicit range confirmation');
await modal.getByText('缺少适用条件,需编辑补充:1 条',{exact:true}).waitFor();
await modal.getByText('已超过有效期:1 条',{exact:true}).waitFor();
await page.screenshot({path:`${root}/01-account-preview.png`,fullPage:true});
await modal.getByRole('checkbox').check();await firstStart.click();
await modal.getByRole('tab',{name:'我的审核任务',exact:true}).waitFor({state:'visible'});
await modal.getByRole('button',{name:/^关\s*闭$/}).click();
await modal.waitFor({state:'hidden'});
const first=await finish(35);
assert(first.total===37&&first.skipped===2,'Unexpected account totals');
const untouched=await api(`items?account_id=${fixture[1].id}`);
assert(untouched.total===40&&untouched.items.every(r=>r.status==='draft'),'Other account modified');
checks.push('指定账号 37 条跨页审核:35 条进入待发布,2 条保留;关闭弹窗后后台继续,其他账号未修改');
await account('全部账号');
await page.getByRole('button',{name:'一键审核全部授权账号',exact:true}).click();
await modal.getByRole('button',{name:'预览全部待审草稿',exact:true}).click();
const allStart=modal.getByRole('button',{name:'一键审核 40 条并进入待发布',exact:true});await allStart.waitFor();
await page.screenshot({path:`${root}/02-all-accounts-preview.png`,fullPage:true});
await modal.getByRole('checkbox').check();await allStart.click();
const second=await finish(40);assert(second.total===42&&second.skipped===2,'Unexpected all-account totals');
await modal.getByRole('button',{name:'刷新任务',exact:true}).click();
await modal.getByText('缺少适用条件,需编辑补充',{exact:true}).waitFor();
await page.screenshot({path:`${root}/03-results.png`,fullPage:true});
const all=await api('overview?account_id=-1');
assert(all.counts.approved===75&&all.counts.draft===2&&!all.counts.published,JSON.stringify(all.counts));
checks.push('全部授权账号覆盖剩余 42 条,40 条通过;累计 75 条待发布,0 条发布,异常原因可查看');
await modal.getByRole('button',{name:'查看知识',exact:true}).first().click();
await page.getByRole('dialog').filter({has:page.getByText('知识审核与来源',{exact:true})}).waitFor();
checks.push('异常结果可直接跳转对应账号的知识详情');
assert(!errors.length,JSON.stringify(errors));
const result={passed:true,checks,pageErrors:errors};writeFileSync(`${root}/result.json`,JSON.stringify(result,null,2));console.log(JSON.stringify(result));
}catch(error){await page.screenshot({path:`${root}/failure.png`,fullPage:true});writeFileSync(`${root}/failure.txt`,String(error)+'\n'+await page.locator('body').innerText());throw error;}
finally{await browser.close();}