Je l'ai vu tellement de fois où les gens suggèrent d'utiliser:
browser.ignoreSynchronization=true; // or false
Mais je ne comprends pas pourquoi en avons-nous besoin?
La réponse simple est que cela ne fait pas attendre le rapporteur si Angular promesses, comme celles de $http
ou $timeout
à résoudre, ce que vous voudrez peut-être faire si vous testez le comportement au cours de $http
ou $timeout
(par exemple, un message de "chargement") ou le test de sites ou de pages non angulaires, tels qu'une page de connexion distincte.
Par exemple, pour tester un bouton qui définit un message de chargement lors d'une demande, vous pouvez le définir sur true
lors de la récupération d'un élément et de la vérification de son contenu.
element(by.css('button[type="submit"]')).click();
browser.ignoreSynchronization = true;
expect(element(by.css('.message')).getText().toBe('Loading...');
browser.ignoreSynchronization = false;
expect(element(by.css('.message')).getText().toBe('Loaded');
Une réponse plus compliquée est que le fait de lui attribuer la valeur true
signifie que les ajouts/injections ultérieurs dans le flux de contrôle n’ajoutent pas aussi browser.waitForAngular
. Il existe des cas où il est important de comprendre le flux de contrôle et quand/comment les éléments sont ajoutés/injectés. Par exemple, si vous utilisez browser.wait
pour tester un processus à plusieurs étapes, la fonction passée à wait
est injectée dans le flux de contrôle après les autres fonctions du test ont été ajoutées au flux de contrôle.
element(by.css('button[type="submit"]')).click();
browser.ignoreSynchronization = true;
expect(element(by.css('.message')).getText().toBe('Stage 1');
browser.wait(function () {
// This function is added to the control flow after the final
// browser.ignoreSynchronization = false in the test
// so we need to set it again here
browser.ignoreSynchronization = true;
return element(by.cssContainingText('.message', 'Stage 2')).isPresent().then(function(isPresent) {
// Cleanup so later tests have the default value of false
browser.ignoreSynchronization = false;
return !isPresent;
});
});
expect(element(by.css('.message')).getText().toBe('Stage 2');
browser.ignoreSynchronization = false;
expect(element(by.css('.message')).getText().toBe('Stage 3');
Une alternative à l'utilisation de browser.ignoreSynchronization
est d’accéder directement à l’API webdriver standard
element(by.css('button[type="submit"]')).click();
expect(browser.driver.findElement(by.css('.message')).getText().toBe('Loading...');
expect(element(by.css('.message')).getText().toBe('Loaded');
L’utilisation directe des méthodes du pilote pour rechercher les éléments signifie que le système essaiera de les trouver sans attendre aucun $http
demandes à terminer, un peu comme la configuration browser.ignoreSynchronization = true
.
Ce paramètre détermine si le rapporteur doit attendre angular sur une page ou non. Il n'est pas correctement documenté, mais voici le chaîne de documentation du code :
/**
* If true, Protractor will not attempt to synchronize with the page before
* performing actions. This can be harmful because Protractor will not wait
* until $timeouts and $http calls have been processed, which can cause
* tests to become flaky. This should be used only when necessary, such as
* when a page continuously polls an API using $timeout.
*
* @type {boolean}
*/
En d'autres termes, si vous effectuez des tests sur un site non angulaire, définissez ignoreSynchronization
setting sur true
. En tant qu'exemple concret, voyez l'un des problèmes rencontrés lors de l'ouverture d'une page non angulaire à partir d'une page angular: page non angulaire ouverte après un clic .