Транспортир: ожидание элемента, который присутствует, но не отображается

Я написал тест, чтобы проверить, отображается ли элемент на экране, в моем случае это складная панель angular-ui-bootstrap, также известная как «предупреждение». Код работает, но тесты дают сбой в ~ 75% случаев.

При отображении «предупреждения» есть анимация сворачивания, и я не могу отключить анимацию для тестов, так как это анимация jquery. Предупреждение всегда «присутствует» в DOM, просто сворачивается, когда нет причин его показывать.

Сначала я протестировал этот код, и это довольно просто:

expect(element('.warning').isDisplayed()).toEqual(true);

Проблема возникла, когда мне нужно было проверить, что элемент не отображается, например : как только предупреждение отображается, какое-то действие вызывает его сворачивание.

Этот тест:

expect(element('.warning').isDisplayed()).toEqual(false);

пройдет, только если анимация запустилась. Он завершится ошибкой, если условие проверено, пока элемент все еще отображается.

Я придумал два решения.

Самый простой - с использованием ptor.driver.sleep(2000). Это замедляет мои тесты и неприемлемо.

Трудный, уродливый, но дает хорошие результаты:

exports.isWarningDisplayed = function (expectedVisibility) {
  return ptor.driver.wait(function () {
     if (expectedVisibility) {
       return element(by.css('.warning')).isDisplayed().then(function(visibility) {
         return visibility === expectedVisibility;
       });
      } else {
        return element.all(by.css('.warning .collapse.in')).then(function(items) {
          return items.length === 0;
       });
      }
    }, 2000).then(function() {
      return element.all(by.css('.warning .collapse.in'));
    }).then(function (items) {
      return items.length > 0;
    });
};

Моя проблема в том, что это просто ужасно неправильно. Вы нашли лучший способ справиться с этой ситуацией? Я ожидал, что получится что-то вроде:

expect(element('.warning').not.isDisplayed()).toEqual(true);

... но нет .not в транспортире или webDriver AFAIK.


person Julien Bérubé    schedule 15.04.2014    source источник


Ответы (4)


У меня была аналогичная проблема - я хотел проверить, когда элемент больше не отключен. Я изо всех сил пытался обойти ситуацию без теста .not, а затем понял, что могу просто переместить тест 'not' в селектор css:

// we're looking for when the element doesn't have a .disabled class
var availableElement = by.css('.some-class:not(.disabled)');
browser.wait(function() {
  return ptor.isElementPresent(availableElement);
}, 30000);

expect(ptor.isElementPresent(availableElement)).toBeTruthy();

Не уверен, что это поможет, но у меня был момент ясности, поэтому я подумал, что поделюсь.

person mattgi    schedule 01.07.2014
comment
Это действительно помогает! Спасибо, это намного чище, чем то, что у меня есть! - person Julien Bérubé; 03.07.2014
comment
Я получаю сообщение об ошибке TypeError: Unimplemented function: "isPending" из обещания selenium-webdriver.js при использовании isElementPresent :-( ?! - person Sebastian; 31.07.2014
comment
Мне нужно использовать browser.isElementPresent( ... - person mvndaai; 17.01.2015
comment
У меня возникла очень похожая проблема, из-за которой многие наши тесты были нестабильными, с кажущимися случайными сбоями в зависимости от того, на какой машине они выполнялись. Я обнаружил, что отключение переходов css значительно помогло, поскольку они использовались в некоторых компонентах начальной загрузки пользовательского интерфейса, на которые мы полагаемся: stackoverflow.com/a/ 32264842/446030 - person JcT; 28.08.2015

Использование elementexplorer (https://github.com/angular/protractor/blob/master/docs/debugging.md) Я посмотрел на объект транспортира и нашел ответ, который у меня замечательно работает:

var el = element(by.id('visibleElementId'));
browser.driver.wait(protractor.until.elementIsNotVisible(el));
person Al Joslin    schedule 28.12.2014

expect(ptor.isElementPresent(by.css('.warning'))).toBe(false);

Это еще один способ проверить, отображается что-то на странице или нет.

person Liam's musings    schedule 15.05.2014
comment
Не совсем то, что я ищу, так как оно оправдает ожидания, если элемент отсутствует в DOM. В моем случае он всегда находится в DOM, но скрыт. - person Julien Bérubé; 15.05.2014
comment
Я получаю ReferenceError: isElementPresent is not defined. - person Kees de Kooter; 12.06.2014
comment
Согласно Protractor API, вы можете вызвать isElementPresent из транспортира например, elementFinder или webElement. - person glepretre; 01.07.2014
comment
Спасибо, это помогло мне! Вам нужно просто добавить by.css() вокруг строки локатора. - person Lodewijk Bogaards; 09.07.2014

По моему опыту, это обычная «грустная» проблема. Вы знаете, что ваш код написан правильно, но тест не прошел из-за ожидания. Например, в Chrome я получаю в консоли следующую ошибку:

‹Неизвестная ошибка: элемент не активен в точке (952, 275). >

Итак, я создал отдельную функцию в своем классе WebDriver и, похоже, она работает:

this.waitElementToBeShown = function (elmLocator) {
        browser.sleep(500);
        browser.wait(function () {
            return (elmLocator).isPresent();
        }, 3000);
        browser.wait(function () {
            return (elmLocator).isDisplayed();
        }, 3000);
    }
person Alex Svyatenko    schedule 04.08.2015
comment
Я настоятельно рекомендую не использовать browser.sleep, если еще доступен какой-либо другой вариант. По моему опыту, медленные тесты запускаются реже, что делает их менее полезными, поэтому они запускаются реже. - person Julien Bérubé; 18.08.2015