mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Output Browser logs on failure for Cuprite Capybara driver
This commit is contained in:
@@ -4,21 +4,79 @@ module Capybara::BrowserLogs
|
||||
# Capture browser logs on failed examples and output them in Progress and
|
||||
# Documentation formatters.
|
||||
class Capture
|
||||
# Regex matching Ferrum's incoming CDP message format: " ◀ 0.123 {json}"
|
||||
CDP_INCOMING_MESSAGE_PATTERN = /^\s+◀\s+[\d.]+\s+(.+)$/
|
||||
|
||||
class << self
|
||||
def after_failed_example(example)
|
||||
return unless failed?(example)
|
||||
return unless example.example_group.include?(Capybara::DSL)
|
||||
return if Capybara.page.current_url.blank?
|
||||
return unless Capybara.page.driver.browser.respond_to?(:manage)
|
||||
|
||||
logs = Capybara.page.driver.browser.manage.instance_variable_get(:@bridge).log("browser")
|
||||
example.metadata[:browser_logs] = logs
|
||||
logs = extract_logs
|
||||
example.metadata[:browser_logs] = logs if logs
|
||||
rescue StandardError => e
|
||||
warn "Unable to get browser logs: #{e}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def extract_logs
|
||||
if cuprite_driver?
|
||||
extract_cuprite_logs
|
||||
elsif selenium_driver?
|
||||
extract_selenium_logs
|
||||
end
|
||||
end
|
||||
|
||||
def cuprite_driver?
|
||||
Capybara.page.driver.is_a?(Capybara::Cuprite::Driver)
|
||||
end
|
||||
|
||||
def selenium_driver?
|
||||
Capybara.page.driver.browser.respond_to?(:manage)
|
||||
end
|
||||
|
||||
def extract_selenium_logs
|
||||
Capybara.page.driver.browser.manage.instance_variable_get(:@bridge).log("browser")
|
||||
end
|
||||
|
||||
def extract_cuprite_logs
|
||||
logger = CupriteCdpLogger.logger
|
||||
return unless logger
|
||||
|
||||
logger.string.each_line.filter_map do |line|
|
||||
match = line.match(CDP_INCOMING_MESSAGE_PATTERN)
|
||||
next unless match
|
||||
|
||||
parse_console_api_called(match[1])
|
||||
end
|
||||
end
|
||||
|
||||
def parse_console_api_called(json_string)
|
||||
data = JSON.parse(json_string)
|
||||
return unless data["method"] == "Runtime.consoleAPICalled"
|
||||
|
||||
params = data["params"]
|
||||
type = params["type"]
|
||||
args = params["args"].map { |arg| format_cdp_arg(arg) }
|
||||
"#{type}: #{args.join(' ')}"
|
||||
rescue JSON::ParserError
|
||||
nil
|
||||
end
|
||||
|
||||
def format_cdp_arg(arg)
|
||||
return arg["value"].to_s if arg.key?("value")
|
||||
|
||||
if (preview = arg["preview"]) && (properties = preview["properties"])
|
||||
formatted = properties.map { |p| "#{p['name']}: #{p['value']}" }.join(", ")
|
||||
overflow = preview["overflow"] ? ", ..." : ""
|
||||
return "{#{formatted}#{overflow}}"
|
||||
end
|
||||
|
||||
arg["description"] || arg["type"]
|
||||
end
|
||||
|
||||
# borrowed from capybara-screenshot code
|
||||
def failed?(example)
|
||||
return true if example.exception
|
||||
@@ -59,6 +117,8 @@ module Capybara::BrowserLogs
|
||||
logs = example.metadata[:browser_logs]
|
||||
.map(&:to_s)
|
||||
.grep_v(EXCLUDE_PATTERN)
|
||||
return if logs.empty?
|
||||
|
||||
output.puts(" Browser logs:\n #{logs.join("\n ")}")
|
||||
end
|
||||
end
|
||||
@@ -68,6 +128,10 @@ end
|
||||
RSpec.configure do |config|
|
||||
config.after(type: :feature) do |example|
|
||||
Capybara::BrowserLogs::Capture.after_failed_example(example)
|
||||
if (logger = CupriteCdpLogger.logger)
|
||||
logger.truncate(0)
|
||||
logger.rewind
|
||||
end
|
||||
end
|
||||
|
||||
config.before(:suite) do
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
|
||||
require "capybara/cuprite"
|
||||
|
||||
module CupriteCdpLogger
|
||||
class << self
|
||||
attr_accessor :logger
|
||||
end
|
||||
end
|
||||
|
||||
def headful_mode?
|
||||
ActiveRecord::Type::Boolean.new.cast(ENV.fetch("OPENPROJECT_TESTING_NO_HEADLESS", nil))
|
||||
end
|
||||
@@ -80,6 +86,9 @@ def register_better_cuprite(language, name: :"better_cuprite_#{language}")
|
||||
|
||||
options = configure_remote_chrome(options)
|
||||
|
||||
CupriteCdpLogger.logger = StringIO.new
|
||||
options = options.merge(logger: CupriteCdpLogger.logger)
|
||||
|
||||
browser_options = {
|
||||
"disable-dev-shm-usage": nil,
|
||||
"disable-gpu": nil,
|
||||
|
||||
Reference in New Issue
Block a user