Je suis nouveau sur Protractor et j'essaie d'exécuter mon script.
describe('Navigator homepage', function() {
it('should proceed to login', function() {
browser.get('url');
})
it('Clicks the proceed button',function() {
const proceedButton = element(by.id('auth-login-page-button'));
proceedButton.click();
});
});
Mais chaque fois que je l'exécute, le navigateur s'ouvre et passe au site Web, puis attend 20 secondes et j'obtiens une erreur: ScriptTimeoutError: asynchronous script timeout: result was not received in 20 seconds
. L'élément est clairement là et peut être cliqué, mais pas pour le rapporteur. Est-ce que je fais quelque chose de mal? Le fichier de configuration ressemble à ceci:
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['login_spec.js'],
allScriptsTimeout: 20000,
getPageTimeout: 15000,
framework: 'jasmine',
jasmineNodeOpts: {
isVerbose: false,
showColors: true,
includeStackTrace: false,
defaultTimeoutInterval: 40000
}
};
Compte tenu de votre message d'erreur ajouté (voir commentaire), la cause semble être une interrogation continue $timeout
, Qui laisse une promesse non résolue pour une durée indéfinie et conduit donc à un délai d'attente asynchrone du rapporteur ( voir les détails ici ).
solution
La bonne solution consiste à éviter l'utilisation de $timeout
Et à utiliser à la place $interval
. De cette façon, le rapporteur peut rester en charge du ControlFlow et gérer vos tâches asynchrones. C'est donc une sorte de bug logiciel, pas une erreur de rapporteur.
votre message d'erreur:
Failed: Timed out waiting for asynchronous Angular tasks to finish after 20 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular While waiting for element with locator - Locator: By(css selector, md-raised md-primary md-button md-ink-ripple). *The following tasks were pending: - $timeout: function (){return _this.getVersion()}*
Solution
La solution de contournement pas si agréable est de désactiver la partie waitForAngular de Protractor en définissant browser.waitForAngularEnabled(false);
(soit dans un beforeEach soit directement dans la spécification.
Cependant, cela signifie également, en prenant soin manuellement du controlFlow dans les spécifications de test lui-même. Cela nécessite d'utiliser beaucoup de .then()
et ExpectedConditions
, perdant ainsi l'un des principaux avantages de Protractor.
Possibilités de débogage
Vérifiez les descriptions ici pour les causes potentielles et les solutions . Spécifiquement, essayez également browser.waitForAngularEnabled(false);
pour exclure les problèmes de rapporteur angulaire.
Si vous ne trouvez pas de cause, cela pourrait être un problème de timing (peu probable, mais mérite d'être examiné à ce stade).
Vous pouvez essayer d'ajouter des messages de journal pour affiner l'ordre effectif d'exécution:
describe('Navigator homepage', function() {
it('should proceed to login', function() {
browser.get('url').then(function(){
console.log("Page is fully loaded");
});
});
it('Clicks the proceed button',function() {
console.log("Start 2nd Test");
const proceedButton = element(by.id('auth-login-page-button'));
proceedButton.click();
});
});
Ou vous placez les actions dans le même scénario de test, en utilisant then()
pour les exécuter de manière synchrone:
describe('Navigator homepage', function() {
it('should proceed to login', function() {
browser.get('url').then(function(){
const proceedButton = element(by.id('auth-login-page-button'));
proceedButton.click();
});
});
Ouvrir la page d'accueil dans onPrepare
Comme une remarque intéressante: si vous chargez toujours la page d'accueil en premier, placez-la simplement dans une partie onPrepare de votre conf.js et elle sera toujours exécutée une fois avant le début de vos tests:
onPrepare: function () {
browser.driver.manage().window().maximize();
browser.get('url');
},
J'ai eu un problème similaire, je l'ai résolu en activant ignorer la synchronisation
browser.ignoreSynchronization = true