From 10b963286cb1d7434c6a7e07c49f72ae88c57166 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 12 Sep 2026 23:01:11 -0700 Subject: [PATCH] fix: issues in code --- lib/appium_lib/appium.rb | 10 +-- lib/appium_lib/driver.rb | 3 +- test/regression_test.rb | 132 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 test/regression_test.rb diff --git a/lib/appium_lib/appium.rb b/lib/appium_lib/appium.rb index 8db8f739..5664459b 100644 --- a/lib/appium_lib/appium.rb +++ b/lib/appium_lib/appium.rb @@ -110,7 +110,7 @@ def load_settings(opts = {}) # @return [Array] list of require files as an array, nil if require doesn't exist def expand_required_files(base_dir, file_paths) # ensure files are absolute - Array(file_paths).map! do |f| + file_paths = Array(file_paths).map do |f| file = File.exist?(f) ? f : File.join(base_dir, f) file = File.expand_path file @@ -171,10 +171,10 @@ def promote_singleton_appium_methods(modules, driver = $driver) # override unless there's an existing method with matching arity next if const.respond_to?(m) && const.method(m).arity == driver.method(m).arity - const.send(:define_singleton_method, m) do |*args, &block| - super(*args, &block) # promote.rb + const.send(:define_singleton_method, m) do |*args, **kwargs, &block| + super(*args, **kwargs, &block) # promote.rb rescue NoMethodError, ArgumentError - driver.send m, *args, &block if driver.respond_to?(m) + driver.send m, *args, **kwargs, &block if driver.respond_to?(m) end end end @@ -219,7 +219,7 @@ def promote_appium_methods(class_array, driver = $driver) # https://github.com/appium/ruby_lib/issues/917 # Remove the method before adding it. - remove_method method if method_defined? method + remove_method method if instance_methods(false).include? method define_method method do |*args, &block| # Prefer existing method. diff --git a/lib/appium_lib/driver.rb b/lib/appium_lib/driver.rb index 8135e42f..399e9840 100644 --- a/lib/appium_lib/driver.rb +++ b/lib/appium_lib/driver.rb @@ -564,7 +564,8 @@ def window_rect # @option http_client_ops [Hash] :read_timeout Custom read timeout for http client. # @return [Selenium::WebDriver] the new global driver def start_driver(http_client_ops = { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 }) - if http_client_ops[:http_client].nil? + http_client = http_client_ops[:http_client] + if http_client.nil? http_client = ::Appium::Http::Default.new(open_timeout: http_client_ops[:open_timeout], read_timeout: http_client_ops[:read_timeout]) end diff --git a/test/regression_test.rb b/test/regression_test.rb new file mode 100644 index 00000000..cccf6750 --- /dev/null +++ b/test/regression_test.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require 'appium_lib' +require 'tmpdir' + +class RegressionTest < Minitest::Test + def test_expand_single_required_file + Dir.mktmpdir do |dir| + path = File.join(dir, 'helper.rb') + File.write(path, '') + + assert_equal [path], Appium.expand_required_files(dir, 'helper.rb') + end + end + + def test_expand_required_directory_and_skip_missing_files + Dir.mktmpdir do |dir| + nested = File.join(dir, 'helpers') + Dir.mkdir(nested) + path = File.join(nested, 'helper.rb') + File.write(path, '') + File.write(File.join(nested, 'notes.txt'), '') + + assert_equal [path], Appium.expand_required_files(dir, %w(helpers missing.rb)) + assert_empty Appium.expand_required_files(dir, 'missing.rb') + end + end + + def test_promote_preserves_inherited_method + parent = Class.new do + def back + :inherited + end + end + child = Class.new(parent) + driver = Object.new + def driver.back + :driver + end + + Appium.promote_appium_methods(child, driver) + + assert_equal :inherited, child.new.back + end + + def test_promote_again_uses_new_driver + target = Class.new + first = Object.new + def first.back + :first + end + second = Object.new + def second.back + :second + end + + Appium.promote_appium_methods(target, first) + assert_equal :first, target.new.back + Appium.promote_appium_methods(target, second) + assert_equal :second, target.new.back + end + + def test_singleton_promotion_forwards_keywords_and_block + driver = Object.new + def driver.log_event(vendor:, event:) + yield [vendor, event] + end + target = Module.new + Appium.promote_singleton_appium_methods([target], driver) + + result = target.log_event(vendor: 'test', event: 'event') { |values| values.join(':') } + + assert_equal 'test:event', result + end + + def test_singleton_promotion_preserves_positional_hash + driver = Object.new + def driver.command(options) + options + end + target = Module.new + Appium.promote_singleton_appium_methods([target], driver) + + assert_equal({ value: 1 }, target.command({ value: 1 })) + end + + class RecordingCore + attr_reader :http_client + + def automation_name + :uiautomator2 + end + + def start_driver(http_client_ops:, **) + @http_client = http_client_ops[:http_client] + nil + end + + def appium_server_version + {} + end + end + + def test_start_driver_passes_custom_http_client + client = Object.new + driver = build_driver + + driver.start_driver(http_client: client) + + assert_same client, driver.http_client + end + + def test_start_driver_builds_default_http_client + driver = build_driver + + driver.start_driver + + assert_instance_of Appium::Http::Default, driver.http_client + end + + private + + def build_driver + driver = Appium::Driver.allocate + driver.instance_variable_set(:@core, RecordingCore.new) + def driver.server_url + 'http://127.0.0.1:4723' + end + driver + end +end