lib/knapsack_pro/runners/queue/cucumber_runner.rb
# frozen_string_literal: true
module KnapsackPro
module Runners
module Queue
class CucumberRunner < BaseRunner
def self.run(args)
require 'cucumber/rake/task'
ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_cucumber
ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
adapter_class = KnapsackPro::Adapters::CucumberAdapter
KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
runner = new(adapter_class)
accumulator = {
status: :next,
runner: runner,
can_initialize_queue: true,
args: args,
exitstatus: 0,
node_test_file_paths: [],
}
while accumulator[:status] == :next
handle_signal!
accumulator = run_tests(accumulator)
end
Kernel.exit(accumulator[:exitstatus])
end
def self.run_tests(accumulator)
runner = accumulator.fetch(:runner)
can_initialize_queue = accumulator.fetch(:can_initialize_queue)
args = accumulator.fetch(:args)
exitstatus = accumulator.fetch(:exitstatus)
node_test_file_paths = accumulator.fetch(:node_test_file_paths)
test_file_paths = runner.test_file_paths(
can_initialize_queue: can_initialize_queue,
executed_test_files: node_test_file_paths
)
if test_file_paths.empty?
unless node_test_file_paths.empty?
KnapsackPro::Adapters::CucumberAdapter.verify_bind_method_called
end
KnapsackPro::Hooks::Queue.call_after_queue
KnapsackPro::Report.save_node_queue_to_api
return {
status: :completed,
exitstatus: exitstatus,
}
else
subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
KnapsackPro.tracker.reset!
KnapsackPro.tracker.set_prerun_tests(test_file_paths)
KnapsackPro::Hooks::Queue.call_before_subset_queue
node_test_file_paths += test_file_paths
result_exitstatus = cucumber_run(runner, test_file_paths, args)
exitstatus = result_exitstatus if result_exitstatus != 0
# KnapsackPro::Hooks::Queue.call_after_subset_queue
# KnapsackPro::Report.save_subset_queue_to_file
# are called in adapter: lib/knapsack_pro/adapters/cucumber_adapter.rb
return {
status: :next,
runner: runner,
can_initialize_queue: false,
args: args,
exitstatus: exitstatus,
node_test_file_paths: node_test_file_paths,
}
end
end
private
def self.cucumber_run(runner, test_file_paths, args)
stringify_test_file_paths = KnapsackPro::TestFilePresenter.stringify_paths(test_file_paths)
cmd = [
KnapsackPro::Config::Env.cucumber_queue_prefix,
%Q[cucumber #{args} --require #{runner.test_dir} -- #{stringify_test_file_paths}]
].join(' ')
Kernel.system(cmd)
# it must be set here so when we call next time above cmd we won't run again:
# KnapsackPro::Hooks::Queue.call_before_queue
# which is defined in lib/knapsack_pro/adapters/cucumber_adapter.rb
ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED'] = 'true'
unless child_status.exited?
raise "Cucumber process execution failed. It's likely that your CI server has exceeded"\
" its available memory. Please try changing CI config or retrying the CI build.\n"\
"Failed command: #{cmd}\n"\
"Process status: #{child_status.inspect}"
end
child_status.exitstatus
end
end
end
end
end