// Real user dropdown, confirmation and router; all APIs simulated.
|
const assert=require('node:assert/strict'),fs=require('fs'),path=require('path');
|
const {chromium}=require('C:/Users/云/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
|
(async()=>{
|
const server=await(await import('vite')).createServer({root:path.resolve(__dirname,'..'),server:{host:'127.0.0.1',port:5183}});await server.listen();
|
const browser=await chromium.launch({headless:true,executablePath:'C:/Program Files/Google/Chrome/Application/chrome.exe'});
|
const page=await browser.newPage({viewport:{width:1440,height:950},reducedMotion:'reduce'});const errors=[];let logoutCalls=0;let releaseLogout;let logoutHeader;
|
page.on('pageerror',e=>errors.push(e.message));
|
await page.route('**/admin-api/**',async route=>{
|
const url=route.request().url();
|
if(url.includes('/system/auth/logout')){logoutCalls++;logoutHeader=route.request().headers().authorization;await new Promise(r=>releaseLogout=r);}
|
const data=url.includes('company-config')?{companyName:'退出验证平台'}:url.includes('count')?0:url.includes('list')?[]:null;
|
await route.fulfill({contentType:'application/json',body:JSON.stringify({code:0,data,msg:''})}).catch(()=>{});
|
});
|
try{
|
await page.goto('http://127.0.0.1:5183/auth/login',{waitUntil:'domcontentloaded'});await page.getByRole('heading',{name:'欢迎回来'}).waitFor();
|
await page.waitForFunction(()=>!document.querySelector('#__app-loading__')||getComputedStyle(document.querySelector('#__app-loading__')).opacity==='0');
|
await page.evaluate(async()=>{
|
const stores=await import('/src/packages/stores/src/index.ts'),{router}=await import('/src/router/index.ts'),{h}=await import('/node_modules/.vite/deps/vue.js');
|
stores.useAccessStore().setAccessToken('qa-session-token');stores.useAccessStore().setRefreshToken('qa-refresh-token');stores.useAccessStore().setIsAccessChecked(true);
|
stores.useUserStore().setUserInfo({userId:'1',username:'logout-qa',nickname:'退出验证用户',avatar:''});
|
router.addRoute('Root',{name:'LogoutQa',path:'/qa-logout-session',meta:{title:'退出验证工作区'},component:{render(){return h('div','退出验证工作区')}}});
|
await router.push('/qa-logout-session');
|
});
|
await page.locator('[id="__vben_main_content"]').getByText('退出验证工作区',{exact:true}).waitFor({timeout:60000});
|
const avatars=page.locator('button[aria-haspopup="menu"]').filter({has:page.locator('.size-8')}).first();
|
await avatars.click();
|
await page.getByRole('menuitem',{name:/退出登录/}).click();
|
const dialog=page.getByRole('dialog');await dialog.waitFor();
|
const started=Date.now();await dialog.getByRole('button',{name:/^确\s*[认定]$/}).click();
|
await page.waitForURL('**/auth/login',{timeout:5000});await page.getByRole('heading',{name:'欢迎回来'}).waitFor();
|
const elapsed=Date.now()-started;
|
const state=await page.evaluate(async()=>{const s=await import('/src/packages/stores/src/index.ts');return{access:s.useAccessStore().accessToken,refresh:s.useAccessStore().refreshToken,user:s.useUserStore().userInfo}});
|
assert.equal(state.access,null);assert.equal(state.refresh,null);assert.equal(state.user,null);
|
assert.equal(logoutCalls,1);assert.equal(logoutHeader,'Bearer qa-session-token');assert.equal(typeof releaseLogout,'function','Server logout must still be pending when login page appears');
|
releaseLogout();await page.waitForTimeout(100);
|
const result={passed:true,scope:'Real application user dropdown, confirmation, stores and routing; simulated authenticated session and pending backend, no real account login',checks:['click logout and confirm','navigate without refresh while server pending','access and refresh token cleared','user info cleared','server revoke uses original token'],elapsedMs:elapsed,errors};
|
assert.deepEqual(errors,[]);
|
const out=path.resolve(__dirname,'../../scripts/logout-fix-20261015');fs.mkdirSync(out,{recursive:true});fs.writeFileSync(path.join(out,'browser-result.json'),JSON.stringify(result,null,2));console.log(JSON.stringify(result));
|
}catch(error){console.error(JSON.stringify({message:error.message,errors,body:(await page.locator('body').innerText()).slice(0,1800)}));throw error;}
|
finally{releaseLogout?.();await browser.close();await server.close();}
|
})();
|