如何在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
相关产品推荐
相关产品推荐

