Come utilizzare il goniometro per verificare se un elemento è visibile?


111

Sto cercando di verificare se un elemento è visibile utilizzando il goniometro. Ecco come appare l'elemento:

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

Quando sono nella console di Chrome, posso utilizzare questo selettore jQuery per verificare se l'elemento è visibile:

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

Tuttavia, quando provo a fare lo stesso con il goniometro, ottengo questo errore in fase di esecuzione:

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

Perché non è valido? Come posso verificare la visibilità utilizzando il goniometro?


Ehi @limp_chimp, la mia risposta qui sotto ti ha aiutato?
Leo Gallucci

@limp_chimp per cose come la visibilità, pensa di usare gli unit test DOM del client AngularJS. Sono molto più veloci da eseguire e più facili da sviluppare.
Offirmo

Risposte:


144

Questo dovrebbe farlo:

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

Ricorda che il goniometro $non è jQuery e :visiblenon fa ancora parte dei selettori CSS + pseudo-selettori disponibili

Maggiori informazioni su https://stackoverflow.com/a/13388700/511069


1
Aw amico. Così bello. Questo è esattamente ciò di cui avevo bisogno per essere in grado di determinare. Grazie mille amico.
racl101

2
Anche la risposta di seguito utilizza isDisplayed()ma si espande per risolvere la promessa di completezza sebbene quel passaggio sia facoltativo e inteso solo per includere i condizionali nei test, il che è una cattiva pratica. @asenovm puoi elaborare ulteriormente il tuo commento "Questo è semplicemente sbagliato"?
Leo Gallucci

@LeoGallucci, isDisplayed () restituisce ElementFinder e non un valore booleano.
asenovm

1
Si prega di non .toBeTruthy();utilizzare .toBe(true)invece l' uso . .toBeTruthy();corrisponderà a cose come [], 'false', 42. Fondamentalmente qualsiasi cosa si aspetta 0, "", null, undefined, NaN o false è vero.
Brian

78

Il modo corretto per controllare la visibilità di un elemento con Goniometro è chiamare il isDisplayedmetodo. Dovresti fare attenzione però poiché isDisplayednon restituisce un valore booleano, ma piuttosto promisefornisce la visibilità valutata. Ho visto molti esempi di codice che utilizzano questo metodo in modo errato e quindi non valutano la sua effettiva visibilità.

Esempio per ottenere la visibilità di un elemento:

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

Tuttavia, non ne hai bisogno se stai solo controllando la visibilità dell'elemento (invece di ottenerlo) perché le patch del goniometro Jasmine si aspettano () quindi aspetta sempre che le promesse vengano risolte. Vedi github.com/angular/jasminewd

Quindi puoi semplicemente fare:

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

Dato che stai usando AngularJSper controllare la visibilità di quell'elemento, puoi anche controllare il suo attributo di classe in ng-hidequesto modo:

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

8

Ho avuto un problema simile, in quanto volevo solo gli elementi di ritorno che erano visibili in un oggetto pagina. Ho scoperto di essere in grado di utilizzare il css :not. Nel caso di questo problema, questo dovrebbe farti ...

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

Nel contesto di un oggetto pagina, puoi ottenere SOLO quegli elementi che sono visibili anche in questo modo. Per esempio. data una pagina con più elementi, di cui solo alcuni sono visibili, puoi utilizzare:

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

Questo lo restituiamo tutti visibili i.icons


1
isDisplayed () dovrebbe rientrare nell'ambito previsto come spiegato da @leoGallucci.
Striped

5

Se sono presenti più elementi nel DOM con lo stesso nome di classe. Ma solo uno degli elementi è visibile.

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

In questo esempio, il filtro accetta una raccolta di elementi e restituisce un singolo elemento visibile utilizzando isDisplayed () .


Questa è un'ottima risposta; considera il caso in cui non esiste un tale elemento! $ ('. text-input-input') avviserebbe l'utente in modo elegante; questo potrebbe fallire perché filteredElement.length === 0?
The Red Pea

1

Questa risposta sarà abbastanza robusta da funzionare per elementi che non sono nella pagina, quindi fallendo con garbo (non generando un'eccezione) se il selettore non è riuscito a trovare l'elemento.

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

Aspettare visibilità

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

Trucco Xpath per trovare solo elementi visibili

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

Ecco i pochi frammenti di codice che possono essere utilizzati per framework che utilizzano Typescript, goniometro, gelsomino

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

// Asserire un testo

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

// Asserire un elemento

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

    );

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

// Asserire un modulo

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);
                    });     
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.