module ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper

def absolute_html_path

def absolute_html_path
  "#{absolute_path}.html"
end

def absolute_image_path

def absolute_image_path
  "#{absolute_path}.png"
end

def absolute_path

def absolute_path
  Rails.root.join(screenshots_dir, image_name)
end

def display_image(html:, screenshot_output:)

def display_image(html:, screenshot_output:)
  message = +"[Screenshot Image]: #{image_path}\n"
  message << +"[Screenshot HTML]: #{html_path}\n" if html
  case screenshot_output || output_type
  when "artifact"
    message << "\e]1338;url=artifact://#{absolute_image_path}\a\n"
  when "inline"
    name = inline_base64(File.basename(absolute_image_path))
    image = inline_base64(File.read(absolute_image_path))
    message << "\e]1337;File=name=#{name};height=400px;inline=1:#{image}\a\n"
  end
  message
end

def failed?

def failed?
  !passed? && !skipped?
end

def html_from_env?

def html_from_env?
  ENV["RAILS_SYSTEM_TESTING_SCREENSHOT_HTML"] == "1"
end

def html_path

def html_path
  absolute_html_path.to_s
end

def image_name

def image_name
  sanitized_method_name = method_name.gsub(/[^\w]+/, "-")
  name = "#{unique}_#{sanitized_method_name}"
  name[0...225]
end

def image_path

def image_path
  absolute_image_path.to_s
end

def increment_unique

def increment_unique
  @_screenshot_counter ||= 0
  @_screenshot_counter += 1
end

def inline_base64(path)

def inline_base64(path)
  Base64.strict_encode64(path)
end

def output_type

def output_type
  # Environment variables have priority
  output_type = ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] || ENV["CAPYBARA_INLINE_SCREENSHOT"]
  # Default to outputting a path to the screenshot
  output_type ||= "simple"
  output_type
end

def relative_image_path

def relative_image_path
  "#{absolute_path.relative_path_from(Rails.root)}.png"
end

def save_html

def save_html
  page.save_page(absolute_html_path)
end

def save_image

def save_image
  page.save_screenshot(absolute_image_path)
end

def screenshots_dir

def screenshots_dir
  Capybara.save_path.presence || "tmp/screenshots"
end

def show(img)

def show(img)
  puts img
end

def supports_screenshot?

def supports_screenshot?
  Capybara.current_driver != :rack_test
end

def take_failed_screenshot

+take_failed_screenshot+ is called during system test teardown.

failed.
Takes a screenshot of the current page in the browser if the test
def take_failed_screenshot
  return unless failed? && supports_screenshot? && Capybara::Session.instance_created?
  take_screenshot
  metadata[:failure_screenshot_path] = relative_image_path if Minitest::Runnable.method_defined?(:metadata)
end

def take_screenshot(html: false, screenshot: nil)

artifact format (https://buildkite.github.io/terminal-to-html/inline-images/).
* [+artifact+] Display the screenshot in the terminal, using the terminal
iTerm image protocol (https://iterm2.com/documentation-images.html).
* [+inline+] Display the screenshot in the terminal using the
This is the default value.
* [+simple+ (default)] Only displays the screenshot path.
environment variable to control the output. Possible values are:
You can use the +screenshot+ argument or set the +RAILS_SYSTEM_TESTING_SCREENSHOT+

so you can investigate the elements on the page at the time of the screenshot
environment variable to save the HTML from the page that is being screenshotted
You can use the +html+ argument or set the +RAILS_SYSTEM_TESTING_SCREENSHOT_HTML+

one with +Capybara.save_path+
The default screenshots directory is +tmp/screenshots+ but you can set a different

named with a sequential prefix (or 'failed' for failing tests)
to investigate changes at different points during your test. These will be
automating visual testing. You can take multiple screenshots per test
a screenshot of the current state. This can be useful for debugging or
+take_screenshot+ can be used at any point in your system tests to take

Takes a screenshot of the current page in the browser.
def take_screenshot(html: false, screenshot: nil)
  showing_html = html || html_from_env?
  increment_unique
  save_html if showing_html
  save_image
  show display_image(html: showing_html, screenshot_output: screenshot)
end

def unique

def unique
  failed? ? "failures" : (_screenshot_counter || 0).to_s
end