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 +4 -4
- data/percy/metadata/android_metadata.rb +13 -7
- data/percy/metadata/ios_metadata.rb +1 -5
- data/percy/metadata/metadata.rb +41 -6
- data/percy/metadata/metadata_resolver.rb +5 -4
- data/percy/version.rb +1 -1
- data/specs/android_metadata.rb +24 -0
- data/specs/ios_metadata.rb +11 -0
- data/specs/metadata.rb +22 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85a82be9fb7970cea7e6bfbf92341377a6cf4647f07ce09b3a3c4bb52ff25c11
|
|
4
|
+
data.tar.gz: 03be307ae51ff85c7853cf0284ded40713a91f8bbf4ce36f8f6b7ae69165d26e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
80
|
-
|
|
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 =
|
|
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
|
|
data/percy/metadata/metadata.rb
CHANGED
|
@@ -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
|
-
|
|
71
|
+
get_capability_value('platformName')
|
|
34
72
|
end
|
|
35
73
|
|
|
36
74
|
def os_version
|
|
37
|
-
|
|
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] ||
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
platform_name =
|
|
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
data/specs/android_metadata.rb
CHANGED
|
@@ -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
|
data/specs/ios_metadata.rb
CHANGED
|
@@ -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
|