Pracuję z wieloma wtyczkami jQuery, które często tworzą elementy DOM bez id lub innych właściwości identyfikacyjnych, a jedynym sposobem, aby uzyskać je w Kapibara (na przykład na kliknięcie) - jest najpierw zdobycie sąsiada (innego dziecka swojego przodka) . Ale nigdzie nie znalazłem, czy Kapibara obsługuje takie rzeczy np:
find('#some_button').parent.fill_in "Name:", :with => name
?
Odpowiedzi:
Naprawdę uznałem, że odpowiedź jamuraa jest pomocna, ale przejście na pełną ścieżkę xpath dało mi koszmar w postaci ciągu znaków w moim przypadku, więc szczęśliwie skorzystałem z możliwości łączenia znalezisk w Kapibara, co pozwoliło mi mieszać wybór css i xpath. Twój przykład wyglądałby wtedy następująco:
find('#some_button').find(:xpath,".//..").fill_in "Name:", :with => name
Aktualizacja Kapibary 2.0 :
find(:xpath,".//..")
najprawdopodobniej spowodujeAmbiguous match
błąd. W takim przypadku użyjfirst(:xpath,".//..")
zamiast tego.źródło
.//..
szukać rodzica -..
wystarczy, i to też nigdy nie jest niejednoznaczne.Nie da się tego zrobić w przypadku kapibary i CSS. W przeszłości używałem XPath, aby osiągnąć ten cel, który ma sposób na uzyskanie elementu nadrzędnego i jest obsługiwany przez Capybarę:
find(:xpath, '//*[@id="some_button"]/..').fill_in "Name:", :with => name
źródło
find(:xpath, '//*[@id="some_button"]/..')
Znalazłem następujące, które działają:
find(:xpath, '..')
Kapibara została zaktualizowana, aby to wspierać.
https://github.com/jnicklas/capybara/pull/505
źródło
Jeśli natknąłeś się na to, próbując dowiedzieć się, jak znaleźć dowolny węzeł nadrzędny (jak w przodku ) (jak wskazano w komentarzu @ vrish88 do odpowiedzi @Pascal Lindelauf):
find('#some_button').find(:xpath, 'ancestor::div[@id="some_div_id"]')
źródło
Ta odpowiedź dotyczy tego, jak manipulować elementem rodzeństwa, do czego, moim zdaniem, nawiązuje pierwotne pytanie
Twoja hipoteza pytania działa z niewielkimi zmianami. Jeśli dynamicznie generowane pole wygląda tak i nie ma identyfikatora:
<div> <input></input> <button>Test</button> </div>
Twoje zapytanie byłoby wtedy:
find('button', text: 'Test').find(:xpath, "..").find('input').set('whatever')
Jeśli dynamicznie generowane dane wejściowe są dołączone do elementu id (uważaj na te, choć jak w angularach, zwykle zmieniają się w oparciu o dodawanie i usuwanie elementów), byłoby to mniej więcej tak:
find('button', text: 'Test').find(:xpath, "..").fill_in('#input_1', with: 'whatever')
Mam nadzieję, że to pomoże.
źródło
Używam innego podejścia, znajdując element nadrzędny, najpierw używając tekstu w tym elemencie nadrzędnym:
find("<parent element>", text: "text within your #some_button").fill_in "Name:", with: name
Może jest to przydatne w podobnej sytuacji.
źródło
Musiałem znaleźć przodka z klasą css, chociaż było to nieokreślone, jeśli docelowy przodek miał jedną lub więcej klas css, więc nie widziałem sposobu na wykonanie deterministycznego zapytania xpath. Zamiast tego opracowałem to:
def find_ancestor_with_class(field, cssClass) ancestor = field loop do ancestor = ancestor.find(:xpath, '..') break if ancestor.nil? break if ancestor.has_css? cssClass end ancestor end
Ostrzeżenie: używaj tego oszczędnie, może to kosztować dużo czasu w testach, więc upewnij się, że przodek jest tylko kilka przeskoków.
źródło
break if ancestor[:class].split(" ").include?(css_class)
.ancestor(selector)
metodę zbudowany w See. Github.com/teamcapybara/capybara/commit/...Tutaj jest
http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Base:parent
Istnieje metoda nadrzędna;)
źródło