Como selecionar a opção no menu suspenso usando Capivara

125

Estou tentando selecionar um item em um menu suspenso usando a Capivara (2.1.0).

Quero selecionar por número (ou seja, selecione a segunda, terceira, etc).

Eu pesquisei no Google como um louco tentando todo tipo de coisa, mas sem sorte.

Consegui selecioná-lo usando o valor:

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

Mas não quero usar esse método porque o valor é algo que mudará e tornará meu teste frágil.

O HTML da lista suspensa é:

<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>

Eu também tentei isso:

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

Mas resulta neste erro:

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

Então, como posso selecionar a primeira, a segunda, a terceira, etc opção no menu suspenso (usando Capivara)?

Farooq
fonte

Respostas:

129

Se você der uma olhada na fonte do selectmétodo , poderá ver que o que faz quando você passa uma fromchave é essencialmente:

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

Em outras palavras, ele encontra o que <select>você está interessado, depois encontra o <option>que está dentro e chama select_optiono <option>nó.

Você já fez as duas primeiras coisas, eu as reorganizava. Então você pode seguir o select_optionmétodo no final:

find('#organizationSelect').find(:xpath, 'option[2]').select_option
carols10cents
fonte
1
Muito obrigado Carol! Realmente aprecio a ajuda! : D
Farooq
2
Gostaria de adicionar essa referência para aqueles pesquisando esse no futuro: gist.github.com/zhengjia/428105
BKSpurgeon
3
Ótima resposta! Gostaria de acrescentar que, em Rails 5 você pode fazê-lo da seguinte maneira bem: select('option_name', from: 'select_box'). Onde os valores podem estar: id, nome, elemento de rótulo relacionado. Você pode ler mais sobre as opções de Capivara e DSL aqui .
Nesha Zoric
178

Por alguma razão, não funcionou para mim. Então eu tive que usar outra coisa.

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

trabalhou para mim.

RVM
fonte
1
Estranho, isso não funciona para mim, pois o método parece ter pelo menos três opções. Embora o código que você sugeriu corresponda ao código de exemplo do guia da capivara.
Linus
1
não é form, é from. Aqui está a documentação sobre select
fontno
3
Talvez seja interessante notar que o valor from é o nome, o ID ou o texto do rótulo. ou seja, "#organizationSelect" está incorreto, mas "organizationSelect" deve funcionar.
MZB 12/03
Isso não funcionou para mim, mas a solução de carols10cents funcionou. Isso não é crítico da sua resposta. Eu acho realmente estranho que, mesmo na versão mais recente da capivara, algumas chamadas funcionem e outras nem quando a intuição o leva a acreditar que várias soluções parecem válidas. Está me deixando louco. Isso está relacionado ao firefox (ou qualquer que seja a capivara do navegador que acabe usando)?
teoria do caos
Eu acho que isso só funcionará quando o nome e o valor da opção forem os mesmos.
pixelearth
8

Outra opção é adicionar um método como este

  def select_option(css_selector, value)
    find(:css, css_selector).find(:option, value).select_option
  end
montrealmike
fonte
Opções úteisfind("select[name='organization_search[role]']").find(:option, text: :Staff).select_option
pixelearth 03/03
find(:css, "#search_field").find(:option, "Opp Last Name").select_option, que é o texto da opção exibida, funcionou para mim, enquanto o valor da opção não.
codenoob 12/06
4

Infelizmente, a resposta mais popular não funcionou totalmente para mim. Eu tive que adicionar .select_optionao final da declaração

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

sem o select_option, nenhuma seleção estava sendo executada

Sam D
fonte
Como você pode chamar .select_option, já que o selectmétodo retorna um valor booleano?
Ruby
4

Para adicionar mais uma resposta à pilha (porque aparentemente existem muitas maneiras de fazer isso, dependendo da sua configuração) - eu fiz isso selecionando o optionelemento literal e clicando nele

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

Não é muito bonito, mas funciona: /

user2490003
fonte
2

nenhuma das respostas funcionou para mim em 2017 com a capivara 2.7. Eu recebi "ArgumentError: número errado de argumentos (dado 2, esperado 0)"

Mas isso fez:

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

Não é uma resposta direta, mas você pode (se o seu servidor permitir):

1) Crie um modelo para sua organização; extra: será mais fácil preencher seu HTML.

2) Crie uma fábrica (FactoryGirl) para o seu modelo;

3) Crie uma lista (create_list) com a fábrica;

4) 'escolha' (amostra) uma organização da lista com:

# 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... 
David V. Teixeira
fonte
4
se eu tenho que criar um modelo, não há nenhum ponto em usar capivara
user1735921
Não é uma resposta. Esta é uma pergunta sobre a Capivara.
Robin Daugherty
0

Aqui está a maneira mais concisa que eu encontrei (usando o capybara 3.3.0 e o driver de cromo):

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

selecionará a segunda opção. Incremente o índice conforme necessário.

pduey
fonte
0

Na Capivara, você pode usar somente find com xpath

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

e clique no método

Alexandr
fonte