class ReportPortal::Cucumber::Report
@api private
Public Class Methods
new()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 21 def initialize @last_used_time = 0 @root_node = Tree::TreeNode.new('') @parent_item_node = @root_node start_launch end
Public Instance Methods
attach_to_launch?()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 17 def attach_to_launch? ReportPortal::Settings.instance.formatter_modes.include?('attach_to_launch') end
embed(path_or_src, mime_type, label, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 133 def embed(path_or_src, mime_type, label, desired_time = ReportPortal.now) ReportPortal.send_file(:info, path_or_src, label, time_to_send(desired_time), mime_type) end
parallel?()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 13 def parallel? false end
puts(message, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 129 def puts(message, desired_time = ReportPortal.now) ReportPortal.send_log(:info, message, time_to_send(desired_time)) end
start_launch(desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 28 def start_launch(desired_time = ReportPortal.now) if attach_to_launch? ReportPortal.launch_id = if ReportPortal::Settings.instance.launch_id ReportPortal::Settings.instance.launch_id else file_path = ReportPortal::Settings.instance.file_with_launch_id || (Pathname(Dir.tmpdir) + 'rp_launch_id.tmp') File.read(file_path) end $stdout.puts "Attaching to launch #{ReportPortal.launch_id}" else description = ReportPortal::Settings.instance.description description ||= ARGV.map { |arg| arg.gsub(/rp_uuid=.+/, 'rp_uuid=[FILTERED]') }.join(' ') ReportPortal.start_launch(description, time_to_send(desired_time)) end end
test_case_finished(event, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 65 def test_case_finished(event, desired_time = ReportPortal.now) result = event.result status = result.to_sym issue = nil if %i[undefined pending].include?(status) status = :failed issue = result.message end ReportPortal.finish_item(ReportPortal.current_scenario, status, time_to_send(desired_time), issue) ReportPortal.current_scenario = nil end
test_case_started(event, desired_time = ReportPortal.now)
click to toggle source
TODO: time should be a required argument
# File lib/report_portal/cucumber/report.rb, line 46 def test_case_started(event, desired_time = ReportPortal.now) test_case = event.test_case feature = test_case.feature if report_hierarchy? && !same_feature_as_previous_test_case?(feature) end_feature(desired_time) unless @parent_item_node.is_root? start_feature_with_parentage(feature, desired_time) end name = "#{test_case.keyword}: #{test_case.name}" description = test_case.location.to_s tags = test_case.tags.map(&:name) type = :STEP ReportPortal.current_scenario = ReportPortal::TestItem.new(name: name, type: type, id: nil, start_time: time_to_send(desired_time), description: description, closed: false, tags: tags) scenario_node = Tree::TreeNode.new(SecureRandom.hex, ReportPortal.current_scenario) @parent_item_node << scenario_node ReportPortal.current_scenario.id = ReportPortal.start_item(scenario_node) end
test_run_finished(_event, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 119 def test_run_finished(_event, desired_time = ReportPortal.now) end_feature(desired_time) unless @parent_item_node.is_root? unless attach_to_launch? close_all_children_of(@root_node) # Folder items are closed here as they can't be closed after finishing a feature time_to_send = time_to_send(desired_time) ReportPortal.finish_launch(time_to_send) end end
test_step_finished(event, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 91 def test_step_finished(event, desired_time = ReportPortal.now) test_step = event.test_step result = event.result status = result.to_sym if %i[failed pending undefined].include?(status) exception_info = if %i[failed pending].include?(status) ex = result.exception format("%s: %s\n %s", ex.class.name, ex.message, ex.backtrace.join("\n ")) else format("Undefined step: %s:\n%s", test_step.text, test_step.source.last.backtrace_line) end ReportPortal.send_log(:error, exception_info, time_to_send(desired_time)) end if status != :passed log_level = status == :skipped ? :warn : :error step_type = if step?(test_step) 'Step' else hook_class_name = test_step.source.last.class.name.split('::').last location = test_step.location "#{hook_class_name} at `#{location}`" end ReportPortal.send_log(log_level, "#{step_type} #{status}", time_to_send(desired_time)) end end
test_step_started(event, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 77 def test_step_started(event, desired_time = ReportPortal.now) test_step = event.test_step if step?(test_step) # `after_test_step` is also invoked for hooks step_source = test_step.source.last message = "-- #{step_source.keyword}#{step_source.text} --" if step_source.multiline_arg.doc_string? message << %(\n"""\n#{step_source.multiline_arg.content}\n""") elsif step_source.multiline_arg.data_table? message << step_source.multiline_arg.raw.reduce("\n") { |acc, row| acc << "| #{row.join(' | ')} |\n" } end ReportPortal.send_log(:trace, message, time_to_send(desired_time)) end end
Private Instance Methods
close_all_children_of(root_node)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 203 def close_all_children_of(root_node) root_node.postordered_each do |node| if !node.is_root? && !node.content.closed ReportPortal.finish_item(node.content) end end end
end_feature(desired_time)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 195 def end_feature(desired_time) ReportPortal.finish_item(@parent_item_node.content, nil, time_to_send(desired_time)) # Folder items can't be finished here because when the folder started we didn't track # which features the folder contains. # It's not easy to do it using Cucumber currently: # https://github.com/cucumber/cucumber-ruby/issues/887 end
report_hierarchy?()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 215 def report_hierarchy? !ReportPortal::Settings.instance.formatter_modes.include?('skip_reporting_hierarchy') end
same_feature_as_previous_test_case?(feature)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 153 def same_feature_as_previous_test_case?(feature) @parent_item_node.name == feature.location.file.split(File::SEPARATOR).last end
start_feature_with_parentage(feature, desired_time)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 157 def start_feature_with_parentage(feature, desired_time) parent_node = @root_node child_node = nil path_components = feature.location.file.split(File::SEPARATOR) path_components.each_with_index do |path_component, index| child_node = parent_node[path_component] unless child_node # if child node was not created yet if index < path_components.size - 1 name = "Folder: #{path_component}" description = nil tags = [] type = :SUITE else name = "#{feature.keyword}: #{feature.name}" description = feature.file # TODO: consider adding feature description and comments tags = feature.tags.map(&:name) type = :TEST end # TODO: multithreading # Parallel formatter always executes scenarios inside the same feature in the same process if parallel? && index < path_components.size - 1 && # is folder? (id_of_created_item = ReportPortal.item_id_of(name, parent_node)) # get id for folder from report portal # get child id from other process item = ReportPortal::TestItem.new(name: name, type: type, id: id_of_created_item, start_time: time_to_send(desired_time), description: description, closed: false, tags: tags) child_node = Tree::TreeNode.new(path_component, item) parent_node << child_node else item = ReportPortal::TestItem.new(name: name, type: type, id: nil, start_time: time_to_send(desired_time), description: description, closed: false, tags: tags) child_node = Tree::TreeNode.new(path_component, item) parent_node << child_node item.id = ReportPortal.start_item(child_node) # TODO: multithreading end end parent_node = child_node end @parent_item_node = child_node end
step?(test_step)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 211 def step?(test_step) !::Cucumber::Formatter::HookQueryVisitor.new(test_step).hook? end
time_to_send(desired_time)
click to toggle source
Report
Portal sorts logs by time. However, several logs might have the same time.
So to get Report Portal sort them properly the time should be different in all logs related to the same item. And thus it should be stored.
Only the last time needs to be stored as:
* only one test framework process/thread may send data for a single Report Portal item * that process/thread can't start the next test until it's done with the previous one
# File lib/report_portal/cucumber/report.rb, line 145 def time_to_send(desired_time) time_to_send = desired_time if time_to_send <= @last_used_time time_to_send = @last_used_time + 1 end @last_used_time = time_to_send end