【问题标题】:Cypress: check if element exists without exception赛普拉斯:检查元素是否存在无异常
【发布时间】:2019-01-16 11:55:50
【问题描述】:

我正在使用 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;
      }
    }
  });
});

【问题讨论】:

  • 我面临同样的问题。你有没有找到不用while循环的方法?
  • @Manspof 我添加了一个有效的答案。我无法让它与 while 循环一起工作。

标签: cypress


【解决方案1】:

你可以试试这个代码。您的元素不可用,从而导致无限循环。一定时间后需要跳出循环。

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;
      }
    }
  });
});

【讨论】:

  • 我不推荐在 Cypress 中使用这样的 while 循环,因为您将同步语句(例如 Cypress.$)和异步语句(例如 cy.reload)混合在一起。尝试将.fake-selector 替换为页面上存在的内容,例如h2,您的循环将无法拾取它。
【解决方案2】:

我不建议在 Cypress 中使用 while 循环,因为您将同步语句(例如 Cypress.$())和异步语句(例如 cy.reload())混合在一起。

Cypress.$() 要获取新元素,它需要一个新的上下文,例如在.then().should() 中。

我建议使用 recursion 来实现重复的重新加载周期。这是一个例子:

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) {
    ....
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多