2013-08-27 11 views
5

Używam Capybara 2.1 z Ruby 1.9.3, używając sterownika selenu (z Minitest i Test Unit) w celu przetestowania aplikacji internetowej.StaleElementReference Błąd Element nie został znaleziony w pamięci podręcznej

Mam problem z problemem StaleElementReferenceException. Widziałem już wiele dyskusji na ten temat, ale nie byłem w stanie znaleźć rozwiązania problemu, z którym się borykam.

Więc w zasadzie, staram się znaleźć wszystkie elementy paginacji na mojej stronie za pomocą tego kodu:

pagination_elements = page.all('.pagination a') 

Potem robię pewne twierdzenia na temat tych elementów, takich jak:

pagination_elements.first.must_have_content('1') 

Po te twierdzenia, kontynuuję test, klikając link Next Page, aby upewnić się, że mój przyszły pierwszy element paginacji będzie poprzednią stroną. Aby to zrobić, że jestem znowu pobierania elementów paginations:

new_pagination_elements = page.all('.pagination a') 

A Stale Błąd występuje tutaj, bo jestem elementy, które ja już osiągnęły idące. (Here is the error)

Możesz zobaczyć stany linków here.

Naprawdę nie mam pojęcia, jak sprawić, aby ten wspólny test działał prawidłowo. Czy masz jakieś wskazówki, aby uzyskać lepszy sposób dotarcia do elementów stronicowania?

+0

Proszę spojrzeć https://github.com/jnicklas/capybara/issues/843 –

+0

@RajarshiDas ja już przeczytać ten temat i te związane, ale jest to bardzo stary problem, od A poprzednia wersja Capybara, i to nie pomaga w moim problemie. – Evers

Odpowiedz

1

Widziałem główne przesłanie w GIST jest:

Element not found in the cache - 
perhaps the page has changed since it was looked up 

mam podobną sprawę. Istnieją dwa rozwiązania:

  1. Dodaj page.reload przed sprawdzeniem same rzeczy w nowej strony, jeśli masz ustawione Capybara.automatic_reload = false w spec_helper

  2. find specjalny element nowej strony, które poprzednia strona nie posiada. Ten efekt jest równoważny oczekiwaniu.

Inną metodą jest użycie określonego selektora. Na przykład, zamiast

pagination_elements = page.all('.pagination a') 

Korzystanie

pagination_elements = page.all('#post_123 .pagination a') 

Dołącz unikalny identyfikator obszaru selektora i nie powinien spełniać taki problem.

+0

Chciałbym uniknąć użycia strony .load, ponieważ moje testy integracyjne śledzą przepływ użytkownika, a ponowne ładowanie strony nie jest jej częścią. – Evers

+0

@Evers, nic tu nie jest. Domyślne ustawienie to "true", więc każda akcja przeładuje zawartość, po prostu jej nie zauważyłeś. Zawsze ustawiam go na 'false', ponieważ ja często używam Javascript. Zapomnij tę część, jeśli nie masz takiego ustawienia w 'spec_helper' –

+0

Ale siła do' przeładowania' może pomóc, jeśli sprawdzisz to samo dwa razy. Warto spróbować. –

3

czasami mają jakiś problem z AJAX intensywnych stron, w moim przypadku to rozwiązanie rozwiązuje go:

begin 
    ... 
rescue Selenium::WebDriver::Error::StaleElementReferenceError 
    sleep 1 
    retry 
end 
0

Czy próbowałeś użyć WebDriver bezpośrednio raczej niż przez Kapibara? Woudl potencjalnie daje większą kontrolę nad tym, kiedy i kiedy nie buforować obiektów.

np.(Przepraszam za składni Javy ale powinien dostać ten pomysł)

WebElement searchField = driver.findElement(By.CssSelector("input.foo")); 

searchField.click(); 

searchField.sendKeys("foo foo"); 

System.out.println(searchField.getText()); 

//Do something elsewhere on the page which causes html to change (e.g. submit form) 

..... 
.... 

//This next line would throw stale object 

System.out.println(searchField.getText()); 

//This line will not throw exception 

searchField = driver.findElement(By.CssSelector("input.foo")); 

System.out.println(searchField.getText()); 

Przypisywanie „findElement” znowu „searchField” oznacza, że ​​możemy ponownie znaleźć tego elementu. Wiedza na temat tego, kiedy i kiedy nie należy ponownie przypisać, jest kluczem do podjęcia decyzji o przechowywaniu w pamięci podręcznej stron WWW.

Nie użyłem kapibary, ale zakładam, że ukrywa ona przed tobą strategię buforowania?

+1

Używamy już Capybara w naszych innych projektach i nie rozważamy powrotu do samego Webdrivera. Kapibara oszczędza nam dużo czasu. Ale masz rację, kapibara ma strategie buforowania, wśród wielu innych :) – Evers

+0

Mam zamiar przenieść się do Rubiego i próbuję zdecydować, której biblioteki użyć. Takie rzeczy sprawiają, że po prostu użyję Webdrivera bezpośrednio. Chciałbym mieć zbyt dużą kontrolę, aby użyć czegoś takiego jak Kapibara –

+0

Downvote? Nieco trudny –

1

Podobno oprócz rasy warunki, błąd ten pojawia się również ze względu na nadużyli within bloków. Na przykład:

within '.edit_form' do 
    click '.edit_button' 
    # The error will appear here if the 'edit_button' is not a 
    # descendant of the 'edit_form' 
end 
+1

to mój przypadek! Byłem zamknięty wewnątrz bloku 'wewnątrz ', który powodował fałszywy błąd na nieaktualnym obiekcie w środku - co było nieświeże, nie było tym, co" znajdowałem ", ale zamiast tego blok! – igorsantos07

Powiązane problemy