percy-appium-app 0.0.9 → 1.0.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: 82432d403ea8909fd0dd473251c8b406378497ff06e6e1806144e83350598013
4
- data.tar.gz: 1f351d8ede37fef600554f98f1ac8bdc7b60124ea62374be65175a26b0cd74c0
3
+ metadata.gz: 85a82be9fb7970cea7e6bfbf92341377a6cf4647f07ce09b3a3c4bb52ff25c11
4
+ data.tar.gz: 03be307ae51ff85c7853cf0284ded40713a91f8bbf4ce36f8f6b7ae69165d26e
5
5
  SHA512:
6
- metadata.gz: 0bc03604787ae7757d95e29d33dfcdc176c9b0733c0b639ed04d75a7aac4061ff915046b34c0d65f21cf3360514f3c9f970dfef46e6bb38f363a5c2b3cd611d7
7
- data.tar.gz: c339d7e5282e110b6351284f72124cab0876ddb4b40c95606096219923ca64cf9b4cd4c8084022274625a6bbdd6c087a90bec4a6a105a3ed9c61a49b756bb1f3
6
+ metadata.gz: 986183165da611f44bfd356562c084bdb942d7f87a2e38418746562c1d056894e8a373c4fe3e61a5aa2c3a44a48c9c42d7701e845b30eec7727fdafbe2a78faa
7
+ data.tar.gz: a21a495cb3cda29740602eb262e23ef67ed7c3fce651d191d1ec91c73bc56b0540f6c8cf55772816da6acdcadf1d07c6040e35a49f4fdfae95e1ca0016ccf2fe
@@ -9,20 +9,24 @@ module Percy
9
9
  def initialize(driver)
10
10
  super(driver)
11
11
  @_bars = nil
12
+ # Intentionally left as the original lookup: this path already degrades to
13
+ # driver.get_system_bars consistently across all appium_lib_core versions
14
+ # (the rect read yields a non-Hash, so the rect arithmetic in
15
+ # get_system_bars rescues to nil and falls back), so it is out of scope for
16
+ # the snake_case capability fix.
12
17
  @_viewport_rect = capabilities.to_json['viewportRect']
13
18
  end
14
19
 
15
20
  def device_screen_size
16
- caps = capabilities
17
- caps = caps.as_json unless caps.is_a?(Hash)
18
21
  # Use string keys to match the IosMetadata implementation and every
19
22
  # consumer (generic_provider, app_automate, _get_tag), all of which read
20
23
  # device_screen_size['width'] / ['height'].
21
- if caps['deviceScreenSize'].nil?
24
+ device_screen_size_cap = get_capability_value('deviceScreenSize')
25
+ if device_screen_size_cap.nil?
22
26
  size = driver.window_size
23
27
  { 'width' => size.width.to_i, 'height' => size.height.to_i }
24
28
  else
25
- width, height = caps['deviceScreenSize'].split('x')
29
+ width, height = device_screen_size_cap.split('x')
26
30
  { 'width' => width.to_i, 'height' => height.to_i }
27
31
  end
28
32
  end
@@ -76,11 +80,13 @@ module Percy
76
80
 
77
81
  def _device_name
78
82
  if @device_name.nil?
79
- desired_caps = capabilities.to_json['desired'] || {}
80
- device_name = desired_caps['deviceName']
83
+ # Normalize the nested desired-caps hash too, so its keys are matched
84
+ # regardless of casing (camelCase or appium_lib_core 13+ snake_case).
85
+ desired_caps = Percy::Metadata.normalize_hash(get_capability_value('desired'))
86
+ device_name = desired_caps['devicename']
81
87
  device = desired_caps['device']
82
88
  device_name ||= device
83
- device_model = capabilities.to_json['deviceModel']
89
+ device_model = get_capability_value('deviceModel')
84
90
  @device_name = device_name || device_model
85
91
  end
86
92
  @device_name
@@ -67,11 +67,7 @@ module Percy
67
67
  end
68
68
 
69
69
  def device_name
70
- if @device_name.nil?
71
- caps = capabilities
72
- caps = caps.as_json unless caps.is_a?(Hash)
73
- @device_name = caps['deviceName']
74
- end
70
+ @device_name = get_capability_value('deviceName') if @device_name.nil?
75
71
  @device_name
