Skip to content

Instantly share code, notes, and snippets.

@gkop
Created November 17, 2011 00:13
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save gkop/1371962 to your computer and use it in GitHub Desktop.
Save gkop/1371962 to your computer and use it in GitHub Desktop.
Capture javascript errors in Cucumber+Capybara+Webdriver tests
# in features/support/env.rb
require 'selenium/webdriver'
# we need a firefox extension to start intercepting javascript errors before the page
# scripts load
Capybara.register_driver :selenium do |app|
profile = Selenium::WebDriver::Firefox::Profile.new
# see https://github.com/mguillem/JSErrorCollector
profile.add_extension File.join(Rails.root, "features/support/extensions/JSErrorCollector.xpi")
Capybara::Selenium::Driver.new app, :profile => profile
end
After do |scenario|
if page.driver.to_s.match("Selenium")
errors = page.execute_script("return window.JSErrorCollector_errors.pump()")
if errors.any?
puts '-------------------------------------------------------------'
puts "Found #{errors.length} javascript #{pluralize(errors.length, 'error')}"
puts '-------------------------------------------------------------'
errors.each do |error|
puts " #{error["errorMessage"]} (#{error["sourceName"]}:#{error["lineNumber"]})"
end
raise "Javascript #{pluralize(errors.length, 'error')} detected, see above"
end
end
end
@jacob-s-son
Copy link

May I suggest a small improvement over @alexspeller suggestion.

class DriverJSError < StandardError; end

AfterStep do |scenario, step|
  errors = page.driver.browser.manage.logs.get(:browser)
    .select {|e| e.level == "SEVERE" && message.present? }
    .map(&:message)
    .to_a

  if errors.present?
    raise DriverJSError, errors.join("\n\n")
  end
end

Main difference here is that it only collects errors (in practice my instance of browser throws quite a lot of warnings, but errors are marked as "SEVERE" in Selenium) and also filters out entries with empty messages (I encountered entries with empty message, though not sure if there are any for "SEVERE" entries).

@anandchavan
Copy link

Not a geek, but would love to understand above lines.

.select {|e| e.level == "SEVERE" && message.present? }
.map(&:message)

To learn above lines, which instance of message variable are we referring to? should it be written as e.message.present?

@jacob-s-son ?

@tyler-boyd
Copy link

@anandchavan you're correct, it should be e.message.present?.

@calebkeene
Copy link

@jacob-s-son the to_a is not necessary

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