web-dev-qa-db-fra.com

Nightwatch: Meilleur moyen que `.pause (1000)` pour éviter les tests fragiles?

.pause(1000) est-il vraiment la meilleure pratique pour attendre la soumission d'un formulaire? Je cherche un moyen de soumettre un formulaire de manière fiable sans avoir à connaître les détails de la page apparaissant à la suite de la soumission du formulaire.

L'exemple de la page d'accueil utilise .pause(1000) pour attendre les soumissions de formulaire, et ironiquement ne fonctionne plus, mais cette version avec une version modifiée du sélecteur css fait:

module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'rembrandt van rijn')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      // This selector is different from the home page's - this one
      // works...
      .assert.containsText('ol#rso div.g:first-of-type',
        'Rembrandt - Wikipedia')
  }
};

Le problème avec .pause(1000) pour s'assurer que le formulaire est soumis est de savoir comment déterminer le délai d'expiration. Cela va ralentir nos tests si le délai est trop long ou les rendre cassants si le délai est trop court. Matériel lent, autres processus sur le serveur, alignement de la lune, vous pouvez nommer que cela peut influencer les "bonnes" valeurs de timeout.

Y a-t-il une meilleure façon de dire: "Attendez que le formulaire soit soumis avant de continuer"?

Nous avons plutôt expérimenté avec .waitForElementVisible('body', VERY_LONG_TIMEOUT), et cela semble fonctionner et ne pas prendre plus de temps que nécessaire, mais je suppose que ce n'est pas fiable non plus. Que cela ne fonctionne que parce que la page "actuelle" a disparu (cette fois) et nous attendons donc que le corps de la "nouvelle" page apparaisse. Et que demain une certaine bizarrerie se produira et ce sera plus rapide que la normale et .waitForElementVisible('body') reviendra immédiatement parce que l'ancienne page est toujours là. == également fragile. Est-ce exact?

Dans l'affirmative, existe-t-il un moyen moins fragile que .pause(1000) ou .waitForElementVisible('body')? Surtout si nous ne savons pas grand-chose sur la page renvoyée après la soumission, nous ne pouvons donc pas .waitForElementVisible('.element-only-on-new-page')?

La raison pour laquelle je demande, c'est que nos tests ressemblaient plus à:

module.exports = {
  'Test1 - submit form' : function (client) {
    client
      .url('http://some/url')
      .waitForElementVisible('body', 1000)
      .assert.title('MyTitle')
      .setValue('input[name="widget"]', 'value')
      // Click to submit the form to change some internal state
      .click('button[name="postForm"]')

      // Form got submitted fine in chromium 42 every single time. chromium
      // 45 needs additionally:
      //
      // .pause(1000)
      // or
      // .waitForElementVisible('body', 1000)
  }
  'Test2 - continue using new value' : function (client) {
    client
      .url('http://some/other/url')
      .waitForElementVisible('body', 1000)
      .assert.title('MyOtherTitle')
      .setValue('input[name="widget2"]', 'value2')
      .waitForElementVisible('.bla-bla', 1000)
  }
};

Cela s'est cassé parce que le formulaire à ' http: // some/url ' n'est plus soumis en chrome 45 :-( Nous aimerions trouver une bonne solution, pas seulement celle qui semble fonctionner avec celle d'aujourd'hui conditions...

14
Peter V. Mørch

Avez-vous essayé de chaîner waitForElementNotVisible avec waitForElementVisible pour le corps html? Cela ne devrait attendre que le temps approprié à chaque étape. Je ferais quelques tests pour m'assurer qu'il n'est pas fragile cependant. Nous l'utilisons pour surveiller une "transition de page simulée" dans une application à page unique.

par exemple.

module.exports = {
  'Test1 - submit form' : function (client) {
    client
      .url('http://some/url')
      .waitForElementVisible('body', 1000)
      .assert.title('MyTitle')
      .setValue('input[name="widget"]', 'value')
      // Click to submit the form to change some internal state
      .click('button[name="postForm"]')
      .waitForElementNotVisible('body', 5000)
      .waitForElementVisible('body', 10000)
  }
};
9
Stuart Brock