webentwicklung-frage-antwort-db.com.de

Wie kann ich einen Rails 4-Bestätigungsdialog mit Capybara und Poltergeist testen?

Ich versuche zu testen, ob ein Link zu einer Zerstörungsaktion eine confirm Box eines nativen Browsers mit der richtigen Meldung auslöst.

Der Link wird mit dem link_to von Rails generiert:

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

Und generiert das folgende HTML:

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

Die Funktionalität im Browser funktioniert ordnungsgemäß, ich möchte sie jedoch in meiner rspec-Feature-Spezifikation testen.

Ich versuche, die confirm-Funktion des Browsers wie in hier und in diesem Gist beschrieben zu testen, aber ich kann sie nicht zum Laufen bringen.

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

Gibt den folgenden Fehler von rspec aus:

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

       expected: "Are you sure?"
            got: nil

       (compared using ==)

Wenn ich jedoch eine confirm direkt über page.execute_script aufrufe:

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

Dann ist der Test bestanden.

Wenn Sie auch auf den Link Löschen klicken, schlägt der Test fehl, auch wenn confirm direkt für page.execute_script aufgerufen wurde:

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

Gibt den gleichen Fehler aus rspec:

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

       expected: "Are you sure?"
            got: nil

       (compared using ==)

Warum schlägt der Test fehl? Und wie kann ich Bestätigungsdialoge richtig testen?


Kontext:

Ich führe meine Tests von einer virtuellen Vagrant-Maschine aus, die Ubuntu 12.04.4 LTS ist und Ruby 2.1.2p95 ausführt.

Mein Gemfile.lock zeigt, dass ich die folgenden Versionen habe:

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

page.driver.browser.accept_js_confirms ist veraltet. Verwenden Sie stattdessen

page.accept_confirm do
  click_link 'Delete'
end
26
Obromios

Leider können Sie dies nicht tun , da Poltergeist nur in einem Fenster funktioniert.

Für diesen speziellen Test müssen Sie Selen und diese API verwenden:

page.driver.browser.switch_to.alert.accept

Wenn Sie keine Lust haben, Ihre Tests kopflos auszuführen, können Sie Xvfb (X Virtual Framebuffer) folgendermaßen verwenden:

Xvfb :1 -screen 0 1024x768x24+32

Alternativ können Sie auch das Capybara-Webkit verwenden:

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

Die besten Erfahrungen habe ich jedoch mit einer Mischung aus (meistens) Poltergeist und Selen gemacht, wo dies erforderlich ist.

6
Munen

Wenn Sie Selenium verwenden, können Sie den tatsächlichen Text des Bestätigungsdialogs folgendermaßen testen:

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

Ich habe gerade einen guten Test gefunden, um festzustellen, ob die Warnung hier vorhanden ist: Selen 2.4.0, wie das Vorhandensein einer Warnung überprüft wird Ich habe sie geringfügig geändert und in meine spec_helper-Datei Folgendes eingefügt:

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

Und dann machen Sie in Ihrem Test einfach:

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

Mit diesem Javascript:

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

Für Poltergiest habe ich folgendes gefunden:

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

Es ist schwierig, das JavaScript-Verhalten zu testen. Wenn Sie die Bestätigungsnachricht überprüfen möchten, ist es möglicherweise in Ordnung, das Linkattribut nur ohne Poltergeist zu testen:

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

Hier ist die 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

Dieser Test kann nicht überprüfen, ob JS ordnungsgemäß funktioniert, aber in den meisten Fällen ist er ausreichend. (Und schnell!)

0
Junichi Ito