Jak wybrać opcję z listy rozwijanej za pomocą Kapibary


125

Próbuję wybrać pozycję z menu rozwijanego za pomocą Kapibary (2.1.0).

Chcę wybierać według numeru (czyli wybrać drugą, trzecią itd. Opcję).

Szukałem w Google jak szalony, próbując różnych rzeczy, ale bez powodzenia.

Udało mi się go wybrać za pomocą wartości:

 find("option[value='4c430d62-f1ba-474f-8e8a-4452c55ea0a8']").click

Ale nie chcę używać tej metody b / c, wartość jest czymś, co się zmieni i to sprawi, że mój test będzie kruchy.

Kod HTML listy rozwijanej to:

<td class="value">
    <select name="organizationSelect" id="organizationSelect" class="required">
     <option value="NULL">Choose...</option>
     <option value="4c430d62-f1ba-474f-8e8a-4452c55ea0a8">&nbsp;Institution1</option>
     <option value="e1a4efa7-352d-410a-957e-35c8a3b92944">&nbsp;Institution / test</option>
    </select>
</td>

Próbowałem też tego:

  option = find(:xpath, "//*[@id='organizationSelect']/option[2]").text  
  select(option, :from => organizationSelect)

Ale skutkuje tym błędem:

Ambiguous match, found 2 elements matching option "Institution" (Capybara::Ambiguous)

Jak więc mogę wybrać pierwszą, drugą, trzecią itd. Opcję z listy rozwijanej (używając Kapibary)?

Odpowiedzi:


129

Jeśli spojrzysz na źródło selectmetody , zobaczysz, że to, co robi, gdy podajesz fromklucz, to zasadniczo:

find(:select, from, options).find(:option, value, options).select_option

Innymi słowy, to znajdzie <select>jesteś zainteresowany, to znajdzie <option>w zasięgu, wtedy nazywa select_optionsię na <option>węźle.

Prawie już wykonałeś dwie pierwsze rzeczy, po prostu przestawiłbym je. Następnie możesz przyczepić select_optionmetodę na końcu:

find('#organizationSelect').find(:xpath, 'option[2]').select_option

1
Wielkie dzięki Carol! Naprawdę doceniam pomoc! : D
Farooq

2
Chciałbym dodać to odniesienie dla osób badających to w przyszłości: gist.github.com/zhengjia/428105
BKSpurgeon

3
Świetna odpowiedź! Chciałbym dodać, że w Rails 5 można to zrobić w następujący sposób także: select('option_name', from: 'select_box'). Gdzie wartościami mogą być: id, nazwa, powiązany element etykiety. Możesz przeczytać więcej o opcjach Kapibara i DSL tutaj .
Nesha Zoric

177

Z jakiegoś powodu to nie zadziałało. Musiałem więc użyć czegoś innego.

select "option_name_here", :from => "organizationSelect"

pracował dla mnie.


1
Dziwne, to nie działa dla mnie, ponieważ metoda wydaje się mieć co najmniej 3 opcje. Chociaż kod, który zasugerowałeś, pasuje do przykładowego kodu z przewodnika po kapibarach.
Linus

1
to nie jest form, to jest from. Oto dokumentacja na temat select
fontno

3
Być może warto zauważyć, że wartość od to nazwa, identyfikator lub tekst etykiety. tzn. „#organizationSelect” jest niepoprawne, ale „organizationSelect” powinno działać.
MZB

To nie zadziałało, ale rozwiązanie Carols10cents działało. To nie jest krytyka twojej odpowiedzi. Po prostu uważam to za naprawdę dziwne, że nawet w najnowszej wersji kapibary niektóre połączenia działają, a niektóre nie, nawet jeśli intencja doprowadziłaby do przekonania, że ​​wiele rozwiązań wygląda na prawidłowe. To doprowadza mnie do szaleństwa. Czy jest to związane z Firefoksem (lub jakąkolwiek kapibarą przeglądarki, której ostatecznie używa)?
chaostheory

Myślę, że zadziała to tylko wtedy, gdy nazwa opcji i wartość opcji są takie same.
pixelearth

8

inną opcją jest dodanie takiej metody

  def select_option(css_selector, value)
    find(:css, css_selector).find(:option, value).select_option
  end

Pomocne opcjefind("select[name='organization_search[role]']").find(:option, text: :Staff).select_option
pixelearth

find(:css, "#search_field").find(:option, "Opp Last Name").select_option, czyli wyświetlany tekst opcji, zadziałał u mnie, podczas gdy wartość opcji nie.
codenoob

4

Niestety najpopularniejsza odpowiedź nie działała w moim przypadku całkowicie. Musiałem dodać .select_optionna końcu oświadczenia

select("option_name_here", from: "organizationSelect").select_option

bez select_option, żaden wybór nie był wykonywany


Jak możesz zadzwonić .select_option, skoro selectmetoda zwraca wartość logiczną?
Ruby,

4

Aby dodać jeszcze jedną odpowiedź do stosu (ponieważ podobno jest tak wiele sposobów na zrobienie tego w zależności od twojej konfiguracji) - zrobiłem to, wybierając optionelement dosłowny i klikając go

find(".some-selector-for-dropdown option[value='1234']").select_option

Nie jest zbyt ładna, ale działa: /


2

żadna z odpowiedzi nie zadziałała dla mnie w 2017 roku z kapibarą 2.7. Otrzymałem „ArgumentError: zła liczba argumentów (dane 2, oczekiwano 0)”

Ale to zrobiło:

find('#organizationSelect').all(:css, 'option').find { |o| o.value == 'option_name_here' }.select_option

0

Nie jest to bezpośrednia odpowiedź, ale możesz (jeśli pozwala na to Twój serwer):

1) Utwórz model dla swojej Organizacji; dodatkowo: łatwiej będzie wypełnić swój kod HTML.

2) Utwórz fabrykę (FactoryGirl) dla swojego modelu;

3) Utwórz listę (create_list) z fabryką;

4) „wybierz” (przykład) organizację z listy zawierającą:

# Random select
option = Organization.all.sample 

# Select the FIRST(0) by id
option = Organization.all[0] 

# Select the SECOND(1) after some restriction
option = Organization.where(some_attr: some_value)[2]
option = Organization.where("some_attr OP some_value")[2] #OP is "=", "<", ">", so on... 

4
jeśli muszę stworzyć model, nie ma sensu używać kapibary
user1735921

To wcale nie jest odpowiedź. To jest pytanie dotyczące Kapibary.
Robin Daugherty

0

Oto najbardziej zwięzły sposób, jaki znalazłem (przy użyciu kapibary 3.3.0 i sterownika chromowego):

all('#id-of-select option')[1].select_option

wybierze drugą opcję. Zwiększ indeks według potrzeb.


0

W Kapibara możesz używać tylko znajdowania z xpath

find(:xpath, "//*[@id='organizationSelect']/option[2]").click

i kliknij metodę

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.