web-dev-qa-db-fra.com

créer et résoudre des promesses dans le rapporteur

J'écris un scénario de test pour ajouter des informations sur les magasins dans la page de l'application Angular à l'aide de Protractor. Initialement, je compte le nombre de magasins que j'ai déjà et, une fois le bloc de test terminé, je m'attends à ce que le nombre augmente d'un jour. Je fais cela en suivant ce lien de création de promesses Comment créer et manipuler des promesses dans Protractor?

describe('myApp', function() {
  var items,startCount;

  var testPromise = function(){
    items = element.all(by.repeater('store in storelist'));
    var deferred = protractor.promise.defer();
    items.count().then(function(orgCount){
       startCount = orgCount;
       console.log('Start Count: '+ startCount); //prints correct value e.g, 6
    }, function(error){
       console.log(error);
    });
    return deferred.promise;
  };

it('should accept valid data for adding new store', function() {
   var cNum = null;
   testPromise().then(function(result){
      cNum = result;
      console.log('cNUm value: '+ cNum); //this value doesn't get printed in console
   });
   /* Code for adding test fields in store page */

   expect(items.count()).toBe(cNum+1);
 });
});

Je pense que le nombre de magasins sera le même à la fin du test. count () résout une promesse et la valeur correcte de store count est imprimée dans testPromise (), mais dans ce bloc, lorsque j'appelle testPromise (), alors la méthode n'est jamais insérée dans le bloc 'then'

et le résultat final dit 

Message:
 Expected 6 to be 1.
 Stacktrace:
  Error: Failed expectation

J'ai également cherché un peu plus dans webdriver.promise.Promise () à partir de ce lien http://Selenium.googlecode.com/git/docs/api/javascript/class_webdriver_promise_Promise.html et j'ai essayé de l'utiliser pour créer une promesse et résolvant sa valeur mais ne sachant pas quel est le problème. Je reçois un message d'erreur disant «6 attendus comme NaN» ou «6 attendus comme 1» «Ne suis-je pas en train de résoudre une promesse ou si j'écris« alors »ne pas bloquer correctement? Apprécierait quelques idées/aide sur cette question.

22
DesaiM

Voici un exemple fonctionnel d'une fonction définie par l'utilisateur à utiliser dans Protractor qui crée et remplit (ou rejette) une promesse:

// Get the text of an element and convert to an integer.
// Returns a promise.
function getTextAsInteger(element, radix) {
  // Specify a default radix for the call to parseInt.
  radix = radix || 10;
  // Create a promise to be fulfilled or rejected later.
  var deferred = protractor.promise.defer();
  // Get the text from the element. The call to getText
  // returns a promise.
  element.getText().then(
    function success(text) {
      var num = parseInt(text, radix);
      if (!isNaN(num)) {
        // Successfully converted text to integer.
        deferred.fulfill(num);
      } else {
        // Error converting text to integer.
        deferred.reject('could not parse "$1" into an integer'
          .replace('$1', text));
      }
    },
    function error(reason) {
      // Reject our promise and pass the reason from the getText rejection.
      deferred.reject(reason);
    });

  // Return the promise. This will be resolved or rejected
  // when the above call to getText is resolved.
  return deferred.promise;
}

La fonction prend element en argument et appelle sa méthode getText() qui renvoie elle-même une promesse. En cas d'appel réussi à getText(), analysez le texte comme un entier et remplissez la promesse. Si getText() rejette, nous transmettons la raison à notre propre appel de rejet.

Pour utiliser cette fonction, passez une promesse d'élément:

var numField = element(by.id('num-field'));
getTextAsInteger(numField).then(
    function success(num) {
        console.log(num);
    }, 
    function error(reason) {
        console.error(reason);
    });

ou:

var numField = element(by.id('num-field'));
expect(getTextAsInteger(numField)).toEqual(jasmine.any(Number));
expect(getTextAsInteger(numField)).toBeGreaterThan(0);
11
t.888

Création

Pour créer une promesse dans un rapporteur, vous devez écrire:

var deferred = protractor.promise.defer();
var promise = deferred.promise;

Rappels

Les callbacks sont appelés de manière asynchrone . Vous pouvez enregistrer un (ou plusieurs) callback "en cas de succès":

promise.then(function() {
   ...
});

vous pouvez également enregistrer un (ou plusieurs) rappel (s) "en cas d'erreur":

promise.then(null, function() {
   ...
});

Ces inscriptions pourraient être chaînées:

promise.then(function() {
   ...
}).then(function() {
   ...
}).then(null, function() {
   ...
}).then(function() {

}, function() {
   ...
}).then(onSuccess, onFailure);

Résolution

Succès

Les rappels "en cas de succès" sont appelés lorsque la promesse est résolue avec succès:

deferred.fulfill(value);

Failure

Les rappels "en cas d'échec" sont appelés lorsque la promesse est résolue avec succès:

deferred.reject(new Error('a problem occurs'));

Dans votre code

vous avez raté l'étape de résolution. Vous devez remplir la promesse.

Une référence plus complète est disponible dans documentation Webdriver.js

47
gontard

J'ai eu le même problème et l'ai résolu en créant une promesse pour le nombre d'éléments attendu:

it('should accept valid data for adding new store', function() {
    // Given
    let expectedCountAfterNewRow = items.count().then((cnt)=>{return cnt+1}); 
    // Note: items.count() is a promise so the expected count should a promise too

    // When
    /* Code for adding test fields in store page */

    // Then
   expect(items.count()).toEqual(expectedCountAfterNewRow);
});
0
Julien Kronegg