76
72
  end
77
73
 
@@ -25,19 +25,54 @@ module Percy
25
25
  caps
26
26
  end
27
27
 
28
+ # Normalizes a capability key so lookups are resilient to the differences
29
+ # across appium_lib_core versions and protocols: camelCase ("platformName"),
30
+ # snake_case ("platform_name", as returned by appium_lib_core 13+),
31
+ # SCREAMING ("PLATFORM_NAME") and the W3C vendor prefix ("appium:platformName").
32
+ # Note: all colons are stripped, not just the vendor-prefix one. This is safe
33
+ # for every known Appium capability (e.g. "bstack:options" -> "bstackoptions").
34
+ def self.normalize_capability_key(key)
35
+ key.to_s.downcase.gsub(/[_:]/, '').sub(/\Aappium/, '')
36
+ end
37
+
38
+ # Builds a {normalized_key => value} view of a capabilities hash. First key
39
+ # wins, so a camelCase key (e.g. "platformName") takes precedence over a
40
+ # snake_case duplicate ("platform_name") when both are present, matching the
41
+ # previous MetadataResolver semantics.
42
+ def self.normalize_hash(hash)
43
+ normalized = {}
44
+ (hash || {}).each do |k, v|
45
+ nk = normalize_capability_key(k)
46
+ normalized[nk] = v unless normalized.key?(nk)
47
+ end
48
+ normalized
49
+ end
50
+
51
+ # Builds a {normalized_key => value} view of the driver's capabilities,
52
+ # coercing the appium_lib_core Capabilities object into a plain Hash first.
53
+ def self.normalized_capabilities(driver)
54
+ caps = driver.capabilities
55
+ caps = caps.as_json if caps.respond_to?(:as_json) && !caps.is_a?(Hash)
56
+ caps = caps.to_h if caps.respond_to?(:to_h) && !caps.is_a?(Hash)
57
+ normalize_hash(caps)
58
+ end
59
+
60
+ # Reads capabilities fresh on every call (no memoization) so callers always
61
+ # observe the driver's current capabilities, matching the prior behaviour.
62
+ def get_capability_value(name)
63
+ self.class.normalized_capabilities(driver)[self.class.normalize_capability_key(name)]
64
+ end
65
+
28
66
  def session_id
29
67
  driver.session_id
30
68
  end
31
69
 
32
70
  def os_name
33
- capabilities['platformName']
71
+ get_capability_value('platformName')
34
72
  end
35
73
 
36
74
  def os_version
37
- caps = capabilities
38
- caps = caps.as_json unless caps.is_a?(Hash)
39
-
40
- os_version = caps['os_version'] || caps['platformVersion'] || ''
75
+ os_version = get_capability_value('os_version') || get_capability_value('platformVersion') || ''
41
76
  os_version = @os_version || os_version
42
77
  begin
43
78
  os_version.to_f.to_i.to_s
@@ -51,7 +86,7 @@ module Percy
51
86
  end
52
87
 
53
88
  def get_orientation(**kwargs)
54
- orientation = kwargs[:orientation] || capabilities['orientation'] || 'PORTRAIT'
89
+ orientation = kwargs[:orientation] || get_capability_value('orientation') || 'PORTRAIT'
55
90
  orientation = orientation.downcase
56
91
  orientation = orientation == 'auto' ? _orientation : orientation
57
92
  orientation.upcase
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../exceptions/exceptions'
4
+ require_relative 'metadata'
4
5
  require_relative 'android_metadata'
5
6
  require_relative 'ios_metadata'
6
7
 
7
8
  module Percy
8
9
  class MetadataResolver
9
10
  def self.resolve(driver)
10
- capabilities = driver.capabilities
11
- capabilities = capabilities.as_json unless capabilities.is_a?(Hash)
12
- key = capabilities.keys.find { |k| k.downcase.gsub('_', '') == 'platformname' }
13
- platform_name = capabilities[key]&.downcase
11
+ # Resolve via normalized capability keys so platformName is found
12
+ # regardless of casing/prefix (camelCase, snake_case as in appium_lib_core
13
+ # 13+, or the appium: vendor prefix).
14
+ platform_name = Percy::Metadata.normalized_capabilities(driver)['platformname']&.to_s&.downcase
14
15
  case platform_name
