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

Cypress中是否支持等待多个预期条件?(Protractor迁移场景)

在Cypress中实现Protractor ExpectedConditions.or 的逻辑

Cypress本身没有提供和Protractor ExpectedConditions.or 完全对应的内置命令,但可以通过自定义命令或轮询逻辑来实现“等待任一条件满足”的需求,同时契合Cypress的异步重试机制。

针对你提供的Protractor测试场景(点击确认按钮后,等待合约状态变为Cancelled或弹出可点击的确认弹窗),可以按以下方式实现:

方法1:自定义waitForEither命令

先在cypress/support/commands.js中添加自定义命令,实现轮询检查两个条件:

Cypress.Commands.add('waitForEither', (statusSelector, modalBtnSelector, timeout = 5000) => {
  return cy.wrap(null, { timeout }).then(() => {
    return new Cypress.Promise((resolve, reject) => {
      const startTime = Date.now();
      const checkConditions = () => {
        // 检查第一个条件:状态文本包含"Cancelled"
        cy.get(statusSelector, { timeout: 0 })
          .invoke('text')
          .then(text => {
            if (text.includes('Cancelled')) {
              resolve('status-updated');
            }
          })
          .catch(() => {
            // 第一个条件不满足,检查第二个:弹窗按钮可点击
            cy.get(modalBtnSelector, { timeout: 0 })
              .should('be.enabled')
              .then(() => {
                resolve('modal-shown');
              })
              .catch(() => {
                // 超时则抛出错误,否则继续轮询
                if (Date.now() - startTime >= timeout) {
                  reject(new Error('超时:未触发任一预期条件'));
                } else {
                  setTimeout(checkConditions, 100);
                }
              });
          });
      };
      checkConditions();
    });
  });
});

在测试中使用该命令

替换原Protractor逻辑,同时注意避免使用sleep(Cypress推荐通过等待元素状态变化来同步测试流程):

// 点击确认按钮
cy.get('[data-testid="confirm-button"]').click();

// 等待任一条件满足
cy.waitForEither('.view-all-first-status', '.modal-ok-button', 5000).then((triggeredCondition) => {
  if (triggeredCondition === 'modal-shown') {
    // 处理弹窗:点击OK,等待弹窗关闭后重试取消
    cy.get('.modal-ok-button').click();
    // 等待弹窗关闭的标识元素(比如弹窗容器消失)
    cy.get('.modal-container').should('not.exist');
    // 执行取消合约操作
    cancelFirstContract();
  }
  // 若触发的是状态更新条件,无需额外操作
});

方法2:直接使用Cypress的元素查询与重试

如果不需要复用逻辑,也可以直接在测试中通过cy.get()结合条件判断实现:

cy.get('[data-testid="confirm-button"]').click();

// 轮询检查两个条件,利用Cypress的自动重试特性
cy.get('body').then($body => {
  const isModalBtnEnabled = $body.find('.modal-ok-button').is(':enabled');
  if (isModalBtnEnabled) {
    cy.get('.modal-ok-button').click();
    cy.get('.modal-container').should('not.exist');
    cancelFirstContract();
  } else {
    cy.get('.view-all-first-status').should('contain', 'Cancelled');
  }
});

关键注意点

  • 替换browser.sleep():Cypress会自动等待元素可见/可交互,无需手动设置固定等待时间,建议通过等待目标元素的状态变化(如弹窗消失)来同步流程。
  • 选择器优化:尽量使用data-testid这类语义化、不易变更的选择器,避免依赖CSS类名或文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:54:31