web-dev-qa-db-fra.com

Comment tester un dialogue de confirmation Rails 4 avec Capybara et Poltergeist?

J'essaie de tester qu'un lien vers une action de destruction jette une boîte confirm de navigateur natif avec le message correct.

Le lien est généré à l'aide de link_to:

link_to 'Delete', user_path, method: :delete, data: { confirm: "Are you sure?" }

Et génère le code HTML suivant:

<a data-confirm="Are you sure?" data-method="delete" href="/users/6" rel="nofollow">Delete</a>

La fonctionnalité fonctionne correctement dans le navigateur, mais je souhaite la tester dans ma spécification de fonctionnalité rspec.

J'essaie de masquer la fonction confirm du navigateur, comme décrit ici et dans ce Gist , mais je n'arrive pas à le faire fonctionner.

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

Donne l'erreur suivante de rspec:

Failure/Error: expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')

       expected: "Are you sure?"
            got: nil

       (compared using ==)

Cependant, si j'appelle une confirm directement via 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

Ensuite, le test réussit.

Si vous cliquez également sur le lien Supprimer, le test échouera, même si confirm a été appelé directement pour 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

Donne la même erreur de rspec:

Failure/Error: expect(page.evaluate_script('window.confirmMsg')).to eq('Are you sure?')

       expected: "Are you sure?"
            got: nil

       (compared using ==)

Pourquoi le test échoue-t-il? Et comment puis-je tester les dialogues de confirmation correctement?


Contexte:

J'exécute mes tests à partir d'une machine virtuelle Vagrant, qui s'appelle Ubuntu 12.04.4 LTS et exécute Ruby 2.1.2p95.

Mon Gemfile.lock indique que j'ai les versions suivantes:

Rails (4.1.4)
poltergeist (1.5.1)
capybara (2.4.1)
16
tommarshall

page.driver.browser.accept_js_confirms est obsolète. Utilisez plutôt

page.accept_confirm do
  click_link 'Delete'
end
26
Obromios

Malheureusement, vous ne pouvez pas faire cela , car Poltergeist ne fonctionne que dans une seule fenêtre.

Pour ce test spécifique, vous devrez utiliser Selenium et cette API:

page.driver.browser.switch_to.alert.accept

Si vous souhaitez exécuter vos tests sans tête, vous pouvez utiliser Xvfb (X Virtual Framebuffer) comme ceci:

Xvfb :1 -screen 0 1024x768x24+32

Sinon, vous pouvez aussi utiliser capybara-webkit:

page.driver.browser.accept_js_confirms
page.driver.browser.reject_js_confirms

Cependant, j'ai fait la meilleure expérience en utilisant un mélange de Poltergeist (principalement) et de Sélénium si nécessaire.

6
Munen

Pour développer ce qui précède, lorsque vous utilisez Selenium, vous pouvez tester le texte réel de la boîte de dialogue de confirmation en utilisant les éléments suivants:

    click_link 'Delete'
    a = page.driver.browser.switch_to.alert
    expect(a.text).to eq("Are you sure?")
    a.accept

En outre, je viens de trouver un bon test pour savoir si l'alerte est présente ici: Selenium 2.4.0, comment vérifier la présence d'une alerte je l'ai légèrement modifié, mis dans mon fichier spec_helper de la manière suivante:

def alert_present?
  begin
    page.driver.browser.switch_to.alert
    return true
  rescue
    return false
  end
end

Et dans votre test, faites simplement:

click_link 'Delete'
expect(alert_present?).to eq(true)
1
mahi-man

Compte tenu de ce Javascript:

confirm('You have unsaved changes, do you want to continue?')

Pour Poltergiest j'ai trouvé ce qui suit fonctionner:

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

Il est difficile de tester le comportement de JavaScript. Mais si vous voulez vérifier le message de confirmation, vous pouvez peut-être tester l'attribut link uniquement sans 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

Voici l'alternative:

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

Ce test ne peut pas vérifier si JS fonctionne correctement, mais il peut suffire dans la plupart des cas. (Et vite!)

0
Junichi Ito