class CucumberJunitToJson::App
The Cucumber Junit to Json app class that handles std inputs and command line args
Constants
- Error
Attributes
feature_parser[R]
junit_parser[R]
stderr[R]
stdin[R]
stdout[R]
Public Class Methods
new(options = {})
click to toggle source
# File lib/cucumber_junit_to_json/app.rb, line 22 def initialize(options = {}) @stdin = options[:stdin] || STDIN @stdout = options[:stdout] || STDOUT @stderr = options[:stderr] || STDERR @feature_id = 1 @scenario_id = 1 end
Public Instance Methods
run(*args)
click to toggle source
# File lib/cucumber_junit_to_json/app.rb, line 32 def run(*args) options = parse_args(args) @junit_parser = CucumberJunitToJson::Parsers::JunitParser.new(options.junit_dir) @feature_parser = CucumberJunitToJson::Parsers::FeatureParser.new(options.feature_dir) output_file = options.output_file || 'cucumber.json' features = [] unless File.file?(output_file) output_directory = File.dirname(output_file) FileUtils.mkdir_p(output_directory) unless File.directory?(output_directory) FileUtils.touch(output_file) raise Error, "Could not create output file #{output_file}" unless File.file?(output_file) end # if we are dealing with a directory of xml files if File.directory?(junit_parser.path_to_junit) Find.find(junit_parser.path_to_junit) do |path_to_file| next unless File.file?(path_to_file) && File.extname(path_to_file) == '.xml' features.push(convert_to_json(path_to_file)) end # if we are dealing with just a single xml file elsif File.exist?(junit_parser.path_to_junit) features.push(convert_to_json(junit_parser.path_to_junit)) end open(output_file, 'w') { |f| f.write(features.to_json) } 0 rescue Error, OptionParser::ParseError => error stderr.puts error.message 1 end
Private Instance Methods
convert_to_json(file)
click to toggle source
# File lib/cucumber_junit_to_json/app.rb, line 63 def convert_to_json(file) file_content = @junit_parser.read(file) return if file_content.empty? document = Nokogiri::XML::Document.parse(file_content) testsuite = document.at_css('testsuite') feature_uri = Pathname.new(File.join(@feature_parser.path_to_features, @junit_parser.path_to_file(testsuite['name']))).realpath.to_s feature = CucumberJunitToJson::Models::Feature.new feature.keyword = 'Feature' feature.name = @junit_parser.feature_name(testsuite['name']) feature.uri = feature_uri feature.id = @feature_id feature.tags, feature.line = @feature_parser.tags_and_line_number_matching(feature_uri, "#{feature.keyword}:") testcases = testsuite.css('testcase') scenarios = [] testcases.each do |testcase| scenario = CucumberJunitToJson::Models::Scenario.new failing_step = nil failure_message = nil if testcase['status'] == 'failed' failure = testcase.css('failure') # Sometimes <failure> node come as <error> failure ||= testcase.css('error') if failure && !failure.nil? # Gracefully rescue issues with failure node not being properly formatted begin failure_info = failure.text.split(failure.attribute('message')).first failure_message = failure.attribute('message') failing_step = failure_info.split('Failing step:').last.split('...').first.strip rescue StandardError => e puts "Rescuing Error with failure node #{failure}\n#{e.message}\n" end end end # Removing scenario outline added blob gives you the actual scenario name use_similar_matcher = false use_similar_matcher = true if testcase['name'].include?('-- @') scenario.name = testcase['name'].split('-- @').first.strip scenario.tags, scenario.line = @feature_parser.tags_and_line_number_matching(feature_uri, scenario.name, use_similar_matcher) scenario_line_text = @feature_parser.text_and_line_number_matching(feature_uri, scenario.name).first scenario.keyword = scenario_line_text.split(':').first.strip scenario.type = 'scenario' scenario.uri = feature_uri scenario.id = @scenario_id scenario_output = get_string_between(testcase.at_css('system-out').text, '@scenario.begin', '@scenario.end') scenario.steps = CucumberJunitToJson::Models::Step.get_steps_for(scenario.name, scenario_output, feature_uri, failing_step, failure_message) scenarios.push(scenario) @scenario_id += 1 end feature.elements = scenarios builder = CucumberJunitToJson::FeatureJsonBuilder.new(feature) @feature_id += 1 JSON.parse(builder.feature_json) end
get_string_between(str, start_at, end_at)
click to toggle source
# File lib/cucumber_junit_to_json/app.rb, line 120 def get_string_between(str, start_at, end_at) regex = /#{start_at}(.*?)#{end_at}/m str[regex, 1] end
parse_args(args)
click to toggle source
# File lib/cucumber_junit_to_json/app.rb, line 125 def parse_args(args) options = OpenStruct.new options.junit_dir = nil options.feature_dir = nil options.output_file = nil parser = OptionParser.new do |p| p.banner = "USAGE: #{$PROGRAM_NAME} --junit-dir JUNITDIR --feature-dir FEATUREDIR" p.separator '' p.separator 'Specific options:' p.on '-j', '--junit-dir JUNITDIR', 'Provide a path to junit .xml files.' do |junit_dir| options.junit_dir = junit_dir end p.on '-f', '--feature-dir FEATUREDIR', 'Provide a path to .feature files.' do |feature_dir| options.feature_dir = feature_dir end p.on '-o', '--output [OUTPUT]', 'Provide a path to output json file.' do |output| options.output_file = output end p.on_tail('-h', '--help', 'Show this message') do puts p exit end # Another typical switch to print the version. p.on_tail('--version', 'Show version') do puts CucumberJunitToJson::VERSION exit end end parser.parse!(args) raise Error, parser.banner unless options.junit_dir && options.feature_dir options end