¿Cómo utilizar el transportador para comprobar si un elemento es visible?


Estoy tratando de probar si un elemento es visible usando protractor. Así es como se ve el elemento:

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

Cuando estoy en la consola de chrome, puedo usar este selector de jQuery para probar si el elemento es visible:

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

Sin embargo, cuando intento hacer lo mismo en protractor, obtengo este error en tiempo de ejecución:

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

¿Por qué esto no es válido? ¿Cómo puedo comprobar la visibilidad usando el transportador?

Author: limp_chimp, 2014-04-04

6 answers

Esto debería hacerlo:

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

Recuerde que el transportador $ no es jQuery y :visible no es todavía una parte de selectores CSS + pseudo-selectores disponibles

Más información en https://stackoverflow.com/a/13388700/511069

 131
Author: Leo Gallucci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:23

La forma correcta de comprobar la visibilidad de un elemento con Transportador es llamar al isDisplayed método. Sin embargo, debe tener cuidado ya que isDisplayed no devuelve un booleano, sino más bien un promise proporcionar la visibilidad evaluada. He visto muchos ejemplos de código que usan este método incorrectamente y, por lo tanto, no evalúan su visibilidad real.

Ejemplo para obtener la visibilidad de un elemento:

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

Sin embargo, no necesita esto si solo están comprobando la visibilidad del elemento (en lugar de obtenerlo) porque el transportador remienda a Jasmine expect() para que siempre espere a que se resuelvan las promesas. Véase github.com/angular/jasminewd

Así que solo puedes hacer:

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

Dado que estás usando AngularJS para controlar la visibilidad de ese elemento, también puedes verificar su atributo de clase para ng-hide de la siguiente manera:

var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible
 72
Author: Mobiletainment,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-22 10:34:15

Tuve un problema similar, ya que solo quería devolver elementos que fueran visibles en un objeto de página. Descubrí que soy capaz de usar el css :not. En el caso de este problema, esto debería hacer usted...

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

En el contexto de un objeto de página, también puede obtener SOLO aquellos elementos que son visibles de esta manera. Eg. dada una página con varios elementos, donde solo algunos son visibles, puede usar:

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

Esto te devolverá todo visible i.icon s

 6
Author: Brine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-12 14:12:45

Si hay varios elementos en DOM con el mismo nombre de clase. Pero solo uno de los elementos es visible.

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

En este ejemplo, el filtro toma una colección de elementos y devuelve un solo elemento visible usando isDisplayed().

 5
Author: A Qadeer Qureshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-24 12:39:00

Esta respuesta será lo suficientemente robusta como para funcionar con elementos que no están en la página, por lo tanto fallando correctamente (no lanzando una excepción) si el selector no pudo encontrar el 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
Author: activedecay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-17 00:12:42

Esperar la visibilidad

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

Truco Xpath para encontrar solo elementos visibles

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))
 1
Author: Drew Royster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-01 21:08:41