How do I confirm a javascript popup with Capybara?
Asked Answered
A

8

83

I've tried several examples found online, but with no luck. I am looking to confirm the confirm message of a delete link. The last attempt was the code below, but that resulted in an Capybara::NotSupportedByDriverError error.

def confirm_dialog
  page.evaluate_script('window.confirm = function() { return true; }')
end
Arteriovenous answered 3/8, 2011 at 17:55 Comment(2)
possible duplicate of How to test a confirm dialog with Cucumber?. The accepted answer's author agrees with duplicate.Wat
See my answer here for the newer way to do this: https://mcmap.net/q/244091/-rspec-capybara-how-to-click-on-alert-boxSniperscope
C
89

Adding an answer for those hitting this in 2016 and beyond. You can now use Capybara directly to accept a confirmation box. You do this by wrapping the code that causes the confirmation box to appear in the accept_confirm function.

accept_confirm do
  click_link 'Destroy'
end
Christie answered 20/7, 2016 at 18:50 Comment(2)
In addition to wrapping your action in a block like this, for me simply calling accept_confirm after the action which caused the confirmation dialog also successfully proceeded past it.Corneliacornelian
Good to know: accept_confirm implicitly asserts that the confirmation dialog pops up.Detrimental
T
57

First of all switch to using Selenium as the driver by putting an @javascript tag in front of your scenario.

The following code in your cucumber step will then confirm the dialogue:

page.driver.browser.switch_to.alert.accept
# or
page.driver.browser.switch_to.alert.dismiss
# or
page.driver.browser.switch_to.alert.text

As @NobbZ said, this question has been asked and answered before here: How to test a confirm dialog with Cucumber?.

More selenium documentation available here too: http://code.google.com/p/selenium/wiki/RubyBindings#JavaScript_dialogs

Twister answered 3/8, 2011 at 18:29 Comment(5)
undefined method `switch_to' for #<Capybara::RackTest::Browser:0x007ffca8a79890>Cheese
I got that undefined method error and then discovered that I didn't need the switch_to call at all because selenium (I think) is automatically returning true on any confirms. That won't help everyone, but might help some.Ceramic
@DimaGoltsman You're using RackTest. the answer refers to the selenium driver. You need to set the driver before the test is run by Capybara.current_driver = :selenium or else add js: true to the example which should set the driver to :selenium by default as it is the default Capybara.javascript_driverMorbid
Works with Capybara using selenium driver in Rails. ThanksExcrescence
I tried to use page.driver.browser.switch_to but got a DEPRECATION warning but was brought to this: #26275859Fervency
S
16

for capybara-webkit:

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

which is still working, but the documentation says also:

page.driver.accept_js_confirms!
page.driver.accept_js_confirms!

See https://github.com/thoughtbot/capybara-webkit , search "accept_js_confirms"

Sanfordsanfourd answered 20/4, 2013 at 15:13 Comment(3)
It worked for me with page.driver.accept_js_confirms! (indeed from github.com/thoughtbot/capybara-webkit)Dutra
currently this line works for capybara: page.driver.browser.switch_to.alert.acceptMalena
Looks like your one of those should be page.driver.reject_js_confirms!Christie
S
10

I've had timing issues with browser dialogs in a CI environment so I'm polling for a dialog before accepting it:

def accept_browser_dialog
  wait = Selenium::WebDriver::Wait.new(:timeout => 30)
  wait.until {
    begin
      page.driver.browser.switch_to.alert
      true
    rescue Selenium::WebDriver::Error::NoAlertPresentError
      false
    end
  }
  page.driver.browser.switch_to.alert.accept
end
Schoenberg answered 11/9, 2013 at 12:26 Comment(0)
R
6

I had to use a sleep in the webkit test since it would fail everynow and then otherwise.

Here is what I came up with after reading everyones posts:

if page.driver.class == Capybara::Selenium::Driver
  page.driver.browser.switch_to.alert.accept
elsif page.driver.class == Capybara::Webkit::Driver
  sleep 1 # prevent test from failing by waiting for popup
  page.driver.browser.accept_js_confirms
else
  raise "Unsupported driver"
end
Rufinaruford answered 1/8, 2013 at 23:39 Comment(1)
Yep, just be really careful not to add too many of those, it makes your tests really expensive to run (i.e. they will take longer because of the sleeps)Rufinaruford
B
3

try to add :js => true to your test.

RSpec’s metadata feature can be used to switch to a different driver. Use :js => true to switch to the javascript driver, or provide a :driver option to switch to one specific driver. For example:

it 'will use the default js driver' :js => true do
  ...
end
Bungle answered 3/8, 2011 at 18:8 Comment(0)
B
3

In Capybara its very simple to accept the model window. Even we can do the same in selenium but its little tough for people who are not aware about selenium.

page.accept_modal #This will accept the modal window

page.dismiss_modal #This will Reject/Dismiss the modal window

Benignant answered 4/4, 2017 at 13:22 Comment(1)
This returns me NoMethodError: private method 'accept_modal' called for #<Capybara::Session>Mcnary
D
2

I would guess that you have to add selenium to your gem-file and configure it and capybara that capybara uses selenium as the driver.

I think also that How to test a confirm dialog with Cucumber? is very similar to your question, especially the accepted answer.

Dacosta answered 3/8, 2011 at 18:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.