如何使用Cypress点击打开新标签页并切换,解决windowOpen未触发报错
报错原因
Timed out retrying after 4000ms: expected windowOpen to have been called at least once, but it was never called
中文释义:4000毫秒后重试超时:预期windowOpen至少被调用一次,但从未触发
该报错的核心原因为:当前你为顶层window对象绑定了window.open的桩函数,但点击的链接属于iframe内部元素,新标签页打开操作实际调用的是iframe自身的window.open方法,因此顶层的桩函数无法捕获到对应调用事件。
修复方案
方案1:将桩函数绑定到iframe的window对象
直接监听iframe内部window的open事件,适配所有通过window.open触发新标签打开的场景,代码示例如下:
let newUrl = ''; // 先获取iframe对应的window对象绑定桩 getIframeBody().its('0.contentWindow').then((iframeWin) => { cy.stub(iframeWin, 'open').as('windowOpen').callsFake(url => { newUrl = url; }); }) // 绑定完成后再点击链接 getIframeBody().find('table#emailContainer tr td a').click(); cy.get('@windowOpen').should('be.called');
方案2:直接读取a标签的href属性
如果你的需求只是获取链接地址、不需要校验window.open的调用行为,可以直接读取a标签的href属性,实现更简单稳定:
getIframeBody().find('table#emailContainer tr td a').invoke('attr', 'href').then(href => { const newUrl = href; // 无需模拟新标签打开,直接访问对应地址即可 cy.visit(newUrl); })
注意事项
- 如果a标签的href为相对路径,需要自行拼接对应邮件服务的域名前缀生成完整访问地址
- 如果点击链接存在动态拼接跳转地址的逻辑,优先使用方案1捕获open调用的最终地址
内容的提问来源于stack exchange,提问作者Jelena Dimitrijevic
相关产品推荐
相关产品推荐

