2016-01-23 13 views
5

Ich schreibe einen Winkelmesser Test, der warten muss, bis ein Element-Attribut einen nicht leeren Wert hat, und dann möchte ich diesen Wert an die aufrufende Funktion zurückgeben. Das hat sich als schwieriger als erwartet herausgestellt!Get Element Attribut Wert in Winkelmesser

Ich bin in der Lage, einen browser.wait() Befehl zu warten, bis das Element Attribut einen nicht leeren Wert haben, und ich habe überprüft, dass dieser Wert tatsächlich ist, was ich erwartet, in die Callback-Funktion zu bekommen, aber für einige Grund, ich kann diesen Wert nicht außerhalb der Callback-Funktion und auf den Rest des Testcodes zurückgeben.

Hier ist, wie mein Code wie folgt aussieht:

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

ich, dass die Reihenfolge der Ausführung sagen kann, ist nicht, wie ich es erwarten, denn wenn ich Kommentar- den console.log() Anruf innerhalb der Callback-Funktion, ich sehe der erwartete Wert wird ausgedruckt. Derselbe Aufruf in der test()-Funktion druckt jedoch "undefined".

Was geht hier vor? Was vermisse ich? Wie kann ich den Attributwert richtig aus der Callback-Funktion abrufen?

Ich schätze Ihre Hilfe.

Antwort

9

Ich würde nicht die Warte kombinieren und die immer Attribut Teile - logisch das sind zwei verschiedene Dinge, halten sie trennen:

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

Beachten Sie, dass Sie den Wartezustand auf diese Weise vereinfachen kann:

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

Gerade FYI, können Sie Ihr aktuelles Problem mit dem deferred gelöst haben:

+1

Danke! Mit einigen kleineren Korrekturen funktioniert der letzte Ansatz in meinem Fall. Ich hatte gehofft, den Wert des Artikels direkt an die Caller-Funktion zurückgeben zu können, aber anscheinend ist das nicht die richtige Art zu denken, wenn es um Versprechen in asynchronen Aufrufen geht. Die letzte Zeile sollte 'return item.promise;' lauten. – exbuddha

1

Nachdem ich etwas mehr darüber gelesen habe, wie Winkelmesser mit Versprechungen arbeitet und sie mit dem Kontrollfluss plant oder registriert, fand ich einen leichteren Workaround nahe bei der ersten bereitgestellten Lösung @alecxe. Hier geht es:

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

Seit browser.wait() kehrt ein Versprechen selbst, kann es mit einem anderen then() innerhalb des Anrufers und auf diese Weise die richtige Reihenfolge der Ausführung garantiert verkettet werden.