class ReportPortal::Cucumber::Report
@api private
Public Class Methods
new()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 39 def initialize @last_used_time = 0 @root_node = Tree::TreeNode.new('') start_launch end
Public Instance Methods
attach_to_launch?()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 35 def attach_to_launch? ReportPortal::Settings.instance.formatter_modes.include?('attach_to_launch') end
done(desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 135 def done(desired_time = ReportPortal.now) end_feature(desired_time) if @feature_node 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
embed(src, mime_type, label, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 149 def embed(src, mime_type, label, desired_time = ReportPortal.now) ReportPortal.send_file(:info, src, label, time_to_send(desired_time),mime_type) end
parallel?()
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 31 def parallel? false end
puts(message, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 145 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 45 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 81 def test_case_finished(event, desired_time = ReportPortal.now) result = event.result status = result.to_sym issue = nil if [: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
# File lib/report_portal/cucumber/report.rb, line 62 def test_case_started(event, desired_time = ReportPortal.now) # TODO: time should be a required argument test_case = event.test_case feature = test_case.feature unless same_feature_as_previous_test_case?(feature) end_feature(desired_time) if @feature_node 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, type, nil, time_to_send(desired_time), description, false, tags) scenario_node = Tree::TreeNode.new(SecureRandom.hex, ReportPortal.current_scenario) @feature_node << scenario_node ReportPortal.current_scenario.id = ReportPortal.start_item(scenario_node) end
test_step_finished(event, desired_time = ReportPortal.now)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 107 def test_step_finished(event, desired_time = ReportPortal.now) test_step = event.test_step result = event.result status = result.to_sym if [:failed, :pending, :undefined].include?(status) exception_info = if [:failed, :pending].include?(status) ex = result.exception sprintf("%s: %s\n %s", ex.class.name, ex.message, ex.backtrace.join("\n ")) else sprintf("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 93 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 219 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 211 def end_feature(desired_time) ReportPortal.finish_item(@feature_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
same_feature_as_previous_test_case?(feature)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 169 def same_feature_as_previous_test_case?(feature) @feature_node && @feature_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 173 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, type, id_of_created_item, time_to_send(desired_time), description, false, tags) child_node = Tree::TreeNode.new(path_component, item) parent_node << child_node else item = ReportPortal::TestItem.new(name, type, nil, time_to_send(desired_time), description, false, 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 @feature_node = child_node end
step?(test_step)
click to toggle source
# File lib/report_portal/cucumber/report.rb, line 227 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 161 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