¿Cómo puedo esperar una afección?


Soy nuevo en protractor, y estoy tratando de implementar una prueba e2e. No se si esta es la manera correcta de hacer esto, pero... La página que quiero probar no es una página angular completa basada, por lo tanto... Estoy teniendo problemas.

En mi primera especificación tengo:

describe('should open contact page', function() {
var ptor = protractor.getInstance();

beforeEach(function(){

   var Login = require('./util/Login');
   new Login(ptor);
});

He creado esta clase de inicio de sesión, pero después de iniciar sesión quiero abrir la página de contacto, pero protractor inmediatamente intenta encontrar el elemento antes de que la página esté completamente cargada.

He tratado de usar:

browser.driver.wait(function() {

    expect(browser.findElement(by.xpath("//a[@href='#/contacts']")).isDisplayed());
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();

});

Pero no funciona... siempre trata de encontrar el elemento antes de que se cargue la página. Probé este también:

browser.driver.wait(function() {
    expect(ptor.isElementPresent(by.xpath("//a[@href='#/contacts']")));          
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});

Puedo hacer eso usando browser.sleep(); pero no creo que sea una buena opción. Alguna idea? En mi clase de inicio de sesión tengo:

ptor.ignoreSynchronization = true;

¿Cómo puedo esperar esto @href='#/contacts antes de que el transportador intente hacer clic en él?

Author: Mohsin Awan, 2014-02-27

7 answers

Tuve el mismo problema que tenías durante más tiempo mientras usabas protractor. En mi prueba e2e empiezo en una aplicación no angular, luego entro en una porción angular, luego vuelvo a una porción no angular. Hizo las cosas difíciles. La clave es entender las promesas y cómo funcionan. Aquí hay algunos ejemplos de mi código del mundo real en una prueba e2e en funcionamiento. Esperar que esto le dé una idea de cómo estructurar sus pruebas. Probablemente alguna mala práctica en este código, por favor siéntase libre de mejorar esto, pero sé que funciona, tal vez no de la mejor manera.

Para llegar a angular utilizo

var ptor;
var events = require('events');
var eventEmitter = new events.EventEmitter();
var secondClick = require('./second-click');

beforeEach(function () {
    browser.driver.get('http://localhost:8080/');
},10000);

it("should start the test", function () {
    describe("starting", function () {
        it("should find the  link and start the test", function(){
            var elementToFind = by.linkText('Start'); //what element we are looking for
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                expect(isPresent).toBe(true); //the test, kind of redundant but it helps pass or fail
                browser.driver.findElement(elementToFind).then(function(start){
                    start.click().then(function(){ //once we've found the element and its on the page click it!! :) 
                        ptor = protractor.getInstance(); //pass down protractor and the events to other files so we can emit events
                        secondClick(eventEmitter, ptor); //this is your callback to keep going on to other actions or test in another file
                    });
                });
            });
        });
    });
},60000);

Mientras que en angular este código funciona

 describe("type in a message ", function(){
        it("should find and type in a random message", function(){
            var elementToFind = by.css('form textarea.limited');
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                element(elementToFind).sendKeys(randomSentence).then(function(){
                    console.log("typed in random message");
                    continueOn();
                });
            });
        });
    },15000);

Después de salir angular

browser.driver.wait(function(){
   console.log("polling for a firstName to appear");
   return    browser.driver.isElementPresent(by.name('firstName')).then(function(el){
         return el === true;
       });
     }).
   then(function(){
       somefunctionToExecute()
    });

¡Espero que eso te guíe y te ayude!

 23
Author: asherrard,
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-02-27 23:19:55

Transportador 1.7.0 también ha introducido una nueva característica: Condiciones Esperadas.

Hay varias condiciones predefinidas que esperar explícitamente. En caso de que desee esperar a que un elemento esté presente:

var EC = protractor.ExpectedConditions;

var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);

expect(e.isPresent()).toBeTruthy();

Véase también:

 51
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
2017-05-23 12:02:23

Finalmente lo averiguo...

   var waitLoading = by.css('#loading.loader-state-hidden');

   browser.wait(function() {
       return ptor.isElementPresent(waitLoading);
   }, 8000);

   expect(ptor.isElementPresent(waitLoading)).toBeTruthy();

   var openContact = by.xpath("//a[@href='#/contacts']");
   element(openContact).click();

Con este transportador podría esperar ese elemento hasta que desaparezca la página de carga. Gracias por aquellos que trataron de ayudar a XD.

 33
Author: Muratso,
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-02-28 19:10:53
browser.driver.wait(function() {
    return browser.driver.isElementPresent(by.xpath("//a[@href='#/contacts']"));
});

Esto también funciona para mí (sin el parámetro de tiempo de espera)..

Para más información, ver http://angular.github.io/protractor/#/api?view=webdriver.WebDriver.prototype.wait

 9
Author: Henry Neo,
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-26 04:46:59

Gracias a las respuestas anteriores, este fue mi uso simplificado y actualizado

function waitFor (selector) {
  return browser.wait(function () {
    return browser.isElementPresent(by.css(selector));
  }, 50000);
}
 1
Author: Kirk Strobeck,
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-01-18 14:28:27

¿Ha intentado poner el ng-app en la etiqueta <html> (asumiendo que esta parte del código está bajo su control)? Esto resolvió muchos problemas de sincronización de inicialización para mí.

 0
Author: Konstantin A. Magg,
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-25 08:03:41

La mejor manera de usar las condiciones de espera en el transportador que ayuda a mostrar el mensaje de error adecuado a un elemento en particular si el caso de prueba falló

const EC = ExpectedConditions;
const ele = element(by.xpath(your xpath));

return browser.wait(EC.visibilityOf(ele),9000,'element not found').then(() => {
            ele.click();
         });
 0
Author: rohit saini,
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-10-03 08:07:07