Cómo crear una condición en transportador para cuando un elemento existe o no


Estoy usando Transportador JS. Y el sitio está escrito en Angular JS.

Así que tengo un interruptor de palanca. Y me di cuenta de que el valor en el interruptor de palanca va de verdadero a falso y de falso a verdadero cuando se apaga o se enciende.

Estoy tratando de crear una condición cuando el Transportador visita mi página cuando ve el interruptor de palanca 'apagado' lo encenderá. Si el interruptor de palanca ya está 'encendido', primero lo apagará y luego lo volverá a encender.

Se me ocurrió este código, pero para alguna razón por la que no está funcionando:

 if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
            element(By.id('toggle-switch')).click();
            console.log('in the if')
       }

       else{
           element(By.id('toggle-switch')).click();
           browser.sleep(3000);
           element(By.id('toggle-switch')).click();
           console.log('in the else')
       }

Este código parece funcionar solo para la instrucción if. Por alguna razón nunca irá al otro. Aquí está el error que estoy recibiendo:

NoSuchElementError: No se ha encontrado ningún elemento usando locator: By.cssSelector ("[value=\ " false\"]")

Entonces intenté

.isPresent() en lugar de .isDisplayed() Ya no recibo el error anterior, pero por alguna razón cuando lo uso .isPresent () siempre va a la sentencia if y solo se ejecuta eso, y nunca la otra declaración. No se muestran errores.

Si hay una mejor manera, por favor hágamelo saber. Esto parece muy limitante para no poder crear las condiciones adecuadas en este marco.

Author: adbarads, 2015-01-14

4 answers

Recuerda que isDisplayed() devuelve una promesa, puedes probar con:

element(anyFinder).isDisplayed().then(function(result) {
    if ( result ) {
        //Whatever if it is true (displayed)
    } else {
        //Whatever if it is false (not displayed)
    }
});
 30
Author: Lautaro Cozzani,
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-06-04 17:14:32

isDisplayed() no funcionó para mí. La API puede haber sido cambiada. isPresent() es mi solución:

    var logoutButton =  element(by.css('[ng-click="log_out()"]'));
    logoutButton.isPresent().then(function(result) {
    if ( result ) {
        logoutButton.click();
    } else {
        //do nothing
    }
    });
 16
Author: Ebru Yener,
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-06-13 10:38:25

El problema es que isDisplayed(), como muchos métodos en WebdriverJS/Protractor, devuelve una promesa que por definición es "veraz" lo que hace difícil depurar problemas como este.

Trabajemos a través de un ejemplo para obtener una mejor comprensión.

Imagina, tienes el siguiente código, que puede verse bien a primera vista:{[19]]}

var elm = $("#myid");
if (elm.isDisplayed()) {
    // do smth
} else {
    // do smth else
}

Ahora, tiene un problema serio. do smth else parte nunca se alcanzará , ya que elm.isDisplayed() no es un valor booleano, es una promesa. Incluso si el elemento no se muestra, todavía tendría // do smth parte ejecutada.

En su lugar, si necesita verificar el valor de isDisplayed() para usar dentro de una expresión condicional, debe resolver la promesa con then() explícitamente :

var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
  if (isDisplayed) {
      // do smth
  } else {
      // do smth else
  }
});

También Hay una forma de detectar este tipo de errores sin siquiera ejecutar el código - estáticamente con ESLint y eslint-plugin-protractor plugin. Hay un relevante regla que observa si ciertos métodos de transportador se utilizan dentro de las condiciones if directamente.

Esto es lo que produciría para el código anterior:

$ eslint test.js
test.js
  2:1  warning  Unexpected "isDisplayed()" inside if condition  protractor/no-promise-in-if
 5
Author: alecxe,
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-07-25 03:26:21

O pruebe esta solución implementada desde la parte superior de mi cabeza, Programa un comando para probar si un elemento está presente en la página. Si se producen errores durante la evaluación de la espera, se les permitirá propagarse.

function alwaysSwitchOn(element) {
   browser.driver.isElementPresent(element).then(function(isPresent) {
      if (isPresent) {
        isPresent = true;
      } 
      else {
        browser.driver.wait(function () {
          return browser.driver.isElementPresent(element);
        }, 5000);
      }
      // to fail the test, then uncomment this line
      //expect(isPresent).toBeTruthy();
   }).then(function () {
      if (element.getAttribute('value') === 'OFF') {
         element.click();
      }
      else {
         // turn it OFF
         element.click();
         // turn it back ON
         element.click();
      }
   });
}

El uso de Fn es seguir intentándolo una y otra vez durante 5 segundos hasta que sea true. si el elemento no se puede encontrar dentro de 5 sec entonces dará lugar a un código de error; No se encuentra ningún elemento de este tipo.Nota, si la condición se cumple antes de esperar (5s) se moverá rápidamente a then(...).

 1
Author: Simple-Solution,
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-05-12 15:13:01