2016-01-23 14 views
5

Sto scrivendo un test del goniometro che deve attendere che un attributo elemento abbia un valore non vuoto e quindi voglio restituire quel valore alla funzione chiamante. Questo ha dimostrato di essere più difficile da scrivere di quanto mi aspettassi!ottiene il valore di attributo elemento in Goniometro

Sono in grado di pianificare correttamente un comando browser.wait() per attendere che l'attributo elemento abbia un valore non vuoto e ho verificato che questo valore sia in realtà quello che mi aspetto di ottenere all'interno della funzione di callback, ma per alcuni motivo, non sono in grado di restituire tale valore al di fuori della funzione di callback e sul resto del codice di test.

Ecco come il mio codice è simile:

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

posso dire che l'ordine di esecuzione non è come mi aspettavo che fosse, perché quando ho rimuovere il commento dalla console.log() chiamata all'interno della funzione di callback, vedo il valore atteso stampato Tuttavia, la stessa chiamata nella funzione test() stampa 'indefinito'.

Cosa sta succedendo qui? Cosa mi manca? Come posso ottenere correttamente il valore dell'attributo dalla funzione di callback?

Apprezzo il vostro aiuto.

risposta

9

non vorrei coniugare l'attesa e le parti degli attributi che ottengono - logicamente queste sono due cose separate, tenerli separati:

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

Si noti che, si può semplificare la condizione di attesa in questo modo:

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

Proprio a proposito, voi hanno risolto il problema corrente con il 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; 
} 
+1

Grazie! Con alcune correzioni minori, l'ultimo approccio funziona nel mio caso. Speravo di essere in grado di restituire il valore dell'oggetto direttamente alla funzione chiamante, ma a quanto pare questo non è il modo giusto di pensare quando si tratta di promesse in chiamate asincrone. L'ultima riga dovrebbe essere "return item.promise;". – exbuddha

1

Dopo aver fatto un po 'di lettura su come goniometro lavora con le promesse e gli orari/li registra con il flusso di controllo, ho trovato un facile work-around vicino al primo @alecxe soluzione fornita. Qui si va:

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

Dal browser.wait() restituisce una promessa per sé, può essere concatenato con un altro then() all'interno del chiamante e in questo modo il giusto ordine di esecuzione è garantita.

Problemi correlati