Cypress e2e测试:点击无target属性的href新开标签页如何访问
Cypress访问iframe内点击后新开标签页的解决方案
问题场景
- 测试目标站点为yopmail临时邮箱,流程为进入站点、输入邮箱名进入收件箱、点击收件箱iframe(id为
ifmail)内的链接 - 点击链接后会自动打开新标签页,但Cypress无法直接获取、操作新开的标签页
- 常规移除
target属性让链接在当前页打开的方案无效,因为目标链接本身没有设置target属性 - 原有测试代码如下:
cy.visit('https://yopmail.com/en/') cy.get('.ycptinput').type('some_name {enter}') cy.wait(2000) cy.get('#ifmail').its('0.contentDocument.body').then(cy.wrap).find('a').click()
- 目标链接的HTML结构参考:链接HTML结构参考图
实现方案
Cypress本身的运行机制决定了它不支持直接操作多标签页,所有新开标签页的场景都不需要真的触发新标签打开,只需要拦截到目标跳转地址,在当前测试上下文直接访问即可,以下是两种适配当前场景的可行方法:
方法1:直接读取链接href属性访问(优先使用,稳定性最高)
如果链接的跳转地址直接写在href属性上,不需要触发点击事件,直接取出地址访问即可,完全绕开新标签页逻辑:
cy.visit('https://yopmail.com/en/') cy.get('.ycptinput').type('some_name {enter}') cy.wait(2000) cy.get('#ifmail').its('0.contentDocument.body').then(cy.wrap).find('a') .invoke('attr', 'href') .then(href => { // 兼容相对路径场景,拼接完整访问地址 const fullTargetUrl = href.startsWith('http') ? href : new URL(href, 'https://yopmail.com').href cy.visit(fullTargetUrl) }) // 后续直接编写新页面的断言逻辑即可
方法2:劫持iframe内的window.open方法捕获地址(适配JS触发跳转的场景)
如果链接没有直接写href,是通过绑定点击事件调用window.open触发新标签打开,就提前重写iframe上下文里的window.open方法,拦截跳转地址后再访问:
cy.visit('https://yopmail.com/en/') cy.get('.ycptinput').type('some_name {enter}') cy.wait(2000) cy.get('#ifmail').then($iframe => { const iframeWindow = $iframe[0].contentWindow let targetJumpUrl = '' // 重写iframe内的window.open,拦截要打开的地址 iframeWindow.open = (jumpUrl) => { targetJumpUrl = jumpUrl // 阻断原生新标签打开逻辑 return null } // 触发链接点击 cy.wrap($iframe[0].contentDocument.body).find('a').click().then(() => { // 拼接完整地址后在当前页访问 const fullTargetUrl = targetJumpUrl.startsWith('http') ? targetJumpUrl : new URL(targetJumpUrl, 'https://yopmail.com').href cy.visit(fullTargetUrl) }) }) // 后续直接编写新页面的断言逻辑即可
注意:不要尝试通过浏览器窗口句柄获取新开标签页操作,Cypress的测试运行上下文和同源限制决定了这类方案稳定性极差,上述两种拦截地址访问的方案是目前生产环境测试的通用最优解。
内容的提问来源于stack exchange,提问作者Mr.Prasad J
相关产品推荐
相关产品推荐

