diff --git a/CHANGELOG.md b/CHANGELOG.md index 97568cd5..b897768d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ Read `release_notes.md` for commit level details. ### Bug fixes ### Deprecations +- Stop converting snake cases to camel case for symbols in capabilities + - Please define camel/snake cases in capabilities as-is for the WebDriver capabilities +- Stop implicit symbolizing capabilities + - Historically ruby_lib/ruby_lib_core symbolized capabilities keys from string internally. + - `Appium.symbolize_keys` to build symbolized capabilities if issues occurred by this change. ## [8.0.2] - 2024-04-26 diff --git a/lib/appium_lib_core.rb b/lib/appium_lib_core.rb index 12b0ccb0..8d1a1cfa 100644 --- a/lib/appium_lib_core.rb +++ b/lib/appium_lib_core.rb @@ -22,15 +22,17 @@ require_relative 'appium_lib_core/support/event_firing_bridge' module Appium - # @private - # # convert the top level keys to symbols. # # @param [Hash] hash Hash value to make symbolise + # + # @example + # opts = Appium.symbolize_keys(opts) + # def self.symbolize_keys(hash, nested: false, enable_deprecation_msg: true) # FIXME: As https://github.com/appium/ruby_lib/issues/945, we must remove this implicit string to symbol. # But appium_lib_core's some capability handling expect to be symbol, so we should test to remove - # the mehotds which expect the symbol first. + # the methods which expect the symbol first. raise ::Appium::Core::Error::ArgumentError, 'symbolize_keys requires a hash' unless hash.is_a? Hash hash.each_with_object({}) do |pair, acc| diff --git a/lib/appium_lib_core/common/base/capabilities.rb b/lib/appium_lib_core/common/base/capabilities.rb index caaf5c74..4a6ba521 100644 --- a/lib/appium_lib_core/common/base/capabilities.rb +++ b/lib/appium_lib_core/common/base/capabilities.rb @@ -23,6 +23,20 @@ class Capabilities < ::Selenium::WebDriver::Remote::Capabilities # Appium's capabilities could change by depending on Appium versions. So it does not have # standard options like chrome and firefox etc. So, the implementation should differ from # other browsers. But here should inherit `Options` to follow Selenium. + + # Method override + # FIXME: when we drop "symbolize_keys", this can be removed. + def convert_key(key) + case key + when String + key.to_s + when Symbol + # here do not convert to camel case + key.to_s + else + raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}" + end + end end end end diff --git a/lib/appium_lib_core/driver.rb b/lib/appium_lib_core/driver.rb index 5e6c9e22..ceb5eba6 100644 --- a/lib/appium_lib_core/driver.rb +++ b/lib/appium_lib_core/driver.rb @@ -338,12 +338,6 @@ def initialize def setup_for_new_session(opts = {}) @custom_url = opts.delete :url # to set the custom url as :url - # TODO: Remove when we implement Options - # The symbolize_keys is to keep compatiility for the legacy code, which allows capabilities to give 'string' as the key. - # The toplevel `caps`, `capabilities` and `appium_lib` are expected to be symbol. - # FIXME: First, please try to remove `nested: true` to `nested: false`. - opts = Appium.symbolize_keys(opts, nested: true) - @caps = get_caps(opts) set_appium_lib_specific_values(get_appium_lib_opts(opts)) @@ -635,22 +629,27 @@ def get_appium_lib_opts(opts) opts[:appium_lib] || {} end + # @private + def get_app + @caps[:app] || @caps['app'] + end + # @private # Path to the .apk, .app or .app.zip. # The path can be local, HTTP/S, Windows Share and other path like 'sauce-storage:'. # Use @caps[:app] without modifications if the path isn't HTTP/S or local path. def set_app_path # FIXME: maybe `:app` should check `app` as well. - return unless @caps && @caps[:app] && !@caps[:app].empty? - return if @caps[:app] =~ URI::DEFAULT_PARSER.make_regexp - - app_path = File.expand_path(@caps[:app]) - @caps[:app] = if File.exist? app_path - app_path - else - ::Appium::Logger.warn("Use #{@caps[:app]} directly since #{app_path} does not exist.") - @caps[:app] - end + return unless @caps && get_app && !get_app.empty? + return if get_app =~ URI::DEFAULT_PARSER.make_regexp + + app_path = File.expand_path(get_app) + @caps['app'] = if File.exist? app_path + app_path + else + ::Appium::Logger.warn("Use #{get_app} directly since #{app_path} does not exist.") + get_app + end end # @private @@ -676,7 +675,6 @@ def set_appium_lib_specific_values(appium_lib_opts) # @private def set_appium_device # https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile - # TODO: check if the Appium.symbolize_keys(opts, nested: false) enoug with this @device = @caps[:platformName] || @caps['platformName'] return @device unless @device @@ -685,7 +683,6 @@ def set_appium_device # @private def set_automation_name - # TODO: check if the Appium.symbolize_keys(opts, nested: false) enoug with this candidate = @caps[:automationName] || @caps['automationName'] @automation_name = candidate if candidate @automation_name = convert_downcase @automation_name if @automation_name diff --git a/test/unit/common_test.rb b/test/unit/common_test.rb index 035b838d..135c3725 100644 --- a/test/unit/common_test.rb +++ b/test/unit/common_test.rb @@ -158,10 +158,10 @@ def test_add_appium_prefix_already_have_appium_prefix 'platformVersion' => '11.4', 'deviceName' => 'iPhone Simulator', 'useNewWDA' => true, - 'someCapability1' => 'some_capability1', + 'some_capability1' => 'some_capability1', 'someCapability2' => '', 'some_capability3' => 'string_shold_keep', - 'some_capability4' => { 'nested_key1' => 1, 'nestedKey2' => 2 } + 'some_capability4' => { 'nested_key1' => 1, 'nested_key2' => 2 } } assert_equal expected, base_caps.as_json @@ -196,7 +196,7 @@ def test_add_appium_prefix_already_have_appium_prefix 'appium:some_capability3' => 'string_shold_keep', 'appium:some_capability4' => { 'nested_key1' => 1, - 'nestedKey2' => 2 + 'nested_key2' => 2 } } # for testing diff --git a/test/unit/driver_test.rb b/test/unit/driver_test.rb index 6093eeac..ad5eec0b 100644 --- a/test/unit/driver_test.rb +++ b/test/unit/driver_test.rb @@ -49,7 +49,7 @@ def test_with_caps_and_appium_lib opts = { 'caps' => { 'automationName': 'xcuitest' }, appium_lib: {} } driver = ExampleDriver.new(opts) refute_nil driver - assert_equal driver.core.caps[:automationName], 'xcuitest' + assert_equal driver.core.caps[:automationName], nil end def test_verify_appium_core_base_capabilities_create_capabilities @@ -67,7 +67,7 @@ def test_verify_appium_core_base_capabilities_create_capabilities assert_equal 'test/functional/app/UICatalog.app.zip', caps_with_json['app'] assert_equal 'XCUITest', caps_with_json['automationName'] assert_equal 'iPhone Simulator', caps_with_json['deviceName'] - assert_equal 'some_capability1', caps_with_json['someCapability1'] + assert_equal 'some_capability1', caps_with_json['some_capability1'] assert_equal 'someCapability2', caps_with_json['someCapability2'] assert_equal 'ios', caps[:platformName]