15
16
  when 'android'
16
17
  Percy::AndroidMetadata.new(driver)
data/percy/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Percy
4
- VERSION = '0.0.9'.freeze
4
+ VERSION = '1.0.1'.freeze
5
5
  end
@@ -102,4 +102,28 @@ class TestAndroidMetadata < Minitest::Test
102
102
  def test_scale_factor
103
103
  assert_equal(1, @android_metadata.scale_factor)
104
104
  end
105
+
106
+ # Regression: appium_lib_core 13.x returns capabilities with snake_case keys
107
+ # (e.g. "device_screen_size" instead of "deviceScreenSize").
108
+ def test_device_screen_size_with_snake_case_caps
109
+ android_capabilities = get_android_capabilities
110
+ android_capabilities.delete('deviceScreenSize')
111
+ android_capabilities['device_screen_size'] = '1080x2280'
112
+ @mock_webdriver.expect(:capabilities, android_capabilities)
113
+
114
+ result = @android_metadata.device_screen_size
115
+ assert_equal({ 'width' => 1080, 'height' => 2280 }, result)
116
+ @mock_webdriver.verify
117
+ end
118
+
119
+ # Regression: the nested desired-caps hash is also normalized, so a
120
+ # snake_case "device_name" inside "desired" still resolves the device.
121
+ def test_device_name_with_snake_case_desired_caps
122
+ android_capabilities = get_android_capabilities
123
+ android_capabilities['desired'] = { 'device_name' => 'google pixel 4' }
124
+ @mock_webdriver.expect(:capabilities, android_capabilities)
125
+ @mock_webdriver.expect(:capabilities, android_capabilities)
126
+
127
+ assert_equal('google pixel 4', @android_metadata._device_name)
128
+ end
105
129
  end
@@ -105,4 +105,15 @@ class TestIOSMetadata < Minitest::Test
105
105
 
106
106
  assert_equal(2, @ios_metadata.scale_factor)
107
107
  end
108
+
109
+ def test_device_name_with_camel_case_caps
110
+ @mock_webdriver.expect(:capabilities, { 'deviceName' => 'iPhone 14' })
111
+ assert_equal('iPhone 14', @ios_metadata.device_name)
112
+ end
113
+
114
+ # Regression: appium_lib_core 13.x returns capabilities with snake_case keys.
115
+ def test_device_name_with_snake_case_caps
116
+ @mock_webdriver.expect(:capabilities, { 'device_name' => 'iPhone 14' })
117
+ assert_equal('iPhone 14', @ios_metadata.device_name)
118
+ end
108
119
  end
data/specs/metadata.rb CHANGED
@@ -137,4 +137,26 @@ class TestMetadata < Minitest::Test
137
137
  @metadata.value_from_devices_info('scale_factor', ios_device)
138
138
  )
139
139
  end
140
+
141
+ def test_normalize_capability_key
142
+ # camelCase, snake_case, SCREAMING and the appium: vendor prefix all
143
+ # collapse to the same normalized key.
144
+ %w[platformName platform_name PLATFORM_NAME appium:platformName].each do |key|
145
+ assert_equal('platformname', Percy::Metadata.normalize_capability_key(key))
146
+ end
147
+ assert_equal('platformname', Percy::Metadata.normalize_capability_key(:platformName))
148
+ end
149
+
150
+ # Regression: appium_lib_core 13.x returns capabilities with snake_case keys.
151
+ def test_metadata_os_name_with_snake_case_caps
152
+ @mock_webdriver.expect(:capabilities, { 'platform_name' => 'Android' })
153
+ assert_equal('Android', @metadata.os_name)
154
+ end
155
+
156
+ def test_metadata_os_version_with_snake_case_platform_version
157
+ capabilities = { 'platform_version' => '14' }
158
+ @mock_webdriver.expect(:capabilities, capabilities)
159
+ @mock_webdriver.expect(:capabilities, capabilities)
160
+ assert_equal('14', @metadata.os_version)
161
+ end
140
162
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: percy-appium-app
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - BroswerStack