2014-04-03 17 views
93

Sto provando a verificare se un elemento è visibile utilizzando il rapportatore. Ecco cosa l'elemento appare come:Come utilizzare il rapportatore per verificare se un elemento è visibile?

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

Quando nella console cromata, posso usare 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 in 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à usando il goniometro?

+0

Hey @limp_chimp ha fatto la mia risposta qui sotto ha aiutato? –

+0

@limp_chimp per la visibilità, pensa a utilizzare i test delle unità DOM del client AngularJS. Sono molto più veloci da eseguire e più facili da sviluppare. – Offirmo

risposta

124

Questo dovrebbe farlo:

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

Ricordati di goniometro $ non è jQuery e :visible non è ancora una parte di available CSS selectors + pseudo-selectors

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

+1

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

+1

Questo è assolutamente sbagliato. Guarda la risposta qui sotto! – asenovm

+2

La risposta sotto utilizza anche 'isDisplayed()', ma si espande per risolvere la promessa di completezza sebbene quel passaggio sia facoltativo e intenda solo includere i condizionali nei test che è una cattiva pratica. @asenovm puoi approfondire ulteriormente il tuo commento "Questo è semplicemente sbagliato"? –

68

Il modo corretto per verificare la visibilità di un elemento con Goniometro è chiamare il metodo isDisplayed. Si dovrebbe fare attenzione però dal momento che isDisplayed non restituisce un valore booleano, ma piuttosto uno promise che fornisce 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 è necessario questo se si sta solo controllando la visibilità dell'elemento (al contrario di ottenerlo) perché le patch goniometro Jasmine si aspettano() quindi aspetta sempre che le promesse vengano risolte. Vede github.com/angular/jasminewd

Così si può solo fare:

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

Dal momento che si sta utilizzando AngularJS per controllare la visibilità di tale elemento, si potrebbe anche verificare il suo attributo di classe per ng-hide come questo:

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

Ho avuto un problema simile, nel senso che volevo solo gli elementi di ritorno che erano visibili in un oggetto di pagina. Ho scoperto che sono in grado di utilizzare il css :not. Nel caso di questo problema, questo dovrebbe fare voi ...

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

Nel contesto di un oggetto pagina, è possibile ottenere solo gli elementi che sono visibili in questo modo pure. Per esempio. data una pagina con più elementi, in cui solo alcuni sono visibili, è possibile utilizzare:

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

Questo vi restituiamo tutti visibile i.icon s

+1

isDisplayed() dovrebbe essere nello scope expect come @leoGallucci lo ha spiegato. – Striped

3

Se ci sono più elementi in DOM con lo stesso nome della 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 filtro esempio prende un insieme di elementi e restituisce un unico elemento visibile utilizzando isDisplayed().

+0

Questa è una grande risposta; considera il caso in cui non esiste un tale elemento! $ ('. text-input-input') avverte l'utente con eleganza; questo potrebbe fallire perché 'filteredElement.length === 0'? –

1

Questa risposta sarà abbastanza robusta da funzionare per elementi che non si trovano nella pagina, quindi non correttamente (senza generare eccezioni) 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() 
    }) 
}) 
0

di aspettare per la visibilità

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

Xpath trucco per trovare solo gli elementi visibili

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