2015-08-03 14 views
5

Codice 1:comportamento errore "Stale elemento di riferimento" undestanding

element(by.id('myButtonId')).click(); 
return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
    return val; 
}); 

Sopra codice ha funzionato bene molte volte e poi ha cominciato dando sotto l'errore

"Impossibile: di riferimento Elemento stantio: Elemento non è collegato alla pagina documento "

questo id 'myValidationSum maryId 'non è dove usato in precedenza, facendo clic sul modulo dei post dei pulsanti e sul messaggio di successo/fallimento disponibile dal lato del servizio in' myValidationSummaryId '.

Codice 2:

return element(by.id('myButtonId')).click().then(function() { 
    return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
     return val; 
    }); 
}); 

codice di fissaggio come sopra emissione iniziale fisso e ha funzionato costantemente bene molte volte ma in seguito iniziato avendo casualmente con errore elemento di riferimento stantio originale.

Codice 3:

return element(by.id('myButtonId')).click().then(function() { 
    return element(by.id('myValidationSummaryId')).waitReady().then(function (isReady) { 
     if (isReady) { 
      return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
       return val; 
      }); 
     } else { 
      return 'Failed to check success/failure message'; 
     } 
    }); 
}); 

Poi ho fissato codice come sopra e ora funziona benissimo in modo coerente, waitReady funzione attivamente attendere un elemento presente e visualizzato fino a tempo specificato.

Non dovrebbe il goniometro/WebdriverJS supposto per gestire questi problemi in modo nativo.

1> potresti spiegare perché il codice 1 e il codice 2 a volte hanno funzionato e qualche volta hanno fallito?

2> pensi che il codice 3 ora stia bene e si aspetti che funzioni ogni volta?

Elemento 'myValidationSummaryId' utilizzato solo una volta e dopo il clic in modo che se le pagine non sono caricate completamente e se l'elemento non è ancora disponibile dovrebbe dire Nessun elemento trovato ma perché riferimento elemento stantio? Ho usato pageLoadTimeout come 5 minuti e la pagina viene caricata in pochi secondi. Questa non è un'applicazione AngularJS e browser.ignoreSynchronization = true.

ovunque si parli di quale codice è in grado di risolverlo ma non si trova molto sul perché questo comportamento e perché WebdriverJS non sia in grado di gestirlo.

+0

Sì, attesa esplicito è il solito modo per risolvere i problemi come questi. Ma, ho avuto la stessa domanda esatta, perché a volte le attese sono effettivamente necessarie e il goniometro non dovrebbe gestirle in modo naturale. Una cosa che il goniometro non riconosceva nel mio caso era un'animazione - se ci fosse un'animazione che mostrava un elemento dovevo usare le attese. Ottima domanda! – alecxe

+0

Posso confermare che ho avuto lo stesso errore oggi. Senza alcun motivo, qualsiasi codice viene modificato e i test iniziano a non riuscire. Per quanto riguarda il comportamento del goniometro strano - posso raccomandare ** async ** come un modo per domarlo. Se ** async ** non aiuta, allora lancio l'asciugamano. –

risposta

6

Non penso che possiamo essere certi del perché, ma non sei assolutamente solo (1)(2). Ciò può essere dovuto al modo in cui la tua pagina viene resa in modo specifico (ad esempio, come la tua app/framework sta gestendo il rendering degli elementi DOM), o solo una cosa Selenium/driver. Se sei interessato a una spiegazione esatta, potresti avere maggiore fortuna se utilizzi il sistema di segnalazione dei bug di Protractor.

una buona congettura, tuttavia, può essere che si è legato al modo in cui Selenio defines stale element:

Una causa meno comune, ma ancora comuni è dove una libreria JS ha cancellato un elemento e lo ha sostituito con uno con lo stesso ID o attributi

Alcune librerie può ingannare selenio a credere un elemento è andato dal DOM, ma è stato davvero solo sostituito in un istante. Aggiungendo un timing stretto e fragile tra il clic e l'elemento inserito nel DOM (in pratica la condizione di competizione), questa potrebbe essere la causa. Potresti essere interessato a leggere un po 'di più su di esso here.

In ogni caso, se si riscontrano tali problemi, si consiglia di utilizzare browser.wait e Expected Conditions.

Le condizioni previste sono fondamentalmente funzioni che restituiscono vero o falso ed è possibile specificare un timeout che causerà il fallimento del test se true non viene restituito in quel momento: è possibile vedere come viene utilizzato in un similar question.

In sostanza, si potrebbe desiderare di fare in questo modo:

var EC = protractor.ExpectedConditions; 
var summaryId = element(by.id('myValidationSummaryId')); 

browser.wait(EC.presenceOf(summaryId), 5000); 
//rest of your code 
+0

Grazie per i tuoi suggerimenti, la funzione waitReady utilizza browser.wait, e funziona bene, avevo consultato http://docs.seleniumhq.org/exceptions/stale_element_reference.jsp ma nel mio caso l'elemento non è stato rimosso, sostituito o il tipo non cambia. – Morbia

+0

Quindi probabilmente dovresti condividere il tuo codice esatto, o fare qualche debug avanzato da solo. Probabilmente la causa sarà molto difficile da determinare, ma se scopri cosa sia, sarei fantastico se condividessi la causa qui. – wap300

+0

D'accordo, sto lavorando a un progetto in cui ora, se apro gli strumenti di sviluppo in Chrome F12 e guardo il DOM, posso effettivamente vedere gli elementi DOM di Angular's Asynchronous e ottenerne certi (e sconosciuti per il test). Questo rende impossibile testare queste pagine a causa di problemi di temporizzazione ovvi e di "Stale Element Reference". –