2014-07-25 14 views
15

I test E2E del goniometro sono incoerenti e non funzionano correttamente.Test goniometro incoerente con passaggio/guasto per l'app AngularJS

Sembra che questo potrebbe essere dovuto a JavaScript asincrono, come discusso qui: Protractor : How to wait for page complete after click a button?.

Tuttavia, qui è detto che goniometro Predisporre automaticamente in sequenza/sincrono: https://github.com/angular/protractor/issues/909

mio script di test:

describe('Login', function() { 

    var ptor; 

    beforeEach(function() { 
    browser.get('https://127.0.0.1:8443'); 
    ptor = protractor.getInstance(); 
    element(by.id('splash')).click(); 
    browser.ignoreSynchronization = true; // <-- to proceed beyond splash screen 
    }); 

    describe('with correct email and password', function() { 

    beforeEach(function() { 
     element(by.id('email')).sendKeys('[email protected]'); 
     element(by.id('password')).sendKeys('adminpassword'); 
     element(by.id('loginButton')).click(); 
    }); 

    afterEach(function() { 
     ptor.findElement(by.id('logout')).then(function(elem) { 
      elem.click(); 
     }); 
    }); 

    it('does not show alert', function() { // <-- sometimes passes, sometimes fails 
     expect(browser.isElementPresent(by.css('.alert-danger'))).toBe(false); 
    }); 

    it('changes route to /admin', function() { // <-- sometimes passes, sometimes fails 
     expect(browser.getCurrentUrl()).toMatch(/\/admin/); 
    }); 
    }); 
}); 

Nelle due prove di cui sopra, sia entrambi i test passeranno o uno/entrambi i test non riuscirà con questi messaggi:

Failures: 

1) Login with correct email and password does not show alert 
Message: 
    NoSuchElementError: no such element 
... 
==== async task ==== 
WebDriver.findElement(By.id("logout")) 
... 

o

Failures: 

1) Login with correct email and password changes route to /admin 
Message: 
    NoSuchElementError: no such element 
... 
==== async task ==== 
WebDriver.findElement(By.id("logout")) 
... 

Pensieri/aiuto molto apprezzato.

+2

Stai testando un'app angularjs o un'app non-angularjs? perché aggiungi questo codice "browser.ignoreSynchronization = true"? –

+0

È un'app Angular. So che ptor.ignoreSynchronization = true non dovrebbe essere richiesto, ma per qualche motivo, i test non procedono al clic del pulsante senza questa impostazione. Vedi il commento di Harri Siirak qui: http://stackoverflow.com/questions/19741896/protractor-times-out-waiting-for-sync-with-page-when-using-resource – ozandlb

risposta

15

ero in grado di risolvere il problema sulla base della seguente:

Come menzionato da Nguyen Vu Hoang 's commento alla domanda iniziale, sto testando un'applicazione angolare puro con quello che penso è goniometro puro (nessuna chiamata WebDriver). So che in questo caso ptor.ignoreSynchronization = true non dovrebbe essere richiesto, ma per qualche motivo, i test non procedono al clic del pulsante senza questa impostazione.

La mia nuova specifica:

describe('Login', function() { 

    var ptor; 

    beforeEach(function() { 
    ptor = protractor.getInstance(); 
    ptor.ignoreSynchronization = true; 
    ptor.waitForAngular(); 
    ptor.get('https://127.0.0.1:8443'); 
    ptor.findElement(by.id('splash')).then(function(elem) { 
     elem.click(); 
    }); 
    }); 

    describe('with correct email and password', function() { 

    beforeEach(function() { 
     ptor.findElement(by.id('email')).then(function(elem) { 
      elem.sendKeys('[email protected]'); 
     }); 

     ptor.findElement(by.id('password')).then(function(elem) { 
      elem.sendKeys('adminpassword'); 
     }); 

     ptor.findElement(by.id('loginButton')).then(function(elem) { 
      elem.click(); 
     }); 
    }); 

    afterEach(function() { 
     ptor.findElement(by.id('logout')).then(function(elem) { 
      elem.click(); 
     }); 
    }); 

    it('does not show alert', function() { 
     expect(ptor.isElementPresent(by.css('.alert-danger'))).toBe(false); 
    }); 

    it('changes route to /admin', function() { 
     expect(ptor.getCurrentUrl()).toMatch(/\/admin/); 
    }); 
    }); 
}); 
+0

Questa è una bella risposta, adatta solo al tuo caso ma interessante;) Grazie per la condivisione. – glepretre

+0

sfortunatamente non posso fare +1 più volte, mi piace molto la tua risposta! –

+0

Grazie per la condivisione ha aiutato molto. –

4

browser.ignoreSynchronization = true; ha un effetto globale per tutti i tuoi test. potrebbe essere necessario reimpostarlo su falso, quindi il goniometro attende che l'angolare termini la pagina. per esempio. o prima della seconda funzione beforeeach

8

C'è anche un un'altra tecnica per rendere i test più stabile: Explicit Waits and Expected Conditions (docs).

Ho trovato che utilizzare le condizioni previste è particolarmente utile quando si esegue il test su pagine non angolari o applicazioni angolari con un numero elevato di animazioni coinvolte.

Ad esempio, è possibile attendere per un elemento di essere cliccabile prima di effettuare un clic:

var EC = protractor.ExpectedConditions; 
var link = element(by.id("mylink")); 

browser.wait(EC.elementToBeClickable(link), "10000", "The link is still not clickable"); 
link.click(); 

ci sono anche altri built-in condizioni previste, come ad esempio:

  • presenseOf()
  • visibilityOf()
  • alertIsPresent()
  • textToBePresentInElementValue()
  • ecc

E, è facile scrivere una Condizione personalizzato Previsto, ad esempio dei casi d'uso:

È possibile anche combine Expected Conditions usando and, or e not, ad esempio:

var urlChanged = function() { 
    return browser.getCurrentUrl().then(function(url) { 
    return url != 'http://www.angularjs.org'; 
    }); 
}; 

// condition to wait for url to change, title to contain 'foo', and $('abc') element to contain text 'bar' 
var condition = EC.and(urlChanged, EC.titleContains('foo'), EC.textToBePresentInElement($('abc'), 'bar')); 
$('navButton').click(); 
browser.wait(condition, 5000); //wait for condition to be true. 
Problemi correlati