9

I am upgrading from rails 3.2.19 to rails 4.1.5, using rspec-rails 2.14.0.rc1 and capybara 2.4.1. All tests pass, and I only have one deprecation warning left:

[DEPRECATION] Capybara::Webkit::Driver#accept_js_confirms! is deprecated. Please use Capybara::Session#accept_confirm instead.

The line of code that is causing this is

page.driver.accept_js_confirms!

How do I change this line in order to eliminate the deprecation warning?

Obromios
  • 15,408
  • 15
  • 72
  • 127
  • page.driver.browser.accept_confirm ? – coorasse Oct 09 '14 at 12:25
  • Tried that myself as I'm having the same issue. It doesn't work. It does appear to recognize accept_modal(:confirm, options, &blk) but gives an argument error. Still looking for the answer myself. – Art Oct 10 '14 at 17:29

5 Answers5

11

Given that the exception says:

Please use Capybara::Session#accept_confirm instead.

You probably want:

page.accept_confirm

Note that accept_confirm is being run against the Capybara::Session instead of the driver.

This method expects a block that triggers the confirm alert to appear. For example:

page.accept_confirm do
  click_link('that_opens_confirm')
end
Justin Ko
  • 46,526
  • 5
  • 91
  • 101
  • That doesn't work, but you are right it's close to the right answer. It's looking for a block. I just don't understand how to pass it in. Here's the raw code for it. # Execute the block, accepting a confirm. # # @macro modal_params # def accept_confirm(text_or_options=nil, options={}, &blk) if text_or_options.is_a? Hash options=text_or_options else options[:text]=text_or_options end driver.accept_modal(:confirm, options, &blk) end – Art Oct 10 '14 at 19:13
  • Based on the [spec](https://github.com/jnicklas/capybara/blob/master/lib/capybara/spec/session/accept_confirm_spec.rb), the block is supposed to be the actions that trigger the confirmation to appear. – Justin Ko Oct 10 '14 at 19:29
  • That is helpful, but still can't quite place it. I'm using cucumber and have a prompt that pops up in the previous step under page.driver.console_messages.first. Switching to session by using page.accept_confirm should work but doesn't as I'm not passing something in. I'm still a noob though :) – Art Oct 10 '14 at 19:36
  • Actually, added the block like: page.accept_confirm do click_button('Ok) end but it doesn't work. Says can't find the ok button but I am staring at it so it is there. – Art Oct 10 '14 at 19:54
  • @Art, were you able to click the button before adding the `accept_confirm`? Is that OK button actually the button that triggers the confirm alert to *open*? The block is not supposed to be the button to close the alert. – Justin Ko Oct 10 '14 at 19:59
  • In the browser, physically, there's an "OK" button. I have tried click_link("OK") and click_button("OK") but both are not found. And, it did (and does) work with the accept_js_confirms! method. Also the method I put in earlier also works obviously. Just would like to see this successful so I feel like I did :). – Art Oct 10 '14 at 20:07
  • The button that triggers the alert is "Cancel my account" which pops up with the dialog box "Are you sure?" with an OK and Cancel option. I open that earlier and evaluate the popu up iwth page.driver.console_messages.first in the previous step. My guess is I should write these differently. I see the xpath expect in the spec so may play with that. – Art Oct 10 '14 at 20:16
6

Justin Ko's answer is correct as to the usage of #accept_confirm - it's

page.accept_confirm do
  #code that will trigger the modal
end

or you can do

page.accept_confirm 'Are you sure?' do
  #code that will trigger the modal
end

which will verify that "Are you sure?" is the prompt displayed in the confirm box.

In your failing test do you happen to be dealing with another modal first? capybara-webkit had a bug with multiple modals that was fixed a few days ago - https://github.com/thoughtbot/capybara-webkit/commit/86e422f94422d39e537329d64d7bfe8f6360bd8b . It's not in a relased version yet though.

Thomas Walpole
  • 48,548
  • 5
  • 64
  • 78
  • Yes, I had two modals. I separated them into two different scenarios and both tests passed. So all is good apart from the bug you cite. – Obromios Oct 15 '14 at 09:59
3

I had 50/50 success with Justin Ko's answer. The one that worked had code like this:

link_to "Reset", reset_pre_shot_description_mental_game_path(@mental_game), data: {confirm: 'Are you sure?'}, class: "small_button round", id: "reset_pre-shot"

and this test:

page.accept_confirm do
  click_link "Reset"
end

The test that fails (but has code that works in the browser) has code

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

and test

page.accept_confirm do
  click_link "Delete"
end

The failure message was

Failure/Error: page.accept_confirm do
Capybara::ModalNotFound:
  Timed out waiting for modal dialog

I tried moving the method: :delete into the :data hash, but this did not help.

It turns out that the deprecation warning actually found two bugs in the code, as I was using the rails 3 syntax for confirm i.e. not using the :data hash, so my code was broken but the page.driver.accept_js_confirms! test was not picking it up. So this has been worthwhile tracking down.

Obromios
  • 15,408
  • 15
  • 72
  • 127
  • As mentioned in response to user2209090's identification of a bug, there were two modals in the test, when I separated each into a different scenario, the 'Delete" test worked. So I now put Justin Ko's answer at 100% with the proviso in regard to the bug in user229090's answer. – Obromios Oct 15 '14 at 10:02
0

I replaced page.driver.accept_js_confirms! with:

page.execute_script('window.confirm = function() { return true }')

And the test passed.

This was from the documentation here: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#evaluate_script-instance_method

And help from the internets. Now, that doesn't still tell us how to use accept_confirm so I'm still looking for that answer.

The actual code looks like this:

# Execute the block, accepting a confirm.
#
# @macro modal_params
#
def accept_confirm(text_or_options=nil, options={}, &blk)
  if text_or_options.is_a? Hash
    options=text_or_options
  else
    options[:text]=text_or_options
  end

  driver.accept_modal(:confirm, options, &blk)
 end

Honestly, I think it's just page.accept_confirm with SOMETHING else, but I can't figure out what or passing in that block.

Art
  • 781
  • 4
  • 13
0

Works perfect for me:

page.execute_script('window.confirm = function() { return true }')
k1r8r0wn
  • 780
  • 9
  • 21