Skip to content

Instantly share code, notes, and snippets.

@michaelglass
Last active September 24, 2019 10:15
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save michaelglass/8610317 to your computer and use it in GitHub Desktop.
Save michaelglass/8610317 to your computer and use it in GitHub Desktop.
test alerts & confirms in poltergeist & capybara webkit
module AlertConfirmer
class << self
def reject_confirm_from &block
handle_js_modal 'confirm', false, &block
end
def accept_confirm_from &block
handle_js_modal 'confirm', true, &block
end
def accept_alert_from &block
handle_js_modal 'alert', true, &block
end
def get_alert_text_from &block
handle_js_modal 'alert', true, true, &block
get_modal_text 'alert'
end
def get_modal_text(name)
page.evaluate_script "window.#{name}Msg;"
end
private
def handle_js_modal name, return_val, wait_for_call = false, &block
modal_called = "window.#{name}.called"
page.execute_script "
window.original_#{name}_function = window.#{name};
window.#{name} = function(msg) { window.#{name}Msg = msg; window.#{name}.called = true; return #{!!return_val}; };
#{modal_called} = false;
window.#{name}Msg = null;"
block.call
if wait_for_call
timed_out = false
timeout_after = Time.now + Capybara.default_wait_time
loop do
if page.evaluate_script(modal_called).nil?
raise 'appears that page has changed since this method has been called, please assert on page before calling this'
end
break if page.evaluate_script(modal_called) ||
(timed_out = Time.now > timeout_after)
sleep 0.001
end
raise "#{name} should have been called" if timed_out
end
ensure
page.execute_script "window.#{name} = window.original_#{name}_function"
end
end
end
# this should catch the following alert
#
# <button onclick="alert('totally alerted')">make an alert happen!</button>
#
AlertConfirmer.get_alert_text_from do
click_buttton 'make an alert happen!'
end.should == 'totally alerted'
@marnen
Copy link

marnen commented Jul 3, 2014

Copy link

ghost commented Aug 12, 2014

undefined local variable or method page' for AlertConfirmer:Module # ./spec/support/alerts_and_confirms.rb:52:inensure in handle_js_modal'

@andyt
Copy link

andyt commented Oct 21, 2014

You can either pull this module into somewhere, or add an "include Capybara::DSL" after L2

@abevoelker
Copy link

Thanks @michaelglass for the awesome hack to work around Poltergeist's glaring deficiency here!

@tesserakt I deleted the class << self block and saved the file as spec/support/alert_confirmer.rb. Then I told RSpec to load it like so:

RSpec.configure do |config|
  config.include AlertConfirmer, type: :feature
end

and now I can use the helper methods directly in my feature specs (i.e. accept_confirm_from do ... end instead of AlertConfirmer.get_alert_text_from do ... end).

@fgcui1204
Copy link

fgcui1204 commented May 11, 2016

@abevoelker I used this moudle like you

 accept_confirm_from do
      click_buttton 'confirm'
    end

but when I run this test. there is a error:

 NoMethodError:
       undefined method `click_buttton' for #<RSpec::ExampleGroups::FindRoom:0x007fe7bb97e960>

@Jbur43
Copy link

Jbur43 commented May 27, 2016

@fgcui1204 I was getting the same error. I had to include the alerts_and_confirms.rb file in my support folder and remove the class << block. Then I could use accept_alert_from do...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment