在量角器中创造和解决承诺

时间:2014-06-18 15:24:06

标签: angularjs selenium protractor

我正在编写一个测试用例,用于使用Protractor在Angular应用程序的页面中添加商店信息,最初我在计算我已经拥有的商店数量,在测试块完成后我希望计数增加1因为我这样做是通过创建promises How to create and manipulate promises in 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);
 });
});

我希望在测试结束时商店数量相同。 count()正在解析一个承诺,并且当我调用testPromise()时,它会在testPromise()中打印存储计数的正确值。然后它会永远进入那个'然后'块

最终结果是

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

我还在此链接http://selenium.googlecode.com/git/docs/api/javascript/class_webdriver_promise_Promise.html中对webdriver.promise.Promise()进行了更多研究,并尝试使用它来创建承诺并解析其值,但不确定问题是什么。要么我收到错误消息,说“预计6”是NaN'或者'预期6为1'我没有解决承诺或写作'然后'正确阻止?希望得到关于这个问题的一些见解/帮助。

3 个答案:

答案 0 :(得分:47)

创建

要在量角器中创建承诺,您必须写:

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

回调

以异步方式调用回调。 您可以注册一个(或多个)“成功”回调:

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

您还可以注册一个(或多个)“错误”回调:

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

这些注册可以链接:

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

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

分辨率

成功

成功解析promise后,将调用“on success”回调:

deferred.fulfill(value);

失败

成功解析promise后,将调用“on failure”回调:

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

在您的代码中

你错过了决议步骤。你必须履行承诺。

Webdriver.js documentation

中提供了更完整的参考资料

答案 1 :(得分:11)

这是在Protractor中使用的用户定义函数的工作示例,它创建并实现(或拒绝)承诺:

// 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;
}

该函数将element作为参数,并调用其自身返回promise的getText()方法。成功调用getText()后,将文本解析为整数并履行承诺。如果getText()拒绝,我们会将原因传递给我们自己的拒绝来电。

要使用此功能,请传入元素承诺:

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

或:

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

答案 2 :(得分:-1)

我遇到了同样的问题,并通过为预期的项目数量创建承诺解决了这个问题:

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);
});