web-dev-qa-db-ja.com

分度器で要素の属性値を取得する

Element属性が空でない値になるのを待たなければならないProtractorテストを書いていて、その値を呼び出し元の関数に返したいのですが。これは予想以上に書くのが難しいことが証明されています!

browser.wait()コマンドを正しくスケジュールして、要素の属性が空ではない値になるのを待つことができます。この値が実際にコールバック関数内にあると期待している値であることを確認しましたが、何らかの理由で、その値をコールバック関数の外で、残りのテストコードに返すことができません。

これが私のコードがどのように見えるかです:

_function test() {
    var item = getItem();
    console.log(item);
}

function getItem() {
    var item;
    browser.wait(function() {
        return element(by.id('element-id')).getAttribute('attribute-name').then(function(value) {
            item = value;
            // console.log(item);
            return value !== '';
        });
    });
    return item;
}
_

コールバック関数内のconsole.log()呼び出しのコメントを外すと、期待される値が出力されるので、実行順序が期待どおりではないことがわかります。ただし、test()関数での同じ呼び出しは「未定義」を出力します。

ここで何が起こっているのですか?何が欠けていますか?コールバック関数から属性値を適切に取得するにはどうすればよいですか?

私はあなたの助けに感謝します。

8
exbuddha

私は待機と取得属性の部分を組み合わせません-論理的にはこれらは2つの別々のものですそれらを別々にしてください

browser.wait(function() {
    return element(by.id('element-id')).getAttribute("attribute").then(function(value) {
        item = value;
        // console.log(item);
        return value !== '';
    });
});

element(by.id('element-id')).getAttribute("attribute").then(function (value) {
    console.log(value);
});

この方法で待機条件を簡略化できることに注意してください。

var EC = protractor.ExpectedConditions;
var Elm = $('#element-id[attribute="expected value"]');

browser.wait(EC.presenceOf(Elm), 5000);
Elm.getAttribute("attribute").then(function (value) {
    console.log(value);
});

参考までに、現在の問題を deferred で解決した可能性があります。

function test() {
    getItem().then(function (value) {
        console.log(value);
    });
}

function getItem() {
    var item = protractor.promise.defer();
    browser.wait(function() {
        return element(by.id('element-id')).getAttribute('attribute').then(function(value) {
            var result = value !== '';
            if (result) {
                item.fulfill(value);
            }
            return result;
        });
    });
    return item.promise;
}
12
alecxe

分度器がプロミスでどのように機能し、制御フローでスケジュール/登録するかについてさらに読んだ後、提供された最初のソリューション@alecxeに近い簡単な回避策を見つけました。ここに行く:

_function test() {
  var item = getItem().then(function(item) {
    console.log(item);
  });
}

function getItem() {
  return browser.wait(function() {
    return element(by.id('element-id')).getAttribute('attribute-name').then(function(value) {
      return value;
    });
  });
}
_

browser.wait()はpromise自体を返すため、呼び出し元内で別のthen()とチェーンすることができます。これにより、正しい実行順序が保証されます。

1
exbuddha