Як використовувати транспортир, щоб перевірити, чи видно елемент?


111

Я намагаюся перевірити, чи видно елемент за допомогою транспортира. Ось як виглядає елемент:

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

Перебуваючи в хромованій консолі, я можу використовувати цей селектор 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.

Чому це не дійсно? Як я можу перевірити видимість за допомогою транспортира?


Привіт @limp_chimp чи допомогла вам моя відповідь нижче?
Лев Галлуччі

@limp_chimp для таких речей, як видимість, подумайте про те, як використовувати тести клієнтських DOM-модулів AngularJS. Вони набагато швидше бігають і легше розвиваються.
Offirmo

Відповіді:


144

Це слід зробити:

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

Пам'ятайте , транспортир - й $НЕ JQuery і :visibleНЕ ще частина доступних CSS селекторів + псевдо-селектори

Детальніше на https://stackoverflow.com/a/13388700/511069


1
Aw man. Так кльово. Це саме те, що мені потрібно було визначити. Дуже дякую чувак.
racl101

2
Відповідь нижче також використовує, isDisplayed()але просто розширює, щоб вирішити обіцянку про повноту, хоча цей крок є необов’язковим і призначений лише для включення умовних умов у ваші тести, що є поганою практикою. @asenovm Ви можете детальніше розробити свій коментар "Це явно неправильно"?
Лев Галлуччі

@LeoGallucci, isDisplayed () повертає ElementFinder, а не булева.
асеновм

1
Будь ласка, не .toBeTruthy();використовуйте .toBe(true)натомість використання . .toBeTruthy();відповідатиме таким, як [], 'false', 42. В основному все, що очікує, 0, "", null, undefined, NaN or false є truthy.
Брайан

78

Правильний спосіб перевірки видимості елемента за допомогою Protractor - викликати isDisplayedметод. Ви повинні бути обережними, хоча isDisplayedне повертає булевого рівня, а promiseнадає оцінену видимість. Я бачив безліч прикладів коду, які неправильно використовують цей метод і тому не оцінюють його фактичну видимість.

Приклад отримання видимості елемента:

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

Однак вам це не потрібно, якщо ви просто перевіряєте видимість елемента (на відміну від його отримання), оскільки транспортирові патчі Жасмін очікують (), тому він завжди чекає, коли обіцянки будуть вирішені. Див. Github.com/angular/jasminewd

Тож ви можете просто зробити:

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

Оскільки ви використовуєте AngularJSдля контролю видимості цього елемента, ви також можете перевірити його атрибут класу на ng-hideтакий:

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

8

У мене була подібна проблема, оскільки я хотів лише повернути елементи, які були видимі в об’єкті сторінки. Я виявив, що я в змозі використовувати css :not. У випадку з цим питанням це вам слід зробити ...

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

У контексті об’єкта сторінки ви можете отримати ТІЛЬКИ ті ​​елементи, які також видно таким чином. Напр. надавши сторінку з кількома елементами, де видно лише деякі, ви можете використовувати:

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

Це поверне вам усі видимі i.icons


1
isDisplayed () має бути в межах очікування, як @leoGallucci пояснив це.
Смугастий

5

Якщо в DOM є кілька елементів з однаковою назвою класу. Але видно лише один елемент.

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

У цьому прикладі фільтр приймає набір елементів і повертає один видимий елемент за допомогою isDisplayed () .


Це чудова відповідь; розглянемо випадок, коли такого елемента немає! $ ('. text-input-input') елегантно попередить користувача; це може не вдатися через те filteredElement.length === 0?
Червоний горох

1

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

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

1

Дочекатися видимості

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"]))

1
 element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
if (isVisible) {
    // element is visible
} else {
    // element is not visible
}
}).catch(function(err){
console.log("Element is not found");
})

0

Ось кілька фрагментів коду, які можна використовувати для фреймворку, в якому використовуються Typescript, транспортир, жасмин

browser.wait(until.visibilityOf(OversightAutomationOR.lblContentModal), 3000, "Modal text is present");

// Ствердження тексту

OversightAutomationOR.lblContentModal.getText().then(text => {
                    this.assertEquals(text.toString().trim(), AdminPanelData.lblContentModal);
                });

// Затвердження елемента

expect(OnboardingFormsOR.masterFormActionCloneBtn.isDisplayed()).to.eventually.equal(true

    );

OnboardingFormsOR.customFormActionViewBtn.isDisplayed().then((isDisplayed) => {
                        expect(isDisplayed).to.equal(true);
                });

// Затвердження форми

formInfoSection.getText().then((text) => {
                        const vendorInformationCount = text[0].split("\n");
                        let found = false;
                        for (let i = 0; i < vendorInformationCount.length; i++) {
                            if (vendorInformationCount[i] === customLabel) {
                                found = true;
                            };
                        };
                        expect(found).to.equal(true);
                    });     
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.