首页 > 解决方案 > 赛普拉斯 - 等待滚动调整大小

问题描述

我在渲染其余 DOM 后几毫秒调整大小的滚动时遇到问题,这导致滚动几乎到达底部,缺少几个像素,因此我需要单击的按钮保持禁用状态。所以我正在寻找最好和更一致的方式来等待这种情况,而无需添加显式等待。

我已经尝试等待登录后发生的所有可用 XHR 调用,这在大多数情况下都有效,但不是 100%(在电子上,这是我们的 CI 使用的),我还尝试在滚动之前获取其他元素,就像检查按钮被禁用但那个时间似乎不足以让滚动完全调整大小。

这是我的实际代码示例:

 Cypress.Commands.add('waitForRequestAndVisit', (path, url) => {
   cy.server();
   cy.route('GET', path).as('request');
   cy.visit(url);
   cy.wait('@request');
 }),

这是规范文件:

cy.waitForRequestAndVisit('**/api/v1/auth/validate_token', '/');


const termsAndConditionsScroll = '[data-testid=terms-and 
conditions]';
cy.get(termsAndConditionsScroll).scrollTo('bottom');
cy.getSubmitButton()
   .should('not.be.disabled')
   .click();

标签: automationcypress

解决方案


我编写了自己的 cypress 命令,以便在继续之前等待一些任意的 javascript 处理准备好。

/**
 * Waits until call to cb() resolves to something truthy.
 *
 * @param message {string} Error message on timeout
 * @param cb {() => Cypress Command "promise"} 
 *   Callback for checking if condition is met should return 
 *   cy.xxxxxx.then() and resolve to undefined if polling should continue.
 */
Cypress.Commands.add('waitFor', (message, cb, timeoutMs = 2000) => {
  const startTime = new Date().getTime();
  const giveupTime = startTime + timeoutMs;
  const startTimeout = 5;

  function checkCb(timeout) {
    const currentTime = new Date().getTime();

    if (currentTime > giveupTime) {
      throw new Error(`Timeout while waiting for (${currentTime - startTime}ms): ${message}`);
    } else {
      cy.wait(timeout);

      return cb().then(result => {
        if (result === undefined) {
          return checkCb(timeout * 2); // always wait twice as long as the last time
        } else {
          return result;
        }
      });
    }
  }

  return checkCb(startTimeout);
});

然后您可以进行轮询滚动到底部,直到提交按钮处于活动状态:

cy.waitFor('submit to not be disabled', () => {
  cy.get(termsAndConditionsScroll).scrollTo('bottom');
  return cy.getSubmitButton().then(btn => {
    if (!!btn.disabled) {
      return undefined; // undefined means that polling should continue
    }
    return btn;
  });
}, 5000);

cy.getSubmitButton()
  .should('not.be.disabled')
  .click();

推荐阅读