Как использовать транспортир, чтобы проверить, если элемент виден?


Я пытаюсь проверить, если элемент виден с помощью транспортира. Вот как выглядит элемент:

<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>

когда в консоли chrome, я могу использовать этот селектор jQuery, чтобы проверить, если элемент виден:

$('[ng-show=saving].icon-spin')
[
<i class=​"icon-spinner icon-spin ng-hide" ng-show=​"saving">​</i>​
]
> $('[ng-show=saving].icon-spin:visible')
[]
, когда я пытаюсь сделать то же самое в транспортир, я получаю эту ошибку во время выполнения:
InvalidElementStateError: 
invalid element state: Failed to execute 'querySelectorAll' on 'Document': 
'[ng-show=saving].icon-spin:visible' is not a valid selector.

почему это не действует? Как я могу проверить видимость с помощью транспортира?

6 98

6 ответов:

Это должно сделать это:

expect($('[ng-show=saving].icon-spin').isDisplayed()).toBeTruthy();

помните транспортира $ это не jQuery и :visible не пока часть доступные селекторы CSS + псевдо-селекторы

дополнительная информация на https://stackoverflow.com/a/13388700/511069

правильный способ проверки видимости элемента с помощью транспортира-вызвать isDisplayed метод. Вы должны быть осторожны с isDisplayed не возвращает логическое значение, а скорее promise обеспечение оцениваемой видимости. Я видел много примеров кода, которые используют этот метод неправильно и поэтому не оценивают его фактическую видимость.

пример для получения видимости элемент:

element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
    if (isVisible) {
        // element is visible
    } else {
        // element is not visible
    }
});

однако вам это не нужно, если вы просто проверяете видимость элемента (в отличие от его получения), потому что патчи транспортира Jasmine expect() поэтому он всегда ждет обещаний, которые будут решены. Смотрите github.com/angular/jasminewd

так что вы можете просто сделать:

expect(element(by.className('your-class-name')).isDisplayed()).toBeTruthy();

так как вы используете AngularJS чтобы контролировать видимость этого элемента, вы также можете проверить его атрибут class для ng-hide как это:

var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible

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

expect($('i.icon-spinner:not(.ng-hide)').isDisplayed()).toBeTruthy();

в контексте объекта страницы, вы можете получить только те элементы, которые видны на этом пути. Например. учитывая страницу с несколькими элементами, где видны только некоторые из них, вы можете использовать:

this.visibileIcons = $$('i.icon:not(.ng-hide)'); 

это вернет вам все видно i.icons

Если в DOM есть несколько элементов с одинаковым именем класса. Но виден только один из элементов.

element.all(by.css('.text-input-input')).filter(function(ele){
        return ele.isDisplayed();
    }).then(function(filteredElement){
        filteredElement[0].click();
    });

в этом примере фильтр принимает коллекцию элементов и возвращает один видимый элемент с помощью isDisplayed ().

этот ответ будет достаточно надежным для работы с элементами, которые не находятся на странице, поэтому он не будет корректно (не создавая исключения), если селектор не смог найти элемент.

const nameSelector = '[data-automation="name-input"]';
const nameInputIsDisplayed = () => {
    return $$(nameSelector).count()
        .then(count => count !== 0)
}
it('should be displayed', () => {
    nameInputIsDisplayed().then(isDisplayed => {
        expect(isDisplayed).toBeTruthy()
    })
})

ждать видимости

const EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.css('.icon-spinner icon-spin ng-hide')))).then(function() {
  //do stuff
})

Xpath трюк, чтобы найти только видимые элементы

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))