¿Cómo puedo resolver la ambigüedad en el Capibara? Por alguna razón necesito vínculos con los mismos valores en una página pero no puedo crear una prueba ya que me da el error

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

La razón por la que no se puede evitar esto es porque el diseño. Estoy tratando de recrear la página de twitter con tweets/etiquetas de la derecha y las etiquetas de la izquierda de la página. Por lo tanto, será inevitable que idéntico enlaces de la página se muestra en la misma página.

  • Puede usted por favor enviar el código también?
  • Usted no debe asignar el mismo número de identificación de dos elementos en la página. Si usted va a tener la misma enlaces, entonces no se le asigna un id de los elementos, el uso de una clase en su lugar.
  • Es un hashtag.
InformationsquelleAutor neilmarion | 2012-10-30

9 Comentarios

  1. 143

    Mi solución es

    first(:link, link).click

    lugar de

    click_link(link)
    • Esto se detalla en el Carpincho Guía de Actualización usted puede encontrar útil si usted tenía este problema.
    • Como de Carpincho 2.0 no haga esto a menos que sea absolutamente necesario. Ver a @Andrey de respuesta y la explicación de la Ambigua Partidos en la guía de actualización vinculado anteriormente.
    • Específicamente, el Chigüire 2.0 ha inteligente de espera lógica para asegurar que las especificaciones de pasa o falla constantemente a través de máquinas de diferentes velocidades de procesamiento, mientras que sólo espera el mínimo tiempo necesario. El uso de first como se sugirió anteriormente, a menos que sea absolutamente sabes lo que estás haciendo, es probable que el resultado en las especificaciones que pasar para usted, pero no en un CI de construir o de un colega de la máquina.
    • Para una buena discusión, véase: robots.thoughtbot.com/…
  2. 72

    Este tipo de comportamiento de Carpincho es intencional y creo que no debería ser fijo, como se sugiere en la mayoría de las otras respuestas.

    Versiones de Carpincho antes 2.0 devuelve el primer elemento en vez de levantar la excepción, pero más tarde los mantenedores de Carpincho decidido que es una mala idea y es mejor que subir. Se decidió que en muchas situaciones de devolver el primer elemento conduce a la devolución no es el elemento que el desarrollador quería ser devueltos.

    La mayoría de los upvoted respuesta aquí recomendamos el uso de first o all en lugar de find pero:

    1. all y first no espere hasta el elemento con localizador aparecerá en la página aunque find hace esperar
    2. all(...).first y first no protegen a usted de la situación que en el futuro otro elemento con el localizador puede aparecer en la página y como resultado usted puede encontrar incorrecto elemento

    Así es recomendable elegir otra, menos ambiguo localizador de: por ejemplo, seleccione el elemento de identificación, u otra clase css/xpath localizador de modo que sólo uno de los elementos va a coincidir.


    Como una nota aquí están algunos de los localizadores que me suele considerar útil cuando la resolución de la ambigüedad:

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

      Es más útil que first('ul > li') como se va a esperar hasta la primera li aparecerá en la página.

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

      Es mejor que first(:link, 'Create Account').click como se va a esperar por lo menos hasta Crear una Cuenta de enlace aparecerá en la página. Sin embargo creo que es mejor elegir el único localizador de que no aparezca en la página dos veces.

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

      exact: true dice Carpincho sólo encontrar coincidencias exactas, es decir, no encontrar «Confirmación de Contraseña»

    • Esta debe ser la respuesta. Siempre trate de usar un selector que va a hacer uso de la incorporada en las salas de espera de las capacidades de Carpincho.
    • Gracias. Traté de uso :en primer lugar, pero se dio cuenta de que sólo funciona en jQuery. Lo que yo estaba buscando es :primer hijo
  3. 23

    NUEVA RESPUESTA:

    Usted puede tratar de algo como

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

    Puede ser una manera de hacer esto que hace un mejor uso de los disponibles Carpincho sintaxis — algo a lo largo de las líneas de all("a[text='#tag1']").first.click pero no puedo pensar en la sintaxis correcta de la mano y no puedo encontrar la documentación adecuada. Que dijo que es un poco de una situación extraña para empezar, el hecho de tener dos <a> etiquetas con el mismo id, class, y texto. ¿Hay alguna posibilidad de que ellos son los niños de diferentes divs, desde luego, puede hacer su find within el correspondiente segmento de la DOM. (Sería de gran ayuda para ver un poco de su código HTML).


    RESPUESTA anterior: (donde yo pensaba ‘#tag1 » significó el elemento tenía un id de «tag1»)

    Que de los enlaces que hacer clic en? Si es la primera (o no importa), usted puede hacer

    find('#tag1').click

    De lo contrario usted puede hacer

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

    a haga clic en el segundo.

    • Que la solución en la primera de ellas podría ser el trabajo, pero el problema ahora es que quizás es confundido con un css id ——— Fallo/Error: find(‘#tag1’).haga clic en # o de todos(‘#tag1’)[0].haga clic en el Capibara::ElementNotFound: no se puede encontrar css «#tag1»
    • find('#tag1') significa que usted quiere encontrar un solo elemento con id tag1. Excepción, ya que hay varios elementos con id tag1 en la página
    • Usted puede hacer all(:xpath, '//a[text()="#tag1"]').first.click.
  4. 9

    Usted puede asegurarse de que usted encuentre el primero mediante match:

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

    Pero lo más importante, usted probablemente no quiere hacer este, ya que conducirá a frágiles pruebas que están haciendo caso omiso de los duplicados de código de salida de olor, que a su vez conduce a falsos positivos que seguir trabajando cuando deberían haber fallado, porque te quita un elemento coincidente, pero la prueba felizmente encontré el otro.

    La mejor apuesta es usar within:

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

    Esto se asegura de que usted está encontrando el elemento que espera encontrar, mientras que todavía el aprovechamiento de la auto-esperar y auto-retry capacidades de Carpincho (que se pierde si utiliza find('.selector').click), y esto hace que sea mucho más claro lo que la intención es.

  5. 6

    A añadir a los ya existentes cuerpo de conocimiento aquí:

    Para JS pruebas, Carpincho tiene que mantener a dos hilos (uno para RSpec, uno de los Rails) y un segundo proceso (el navegador) en la sincronización. Esto se hace por la espera (hasta el máximo configurado el tiempo de espera) en la mayoría de los dispositivos de comparación y nodo-búsqueda de métodos.

    Carpincho también tiene métodos que no espere, principalmente Node#all. Con ellos es como decirle a tus especificaciones que le gustaría a fallar intermitentemente.

    La aceptada respuesta sugiere page.first('selector'). Esto no es deseable, al menos para JS especificaciones, porque Nodo#primera usos Nodo#todos.

    Que dijo, Node#first se esperar si configura Carpincho así:

    # rails_helper.rb
    Capybara.wait_on_first_by_default = true

    Esta opción fue añadido en Capybara 2.5.0 y es false de forma predeterminada.

    Como Andrei mencionado, usted debería utilizar en su lugar

    find('selector', match: :first)

    o cambiar su selector. Tampoco te va a funcionar bien, independientemente de config o controlador.

    Para complicar aún más las cosas, en versiones antiguas de Carpincho (o con una opción de configuración habilitado), #find estará feliz de ignorar la ambigüedad y acabo de volver de la primera coincidencia de selector. Este no es muy grande, ya que hace que sus especificaciones menos explícita, que me imagino que es por eso que ya no es el comportamiento predeterminado. Voy a dejar fuera de las especificaciones debido a que han sido discutidos anteriormente ya.

    Más recursos:

  6. 5

    Debido a este post, se puede solucionar a través de la «coincidencia» de la opción:

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

    Como la consideración de todas las opciones anteriores, usted puede tratar de esto también

    find("a", text: text, match: :prefer_exact).click

    Si usted está utilizando el pepino, usted puede seguir esta demasiado

    Se puede pasar el texto como un parámetro a partir de los pasos del escenario, que puede ser genérica paso a la reutilización de nuevo

    Algo como When a user clicks on "text" link

    Y en el paso de definición de When(/^(?:user) clicks on "([^"]*)" (?:link)$/) do |text|

    De esta manera, se puede reutilizar el mismo paso a minimizar las líneas de código y sería fácil escribir el nuevo pepino de escenarios

  8. 0

    Para evitar el error ambiguos en pepino.

    Solución 1

    first("#tag1").click

    Solución 2

    Cucumber features/filename.feature --guess

Dejar respuesta

Please enter your comment!
Please enter your name here