cypress.io: содержит () не ожидающий элемента - PullRequest
0 голосов
/ 22 ноября 2018

Мы пишем тесты пользовательского интерфейса на кипарисе, который обычно довольно прост в использовании.Но снова и снова я натыкаюсь на утомительную проблему ожидания.

Сценарий довольно прост.Пользователь нажимает на кнопку поиска.Затем он выбирает один из элементов с определенным текстом.Вот код:

cy.get('#search-button').click();
cy.contains('Test item 1').click();
cy.get('#cheapest-offer-button').click();

Третье событие щелчка не выполняется, потому что уже cy.contains('Test item 1') не ожидает страницы и элемента для визуализации.Из того, что я вижу на этапах тестирования, он просто щелкает в середине страницы, что по сути ничего не делает.Так что все последующие шаги, конечно, терпят неудачу.

Однако, если я добавлю wait() между вызовами, как это:

cy.get('#search-button').click();
cy.wait(2000);
cy.contains('Test item 1').click();
cy.get('#cheapest-offer-button').click();    

Страница отображается правильно, появляется Test item 1, нажимаетсяи все последующие шаги успешны.

В соответствии с передовой практикой вызов wait() не должен быть необходимым и поэтому его следует избегать.Что я тут не так делаю?

Ответы [ 3 ]

0 голосов
/ 05 июня 2019

Добавьте ниже вещи в ваш файл cypress.json и проверьте.Должно работать правильно.

{
  "execTimeout": 60000,
  "taskTimeout": 60000,
  "defaultCommandTimeout": 20000,
  "pageLoadTimeout": 200000,
  "responseTimeout": 10000
}
0 голосов
/ 27 июня 2019

tl; dr

Дайте больший тайм-аут для contains:

cy.get('#search-button').click();
cy.contains('Test item 1', { timeout: 4000 }).click();
cy.get('#cheapest-offer-button').click();  

Объяснение

Как и у многих команд Cypress, contains имеютВторой аргумент , который принимает объект опции.Вы можете передать количество миллисекунд, которые команда должна ждать в ключе timeout, например:

.contains('Stuff', { timeout: 5000 }) // Timeout after 5 secs

Таким образом, команда будет вести себя так, как если бы вы добавили wait перед ней, но если командабыл успешным, он не будет ждать все время, как wait делает.

Официальные документы Cypress о тайм-аутах по таймаутам объясняют эту технику: как она работает, как это должно быть сделано и какэто влияет на цепочечные утверждения.

Если причиной, по которой вы не можете щелкнуть элемент, является видимость, тогда вы можете попробовать .click({ force: true }), хотя это должно быть последним средством, поскольку оно может скрывать фактические ошибки.

0 голосов
/ 05 июня 2019

Похоже, что это распространенная проблема https://github.com/cypress-io/cypress/issues/695.

Решение состоит в том, чтобы заставить Cypress ожидать всех асинхронных операций, как в средах, основанных на веб-драйвере Selenium.Это намного быстрее, чем cy.wait (). Реализуйте метод:

function waitForBrowser() { 
   cy.window().then(win => {
      return new Cypress.Promise(resolve => win['requestIdleCallback'](resolve));
   });
}

И просто используйте его так:

cy.get('#search-button').click();
waitForBrowser();
cy.contains('Test item 1').click();
cy.get('#cheapest-offer-button').click();

Если вы используете Angular Лучше использовать waitForAngular вместо waitForBrowser

function waitForAngular() {
  return cy.window().then(win => {
      return new Cypress.Promise((resolve, reject) => {
        let testabilities = win['getAllAngularTestabilities']();
        if (!testabilities) {
            return reject(new Error('No testabilities. Check Angular API'));
        }
        let count = testabilities.length;
        testabilities.forEach(testability => testability.whenStable(() => {
            count--;
            if (count !== 0) return;
            resolve();
        }));
      });
  });
}
...