From 37b89b5ce084bce511fb820cf99431ea9234dae3 Mon Sep 17 00:00:00 2001 From: hoanle0126 Date: Mon, 26 Oct 2026 15:43:43 +0700 Subject: [PATCH 1/2] fix: guard after_session hook and avoid duplicate newCommandTimeout capability --- lib/appium_console.rb | 36 ++++++++++++++++++++++++------------ lib/start.rb | 4 +++- test/console_test.rb | 17 +++++++++++++++++ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/appium_console.rb b/lib/appium_console.rb index dfdd40b..32cd01d 100644 --- a/lib/appium_console.rb +++ b/lib/appium_console.rb @@ -13,17 +13,17 @@ module Appium module Console class << self def setup(appium_txt_path) - Pry.send(:define_singleton_method, :pry_load_appium_txt) do |opts = {}| + define_pry_method(:pry_load_appium_txt) do |opts = {}| verbose = opts.fetch :verbose, false path = appium_txt_path Appium.load_appium_txt file: path, verbose: verbose end - Pry.send(:define_singleton_method, :reload) do + define_pry_method(:reload) do parsed = Pry.pry_load_appium_txt - return unless parsed && parsed[:appium_lib] && parsed[:appium_lib][:require] + requires = parsed&.dig(:appium_lib, :require) + return unless requires - requires = parsed[:appium_lib][:require] requires.each do |file| # If a page obj is deleted then load will error. load file @@ -38,10 +38,8 @@ def start cmd = ['-r', start] parsed = Pry.pry_load_appium_txt verbose: true - has_requires = parsed && parsed[:appium_lib] && parsed[:appium_lib][:require] - if has_requires - requires = parsed[:appium_lib][:require] - + requires = parsed&.dig(:appium_lib, :require) + if requires unless requires.empty? load_files = requires.map { |f| "require #{f.dump};" }.join "\n" cmd += ['-e', load_files] @@ -50,14 +48,28 @@ def start $stdout.puts "pry #{cmd.join(' ')}" end - Pry.hooks.add_hook(:after_session, 'Release session hook') do |output, _binding, _pry| - output.puts 'Closing appium session...' - x - end + register_release_session_hook opts = Pry::CLI.parse_options cmd Pry::CLI.start(opts) end + + private + + def define_pry_method(name, &) + Pry.singleton_class.send(:remove_method, name) if Pry.respond_to?(name) + Pry.send(:define_singleton_method, name, &) + end + + def register_release_session_hook + if Pry.hooks.hook_exists?(:after_session, 'Release session hook') + Pry.hooks.delete_hook(:after_session, 'Release session hook') + end + Pry.hooks.add_hook(:after_session, 'Release session hook') do |output, _binding, _pry| + output.puts 'Closing appium session...' + x if respond_to?(:x, true) + end + end end end end diff --git a/lib/start.rb b/lib/start.rb index 722d3b6..97e1e4d 100644 --- a/lib/start.rb +++ b/lib/start.rb @@ -11,7 +11,9 @@ opts = Pry.pry_load_appium_txt # override command timeout so the server doesn't shut down after 60 seconds -new_command_timeout = { caps: { newCommandTimeout: 999_999 }.merge(opts[:caps] || {}) } +caps = opts[:caps] || {} +has_command_timeout = caps.key?(:newCommandTimeout) || caps.key?(:'appium:newCommandTimeout') +new_command_timeout = { caps: (has_command_timeout ? {} : { newCommandTimeout: 999_999 }).merge(caps) } opts = opts.merge(new_command_timeout) core = Appium::Driver.new opts, false core.start_driver diff --git a/test/console_test.rb b/test/console_test.rb index 12c5ab9..d309910 100644 --- a/test/console_test.rb +++ b/test/console_test.rb @@ -43,4 +43,21 @@ def test_reload_loads_changed_file_contents end end end + + def test_after_session_hook_handles_missing_driver_and_repeated_start + Appium::Console.setup('appium.txt') + Appium.stub(:load_appium_txt, {}) do + Pry::CLI.stub(:parse_options, ->(args) { args }) do + Pry::CLI.stub(:start, ->(_args) {}) do + Appium::Console.start + Appium::Console.start + end + end + end + output = StringIO.new + Pry.hooks.exec_hook(:after_session, output, binding, Pry.new) + assert_includes output.string, 'Closing appium session...' + ensure + Pry.hooks.delete_hook(:after_session, 'Release session hook') + end end From eee7028bbc2451c335630f08ed34eb8f553bb7de Mon Sep 17 00:00:00 2001 From: Nacy Dev Date: Tue, 27 Oct 2026 18:31:22 +0700 Subject: [PATCH 2/2] test: invoke after_session release hook directly and assert no hook errors --- test/console_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/console_test.rb b/test/console_test.rb index d309910..ae337f6 100644 --- a/test/console_test.rb +++ b/test/console_test.rb @@ -55,7 +55,9 @@ def test_after_session_hook_handles_missing_driver_and_repeated_start end end output = StringIO.new - Pry.hooks.exec_hook(:after_session, output, binding, Pry.new) + Pry.hooks.errors.clear + Pry.hooks.get_hook(:after_session, 'Release session hook').call(output, binding, Pry.new) + assert_empty Pry.hooks.errors assert_includes output.string, 'Closing appium session...' ensure Pry.hooks.delete_hook(:after_session, 'Release session hook')