sanger/sequencescape

View on GitHub
lib/capybara_failure_logger.rb

Summary

Maintainability
A
0 mins
Test Coverage
F
21%
# frozen_string_literal: true

require 'base64'

# Helper for capybara tests to log state on failed tests
module CapybaraFailureLogger
  #
  # Call on test failure to log:
  # - The HTML of the page
  # - The content of the JS error console (if possible)
  # - An image of the failed page (if possible)
  #
  # @param name [String] The name of the test, forms a basis of the filename
  # @param page [Capybara::Session] The Capybara session object (other exposed as page)
  # @yield [String] Yields strings to be logged
  #
  # @return [void]
  #
  def self.log_failure(name, page, &block)
    block ||= method(:puts)

    log_screenshot(name, page, &block)
    log_html(name, page, &block)
    log_js(name, page, &block)
  end

  def self.log_screenshot(name, page, &block)
    return unless page.respond_to?(:save_screenshot)

    page.save_screenshot("#{name}.png")
    filename = "#{Capybara.save_path}/#{name}.png"
    yield "📸 Screenshot saved to #{filename}"
    output_image(filename, &block)
  rescue Capybara::NotSupportedByDriverError
    yield 'Could not save screenshot - Unsupported by this webdriver'
  end

  def self.log_html(name, page)
    return unless page.respond_to?(:save_page)

    page.save_page("#{name}.html")
    yield "📐 HTML saved to #{Capybara.save_path}/#{name}.html"
  end

  def self.log_js(_name, page)
    return unless page.driver.browser.respond_to?(:logs)

    errors = page.driver.browser.logs.get(:browser)
    yield '== JS errors ============'
    errors.each { |jserror| yield jserror.message }
    yield '========================='
  end

  def self.output_image(filename)
    return unless ENV['TERM_PROGRAM'] == 'iTerm.app'

    case ENV.fetch('INLINE_ERROR_SCREENSHOTS', nil)
    when 'enabled'
      encoded_image = Base64.encode64(File.read(filename))
      name = Base64.encode64(filename)
      yield "\e]1337;File=inline=1;name=#{name}:#{encoded_image}\a"
    when nil
      yield 'Want inline images? Set the env INLINE_ERROR_SCREENSHOTS to enabled,'
      yield 'or set INLINE_ERROR_SCREENSHOTS to anything else to disable this message.'
    end
  end
end