venezuela mascota habitat chiguiro chiguire carpincho caracteristicas capibara bebe asado alimentacion ruby-on-rails-3 rspec capybara

ruby-on-rails-3 - mascota - chiguiro asado



Resolución de ambigüedad del capibara (8)

Debido a esta publicación , puede solucionarlo mediante la opción "coincidencia":

Capybara.configure do |config| config.match = :prefer_exact end

¿Cómo resuelvo la ambigüedad en Capibara? Por alguna razón, necesito enlaces con los mismos valores en una página pero no puedo crear una prueba ya que recibo el error

Failure/Error: click_link("#tag1") Capybara::Ambiguous: Ambiguous match, found 2 elements matching link "#tag1"

La razón por la que no puedo evitar esto es por el diseño. Estoy intentando recrear la página de Twitter con tweets / etiquetas a la derecha y las etiquetas a la izquierda de la página. Por lo tanto, será inevitable que la página de enlaces idénticos aparezca en la misma página.



Mi solución es

first(:link, link).click

en lugar de

click_link(link)


NUEVA RESPUESTA:

Puedes intentar algo como

all(''a'').select {|elt| elt.text == "#tag1" }.first.click

Puede haber una manera de hacer esto que haga un mejor uso de la sintaxis de Capybara disponible, algo parecido a all("a[text=''#tag1'']").first.click pero no puedo pensar en el corregir la sintaxis y no puedo encontrar la documentación adecuada. Para empezar, dice que es una situación un tanto extraña, ya que tiene dos <a> etiquetas con la misma id , class y texto. ¿Hay alguna posibilidad de que sean hijos de diferentes divs, ya que entonces podrías hacer tu find within del segmento apropiado del DOM? (Ayudaría ver un poco de su fuente HTML).

ANTIGUA RESPUESTA: (donde pensé que ''# tag1'' significaba que el elemento tenía una id de "tag1")

¿En cuál de los enlaces quieres hacer clic? Si es el primero (o no importa), puede hacer

find(''#tag1'').click

De lo contrario, puedes hacer

all(''#tag1'')[1].click

hacer clic en el segundo.


Para agregar al cuerpo de conocimiento existente aquí:

Para las pruebas JS, Capybara tiene que mantener dos hilos (uno para RSpec, uno para Rails) y un segundo proceso (el navegador) en sincronización. Lo hace esperando (hasta el tiempo de espera máximo configurado) en la mayoría de los métodos de búsqueda de ganglios y de coincidencia.

El carpincho también tiene métodos que no esperan, principalmente Node#all . Usarlos es como decirle a tus especificaciones que te gustaría que fallen de manera intermitente.

La respuesta aceptada sugiere page.first(''selector'') . Esto es indeseable, al menos para las especificaciones JS, porque el Node#first usa el Node#all .

Dicho esto, el Node#first esperará si configura Capybara de la siguiente manera:

# rails_helper.rb Capybara.wait_on_first_by_default = true

Esta opción se agregó en Capybara 2.5.0 y es falsa por defecto.

Como dijo Andrei, deberías usar

find(''selector'', match: :first)

o cambie su selector. Cualquiera de los dos funcionará bien independientemente de la configuración o el controlador.

Para complicar aún más las cosas, en las versiones anteriores de Capybara (o con una opción de configuración habilitada), #find ignorará la ambigüedad y simplemente devolverá el primer selector coincidente. Esto tampoco es bueno, ya que hace que sus especificaciones sean menos explícitas, lo que imagino es por qué ya no es el comportamiento predeterminado. Dejaré de lado los detalles porque ya se discutieron más arriba.

Más recursos:


Para evitar un error ambiguo en el pepino.

Solución 1

first("#tag1").click

Solución 2

Cucumber features/filename.feature --guess


Puedes asegurarte de que encuentres el primero usando match :

find(''.selector'', match: :first).click

Pero lo más importante es que probablemente no desee hacer esto , ya que dará lugar a pruebas frágiles que ignoran el olor del código de salida duplicada, lo que a su vez conduce a falsos positivos que siguen funcionando cuando deberían haber fallado, porque eliminó uno elemento pero la prueba felizmente encontró el otro.

La mejor apuesta es usar within :

within(''#sidebar'') do find(''.selector).click end

Esto asegura que está encontrando el elemento que espera encontrar, mientras aprovecha las capacidades de espera automática y reintento automático de Capybara (que pierde si utiliza find(''.selector'').click ), y lo hace mucho más claro cuál es la intención.


Tal comportamiento de Capybara es intencional y creo que no debería ser corregido como se sugiere en la mayoría de las otras respuestas.

Las versiones de Capybara antes de 2.0 devolvieron el primer elemento en lugar de aumentar la excepción, pero luego los mantenedores de Capybara decidieron que era una mala idea y que es mejor plantearla. Se decidió que, en muchas situaciones, devolver el primer elemento conduce a no devolver el elemento que el desarrollador quería devolver.

La respuesta más votada aquí recomienda usar first o all lugar de find pero:

  1. all y first no espere hasta que el elemento con dicho localizador aparezca en la página, aunque find no espera
  2. all(...).first y first no lo protegerán de la situación que en el futuro, otro elemento con dicho localizador puede aparecer en la página y, como resultado, puede encontrar un elemento incorrecto

Por lo tanto, se recomienda elegir otro localizador menos ambiguo : por ejemplo, seleccionar elemento por id, clase u otro localizador css / xpath para que solo un elemento coincida.

Como nota aquí hay algunos localizadores que generalmente considero útiles para resolver la ambigüedad:

  • find(''ul > li:first-child'')

    Es más útil que el first(''ul > li'') ya que esperará hasta que aparezca el primer li en la página.

  • click_link(''Create Account'', match: :first)

    Es mejor que el first(:link, ''Create Account'').click en first(:link, ''Create Account'').click ya que esperará hasta que aparezca al menos un enlace Crear cuenta en la página. Sin embargo, creo que es mejor elegir un localizador único que no aparezca en la página dos veces.

  • fill_in(''Password'', with: ''secret'', exact: true)

    exact: true le dice a Capybara que busque solo coincidencias exactas, es decir, que no encuentre la "Confirmación de contraseña"