2014-11-25 14 views
6

Sono al mio terzo giorno di lavoro con Goniometro e continuo a colpire i muri di ferro per quanto riguarda l'attesa delle pagine da caricare e degli elementi da visualizzare. In particolare, questo test case è diventato brutto e vorrei risolvere i problemi senza dover fare affidamento sul sonno.Attendi che l'elemento cambi il suo valore (testo)

Attualmente sto "al di fuori della terra di AngularJS"

it('it should reflect in both the field and the title when the personnel name is changed', function() { 
    var inputField, personnelHeader, personnelName; 
    personnelName = element(By.css(".overlay.editnameoverlay")).click(); 
    personnelHeader = element(By.id("personnel_name_header")); 
    inputField = element(By.css("input[name='newvalue']")); 
    inputField.clear(); 
    inputField.sendKeys("Test 123"); 
    element(By.css("input[name='ok_button']")).click(); 
    // browser.driver.sleep(2000); This test only works with this sleep added 
    browser.wait(function() { 
    console.log("Waiting for header to change..."); 
    return personnelHeader.getText().then(function(text) { 
     return text === "Test 123"; 
    }); 
    }, 5000); 
    return expect(personnelHeader.getText()).toBe(personnelName.getText()); 
}); 

Quindi il test qui cambia il nome in un campo di input. lo invia e attende che le modifiche si riflettano nell'intestazione del modale. Il problema è che senza il browser.driver.sleep (2000) ottengo un errore che dice

Stacktrace: 
    StaleElementReferenceError: stale element reference: element is not attached to the page document 

Come posso fare per risolvere questo in questo caso particolare?

risposta

6

Quando si usa il goniometro per verificare le pagine non angolari, si è da soli in attesa di elementi pronti per l'interazione.

StaleElementReferenceError è probabilmente l'errore di selenio più inutile, accade quando l'elemento ottenuto rimosso dal DOM, ma è ancora nella cache in qualche modo, ho anche suffered questo problema quando è iniziato con goniometro e anche tried to convince dovrebbe essere ritentata automaticamente goniometro-side.

La soluzione per me è quella di aspettare sempre in modo esplicito per un elemento ad apparire sulla pagina utilizzando un custom functionwaitReady() che browser.wait per gli elementi pronti, vale a dire: attende l'elemento per essere pronti per l'interazione:

expect($('#login_field').waitReady()).toBeTruthy(); 

prima di integrare questo frammento nel codice: https://gist.github.com/elgalu/2939aad2b2e31418c1bb

Non solo i personalizzati waitReady() attende l'elemento ma inghiotte anche qualche errore WebDriver inutile estranei come StaleElementReferenceError e si limiterà a riprovare fino a trovare il elemento o verrà timeout.

Così waitReady() ogni elemento prima di interagire, vale a dire prima di clear() o sendKeys() o click() ...

// TODO: Move to Page Objects module 
var personnelNameElm = $(".overlay.editnameoverlay"); 
var personnelHeaderElm = $("#personnel_name_header"); 
var inputFieldElm = $("input[name='newvalue']"); 
var okBtnElm = $("input[name='ok_button']"); 

it('it should reflect in both the field and the title when the ' + 
    'personnel name is changed', function() { 

    expect(personnelNameElm.waitReady()).toBeTruthy(); 
    personnelNameElm.click(); 
    expect(inputFieldElm.waitReady()).toBeTruthy(); 
    inputFieldElm.clear().sendKeys("Test 123"); 
    expect(okBtnElm.waitReady()).toBeTruthy(); 
    okBtnElm.click(); 

    browser.wait(function() { 
    console.log("Waiting for header to change..."); 
    // Using waitReady() before getText() avoids Stale element errors 
    return personnelHeaderElm.waitReady().then(function() { 
     return personnelHeaderElm.getText().then(function(text) { 
     return text === "Test 123"; 
     }); 
    }); 
    }, 5000); 

    expect(personnelHeaderElm.getText()).toEqual(personnelNameElm.getText()); 
}); 
8

Dalla documentazione per Expect Conditions:

var EC = protractor.ExpectedConditions; 
// Waits for the element with id 'abc' to contain the text 'foo'. 
browser.wait(EC.textToBePresentInElement($('#abc'), 'foo'), 5000); 
Problemi correlati