How to wait for and accept an alert box with capybara/selenium
Asked Answered
V

3

7

I'm using the following code in my rspec test:

describe "Save should create a BasketItem and a Basket" do
  subject { 
    lambda { 
      click_button I18n.t(:create_basket_and_add_items) 
      page.driver.browser.switch_to.alert.accept    # close the alert box
    } 
  }
  it { should change(BasketItem, :count).by(1) }
  it { should change(Basket,     :count).by(1) }
end

The click_button fires an unobtrusive javascript call, which displays an alert popup window. However closing the alert box is successfully only in about 50% of the test runs, I guess because the alert box is not always on the screen already at the time of the command page.driver.browser.switch_to.alert.accept is running. The next test case runs into "Timeout Error" of course, if the alert box is not closed.

It works always correctly if I'm using sleep 1 between click_button and ...alert.accept, but it is not a very nice solution. Any idea?

Vieira answered 18/2, 2014 at 10:30 Comment(0)
L
23

Here is some code that I've used for this.

wait = Selenium::WebDriver::Wait.new ignore: Selenium::WebDriver::Error::NoAlertPresentError
alert = wait.until { page.driver.browser.switch_to.alert }
alert.accept
Lunar answered 22/2, 2014 at 4:28 Comment(2)
For v4.5.0, I had to use wait = Selenium::WebDriver::Wait.new ignore: Selenium::WebDriver::Error::NoSuchAlertError Radioactivity
additionally you can control the length that Selenium will wait with the timeout: option, that defaults to 5 seconds rubydoc.info/gems/selenium-webdriver/Selenium/WebDriver/WaitOder
H
4
expect{
  accept_alert "Are you sure?" do
    click_link "Destroy"
  end
  sleep 1.second # !important
}.to change(Post, :count).by(-1)
Holly answered 14/11, 2015 at 18:41 Comment(0)
M
0

This is my solution, nothing else worked:

  scenario 'admin deletes user', js: true do
    within(confirmed_user_row) do
      expect {
        accept_confirm do
          click_link_or_button('Delete')
        end
        sleep(0.5) # or it checks too quick as entry in db not updated yet
      }.to change(User, :count).by(-1)
    end

    expect(page).to have_content("User was deleted from system.")
  end
Mallorca answered 8/6, 2022 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.