Firefox中触发window.location跳转时Playwright测试失败原因分析
问题:Firefox中Playwright测试点击登出按钮后跳转失效
我有一个带onClick监听的React组件,代码如下:
<button className='h-10 min-h-[2.5rem] m-2 rounded-lg border-2 text-white bg-violet-400 border-white' id='logout-cta-button' onClick={logout} > Log Out </button>
对应的logout函数定义在同一文件中:
function logout() { fetch('api/logout') .then(() => { document.cookie = 'token=; expires=Fri, 1 Jan 2000 0:00:00 UTC; path=/'; window.location.assign('/login'); }) .catch(err => { console.error("Unable to log out for some reason.", err.toString()); }) }
该API返回状态码200,无需关注具体实现。
我编写的Playwright测试用例如下:
expect(page.locator('#logout-cta-button')).toBeTruthy(); await page.locator('#logout-cta-button').click(); await page.waitForURL('http://localhost:3000/login');
测试在Chromium和Webkit中正常通过,但在Firefox里,logout函数的跳转逻辑似乎被忽略,导致测试失败。请问可能的原因是什么?
原因分析与解决方案
可能原因
- Firefox异步请求处理特性:Firefox在执行
window.location.assign时,若fetch请求尚未完成读取响应体,页面跳转会直接中止该请求,进而打断后续的跳转逻辑执行。Chromium和Webkit对这类场景的处理更宽松,允许跳转逻辑在请求完成基础步骤后执行。 - Playwright跨浏览器行为差异:Playwright的
click方法在Firefox中的事件触发时机或事件循环调度顺序与其他浏览器不同,导致logout中的异步逻辑未完全执行就进入了页面等待阶段。
解决办法
- 确保fetch请求完全完成:在
then中读取响应体,保证请求彻底完成后再执行跳转,避免Firefox中断请求:
function logout() { fetch('api/logout') .then(response => response.text()) // 若API返回JSON则用response.json() .then(() => { document.cookie = 'token=; expires=Fri, 1 Jan 2000 0:00:00 UTC; path=/'; window.location.assign('/login'); }) .catch(err => { console.error("Unable to log out for some reason.", err.toString()); }) }
- 同步等待请求完成再检查跳转:在Playwright测试中,同时等待API响应和点击操作,确保请求完成后再等待页面跳转:
await Promise.all([ page.waitForResponse('**/api/logout'), page.locator('#logout-cta-button').click() ]); await page.waitForURL('http://localhost:3000/login');
- 等待页面状态稳定:点击后添加网络空闲状态等待,确保页面逻辑执行完毕:
await page.locator('#logout-cta-button').click(); await page.waitForLoadState('networkidle'); await page.waitForURL('http://localhost:3000/login');
内容的提问来源于stack exchange,提问作者Steverino
相关产品推荐
相关产品推荐

