From 2f0dd9136800f33d42452f02016ad70836522846 Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Thu, 12 Mar 2026 13:47:24 -0400 Subject: [PATCH 1/6] Starting cucumber 10 support. --- lib/detest/publishers/cucumber.rb | 5 ++ lib/detest/publishers/cucumber_10_x/cli.rb | 51 +++++++++++ .../publishers/cucumber_10_x/runtime.rb | 30 +++++++ lib/detest/workers/cucumber.rb | 6 ++ lib/detest/workers/cucumber_10_x/cli.rb | 51 +++++++++++ lib/detest/workers/cucumber_10_x/event_bus.rb | 35 ++++++++ lib/detest/workers/cucumber_10_x/runtime.rb | 88 +++++++++++++++++++ 7 files changed, 266 insertions(+) create mode 100644 lib/detest/publishers/cucumber_10_x/cli.rb create mode 100644 lib/detest/publishers/cucumber_10_x/runtime.rb create mode 100644 lib/detest/workers/cucumber_10_x/cli.rb create mode 100644 lib/detest/workers/cucumber_10_x/event_bus.rb create mode 100644 lib/detest/workers/cucumber_10_x/runtime.rb diff --git a/lib/detest/publishers/cucumber.rb b/lib/detest/publishers/cucumber.rb index dc3c20f..beff7c1 100644 --- a/lib/detest/publishers/cucumber.rb +++ b/lib/detest/publishers/cucumber.rb @@ -1,8 +1,13 @@ cucumber_version = Gem::Version.new(Cucumber::VERSION) cucumber_4_x_version = Gem::Version.new("4.0.0") +cucumber_10_version = Gem::Version.new("10.0.0") +cucumber_11_version = Gem::Version.new("11.0.0") if cucumber_version < cucumber_4_x_version require_relative "cucumber_3_x/cli" require_relative "cucumber_3_x/runtime" +elsif cucumber_version >= cucumber_10_version && cucumber_version < cucumber_11_version + require_relative "cucumber_10_x/cli" + require_relative "cucumber_10_x/runtime" else require_relative "cucumber_unsupported/cli" end diff --git a/lib/detest/publishers/cucumber_10_x/cli.rb b/lib/detest/publishers/cucumber_10_x/cli.rb new file mode 100644 index 0000000..0ade933 --- /dev/null +++ b/lib/detest/publishers/cucumber_10_x/cli.rb @@ -0,0 +1,51 @@ +require "cucumber/cli/main" + +module Detest + module Publishers + module Cucumber + class Cli < ::Cucumber::Cli::Main + + def execute!(adapter, existing_runtime = nil) + trap_interrupt + + runtime = if existing_runtime + existing_runtime.configure(configuration) + existing_runtime + else + ::Detest::Publishers::Cucumber::Runtime.new(configuration) + end + + runtime.run!(adapter) + if ::Cucumber.wants_to_quit + exit_unable_to_finish + else + if runtime.failure? + exit_tests_failed + else + exit_ok + end + end + rescue SystemExit => e + @kernel.exit(e.status) + rescue ::Cucumber::FileNotFoundException => e + @err.puts(e.message) + @err.puts("Couldn't open #{e.path}") + exit_unable_to_finish + rescue ::Cucumber::FeatureFolderNotFoundException => e + @err.puts(e.message + '. You can use `cucumber --init` to get started.') + exit_unable_to_finish + rescue ::Cucumber::Cli::ProfilesNotDefinedError, ::Cucumber::Cli::YmlLoadError, ::Cucumber::Cli::ProfileNotFound => e + @err.puts(e.message) + exit_unable_to_finish + rescue Errno::EACCES, Errno::ENOENT => e + @err.puts("#{e.message} (#{e.class})") + exit_unable_to_finish + rescue Exception => e + @err.puts("#{e.message} (#{e.class})") + @err.puts(e.backtrace.join("\n")) + exit_unable_to_finish + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/publishers/cucumber_10_x/runtime.rb b/lib/detest/publishers/cucumber_10_x/runtime.rb new file mode 100644 index 0000000..a108ab1 --- /dev/null +++ b/lib/detest/publishers/cucumber_10_x/runtime.rb @@ -0,0 +1,30 @@ +require "cucumber/runtime" + +module Detest + module Publishers + module Cucumber + class Runtime < ::Cucumber::Runtime + def run!(adapter) + load_step_definitions + install_wire_plugin + fire_after_configuration_hook + + adapter.enqueue(feature_file_paths) + end + + def feature_file_paths + our_cwd = Dir.pwd + feature_files.map do |s_file| + s_path = Pathname(s_file) + if s_path.absolute? + s_path.relative_path_from(our_cwd).to_s + else + s_full_path = Pathname(our_cwd) + s_path + s_full_path.relative_path_from(our_cwd).to_s + end + end + end + end + end + end +end diff --git a/lib/detest/workers/cucumber.rb b/lib/detest/workers/cucumber.rb index 5df6e8b..ef5e5e4 100644 --- a/lib/detest/workers/cucumber.rb +++ b/lib/detest/workers/cucumber.rb @@ -1,9 +1,15 @@ cucumber_version = Gem::Version.new(Cucumber::VERSION) cucumber_4_x_version = Gem::Version.new("4.0.0") +cucumber_10_version = Gem::Version.new("10.0.0") +cucumber_11_version = Gem::Version.new("11.0.0") if cucumber_version < cucumber_4_x_version require_relative "cucumber_3_x/cli" require_relative "cucumber_3_x/runtime" require_relative "cucumber_3_x/event_bus" +elsif cucumber_version >= cucumber_10_version && cucumber_version < cucumber_11_version + require_relative "cucumber_10_x/cli" + require_relative "cucumber_10_x/runtime" + require_relative "cucumber_10_x/event_bus" else require_relative "cucumber_unsupported/cli" end diff --git a/lib/detest/workers/cucumber_10_x/cli.rb b/lib/detest/workers/cucumber_10_x/cli.rb new file mode 100644 index 0000000..2decce9 --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/cli.rb @@ -0,0 +1,51 @@ +require "cucumber/cli/main" + +module Detest + module Workers + module Cucumber + class Cli < ::Cucumber::Cli::Main + + def execute!(adapter, existing_runtime = nil) + trap_interrupt + + runtime = if existing_runtime + existing_runtime.configure(configuration) + existing_runtime + else + ::Detest::Workers::Cucumber::Runtime.new(configuration.to_hash.merge(:event_bus => Detest::Workers::Cucumber::EventBus.make_event_bus)) + end + + runtime.run!(adapter) + if ::Cucumber.wants_to_quit + exit_unable_to_finish + else + if runtime.failure? + exit_tests_failed + else + exit_ok + end + end + rescue SystemExit => e + @kernel.exit(e.status) + rescue ::Cucumber::FileNotFoundException => e + @err.puts(e.message) + @err.puts("Couldn't open #{e.path}") + exit_unable_to_finish + rescue ::Cucumber::FeatureFolderNotFoundException => e + @err.puts(e.message + '. You can use `cucumber --init` to get started.') + exit_unable_to_finish + rescue ::Cucumber::Cli::ProfilesNotDefinedError, ::Cucumber::Cli::YmlLoadError, ::Cucumber::Cli::ProfileNotFound => e + @err.puts(e.message) + exit_unable_to_finish + rescue Errno::EACCES, Errno::ENOENT => e + @err.puts("#{e.message} (#{e.class})") + exit_unable_to_finish + rescue Exception => e + @err.puts("#{e.message} (#{e.class})") + @err.puts(e.backtrace.join("\n")) + exit_unable_to_finish + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/workers/cucumber_10_x/event_bus.rb b/lib/detest/workers/cucumber_10_x/event_bus.rb new file mode 100644 index 0000000..6bf73ab --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/event_bus.rb @@ -0,0 +1,35 @@ +module Detest + module Workers + module Cucumber + module EventBus + class TestFileStarted < ::Cucumber::Core::Event.new(:path) + attr_reader :path + end + + class TestFileFinished < ::Cucumber::Core::Event.new(:path) + attr_reader :path + end + + def self.make_event_bus + ::Cucumber::Core::EventBus.new(registry) + end + + def self.registry + ::Cucumber::Core::Events.build_registry( + ::Cucumber::Core::Events::TestCaseStarted, + ::Cucumber::Core::Events::TestCaseFinished, + ::Cucumber::Core::Events::TestStepFinished, + ::Cucumber::Events::TestStepStarted, + ::Cucumber::Events::StepDefinitionRegistered, + ::Cucumber::Events::StepActivated, + ::Cucumber::Events::TestRunFinished, + ::Cucumber::Events::GherkinSourceRead, + ::Cucumber::Events::TestRunStarted, + TestFileStarted, + TestFileFinished + ) + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/workers/cucumber_10_x/runtime.rb b/lib/detest/workers/cucumber_10_x/runtime.rb new file mode 100644 index 0000000..92637a7 --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/runtime.rb @@ -0,0 +1,88 @@ +require "cucumber/runtime" + +module Detest + module Workers + module Cucumber + class Runtime < ::Cucumber::Runtime + def test_file_started(event) + @test_start_time = Time.now + @current_test_file = event.path + @passing = true + end + + def test_case_finished(event) + @passing = false if event.result.failed? + end + + def test_file_finished(event) + test_end_time = Time.now + unless @passing + @adapter.log_failure(@current_test_file) + end + time_elapsed = test_end_time - @test_start_time + @adapter.log_result( + @current_test_file, + @passing, + { + duration: time_elapsed + } + ) + @test_start_time = nil + @current_test_file = nil + end + + def run!(adapter) + @adapter = adapter + load_step_definitions + install_wire_plugin + fire_after_configuration_hook + # TODO: can we remove this state? + self.visitor = report + + receiver = ::Cucumber::Core::Test::Runner.new(@configuration.event_bus) + + @configuration.event_bus.on(:test_file_started) do |event| + self.test_file_started(event) + end + + @configuration.event_bus.on(:test_file_finished) do |event| + self.test_file_finished(event) + end + + @configuration.event_bus.on(:test_case_finished) do |event| + self.test_case_finished(event) + end + + adapter.record_worker + if ENV["DETEST_RERUN"] == "true" + while f_file = adapter.fpop + @configuration.notify :test_file_started, f_file + fs = process_feature_file(f_file) + compile fs, receiver, filters + @configuration.notify :test_file_finished, f_file + end + else + while f_file = adapter.pop + @configuration.notify :test_file_started, f_file + fs = process_feature_file(f_file) + compile fs, receiver, filters + @configuration.notify :test_file_finished, f_file + end + end + @configuration.notify :test_run_finished + adapter.end_worker + end + + def process_feature_file(file) + f_filespecs = ::Cucumber::FileSpecs.new([file]) + f_files = f_filespecs.files + f_files.map do |path| + source = NormalisedEncodingFile.read(path) + @configuration.notify :gherkin_source_read, path, source + ::Cucumber::Core::Gherkin::Document.new(path, source) + end + end + end + end + end +end \ No newline at end of file From 61949dabf7ba09f7ecc7707ff97a602ff1112e5d Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Thu, 12 Mar 2026 14:12:34 -0400 Subject: [PATCH 2/6] Update minor runtime options. --- lib/detest/workers/cucumber_10_x/runtime.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/detest/workers/cucumber_10_x/runtime.rb b/lib/detest/workers/cucumber_10_x/runtime.rb index 92637a7..bba22fd 100644 --- a/lib/detest/workers/cucumber_10_x/runtime.rb +++ b/lib/detest/workers/cucumber_10_x/runtime.rb @@ -33,9 +33,10 @@ def test_file_finished(event) def run!(adapter) @adapter = adapter + load_step_definitions - install_wire_plugin - fire_after_configuration_hook + fire_install_plugin_hook + fire_before_all_hook unless dry_run? # TODO: can we remove this state? self.visitor = report @@ -58,14 +59,14 @@ def run!(adapter) while f_file = adapter.fpop @configuration.notify :test_file_started, f_file fs = process_feature_file(f_file) - compile fs, receiver, filters + compile fs, receiver, filters, @configuration.event_bus @configuration.notify :test_file_finished, f_file end else while f_file = adapter.pop @configuration.notify :test_file_started, f_file fs = process_feature_file(f_file) - compile fs, receiver, filters + compile fs, receiver, filters, @configuration.event_bus @configuration.notify :test_file_finished, f_file end end From 1f12d543d931aef2eae2b3221d92b298c29c36bf Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Thu, 12 Mar 2026 14:14:26 -0400 Subject: [PATCH 3/6] Updating 10x publisher adapter. --- lib/detest/publishers/cucumber_10_x/runtime.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/detest/publishers/cucumber_10_x/runtime.rb b/lib/detest/publishers/cucumber_10_x/runtime.rb index a108ab1..becd0e9 100644 --- a/lib/detest/publishers/cucumber_10_x/runtime.rb +++ b/lib/detest/publishers/cucumber_10_x/runtime.rb @@ -5,9 +5,12 @@ module Publishers module Cucumber class Runtime < ::Cucumber::Runtime def run!(adapter) + @configuration.notify :envelope, Cucumber::Messages::Envelope.new( + meta: MetaMessageBuilder.build_meta_message + ) + load_step_definitions - install_wire_plugin - fire_after_configuration_hook + fire_install_plugin_hook adapter.enqueue(feature_file_paths) end From 45874c3069d9669f6978c8dd2cfc2070008d8f92 Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Thu, 12 Mar 2026 15:37:08 -0400 Subject: [PATCH 4/6] Add messages require. --- lib/detest/publishers/cucumber_10_x/runtime.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/detest/publishers/cucumber_10_x/runtime.rb b/lib/detest/publishers/cucumber_10_x/runtime.rb index becd0e9..9717f5c 100644 --- a/lib/detest/publishers/cucumber_10_x/runtime.rb +++ b/lib/detest/publishers/cucumber_10_x/runtime.rb @@ -1,4 +1,5 @@ require "cucumber/runtime" +require "cucumber/messages" module Detest module Publishers From fbf16c80b991106d93b42e9a386f5c02f27d181f Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Thu, 12 Mar 2026 16:08:58 -0400 Subject: [PATCH 5/6] Fix name reference. --- lib/detest/publishers/cucumber_10_x/runtime.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/detest/publishers/cucumber_10_x/runtime.rb b/lib/detest/publishers/cucumber_10_x/runtime.rb index 9717f5c..12fa2bb 100644 --- a/lib/detest/publishers/cucumber_10_x/runtime.rb +++ b/lib/detest/publishers/cucumber_10_x/runtime.rb @@ -6,7 +6,7 @@ module Publishers module Cucumber class Runtime < ::Cucumber::Runtime def run!(adapter) - @configuration.notify :envelope, Cucumber::Messages::Envelope.new( + @configuration.notify :envelope, ::Cucumber::Messages::Envelope.new( meta: MetaMessageBuilder.build_meta_message ) From 35bd089e0ec472297e1d99f8ab55837fa5be332e Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Mon, 16 Mar 2026 13:29:37 -0400 Subject: [PATCH 6/6] Updating event bus list. --- lib/detest/workers/cucumber_10_x/event_bus.rb | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/detest/workers/cucumber_10_x/event_bus.rb b/lib/detest/workers/cucumber_10_x/event_bus.rb index 6bf73ab..3c522fd 100644 --- a/lib/detest/workers/cucumber_10_x/event_bus.rb +++ b/lib/detest/workers/cucumber_10_x/event_bus.rb @@ -1,3 +1,5 @@ +require "cucumber/events" + module Detest module Workers module Cucumber @@ -15,18 +17,25 @@ def self.make_event_bus end def self.registry - ::Cucumber::Core::Events.build_registry( - ::Cucumber::Core::Events::TestCaseStarted, - ::Cucumber::Core::Events::TestCaseFinished, - ::Cucumber::Core::Events::TestStepFinished, - ::Cucumber::Events::TestStepStarted, - ::Cucumber::Events::StepDefinitionRegistered, - ::Cucumber::Events::StepActivated, - ::Cucumber::Events::TestRunFinished, - ::Cucumber::Events::GherkinSourceRead, - ::Cucumber::Events::TestRunStarted, - TestFileStarted, - TestFileFinished + ::Cucumber::Core::Events.build_registry( + ::Cucumber::Events::GherkinSourceParsed, + ::Cucumber::Events::GherkinSourceRead, + ::Cucumber::Events::HookTestStepCreated, + ::Cucumber::Events::StepActivated, + ::Cucumber::Events::StepDefinitionRegistered, + ::Cucumber::Events::TestCaseCreated, + ::Cucumber::Events::TestCaseFinished, + ::Cucumber::Events::TestCaseStarted, + ::Cucumber::Events::TestCaseReady, + ::Cucumber::Events::TestRunFinished, + ::Cucumber::Events::TestRunStarted, + ::Cucumber::Events::TestStepCreated, + ::Cucumber::Events::TestStepFinished, + ::Cucumber::Events::TestStepStarted, + ::Cucumber::Events::Envelope, + ::Cucumber::Events::UndefinedParameterType, + TestFileStarted, + TestFileFinished ) end end