How can I test a rails 4 confirm dialog with Capybara and Poltergeist?

tommarshall picture tommarshall · Aug 13, 2014 · Viewed 13.4k times · Source

I'm trying to test that a link to a destroy action throws a native browser confirm box with the correct message.

The link is being generated using rails' link_to:

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

And generates the following html:

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

The functionality is working correctly in the browser, but I want to test for it in my rspec feature spec.

I'm trying to stub out the browser's confirm function as described here and in this gist, however I can't get it to work.

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

Gives the following error from rspec:

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

       expected: "Are you sure?"
            got: nil

       (compared using ==)

However, if I call a confirm directly 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

Then the test passes.

Also clicking the Delete link will cause the test to fail, even if confirm has been called directly for 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

Gives the same error from rspec:

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

       expected: "Are you sure?"
            got: nil

       (compared using ==)

Why is the test failing? And, how can I test confirm dialogues correctly?


Context:

I'm running my tests from a Vagrant virtual machine, which is Ubuntu 12.04.4 LTS and running ruby 2.1.2p95.

My Gemfile.lock shows that I have the following versions:

rails (4.1.4)
poltergeist (1.5.1)
capybara (2.4.1)

Answer

Obromios picture Obromios · Jan 19, 2016

page.driver.browser.accept_js_confirms is deprecated. Instead use

page.accept_confirm do
  click_link 'Delete'
end