es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo hacer que RSpec y Capybara esperen el tiempo suficiente para que ActionCable se complete?

Rails 6 con ActionCable
Rspec 3.10
Capybara 3.36

  1. Los usuarios visitan edit_inventory_path @inventory y ven una colección de Counts.
  2. Hacer clic en un recuento desencadena una llamada AJAX para poblar un modal con el formulario _form de recuento.
  3. Completar el formulario y hacer clic en Enviar desencadena:
    ruby
    CountsChannel.broadcast_to(
    @inventory,
    {
    count_id: @count.id,
    html_slug: render_to_string(partial: 'counts/count', collection: @inventory.counts.sort_by { |c| [c.sort_by_status, - c.item.name] }),
    uncounted: "#{view_context.pluralize(@inventory.counts.uncounted.size, 'item')} uncounted."
    }
    )

Esto reemplaza todos los divs de conteo en la página. El recuento recién enviado se ordena en la parte inferior de la página y el texto del botón cambia.

Mi prueba espera que el texto del botón cambie de “Count” a “Edit”.

RSpec.describe 'Realización de un inventario', type: :system do
  ...
  context 'cuando se envía un recuento' do
  ...
it 'cambia el texto del botón de conteo' do
  # asegurarse de que la página esté cargada
  expect(page).to have_content "Edit #{inventory.name}"

  # hacer clic en el botón abre un modal.
  # AJAX coloca el formulario de edición de conteo en el modal antes de que se abra
  find("div#count_#{Count.first.id} a.count-btn").click
  # esperar para asegurarse de que el modal está abierto
  find('input#count_unopened_boxes_count')

  fill_in 'count_unopened_boxes_count', with: 5
  click_button('Submit')
  Rails.logger.debug 'HEYA acabo de presionar el botón de enviar.'
  # hacer clic en el botón cierra y borra el modal
  # y los datos del formulario de AJAXs a CountsController#update
  # que desencadena la transmisión de ActionCable

  # AQUÍ: find('el botón', wait: 5) no hace nada
  # porque el antiguo div todavía está en la página
  # así que Capybara lo encuentra de inmediato
  # wait es un tiempo máximo de espera, no un valor absoluto
  count_1_btn_text = find("div#count_#{Count.first.id} a.count-btn").text
  Rails.logger.debug 'HEYA encontró el botón.'

  Rails.logger.debug 'HEYA esperando que ActionCable esté completo.'
  expect(count_1_btn_text).to eq 'Loose Count'


  # algún tiempo después, el texto del botón realmente cambia
end
end
end

Sé que es un problema de sincronización cuando consulto test.log:
“`ruby

Start de GET “/inventories/1/edit” para 127.0.0.1 en 2021-11-29 12:51:05 -0500

Procesamiento por InventoriesController#edit como HTML
Parámetros: {“id”=>”1”}

Renderizado el diseño layouts/application.haml
Renderizado inventories/edit.haml dentro de layouts/application

Renderizado la colección de conteo/conteo.haml [11 veces] (Duración: 53,0ms | Asignaciones: 26025)

Completado 200 OK en 10635ms (Vistas: 10574,2ms | ActiveRecord: 15,7ms | Asignaciones: 645565)

Inicio de GET “/assets/channels/consumer-ddc23d99c3f3572746769fa1851baebf4ef5d005651f6ac89f0739c1682a80bc.js” para 127.0.0.1 en 2021-11-29 12:51:15 -0500
Inicio de GET “/assets/channels/counts
channel-6e2c07931c38a8f979370ee55ad4ca4783da4a2def12996ad4efe6f213d4fb78.js” para 127.0.0.1 en 2021-11-29 12:51:16 -0500
Inicio de GET “/cable” para 127.0.0.1 en 2021-11-29 12:51:16 -0500
Inicio de GET “/cable/” [WebSocket] para 127.0.0.1 en 2021-11-29 12:51:16 -0500
Subida con éxito a WebSocket (MÉTODODE PETICIÓN: GET, HTTPCONEXIÓN: Upgrade, HTTPUPGRADE: websocket)
User Load (0.6ms) SELECT “users”.* FROM “users” WHERE “users”.”id” = 1 ORDER BY “users”.”id” ASC LIMIT 1
La conexión registrada (Z2lkOi8vYnVpbGQtcGxhbm5lci9Vc2VyLzE)

Inventory Load (44.2ms) SELECT “inventories”.* FROM “inventories” WHERE “inventories”.”id” = 1 LIMIT 1
CountsChannel está transmitiendo la confirmación de la suscripción
CountsChannel se está transmitiendo desde counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ


Renderizado counts/edit.haml (Duración: 48,7ms | Asignaciones: 28122)
Renderizado counts/edit.js.erb (Duración: 50,3ms | Asignaciones: 28697)
Completado 200 OK en 66ms (Vistas: 56,2ms | ActiveRecord: 3,4ms | Asignaciones: 34258)

HEYA acabó de presionar el botón de enviar.


Inicio de PATCH “/inventories/1/counts/1” para 127.0.0.1 en 2021-11-29 12:51:17 -0500
Procesamiento por CountsController#update como JS
Parámetros: {“count”=>{“loosecount”=>”0″, “unopenedboxescount”=>”5″}, “partialbox”=>”Submit Box Count”, “inventory_id”=>”1”, “id”=>”1”}

HEYA encontró el botón.

HEYA esperando que ActionCable esté completo.

… 49 líneas después …
[ActionCable] Transmitiendo a counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ: {:countid=>1, :htmlslug=>”…cadena realmente larga…”, :uncounted=>”11 elementos sin contar.”}
Se está renderizando counts/update.js.erb
CountsChannel transmitiendo {“countid”=>1, “htmlslug”=>”…cadena realmente larga… (vía transmitida desde counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ)
Se está renderizado counts/update.js.erb (Duración: 41,1ms | Asignaciones: 674)
Completado 200 OK en 344ms (Vistas: 56.4ms | ActiveRecord: 123.9ms | Asignaciones:

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una opción es utilizar la opción wait incorporada en Capybara, que esperará un cierto período de tiempo antes de informar un error si no aparece un elemento. Esto se puede usar junto con find u otros métodos de Capybara. Por ejemplo, find('#my-element', wait: 3) esperará 3 segundos para que aparezca un elemento con el ID my-element antes de informar un error si no lo hace.

    Otra opción es utilizar el método eventually del paquete rspec-retry. Este método ejecuta repetidamente un bloque de código hasta que tenga éxito o alcance un timeout. Por ejemplo, eventually { expect(page).to have_content('Success!') } ejecutará expect(page).to have_content('Success!') repetidamente hasta que tenga éxito o hasta que se alcance el timeout especificado.

    Es importante equilibrar el tiempo de espera con la confiabilidad de la suite de pruebas. Esperar demasiado tiempo puede ralentizar las pruebas y generar resultados falsos positivos, mientras que no esperar lo suficiente puede hacer que las pruebas fallen de manera intermitente.

Comments are closed.