diff --git a/README.md b/README.md index d864474..c87ba9e 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,9 @@ Capybara::Webkit.configure do |config| user: "proxy", pass: "secret" ) + + # Raise JavaScript errors as exceptions + config.raise_javascript_errors = true end ``` diff --git a/lib/capybara/webkit/browser.rb b/lib/capybara/webkit/browser.rb index 9aab4b5..e2c966e 100644 --- a/lib/capybara/webkit/browser.rb +++ b/lib/capybara/webkit/browser.rb @@ -5,6 +5,7 @@ module Capybara::Webkit class Browser def initialize(connection) @connection = connection + apply_defaults end def authenticate(username, password) @@ -36,6 +37,7 @@ module Capybara::Webkit end def reset! + apply_defaults command("Reset") end @@ -99,6 +101,14 @@ module Capybara::Webkit command("SetSkipImageLoading", skip_image_loading) end + def set_raise_javascript_errors(is_enabled) + @raise_javascript_errors = is_enabled + end + + def raise_javascript_errors? + @raise_javascript_errors + end + def window_focus(selector) command("WindowFocus", selector) end @@ -209,7 +219,9 @@ module Capybara::Webkit @connection.print arg.to_s end check - read_response + response = read_response + check_javascript_errors(name) + response rescue SystemCallError => exception @connection.restart raise(Capybara::Webkit::CrashError, <<-MESSAGE.strip) @@ -295,6 +307,10 @@ https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes private + def apply_defaults + @raise_javascript_errors = false + end + def check result = @connection.gets result.strip! if result @@ -308,6 +324,14 @@ https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes result end + def check_javascript_errors(command_name) + return if command_name == "ConsoleMessages" + + if raise_javascript_errors? && error_messages.any? + raise JavaScriptError, error_messages + end + end + def read_response response_length = @connection.gets.to_i if response_length > 0 diff --git a/lib/capybara/webkit/configuration.rb b/lib/capybara/webkit/configuration.rb index 2adeeba..41254b5 100644 --- a/lib/capybara/webkit/configuration.rb +++ b/lib/capybara/webkit/configuration.rb @@ -30,6 +30,7 @@ module Capybara attr_accessor :stderr attr_accessor :timeout attr_writer :skip_image_loading + attr_accessor :raise_javascript_errors def initialize @allowed_urls = [] @@ -41,6 +42,7 @@ module Capybara @skip_image_loading = false @stderr = $stderr @timeout = -1 + @raise_javascript_errors = false end def allow_url(url) @@ -93,7 +95,8 @@ module Capybara proxy: proxy, skip_image_loading: skip_image_loading?, stderr: stderr, - timeout: timeout + timeout: timeout, + raise_javascript_errors: raise_javascript_errors, } end end diff --git a/lib/capybara/webkit/driver.rb b/lib/capybara/webkit/driver.rb index b16d4e6..ce9dfa6 100644 --- a/lib/capybara/webkit/driver.rb +++ b/lib/capybara/webkit/driver.rb @@ -398,6 +398,10 @@ module Capybara::Webkit @browser.timeout = @options[:timeout] end + if @options.has_key? :raise_javascript_errors + @browser.set_raise_javascript_errors(@options[:raise_javascript_errors]) + end + Array(@options[:allowed_urls]).each { |url| @browser.allow_url(url) } Array(@options[:blocked_urls]).each { |url| @browser.block_url(url) } end diff --git a/lib/capybara/webkit/errors.rb b/lib/capybara/webkit/errors.rb index 06681fa..3b0c30e 100644 --- a/lib/capybara/webkit/errors.rb +++ b/lib/capybara/webkit/errors.rb @@ -44,4 +44,13 @@ module Capybara::Webkit Capybara::Webkit.const_get @class_name end end + + class JavaScriptError < StandardError + def initialize(errors) + @javascript_errors = errors + super(errors.join(",")) + end + + attr_reader :javascript_errors + end end diff --git a/spec/browser_spec.rb b/spec/browser_spec.rb index a74096b..2d075bf 100644 --- a/spec/browser_spec.rb +++ b/spec/browser_spec.rb @@ -43,4 +43,20 @@ describe Capybara::Webkit::Browser do end end end + + describe "#reset!" do + it "resets to the default state" do + connection = double("connection", puts: nil, print: nil) + allow(connection).to receive(:gets).and_return("ok\n", "{}\n") + + browser = Capybara::Webkit::Browser.new(connection) + browser.set_raise_javascript_errors(true) + + expect(browser.raise_javascript_errors?).to be true + + browser.reset! + + expect(browser.raise_javascript_errors?).to be false + end + end end diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index 00917c4..f7df360 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -3440,4 +3440,50 @@ CACHE MANIFEST def driver_url(driver, path) URI.parse(driver.current_url).merge(path).to_s end + + context "page with JavaScript errors" do + let(:driver) do + driver_for_app do + get "/" do + <<-HTML + + + + + + + HTML + end + end + end + + it "raises errors as an exception, when configured" do + configure do |config| + config.raise_javascript_errors = true + end + + expected_error = Capybara::Webkit::JavaScriptError + expected_message = "ReferenceError: Can't find variable: undefinedFunc" + + expect { visit("/") }.to raise_error(expected_error) do |error| + expect(error.javascript_errors.first[:message]).to eq expected_message + end + expect { driver.find_css("h1") }.to raise_error(expected_error) + end + + it "does not raise an exception when fetching the error messages" do + configure do |config| + config.raise_javascript_errors = true + end + + expect { driver.error_messages }.to_not raise_error + end + + it "does not raise errors as an exception by default" do + expect { visit("/") }.to_not raise_error + expect(driver.error_messages).to_not be_empty + end + end end diff --git a/spec/support/app_runner.rb b/spec/support/app_runner.rb index e79a767..28a1c41 100644 --- a/spec/support/app_runner.rb +++ b/spec/support/app_runner.rb @@ -21,6 +21,7 @@ module AppRunner end self.browser = $webkit_browser + self.browser.reset! self.configuration = Capybara::Webkit::Configuration.new end