appium_lib_core 5.4.0 → 5.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d218a7a8a40159dbd710c8aec292346297a92b98f7026456fd7a29c5794f2914
4
- data.tar.gz: 9606b1256c653c693ed17b344cec7fe2adaf58e8f5f95c9be3f0b9b3811cd79c
3
+ metadata.gz: 36c3e5d802524fd73d0bd2f3f4c383dc8ca315b5fab8d91126aa38360023513e
4
+ data.tar.gz: 3133b9cacbc2ccb65d44be5abc2ead266e70b84603a37d33f4697d71e5a28320
5
5
  SHA512:
6
- metadata.gz: 9cf6fda7cec0c09f3b83e0bd786d3a914a8d24c1f1f6f355570c83f9ae1b33c486608370d6a4c5b5cd2aeab73df802509dce93d6de46efcf12cd8a86e3d9c6f9
7
- data.tar.gz: 4f57441793ffeb9b40d9f6cc5d1456e836b05cd166775d2ec3c2319767daf36e44f66b498b69fa3b4f5f3e304718fd5a32fa717b732983294ed8713d0950c33a
6
+ metadata.gz: 606343375d1a70d5b0d3f6c8b3a01d5bb4cb3b7668bfe622bae0ba3d35ca57997c1dd1b081934cade812a74bce250fa8fd0d3328d98dd94da451a34677021ef3
7
+ data.tar.gz: 7315f007b57556ba24d615aea8fc48d05808a89f6cb408b400a560e5ea032827b732b20c15f3682e36abe48f3d30fcfd6896368e21a479e1adecf73b30459cc3
data/CHANGELOG.md CHANGED
@@ -10,6 +10,21 @@ Read `release_notes.md` for commit level details.
10
10
 
11
11
  ### Deprecations
12
12
 
