Allow JavaScript errors to be raised as exceptions (#988)

When configured, all driver commands (except reading console messages) will
check for JavaScript errors. 

The ConsoleMessages command is excluded from the check to prevent recursion, and
maintain the ease of debugging JavaScript errors interactively.
This commit is contained in:
Oliver Peate 2017-03-17 14:54:36 +00:00 committed by GitHub
parent 56e244e074
commit 2e869bb9b7
8 changed files with 108 additions and 2 deletions

View File

@ -129,6 +129,9 @@ Capybara::Webkit.configure do |config|
user: "proxy",
pass: "secret"
)
# Raise JavaScript errors as exceptions
config.raise_javascript_errors = true
end
```

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
undefinedFunc();
</script>
</body>
</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

View File

@ -21,6 +21,7 @@ module AppRunner
end
self.browser = $webkit_browser
self.browser.reset!
self.configuration = Capybara::Webkit::Configuration.new
end