web-dev-qa-db-ja.com

分度器での約束の作成と解決

AngularアプリをProtractorを使用してページにストア情報を追加するためのテストケースを書いています。最初は、既に所有しているストアの数をカウントし、そのために、Promiseを作成するこのリンクをたどってこれを行っています ProtractorでPromiseを作成および操作する方法

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()はpromiseを解決しており、ストアカウントの正しい値はtestPromise()に出力されますが、testPromise()を呼び出すとブロックになります。

そして最終結果は言う

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

また、このリンクからwebdriver.promise.Promise()でもう少し研究しました http://Selenium.googlecode.com/git/docs/api/javascript/class_webdriver_promise_Promise.html 約束を作成し、その価値を解決しますが、問題が何であるかはわかりません。 「6がNaNになる」または「6が1になる」というエラーメッセージが表示される約束を解決していないか、「then」ブロックを正しく記述していないのですか?この問題に関するいくつかの洞察/ヘルプをいただければ幸いです。

22
DesaiM

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を引数として取り、getText()メソッドを呼び出します。このメソッド自体がプロミスを返します。 getText()の呼び出しに成功すると、テキストを整数として解析し、約束を果たします。 getText()が拒否した場合、その理由を拒否呼び出しに渡します。

この関数を使用するには、要素promiseを渡します。

_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);
_
11
t.888

作成

分度器で約束を作成するには、次のように書く必要があります。

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

コールバック

コールバックは非同期に呼び出されます。 1つ(または複数)の「成功時」コールバックを登録できます。

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

1つ(または複数)の「エラー時」コールバックを登録することもできます。

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

これらの登録は連鎖させることができます。

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

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

解決

成功

「成功時」コールバックは、プロミスが正常に解決されると呼び出されます。

deferred.fulfill(value);

Failure

「失敗時」コールバックは、promiseが正常に解決されると呼び出されます。

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

あなたのコードで

解決手順を逃しました。あなたは約束を果たさなければなりません。

より完全なリファレンスは Webdriver.jsドキュメント で利用可能です

48
gontard

私は同じ問題を抱え、予想されるアイテム数の約束を作成することで解決しました。

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