13
+ ## [5.5.1] - 2022-10-10
14
+
15
+ ### Bug fixes
16
+ - Keep converting String to Symbol for `capabilities`, `caps` and `appium_lib` for the backward compatibility
17
+ - Wrong `automationName` and `platformName` detection in this library before starting a session
18
+
19
+ ### Deprecations
20
+ - Converting `capabilities`, `caps` and `appium_lib` from String to Symbol
21
+ - They are expected to be Symbol. Nothing affects existing users who already give the above keys as Symbol for `Appium::Core.for`.
22
+
23
+ ## [5.5.0] - 2022-10-09
24
+
25
+ ### Bug fixes
26
+ - Removed forcefully converting keys of capabilities into symbol, which caused unexpected capabilities format issue [ruby_lib/945](https://github.com/appium/ruby_lib/issues/945)
27
+
13
28
  ## [5.4.0] - 2022-10-01
14
29
 
15
30
  ### Enhancements
@@ -53,8 +53,8 @@ module Appium
53
53
  # Override
54
54
  # Creates session handling.
55
55
  #
56
- # @param [::Selenium::WebDriver::Remote::Capabilities, Hash] capabilities A capability
57
- # @return [::Selenium::WebDriver::Remote::Capabilities]
56
+ # @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
57
+ # @return [::Appium::Core::Base::Capabilities]
58
58
  #
59
59
  # @example
60
60
  #
@@ -89,10 +89,10 @@ module Appium
89
89
  # Append +appium:+ prefix for Appium following W3C spec
90
90
  # https://www.w3.org/TR/webdriver/#dfn-validate-capabilities
91
91
  #
92
- # @param [::Selenium::WebDriver::Remote::Capabilities, Hash] capabilities A capability
93
- # @return [::Selenium::WebDriver::Remote::Capabilities]
92
+ # @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
93
+ # @return [::Appium::Core::Base::Capabilities]
94
94
  def add_appium_prefix(capabilities)
95
- w3c_capabilities = ::Selenium::WebDriver::Remote::Capabilities.new
95
+ w3c_capabilities = ::Appium::Core::Base::Capabilities.new
96
96
 
97
97
  capabilities = capabilities.send(:capabilities) unless capabilities.is_a?(Hash)
98
98
 
@@ -111,12 +111,12 @@ module Appium
111
111
 
112
112
  private
113
113
 
114
- def camel_case(str)
115
- str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
114
+ def camel_case(str_or_sym)
115
+ str_or_sym.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
116
116
  end
117
117
 
118
118
  def extension_prefix?(capability_name)
119
- snake_cased_capability_names = ::Selenium::WebDriver::Remote::Capabilities::KNOWN.map(&:to_s)
119
+ snake_cased_capability_names = ::Appium::Core::Base::Capabilities::KNOWN.map(&:to_s)
120
120
  camel_cased_capability_names = snake_cased_capability_names.map { |v| camel_case(v) }
121
121
 
122
122
  # Check 'EXTENSION_CAPABILITY_PATTERN'
@@ -126,7 +126,7 @@ module Appium
126
126
  end
127
127
 
128
128
  def json_create(value)
129
- ::Selenium::WebDriver::Remote::Capabilities.json_create(value)
129
+ ::Appium::Core::Base::Capabilities.json_create(value)
130
130
  end
131
131
 
132
132
  public
@@ -182,7 +182,7 @@ module Appium
182
182
 
183
183
  # Port from MJSONWP
184
184
  def session_capabilities
185
- ::Selenium::WebDriver::Remote::Capabilities.json_create execute(:get_capabilities)
185
+ ::Appium::Core::Base::Capabilities.json_create execute(:get_capabilities)
186
186
  end
187
187
 
188
188
  # Override for safe. Newer ruby selenium webdriver already has the same code
@@ -345,6 +345,9 @@ module Appium
345
345
  element_id = element_id_from(arg)
346
346
  return ::Appium::Core::Element.new(self, element_id) if element_id
347
347
 
348
+ shadow_root_id = shadow_root_id_from(arg)
349
+ return ::Selenium::WebDriver::Remote::ShadowRoot.new self, shadow_root_id if shadow_root_id
350
+
348
351
  arg.each { |k, v| arg[k] = unwrap_script_result(v) }
349
352
  else
350
353
  arg
@@ -15,22 +15,14 @@
15
15
  module Appium
16
16
  module Core
17
17
  class Base
18
- module Capabilities
19
- # @private
20
- # @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
21
- # this client sends capabilities to Appium server as JSON format.
22
- # @return [::Selenium::WebDriver::Remote::Capabilities] Return instance of Appium::Core::Base::Capabilities
23
- # inherited ::Selenium::WebDriver::Remote::Capabilities
24
- def self.create_capabilities(opts_caps = {})
25
- # TODO: Move to 'Options' way instead of 'Capabilities'.
26
- # Selenium 5 will have Options instead of 'Capabilities'.
27
- # https://github.com/SeleniumHQ/selenium/blob/trunk/rb/lib/selenium/webdriver/common/options.rb
28
- # Then, Ruby client also shoud move to the Options way.
29
- # Appium's capabilities could change by depending on Appium versions. So it does not have
30
- # standard options like chrome and firefox etc. So, the implementation should differ from
31
- # other browsers. But here should inherit `Options` to follow Selenium.
32
- ::Selenium::WebDriver::Remote::Capabilities.new(opts_caps)
33
- end
18
+ class Capabilities < ::Selenium::WebDriver::Remote::Capabilities
19
+ # TODO: Move to 'Options' way instead of 'Capabilities'.
20
+ # Selenium 5 will have Options instead of 'Capabilities'.
21
+ # https://github.com/SeleniumHQ/selenium/blob/trunk/rb/lib/selenium/webdriver/common/options.rb
22
+ # Then, Ruby client also shoud move to the Options way.
23
+ # Appium's capabilities could change by depending on Appium versions. So it does not have
24
+ # standard options like chrome and firefox etc. So, the implementation should differ from
25
+ # other browsers. But here should inherit `Options` to follow Selenium.
34
26
  end
35
27
  end
36
28
  end
@@ -17,10 +17,6 @@ module Appium
17
17
  module Error
18
18
  class CoreError < StandardError; end
19
19
 
20
- # Capability related errors
21
- class NoCapabilityError < CoreError; end
22
- class CapabilityStructureError < CoreError; end
23
-
24
20
  # Appium related errors
25
21
  class NotSupportedAppiumServer < CoreError; end
26
22
  class NoSuchElementError < CoreError; end
@@ -293,8 +293,11 @@ module Appium
293
293
  @delegate_target = self # for testing purpose
294
294
  @automation_name = nil # initialise before 'set_automation_name'
295
295
 
296
- opts = Appium.symbolize_keys opts
297
- validate_keys(opts)
296
+ # TODO: Remove when we implement Options
297
+ # The symbolize_keys is to keep compatiility for the legacy code, which allows capabilities to give 'string' as the key.
298
+ # The toplevel `caps`, `capabilities` and `appium_lib` are expected to be symbol.
299
+ # FIXME: First, please try to remove `nested: true` to `nested: false`.
300
+ opts = Appium.symbolize_keys(opts, nested: true)
298
301
 
299
302
  @custom_url = opts.delete :url
300
303
  @caps = get_caps(opts)
@@ -371,7 +374,7 @@ module Appium
371
374
  begin
372
375
  @driver = ::Appium::Core::Base::Driver.new(listener: @listener,
373
376
  http_client: @http_client,
374
- capabilities: @caps, # ::Selenium::WebDriver::Remote::Capabilities
377
+ capabilities: @caps, # ::Appium::Core::Base::Capabilities
375
378
  url: @custom_url,
376
379
  wait_timeout: @wait_timeout,
377
380
  wait_interval: @wait_interval,
@@ -489,14 +492,24 @@ module Appium
489
492
 
490
493
  private
491
494
 
495
+ def convert_to_symbol(value)
496
+ if value.nil?
497
+ value
498
+ else
499
+ value.to_sym
500
+ end
501
+ end
502
+
492
503
  # @private
493
504
  def extend_for(device:, automation_name:) # rubocop:disable Metrics/CyclomaticComplexity
494
505
  extend Appium::Core
495
506
  extend Appium::Core::Device
496
507
 
497
- case device
508
+ sym_automation_name = convert_to_symbol(automation_name)
509
+
510
+ case convert_to_symbol(device)
498
511
  when :android
499
- case automation_name
512
+ case sym_automation_name
500
513
  when :espresso
501
514
  ::Appium::Core::Android::Espresso::Bridge.for self
502
515
  when :uiautomator2
@@ -507,7 +520,7 @@ module Appium
507
520
  ::Appium::Core::Android::Uiautomator1::Bridge.for self
508
521
  end
509
522
  when :ios, :tvos
510
- case automation_name
523
+ case sym_automation_name
511
524
  when :safari
512
525
  ::Appium::Logger.debug('SafariDriver for iOS')
513
526
  when :xcuitest
@@ -516,7 +529,7 @@ module Appium
516
529
  ::Appium::Core::Ios::Uiautomation::Bridge.for self
517
530
  end
518
531
  when :mac
519
- case automation_name
532
+ case sym_automation_name
520
533
  when :safari
521
534
  ::Appium::Logger.debug('SafariDriver for macOS')
522
535
  when :gecko
@@ -528,7 +541,7 @@ module Appium
528
541
  ::Appium::Logger.debug('macOS Native')
529
542
  end
530
543
  when :windows
531
- case automation_name
544
+ case sym_automation_name
532
545
  when :gecko
533
546
  ::Appium::Logger.debug('Gecko Driver for Windows')
534
547
  else
@@ -538,7 +551,7 @@ module Appium
538
551
  # https://github.com/Samsung/appium-tizen-driver
539
552
  ::Appium::Logger.debug('tizen')
540
553
  else
541
- case automation_name
554
+ case sym_automation_name
542
555
  when :youiengine
543
556
  # https://github.com/YOU-i-Labs/appium-youiengine-driver
544
557
  ::Appium::Logger.debug('YouiEngine')
@@ -555,32 +568,9 @@ module Appium
555
568
  self
556
569
  end
557
570
 
558
- # @private
559
- def validate_keys(opts)
560
- flatten_ops = flatten_hash_keys(opts)
561
-
562
- raise Error::NoCapabilityError unless opts.member?(:caps) || opts.member?(:capabilities)
563
-
564
- if !opts.member?(:appium_lib) && flatten_ops.member?(:appium_lib)
565
- raise Error::CapabilityStructureError, 'Please check the value of appium_lib in the capability'
566
- end
567
-
568
- true
569
- end
570
-
571
- # @private
572
- def flatten_hash_keys(hash, flatten_keys_result = [])
573
- hash.each do |key, value|
574
- flatten_keys_result << key
575
- flatten_hash_keys(value, flatten_keys_result) if value.is_a?(Hash)
576
- end
577
-
578
- flatten_keys_result
579
- end
580
-
581
571
  # @private
582
572
  def get_caps(opts)
583
- Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || {})
573
+ Core::Base::Capabilities.new(opts[:caps] || opts[:capabilities] || {})
584
574
  end
585
575
 
586
576
  # @private
@@ -593,6 +583,7 @@ module Appium
593
583
  # The path can be local, HTTP/S, Windows Share and other path like 'sauce-storage:'.
594
584
  # Use @caps[:app] without modifications if the path isn't HTTP/S or local path.
595
585
  def set_app_path
586
+ # FIXME: maybe `:app` should check `app` as well.
596
587
  return unless @caps && @caps[:app] && !@caps[:app].empty?
597
588
  return if @caps[:app] =~ URI::DEFAULT_PARSER.make_regexp
598
589
 
@@ -631,7 +622,8 @@ module Appium
631
622
  # @private
632
623
  def set_appium_device
633
624
  # https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile
634
- @device = @caps[:platformName]
625
+ # TODO: check if the Appium.symbolize_keys(opts, nested: false) enoug with this
626
+ @device = @caps[:platformName] || @caps['platformName']
635
627
  return @device unless @device
636
628
 
637
629
  @device = @device.is_a?(Symbol) ? @device.downcase : @device.downcase.strip.intern
@@ -639,7 +631,9 @@ module Appium
639
631
 
640
632
  # @private
641
633
  def set_automation_name
642
- @automation_name = @caps[:automationName] if @caps[:automationName]
634
+ # TODO: check if the Appium.symbolize_keys(opts, nested: false) enoug with this
635
+ candidate = @caps[:automationName] || @caps['automationName']
636
+ @automation_name = candidate if candidate
643
637
  @automation_name = if @automation_name
644
638
  @automation_name.is_a?(Symbol) ? @automation_name.downcase : @automation_name.downcase.strip.intern
645
639
  end
@@ -14,7 +14,7 @@
14
14
 
15
15
  module Appium
16
16
  module Core
17
- VERSION = '5.4.0' unless defined? ::Appium::Core::VERSION
18
- DATE = '2022-10-01' unless defined? ::Appium::Core::DATE
17
+ VERSION = '5.5.1' unless defined? ::Appium::Core::VERSION
18
+ DATE = '2022-10-10' unless defined? ::Appium::Core::DATE
19
19
  end
20
20
  end
@@ -21,16 +21,25 @@ require_relative 'appium_lib_core/device'
21
21
  require_relative 'appium_lib_core/element'
22
22
 
23
23
  module Appium
24
- # convert all keys (including nested) to symbols
24
+ # @private
25
+ #
26
+ # convert the top level keys to symbols.
25
27
  #
26
- # based on deep_symbolize_keys & deep_transform_keys from rails
27
- # https://github.com/rails/docrails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/activesupport/lib/active_support/core_ext/hash/keys.rb#L84
28
28
  # @param [Hash] hash Hash value to make symbolise
29
- def self.symbolize_keys(hash)
29
+ def self.symbolize_keys(hash, nested: false, enable_deprecation_msg: true)
30
+ # FIXME: As https://github.com/appium/ruby_lib/issues/945, we must remove this implicit string to symbol.
31
+ # But appium_lib_core's some capability handling expect to be symbol, so we should test to remove
32
+ # the mehotds which expect the symbol first.
30
33
  raise ::Appium::Core::Error::ArgumentError, 'symbolize_keys requires a hash' unless hash.is_a? Hash
31
34
 
32
35
  hash.each_with_object({}) do |pair, acc|
33
36
  key = begin
37
+ if enable_deprecation_msg && !(pair[0].is_a? Symbol)
38
+ ::Appium::Logger.warn("[Deprecation] The key '#{pair[0]}' must be a symbol while currently it " \
39
+ "is #{pair[0].class.name}. Please define the key as a Symbol. " \
40
+ 'Converting it to Symbol for now.')
41
+ end
42
+
34
43
  pair[0].to_sym
35
44
  rescue StandardError => e
36
45
  ::Appium::Logger.warn(e.message)
@@ -38,7 +47,11 @@ module Appium
38
47
  end
39
48
 
40
49
  value = pair[1]
41
- acc[key] = value.is_a?(Hash) ? symbolize_keys(value) : value
50
+ acc[key] = if nested
51
+ value.is_a?(Hash) ? symbolize_keys(value, nested: false, enable_deprecation_msg: true) : value
52
+ else
53
+ value
54
+ end
42
55
  end
43
56
  end
44
57
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appium_lib_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.0
4
+ version: 5.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuaki MATSUO
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-01 00:00:00.000000000 Z
11
+ date: 2022-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: selenium-webdriver