javascript - español - angularjs documentation
Las pruebas del transportador pasan o fallan de manera inconsistente para la aplicación AngularJS (3)
Mis pruebas de Protractor e2e pasan y fallan de manera inconsistente.
Parece que esto podría deberse a un javascript asíncrono, como se explica aquí: Transportador: ¿Cómo esperar una página completa después de hacer clic en un botón? .
Sin embargo, aquí se menciona que las pruebas de transportadores se ejecutan automáticamente de forma secuencial / sincrónica: https://github.com/angular/protractor/issues/909
Mi guión de prueba:
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/);
});
});
});
En las dos pruebas anteriores, ambas pruebas pasarán o una o ambas pruebas fallarán con estos mensajes:
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"))
...
Pensamientos / ayuda muy apreciados.
Pude resolver el problema en base a lo siguiente:
La respuesta de Avishay aquí acerca de agregar ptor.waitForAngular ():
No se encontró ningún elemento usando el localizador: error de by.model ()Cambiando el navegador .get a ptor .get, como en la respuesta de Harri Siirak aquí:
El transportador agota el tiempo de espera para sincronizarse con la página cuando usa $ resourceEl comentario de juliemr aquí acerca de que ignoreSynchronization es una variable de instancia, y cambiar el navegador .ignoreSynchronization = true a ptor .ignoreSynchronization = true:
https://github.com/angular/protractor/issues/49La respuesta de glepretre aquí sobre el uso de .then ():
Transportador: ¿Cómo esperar a que se complete la página después de hacer clic en un botón?
Como lo mencionó el comentario de Nguyen Vu Hoang a la pregunta original, estoy probando una aplicación Angular pura con lo que creo que es un transportador puro (no hay llamadas a un controlador web). Sé que ptor.ignoreSynchronization = true no debería ser requerido en este caso, pero por alguna razón, las pruebas no se realizan al hacer clic en el botón sin esta configuración.
Mi nueva especificación:
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/);
});
});
});
También hay otra técnica para hacer que sus pruebas sean más estables: esperas explícitas y condiciones esperadas ( docs ).
He encontrado que el uso de Condiciones esperadas es especialmente útil cuando se prueba contra páginas no angulares o aplicaciones angulares que tienen muchas animaciones involucradas.
Por ejemplo, puede esperar a que se pueda hacer clic en un elemento antes de hacer 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();
También hay otras condiciones esperadas incorporadas, tales como:
-
presenseOf()
-
visibilityOf()
-
alertIsPresent()
-
textToBePresentInElementValue()
- etc
Y, es fácil escribir una condición esperada personalizada, ejemplo de caso de uso:
También puede combinar Condiciones esperadas utilizando and
, or
not
, por ejemplo:
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.
browser.ignoreSynchronization = true; Tiene un efecto global para todas tus pruebas. es posible que tenga que volver a establecerlo en falso, por lo que el transportador espera a que se termine de representar la página. por ejemplo, en o antes de su segunda función de BeforeEach