Cómo seleccionar la opción en el menú desplegable usando Carpincho


125

Estoy tratando de seleccionar un elemento de un menú desplegable usando Carpincho (2.1.0).

Quiero seleccionar por número (es decir, seleccionar la segunda opción, la tercera, etc.).

Busqué en Google como un loco intentando todo tipo de cosas pero sin suerte.

Pude seleccionarlo usando el valor:

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

Pero no quiero usar ese método porque el valor es algo que cambiará y hará que mi prueba sea frágil.

El HTML para el menú desplegable es:

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

También probé esto:

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

Pero resulta en este error:

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

Entonces, ¿cómo puedo seleccionar la primera, segunda, tercera, etc. opción del menú desplegable (usando Capybara)?

Respuestas:


129

Si observa el origen del selectmétodo , puede ver que lo que hace cuando pasa una fromclave es esencialmente:

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

En otras palabras, encuentra el <select>que le interesa, luego encuentra el contenido <option>y luego llama select_optional <option>nodo.

Ya has hecho las dos primeras cosas, solo las reorganizaría. Luego puedes agregar el select_optionmétodo al final:

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

1
Muchas gracias Carol! Realmente aprecio la ayuda! : D
Farooq

2
Quisiera agregar esta referencia para aquellos que investiguen esto en el futuro: gist.github.com/zhengjia/428105
BKSpurgeon el

3
¡Gran respuesta! Me gustaría añadir que en los carriles 5 puede hacerlo de la siguiente manera, así: select('option_name', from: 'select_box'). Donde pueden estar los valores: id, nombre, elemento de etiqueta relacionado. Puede leer más sobre las opciones de capibara y DSL aquí .
Nesha Zoric

178

Por alguna razón no me funcionó. Entonces tuve que usar algo más.

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

trabajó para mi.


1
Extraño, eso no funciona para mí, ya que el método parece tomar al menos 3 opciones. Aunque el código que sugirió coincide con el código de ejemplo de la guía capibara.
Linus

1
no es form, es from. Aquí está la documentación sobre select
fontno

3
Quizás valga la pena señalar que el valor de origen es el nombre, la identificación o el texto de la etiqueta. es decir, "#organizationSelect" es incorrecto, pero "organizationSelect" debería funcionar.
MZB

Esto no funcionó para mí, pero la solución de villancicos sí. Esto no es un crítico de su respuesta. Me parece realmente extraño que incluso en la última versión de capibara, algunas llamadas funcionen y algunas llamadas ni siquiera cuando la intuición lo lleve a creer que las soluciones múltiples parecen válidas. Me está volviendo loca. ¿Está relacionado con Firefox (o el navegador que utiliza el carpincho)?
chaostheory

Creo que esto solo funcionará cuando el nombre y el valor de la opción sean iguales.
pixelearth

8

otra opción es agregar un método como este

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

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

find(:css, "#search_field").find(:option, "Opp Last Name").select_option, que es el texto de la opción que se muestra, funcionó para mí, mientras que el valor de la opción no.
codenoob

4

Desafortunadamente, la respuesta más popular no me funcionó por completo. Tuve que agregar .select_optional final de la declaración

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

sin el select_option, no se realizaba ninguna selección


¿Cómo puedes llamar .select_option, ya que el selectmétodo devuelve un valor booleano?
Ruby

4

Para agregar otra respuesta a la pila (porque aparentemente hay muchas formas de hacerlo dependiendo de su configuración): lo hice seleccionando el optionelemento literal y haciendo clic en él

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

No es muy bonito, pero funciona: /


2

ninguna de las respuestas me funcionó en 2017 con capibara 2.7. Obtuve "ArgumentError: número incorrecto de argumentos (dado 2, esperado 0)"

Pero esto hizo:

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

0

No es una respuesta directa, pero puede (si su servidor lo permite):

1) Cree un modelo para su organización; extra: será más fácil llenar tu HTML.

2) Cree una fábrica (FactoryGirl) para su modelo;

3) Crear una lista (create_list) con la fábrica;

4) 'escoger' (muestra) una Organización de la lista con:

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

44
si tengo que crear un modelo, no tiene sentido usar capibara
user1735921

No es una respuesta en absoluto. Esta es una pregunta sobre Carpincho.
Robin Daugherty

0

Aquí está la forma más concisa que he encontrado (usando capibara 3.3.0 y controlador de cromo):

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

seleccionará la segunda opción. Incremente el índice según sea necesario.


0

En Carpincho solo puedes usar find con xpath

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

y haga clic en el método

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.