如何解决Cypress循环内调用cy.stub()触发重复包装报错问题
报错原因
循环中多次执行cy.stub(win, 'open')时,首次循环已经将window.open替换为stub模拟函数,第二次循环再次尝试包装同一个方法时,Cypress检测到目标方法已经被stub占用,就会抛出Attempted to wrap open which is already wrapped错误。
报错截图
修复方案
根据循环内是否会触发页面刷新,选择对应方案即可:
方案1:循环内不刷新页面(推荐)
如果循环过程中页面不会重载、window对象始终是同一个实例,只需要在循环外创建一次stub,每次循环开始前重置stub的历史调用记录即可,避免重复创建stub:
// 循环外仅初始化一次stub cy.window().then((win) => { cy.stub(win, 'open').as('popup'); }) for (/* 你的循环逻辑 */) { // 清空上一次循环的stub调用记录 cy.get('@popup').then(stub => stub.reset()) // 执行触发弹窗的点击等操作 // cy.get('触发弹窗的元素选择器').click() // 断言验证 cy.get("@popup").should("be.called"); }
方案2:循环内会触发页面刷新/跳转
如果每次循环操作后页面会刷新、window对象会重建,那每次创建stub前先检查是否存在已有的stub,先恢复原始方法再创建新的stub:
for (/* 你的循环逻辑 */) { cy.window().then((win) => { // 若open方法已被stub,先恢复原始实现 if (typeof win.open.restore === 'function') { win.open.restore() } cy.stub(win, 'open').as('popup'); }) // 执行触发弹窗的点击等操作 // cy.get('触发弹窗的元素选择器').click() // 断言验证 cy.get("@popup").should("be.called"); }
注意:Cypress默认只会在单个测试用例(it块)执行结束后自动恢复所有stub,同一个用例内的循环逻辑不会触发自动恢复,因此必须手动处理stub的复用或恢复。
内容的提问来源于stack exchange,提问作者Kawal Bajwa
相关产品推荐
相关产品推荐

