From a09bb5d40a1bff26f1a66ce85a55f7f5c0cbfaab Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Fri, 9 Jun 2017 11:28:47 -0700 Subject: [PATCH] Fix headless chrome modals when page changes --- lib/capybara/selenium/driver.rb | 9 +++++++-- lib/capybara/spec/public/test.js | 4 ++++ lib/capybara/spec/session/accept_alert_spec.rb | 8 ++++++++ lib/capybara/spec/views/with_js.erb | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 75c791f0..abe91db5 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -368,6 +368,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base prompt: window.prompt, confirm: window.confirm, alert: window.alert, + called: false } window.capybara.add_handler(modal_handler); @@ -420,15 +421,19 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base ignore: Selenium::WebDriver::Error::NoAlertPresentError) begin wait.until do - called, alert_text = evaluate_script('window.capybara.current_modal_status()') + called, alert_text = evaluate_script('window.capybara && window.capybara.current_modal_status()') if called - execute_script('window.capybara.modal_handlers.shift()') + execute_script('window.capybara && window.capybara.modal_handlers.shift()') regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s) if alert_text.match(regexp) alert_text else raise Capybara::ModalNotFound.new("Unable to find modal dialog#{" with #{options[:text]}" if options[:text]}") end + elsif called.nil? + # page changed so modal_handler data has gone away + warn "Can't verify modal text when page change occurs - ignoring" if options[:text] + "" else nil end diff --git a/lib/capybara/spec/public/test.js b/lib/capybara/spec/public/test.js index 76ed334e..5080fd99 100644 --- a/lib/capybara/spec/public/test.js +++ b/lib/capybara/spec/public/test.js @@ -87,6 +87,10 @@ $(function() { $(link).attr('opened', 'true'); }, 3000); }); + $('#alert-page-change').click(function() { + alert('Page is changing'); + return true; + }); $('#open-confirm').click(function() { if(confirm('Confirm opened')) { $(this).attr('confirmed', 'true'); diff --git a/lib/capybara/spec/session/accept_alert_spec.rb b/lib/capybara/spec/session/accept_alert_spec.rb index b8263cd2..0e504b22 100644 --- a/lib/capybara/spec/session/accept_alert_spec.rb +++ b/lib/capybara/spec/session/accept_alert_spec.rb @@ -47,6 +47,14 @@ Capybara::SpecHelper.spec '#accept_alert', requires: [:modals] do expect(message).to eq('Alert opened [*Yay?*]') end + it "should handle the alert if the page changes" do + @session.accept_alert do + @session.click_link('Alert page change') + sleep 1 # ensure page change occurs before the accept_alert block exits + end + expect(@session).to have_current_path('/with_html') + end + context "with an asynchronous alert" do it "should accept the alert" do @session.accept_alert do diff --git a/lib/capybara/spec/views/with_js.erb b/lib/capybara/spec/views/with_js.erb index 98877be3..7de24afe 100644 --- a/lib/capybara/spec/views/with_js.erb +++ b/lib/capybara/spec/views/with_js.erb @@ -76,6 +76,7 @@

Open alert + Alert page change