2015-08-03 12 views
5

Kod 1:"Stale odniesienia elementem" zachowanie błąd undestanding

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

Powyższy kod pracował dobrze wiele razy, a potem zaczął dawać poniżej błędu

„failed: nieświeże odniesienie elementów: elementu nie jest dołączony do strony " dokument"

ten id 'myValidationSum maryId "nie jest używane wcześniej, kliknięcie formularza postów przycisku i komunikat o sukcesie/niepowodzeniu dostępny od strony usługi w" myValidationSummaryId ".

Kod 2:

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

Mocowanie kod jak powyżej ustalonej pierwotną emisję i to działało konsekwentnie grzywny wiele razy, ale później zaczęło braku losowo z oryginalnym czerstwego błędu odniesienia elementem.

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

Potem stały kod jak wyżej i teraz działa dobrze konsekwentnie waitReady funkcja aktywnie czekać na element obecnego i wyświetlany aż do określonego czasu.

Nie powinien kątomierz/WebdriverJS powinien poradzić sobie z tymi problemami dobrze natywnie.

1> Czy mógłbyś wyjaśnić, dlaczego kod 1 i kod 2 kiedyś działały, a czasami zawodziły?

2> Czy uważasz, że kod 3 jest teraz w porządku i oczekuje się, że będzie działał za każdym razem?

Element "myValidationSummaryId" użyty tylko raz i po kliknięciu, więc jeśli strony nie są w pełni załadowane, a element nie jest jeszcze dostępny, powinien powiedzieć Nie znaleziono elementu, ale dlaczego nieaktualne odwołanie do elementu? Użyłem pageLoadTimeout jako 5 minut, a strona jest ładowana w kilka sekund. To nie jest aplikacja AngularJS i browser.ignoreSynchronization = true.

wszędzie, gdzie mówiono o tym, jaki kod może to naprawić, ale nie znalazłem wiele informacji o tym, dlaczego to zachowanie i dlaczego WebdriverJS sam nie jest w stanie sobie z tym poradzić.

+0

Tak, wyraźne oczekiwania jest zwykły sposób rozwiązania problemów, takich jak te. Ale miałem dokładnie to samo pytanie, dlaczego czasami czekanie jest rzeczywiście konieczne i nie należy go obchodzić naturalnie. Jedną z rzeczy, których protektor nie rozpoznał w moim przypadku była animacja - gdyby była animacja pokazująca element, musiałem użyć czekania. Świetne pytanie! – alecxe

+0

Mogę potwierdzić, że miałem dzisiaj dokładnie ten sam błąd. Bez żadnego powodu zmieniono kod i rozpoczęły się testy. Jeśli chodzi o zachowanie dziwnego Kątomierza - mogę polecić ** asynchroniczne ** jako sposób na jego oswojenie. Jeśli ** asynchronizacja ** nie pomoże, to rzucę ręcznikiem. –

Odpowiedz

6

Nie sądzę, że możemy być pewni, dlaczego tak się dzieje, ale zdecydowanie nie jesteście sami, (1)(2). Może to wynikać ze sposobu, w jaki twoja strona jest renderowana w sposób konkretny (np. W jaki sposób twoja aplikacja/środowisko obsługuje elementy DOM) lub po prostu Selen/sterownik. Jeśli jesteś zainteresowany dokładnym wyjaśnieniem, możesz mieć więcej szczęścia, jeśli korzystasz z systemu raportowania błędów Protractor.

Dobrym przypuszczenie, jednak może być to, że jest to związane ze sposobem Selen defines stale element:

Mniej powszechne, ale nadal częstą przyczyną jest sytuacja, gdy biblioteka JS został usunięty element i zastąpił go jeden z tym samym identyfikatorem lub atrybuty

Niektóre biblioteki mogą oszukać selen, wierząc element jest odszedł z DOM, ale został zastąpiony naprawdę tylko w jednej chwili. Dodając do tego wąski, kruchy czas pomiędzy kliknięciem a elementem umieszczonym w DOM (w zasadzie wyścigu) - to może być przyczyną. Być może zainteresuje Cię nieco więcej informacji na ten temat: here.

W każdym razie, jeśli masz takie problemy, polecam za pomocą browser.wait i Expected Conditions.

Oczekiwane warunki to zasadniczo funkcje, które zwracają wartość true lub false, i można określić limit czasu, który spowoduje niepowodzenie testu, jeśli true nie zostanie zwrócona w tym czasie - można zobaczyć, jak jest on stosowany w similar question.

Zasadniczo, można to zrobić tak:

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

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

Dziękuję za sugestie, funkcja waitReady używa browser.wait, i działa dobrze, przeszedłem http://docs.seleniumhq.org/exceptions/stale_element_reference.jsp, ale w moim przypadku element nie został usunięty, zastąpiony lub typ nie ulega zmianie. – Morbia

+0

Wtedy prawdopodobnie będziesz musiał podać dokładny kod lub samodzielnie przeprowadzić zaawansowane debugowanie. Przyczyna będzie prawdopodobnie bardzo trudna do ustalenia, ale jeśli dowiesz się, co to jest, byłbym świetny, gdybyś podzielił się tą sprawą. – wap300

+0

Zgadzam się, pracuję teraz nad projektem, dzięki któremu, jeśli otworzę narzędzia programistyczne w przeglądarce Chrome F12 i zobaczę DOM, mogę zobaczyć asynchroniczne ustawienia Angulara i uzyskać pewne zmiany (i nieznane w teście) elementy DOM. To sprawia, że ​​testowanie tych stron jest niemożliwe z powodu oczywistych problemów związanych z timingiem i "Stale Element Reference". –

Powiązane problemy