Cypress如何打开新标签页并保留原标签页实现双向切换
问题根因
你原有代码的问题出在stubwindow.open时直接修改当前窗口的location.href,本质是在原标签页内执行跳转,直接覆盖了原页面的上下文,根本没有生成独立的新标签,自然无法保留原页面状态、实现双向切换。
实现方案
推荐使用原生标签句柄控制的方案,可完全保留两个标签的独立运行状态,支持任意方向切换,适配同域、跨域场景。
配置前置要求
先在cypress.config.js中关闭同源安全限制,避免跨标签操作被浏览器拦截:
const { defineConfig } = require("cypress"); module.exports = defineConfig({ e2e: { chromeWebSecurity: false, // 保留你原有其他配置项 }, });
核心实现代码
去掉你之前写的修改当前页href的stub逻辑,替换为以下代码:
// 存储原标签页窗口句柄,用于后续切回 let originalTabWindow; cy.window().then(win => { originalTabWindow = win; // 劫持window.open,但保留原生打开新标签的行为,不覆盖当前页 cy.stub(win, 'open').as('newTabTrigger').callsFake((targetUrl) => { // 调用原生open方法真实打开新标签页 return win.open.wrappedMethod.call(win, targetUrl, '_blank'); }) }) // 点击按钮触发新标签打开 cy.get('#button').click() cy.get('@newTabTrigger').should('be.called') // 等待新标签加载完成后,切换到新标签上下文执行操作 cy.origin(Cypress.config('baseUrl'), () => { // 此处写新标签页内的所有测试逻辑 cy.url().should('include', '/#/myurl'); // 示例:新标签页元素操作 // cy.get('.submit-btn').click(); }) // 新标签操作完成后,切回原标签页 cy.wrap(originalTabWindow).invoke('focus'); // 此处可继续编写原标签页的后续测试逻辑,原页面所有临时状态(未提交表单、弹窗状态等)都会完整保留 cy.url().should('not.include', '/#/myurl');
轻量替代方案(无状态场景适用)
如果你测试的页面不需要保留临时内存状态(比如没有未提交的表单输入、临时弹窗这类刷新就丢失的内容),也可以用拦截跳转+手动切地址的轻量方案,不需要修改安全配置:
let originalPageUrl, newTabUrl; // 先记录原页面地址 cy.url().then(url => originalPageUrl = url); // 拦截新标签打开事件,阻止默认新开标签行为,仅记录目标地址 cy.window().then(win => { cy.stub(win, 'open').as('popup').callsFake((url) => { newTabUrl = url; return false; }) }) cy.get('#button').click(); cy.get('@popup').should('be.called'); // 先执行原页面需要的操作 // ...原页面逻辑 // 跳转到新标签地址执行操作 cy.visit(newTabUrl); // ...新标签页逻辑 // 操作完成后切回原页面 cy.visit(originalPageUrl);
注意事项
- 第一种方案是真实打开两个独立标签页,原页面的所有运行时状态都会完整保留,完全匹配你需要双向切换的需求
- 如果新标签是跨域地址,只需要把
cy.origin()的第一个参数替换为新标签对应的域名即可,不需要其他额外修改
内容的提问来源于stack exchange,提问作者ZombiePie
相关产品推荐
相关产品推荐

