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/knowledge-v4-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:18869'; 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();}