A JavaScript error in an E2E test with Selenium will not cause your test to fail. This may cause you to miss errors in your frontend code.
Using the BrowserConsole helper below you can check your browser's error console from your E2E tests.
The following will raise BrowserConsole::ErrorsPresent if there is an error on the browser console:
BrowserConsole.assert_no_errors!
Ignoring errors
You can ignore errors by their exact message:
BrowserConsole.ignore('Browser is burning')
You can ignore errors with messages matching a regular expression:
BrowserConsole.ignore(/burning/i)
You may also provide a block that inspects an 
  error object
  
    Show archive.org snapshot
  
.
To ignore the error, return a truthy value:
BrowserConsole.ignore do |error|
  error.message.size < 100
end
Default ignore rules
By default BrowserConsole ignores:
- Warnings (error.level === "WARNING")
- Errors containing the phrase Failed to load resource
To delete these defaults, call BrowseConsole.ignore_nothing before your own ignore rules:
# Remove default rules
BrowserConsole.ignore_nothing
# Add your own rules
BrowserConsole.ignore(...)
BrowserConsole.ignore(...)
Automatic checking in RSpec feature specs
In your spec_helper.rb you may configure to automatically check for errors after every user interaction that goes through Capybara.
This requires 
  capybara-lockstep
  
    Show archive.org snapshot
  
 1.3+.
Capybara::Lockstep.after_synchronize do
  BrowserConsole.assert_no_errors!
end
Note that checking the browser console after every Capybara command will slow down your E2E tests somewhat. A compromise might be to only check the console when the spec has ended:
RSpec.configure do |config|
  config.after do
   BrowserConsole.assert_no_errors!
  end
end
Ignoring JavaScript errors for a spec
We can configure RSpec to ignore JavaScript errors in specs tagged as { mute_js_errors: true }:
RSpec.configure do |config|
  config.around(mute_js_errors: true) do |example|
    BrowserConsole.mute(&example)
  end
end
We can now tag individual scenarios to ignore all JavaScript errors:
scenario 'Eating errors', js: true, mute_js_errors: true do
  ...
end
Automatic checking in Cucumber scenarios
In your env.rb you may configure to automatically check for errors after every user interaction that goes through Capybara.
This requires 
  capybara-lockstep
  
    Show archive.org snapshot
  
 1.3+.
Capybara::Lockstep.after_synchronize do
  BrowserConsole.assert_no_errors!
end
Note that checking the browser console after every Capybara command will slow down your E2E tests somewhat. A compromise might be to only check the console when the spec has ended:
After('not @mute-js-errors') do
  BrowserConsole.assert_no_errors!
end
Ignoring JavaScript errors for a scenario
We can configure Cucumber to ignore JavaScript errors in specs tagged with @mute-js-errors:
Around('@mute-js-errors') do |_scenario, block|
  BrowserConsole.mute(&block)
end
To ignore JavaScript errors for an individual scenario, tag it with @mute-js-errors:
@javascript @mute-js-errors
Scenario: Eating errors
  ...
The BrowserConsole helper 
class BrowserConsole
  class ErrorsPresent < StandardError; end
  class << self
    def all_errors
      if enabled?
        driver_logs_proc.call.get(:browser)
      else
        []
      end
    rescue Capybara::NotSupportedByDriverError
      []
    end
    def filtered_errors
      all_errors.select do |error|
        ignore_rules.none? do |rule|
          case rule
          when Proc
            rule.call(error)
          when Regexp
            error.message =~ rule
          when String
            error.message == rule
          end
        end
      end
    end
    def assert_no_errors!
      errors = filtered_errors
      if errors.present?
        message = (['There are JavaScript errors:'] + errors.map(&:message)).join("\n\n")
        raise ErrorsPresent, message
      end
    end
    def ignore(pattern = nil, &block)
      ignore_rules << (pattern || block)
    end
    def mute(&block)
      @muted = true
      if block
        begin
          block.call
        ensure
          unmute
        end
      end
    end
    def unmute
      @muted = false
    end
    def self.current
      @current ||= new
    end
    def ignore_nothing
      @ignore_rules = []
    end
    private
    def muted?
      @muted || false
    end
    def ignore_rules
      @ignore_rules ||= default_ignore_rules
    end
    def default_ignore_rules
      [
        /Failed to load resource/,
        ->(error) { error.level == 'WARNING' },
      ]
    end
    def page
      Capybara.current_session
    end
    def enabled?
      !muted? && driver_has_logs? && !alert_present?
    end
    def alert_present?
      # Chrome 54 and/or Chromedriver 2.24 introduced a breaking change on how
      # accessing browser logs work.
      #
      # Apparently, while an alert/confirm is open, Chrome will block any requests
      # to its `getLog` API. This causes Selenium to time out with a `Net::ReadTimeout` error
      page.driver.browser.switch_to.alert
      true
    rescue Capybara::NotSupportedByDriverError, Selenium::WebDriver::Error::NoSuchAlertError
      false
    end
    def driver_has_logs?
      !!driver_logs_proc
    end
    
    def driver_logs_proc
      browser = page.driver.browser
    
      if browser.respond_to?(:logs) # selenium-webdriver >= 4
        proc { browser.logs }
      elsif browser.respond_to?(:manage) && browser.manage.respond_to?(:logs) # selenium-webdriver < 4
        proc { browser.manage.logs }
      end  
    end
  end
end