Jak używać kątomierza, aby sprawdzić, czy element jest widoczny?

111

Próbuję sprawdzić, czy element jest widoczny za pomocą kątomierza. Oto jak wygląda element:

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

Będąc w konsoli chrome mogę użyć tego selektora jQuery, aby sprawdzić, czy element jest widoczny:

$('[ng-show=saving].icon-spin')
[
<i class=​"icon-spinner icon-spin ng-hide" ng-show=​"saving">​</i>​
]
> $('[ng-show=saving].icon-spin:visible')
[]

Jednak gdy próbuję zrobić to samo w kątomierzu, pojawia się ten błąd w czasie wykonywania:

InvalidElementStateError: 
invalid element state: Failed to execute 'querySelectorAll' on 'Document': 
'[ng-show=saving].icon-spin:visible' is not a valid selector.

Dlaczego to nie jest ważne? Jak mogę sprawdzić widoczność za pomocą kątomierza?

limp_chimp
źródło
Hej @limp_chimp, czy moja poniższa odpowiedź ci pomogła?
Leo Gallucci
@limp_chimp w przypadku takich rzeczy jak widoczność, pomyśl o użyciu testów jednostkowych DOM klienta AngularJS. Są znacznie szybsze w biegu i łatwiejsze w rozwoju.
Offirmo

Odpowiedzi:

144

To powinno wystarczyć:

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

Pamiętaj, że kątomierz $nie jest jQuery i :visiblenie jest jeszcze częścią dostępnych selektorów CSS + pseudoselektorów

Więcej informacji na https://stackoverflow.com/a/13388700/511069

Leo Gallucci
źródło
1
Ah człowieku. Ale fajnie. To jest dokładnie to, czego potrzebowałem, aby móc to określić. Dziękuję bardzo stary.
racl101
2
Poniższa odpowiedź również wykorzystuje, isDisplayed()ale tylko rozszerza obietnicę kompletności, chociaż ten krok jest opcjonalny i przeznaczony tylko do włączenia warunków warunkowych do twoich testów, co jest złą praktyką. @asenovm Czy możesz bardziej szczegółowo rozwinąć swój komentarz „To jest po prostu zły”?
Leo Gallucci,
@LeoGallucci, isDisplayed () zwraca ElementFinder, a nie wartość logiczną.
asenovm
1
Proszę nie .toBeTruthy();używać .toBe(true)zamiast tego. .toBeTruthy();dopasuje takie elementy jak [], 'false', 42. W zasadzie wszystko, czego oczekuje się od 0, "", null, undefined, NaN lub false jest prawdziwe.
Brian
78

Prawidłowym sposobem sprawdzenia widoczności elementu za pomocą Protractor jest wywołanie isDisplayedmetody. Należy jednak zachować ostrożność, ponieważ isDisplayednie zwraca wartości logicznej, a raczej promisezapewnia oszacowaną widoczność. Widziałem wiele przykładów kodu, które nieprawidłowo używają tej metody i dlatego nie oceniają jej rzeczywistej widoczności.

Przykład uzyskania widoczności elementu:

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

Jednak nie jest to potrzebne, jeśli po prostu sprawdzasz widoczność elementu (w przeciwieństwie do uzyskiwania go), ponieważ Jasmine patrzy na kątomierz, więc zawsze czeka na rozwiązanie obietnic. Zobacz github.com/angular/jasminewd

Możesz więc po prostu:

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

Ponieważ używasz AngularJSdo kontrolowania widoczności tego elementu, możesz również sprawdzić jego atrybut class w ng-hidenastępujący sposób:

var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible
Mobiletainment
źródło
8

Miałem podobny problem, ponieważ chciałem zwrócić tylko te elementy, które były widoczne w obiekcie strony. Okazało się, że jestem w stanie korzystać z CSS :not. W przypadku tego problemu powinno to wystarczyć ...

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

W kontekście obiektu strony możesz pobrać TYLKO te elementy, które są w ten sposób widoczne. Na przykład. mając stronę z wieloma elementami, na których widoczne są tylko niektóre, możesz użyć:

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

To zwróci ci wszystkie widoczne i.icons

Solanka
źródło
1
isDisplayed () powinno znajdować się w zakresie oczekiwania, jak wyjaśnił @leoGallucci.
Striped
5

Jeśli w DOM jest wiele elementów o tej samej nazwie klasy. Ale widoczny jest tylko jeden element.

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

W tym przykładzie filtr pobiera kolekcję elementów i zwraca pojedynczy widoczny element za pomocą metody isDisplayed () .

Qadeer Qureshi
źródło
To świetna odpowiedź; rozważ przypadek, w którym nie ma takiego elementu! $ ('. text-input-input') ostrzeże użytkownika elegancko; to może się nie powieść, ponieważ filteredElement.length === 0?
The Red Pea
1

Ta odpowiedź będzie wystarczająco solidna, aby działać dla elementów, których nie ma na stronie, a zatem zakończy się niepowodzeniem (bez zgłaszania wyjątku), jeśli selektor nie odnajdzie elementu.

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()
    })
})
activedecay
źródło
1

Czekać na widoczność

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

Xpath trik, aby znaleźć tylko widoczne elementy

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))
Drew Royster
źródło
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");
})
Anil Kumar
źródło
0

Oto kilka fragmentów kodu, których można użyć we frameworku używającym Typescript, kątomierz, jaśmin

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

// Potwierdzenie tekstu

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

// Potwierdzenie elementu

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

    );

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

// Potwierdzenie formularza

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);
                    });     
Khyati Sehgal
źródło