You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cypress的Promise中退出循环或实现条件判断?

Cypress异步条件循环问题解决方案

问题说明

测试「修改预约」功能时,数据库自动填充仅为部分随机患者生成预约,硬编码患者名会导致GitHub Actions测试不稳定。尝试通过getFirstPatientHavingAppointment()函数找到第一个有预约的患者并修改,但因Cypress异步命令队列特性,同步while循环无法正常工作:

  • 标记变量completed无法同步更新,始终为false
  • 找到目标患者后,循环仍会继续执行所有迭代

尝试的代码:

function getFirstPatientHavingAppointment() {
    let i = 0
    var completed = false // useless 
    while (i < 15) { // big safe number to a naive solution
      cy.log("Finding First Patient Having Appointment")
      cy.get('i[data-memberdetails]').eq(i).click()
      cy.wait(1000);
      cy.get('#appointments-tab').click();
      cy.wait(1000)
      cy.get('body')
        .then($body => {
          if ($body.find('button[data-test-id="open_appt_modal_for_provider"]').length) {
            // appointments exist, exit
            cy.log("Appointment found. Will modify. ")
            cy.get('button[data-test-id="open_appt_modal_for_provider"]').first().click();
            fillOutAppointmentModifyModal();
            completed = true // this doesn't work of course nor does 'return'
          } else {
            cy.log("No appointments found. Will try next patient")
            cy.get("#patient_details_close_button").click();
          }
        })
      cy.log(completed) // this always logs false
      if (completed) {
        cy.log("Completed-- patient updated")
        return
      }
      i++
    }
}

解决方案:使用递归实现异步条件循环

Cypress的命令是异步执行的,同步while循环会先跑完所有循环次数,再执行队列中的命令。改用递归函数可以控制异步流程,每次迭代后决定是否继续执行:

function getFirstPatientHavingAppointment(i = 0, maxAttempts = 15) {
  // 超过最大尝试次数时终止
  if (i >= maxAttempts) {
    cy.log('已尝试所有患者,未找到有预约的患者');
    return;
  }

  cy.log(`正在检查第 ${i + 1} 位患者的预约`);
  
  cy.get('i[data-memberdetails]').eq(i).click()
    .then(() => {
      cy.get('#appointments-tab').click();
      cy.get('body').then($body => {
        const hasAppointment = $body.find('button[data-test-id="open_appt_modal_for_provider"]').length > 0;
        
        if (hasAppointment) {
          cy.log('找到有预约的患者,开始修改');
          cy.get('button[data-test-id="open_appt_modal_for_provider"]').first().click();
          fillOutAppointmentModifyModal();
        } else {
          cy.log('该患者无预约,尝试下一位');
          cy.get("#patient_details_close_button").click().then(() => {
            // 递归调用,尝试下一个患者
            getFirstPatientHavingAppointment(i + 1, maxAttempts);
          });
        }
      });
    });
}

关键优化点

  • 用递归替代同步while循环,确保每次迭代等待异步命令执行完成后再判断下一步
  • 增加maxAttempts参数限制最大尝试次数,避免无限递归
  • 所有操作通过Cypress命令的链式调用实现,保证异步执行顺序正确
  • 移除无效的同步状态变量,直接在异步回调中控制流程

内容的提问来源于stack exchange,提问作者user19377190

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:45:48