ruby-on-rails - rails - capybara testing example
¿Cómo puedo probar un diálogo de confirmación de Rails 4 con Capybara y Poltergeist? (5)
Dado este Javascript:
confirm(''You have unsaved changes, do you want to continue?'')
Para Poltergiest encontré lo siguiente para trabajar:
expect(page.driver.browser.modal_message).eq ''You have unsaved changes, do you want to contine?''
page.driver.browser.dismiss_confirm
page.driver.browser.accept_confirm
Estoy intentando probar que un enlace a una acción de destruir lanza un cuadro de confirm
navegador nativo con el mensaje correcto.
El enlace se está generando usando el enlace de rieles a:
link_to ''Delete'', user_path, method: :delete, data: { confirm: "Are you sure?" }
Y genera el siguiente html:
<a data-confirm="Are you sure?" data-method="delete" href="/users/6" rel="nofollow">Delete</a>
La funcionalidad funciona correctamente en el navegador, pero quiero probarla en mi especificación de función rspec
.
Estoy tratando de apagar la función de confirm
del navegador como se describe here y en esta esencia , sin embargo, no puedo hacer que funcione.
it ''requests confirmation'', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };"
click_link ''Delete''
expect(page.evaluate_script(''window.confirmMsg'')).to eq(''Are you sure?'')
end
Da el siguiente error de rspec
:
Failure/Error: expect(page.evaluate_script(''window.confirmMsg'')).to eq(''Are you sure?'')
expected: "Are you sure?"
got: nil
(compared using ==)
Sin embargo, si llamo a una confirm
directamente a través de page.execute_script
:
it ''requests confirmation'', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };
window.confirm(''Are you sure?'');"
expect(page.evaluate_script(''window.confirmMsg'')).to eq(''Are you sure?'')
end
Luego pasa la prueba.
También haciendo clic en el enlace Eliminar causará que la prueba falle, incluso si se ha llamado directamente a page.execute_script
para page.execute_script
:
it ''requests confirmation'', js: true do
visit user_path(user)
page.execute_script "
window.confirmMsg = null;
window.confirm = function(msg) { window.confirmMsg = msg; return true; };
window.confirm(''Are you sure?'');"
click_link ''Delete''
expect(page.evaluate_script(''window.confirmMsg'')).to eq(''Are you sure?'')
end
Da el mismo error desde rspec
:
Failure/Error: expect(page.evaluate_script(''window.confirmMsg'')).to eq(''Are you sure?'')
expected: "Are you sure?"
got: nil
(compared using ==)
¿Por qué está fallando la prueba? Y, ¿cómo puedo probar confirmar los diálogos correctamente?
Contexto:
Estoy ejecutando mis pruebas desde una máquina virtual Vagrant, que es Ubuntu 12.04.4 LTS
y ejecutando ruby 2.1.2p95
.
Mi Gemfile.lock
muestra que tengo las siguientes versiones:
rails (4.1.4)
poltergeist (1.5.1)
capybara (2.4.1)
Desafortunadamente, no puede hacer esto , porque Poltergeist trabaja solo en una ventana.
Para esa prueba específica necesitarás usar Selenium y esta API:
page.driver.browser.switch_to.alert.accept
Si está preocupado por querer ejecutar sus pruebas sin cabeza, puede usar Xvfb (X Virtual Framebuffer) de esta manera:
Xvfb :1 -screen 0 1024x768x24+32
Alternativamente también puedes usar capybara-webkit:
page.driver.browser.accept_js_confirms
page.driver.browser.reject_js_confirms
Sin embargo, he hecho la mejor experiencia usando una mezcla de (en su mayoría) Poltergeist y Selenium cuando sea necesario.
Es difícil probar el comportamiento de JavaScript. Pero si desea verificar el mensaje de confirmación, podría estar bien probar el atributo de enlace solo sin Poltergeist:
it ''requests confirmation'' do
visit user_path(user)
delete_link = find_link ''Delete'', href: user_path(user)
expect(delete_link[''data-confirm'']).to eq ''Are you sure?''
end
Aquí está la alternativa:
it ''requests confirmation'' do
visit user_path(user)
expect(page).to have_selector "a[data-confirm=''Are you sure?''][href=''#{user_path(user)}'']", text: ''Delete''
end
Esta prueba no puede verificar si JS está funcionando correctamente, pero podría ser suficiente para la mayoría de los casos. (¡Y rápido!)
Para expandir lo anterior, cuando use Selenium puede probar el texto real del diálogo de confirmación usando lo siguiente:
click_link ''Delete''
a = page.driver.browser.switch_to.alert
expect(a.text).to eq("Are you sure?")
a.accept
Además, acabo de encontrar una buena prueba para determinar si la alerta está presente aquí: selenio 2.4.0, cómo verificar la presencia de una alerta Lo modifiqué ligeramente, puse en mi archivo spec_helper como:
def alert_present?
begin
page.driver.browser.switch_to.alert
return true
rescue
return false
end
end
Y luego en tu prueba solo haz:
click_link ''Delete''
expect(alert_present?).to eq(true)
page.driver.browser.accept_js_confirms está en desuso. En lugar de usar
page.accept_confirm do
click_link ''Delete''
end