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

