赛普拉斯(Cypress):毫无例外地检查元素是否存在

时间:2019-01-16 11:55:50

标签: cypress

我正在使用赛普拉斯(Cypress)测试数据导出页面,该页面需要几分钟才能生成导出。该页面不会动态更新,因此我需要让Cypress重新加载页面,直到状态显示为已完成。我浏览了赛普拉斯的文档,看不到一种方法来检查元素是否存在,如果不存在则不引发异常。

我尝试使用jQuery,但这导致了无限循环:

describe('test reloading', function () {
  it('testSelector reload', function () {
    cy.visit('https://docs.cypress.io/api/utilities/$.html#Usage');
    let found = false;
    while (!found) {
      const nonExistent = Cypress.$('.fake-selector');

      if (!nonExistent.length) {
        cy.reload();
      } else {
        found = true;
      }
    }
  });
});

2 个答案:

答案 0 :(得分:3)

您可以尝试使用此代码。您的元素不可用,这就是它进入无限循环的原因。您需要在一定时间后从循环中跳出。

describe('test reloading', function () {
    it('testSelector reload', function () {
      cy.visit('https://docs.cypress.io/api/utilities/$.html#Usage')
      let found = false
      let count=0
      while (!found) {

        const nonExistent = Cypress.$('.fake-selector')

        if (!nonExistent.length) {
          cy.reload()
          found = false
          count=count+1
          cy.wait(1000)
          if(count==30)
          {
            found = true
            cy.log('Element not found after 30 seconds..Exit from loop!!!')
          }
        } else {
          found = true
        }
      }
    })
  })

答案 1 :(得分:0)

我不建议在Cypress中使用while循环,因为您混合了Cypress.$()之类的同步语句和cy.reload()之类的异步语句。

Cypress.$()要使用新元素,需要一个新上下文,例如.then().should()中的上下文。

我建议使用递归来实现重复的重载周期。这是一个示例:

it('testSelector reload', function() {
  let remainingAttempts = 30;

  function waitUntilSelectorExists() {
    let $el = Cypress.$('.fake-selector');
    if ($el.length) {
      // At least one tag was found.
      // Return a jQuery object.
      return $el;
    }

    if (--remainingAttempts) {
      cy.log('Selector not found yet. Remaining attempts: ' +
          remainingAttempts);

      // Requesting the page to reload (F5)
      cy.reload();

      // Wait a second for the server to respond and the DOM to be updated.
      return cy.wait(1000).then(() => {
        return waitUntilSelectorExists();
      });
    }
    throw Error('Selector was not found.');
  }

  waitUntilSelectorExists().then($el => {
    cy.log('$el contains this text: ' + $el.text());
  });
});

为避免对当前可能不存在(但以后存在)的元素引发错误,解决方案是get()父级,并尝试find()子级:

cy.get('#parent_of_sometimesMissing').then($element => {
  if ($element.find('#sometimesMissing').length > 0) {
    ....
  }
});