appium_lib_core 13.1.3 → 13.2.0

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: 2a3e07bd8b81e3b5ff0429d7d3c786373bcaaa89c88c141561079357e0cd30c4
4
- data.tar.gz: 1f1867c731d2a84f9d4853f48c2c9e9e1cb7e2c8e5e262a1e4f4230dfbe31e7e
3
+ metadata.gz: 5f58df4e5db1afd7bdaf68fdcb87493c51d2c0807bbcaa91b031c15bcefdc509
4
+ data.tar.gz: c597388ecf32f065053c5098f52ddf91cad376af02d9996518d31c1962d41c76
5
5
  SHA512:
6
- metadata.gz: 1addf77654cbd05b97054d930104d8635c32718cb7841682fd011910887cc1a31adae15d81cc20d8282e1b7babdad1a0c3bbd82d6e6cf5772465988c715b68c5
7
- data.tar.gz: '0190a838d93f05ef1bad95db3166f8a47731155465031ddd4dba8635761bbe518c6aba08da049c7f5163c25b5585b21f20ab3230d39b663ab2d201365d2804ed'
6
+ metadata.gz: 7f8afcd5b9d81aae9e7ea0ca51d5a98e184534b906793a358823956512a39e32caa1c24983c2ded9ba1ecccb2e16f6971974bec0f5541887a0bac0f25225be24
7
+ data.tar.gz: f82582b27f5520d4992565cac86a86e2b1b8d465f30f8867646e090e2f4588786e5bb869bf83cc1d7df28710e3c03eb59a1cb6a8a41b99998d63b9600e38584d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  New entries are generated by Release Please. Historical commit-level details through 13.1.0 remain in `release_notes.md`.
4
4
 
5
+ ## [13.2.0](https://github.com/appium/ruby_lib_core/compare/v13.1.4...v13.2.0) (2026-10-26)
6
+
7
+
8
+ ### Features
9
+
10
+ * Implement Cached Element for shouldUseCompactResponses and elementResponseAttributes ([#727](https://github.com/appium/ruby_lib_core/issues/727)) ([a0b22c5](https://github.com/appium/ruby_lib_core/commit/a0b22c5d8d757b787b44ba0468e6a216a7c46725))
11
+
12
+ ## [13.1.4](https://github.com/appium/ruby_lib_core/compare/v13.1.3...v13.1.4) (2026-10-03)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * add missing RBS for direct connect DNS constants ([#718](https://github.com/appium/ruby_lib_core/issues/718)) ([f288cf2](https://github.com/appium/ruby_lib_core/commit/f288cf23de843bef7af97562d37d01a356ee0a3e))
18
+
5
19
  ## [13.1.3](https://github.com/appium/ruby_lib_core/compare/v13.1.2...v13.1.3) (2026-09-13)
6
20
 
7
21
 
data/README.md CHANGED
@@ -151,6 +151,31 @@ assert attached_driver.session_id == @driver.session_id
151
151
  attached_driver.page_source
152
152
  ```
153
153
 
154
+ ### Element response attributes
155
+
156
+ When the server is configured with `shouldUseCompactResponses: false` and
157
+ `elementResponseAttributes`, returned attributes are available through `element.cached`:
158
+
159
+ ```ruby
160
+ element = @driver.find_element(:accessibility_id, 'some accessibility')
161
+ element.cached.text # text returned with this element
162
+ element.cached['content-desc'] # also accepts attribute/content-desc
163
+ element.cached.attributes # returned attributes, excluding element IDs
164
+ element.text # fetches current text; does not update cached
165
+ ```
166
+
167
+ `cached` only reads the response snapshot. It cannot find elements or send commands.
168
+ Standard boolean fields (`enabled`, `displayed`, `selected`) normalize `"true"` and
169
+ `"false"` to booleans. `cached.rect`, `cached.location`, and `cached.size` return
170
+ Selenium Rectangle, Point, and Dimension objects; `cached.tag_name` reads `name`.
171
+ These conversions also apply to `cached[name]`. Explicit `cached['attribute/...']`
172
+ lookups and custom attributes retain their server types. `cached.attributes`
173
+ exposes the original server values.
174
+ Use `cached[name]` for optional attributes; it returns `nil` when absent. Dynamic
175
+ methods such as `cached.text` are available only for attributes in the response.
176
+ Standard accessors such as `cached.enabled?` and `cached.rect` return `nil` when
177
+ their data is absent.
178
+
154
179
  ### Capabilities
155
180
 
156
181
  Read [Appium/Core/Driver](https://rubydoc.info/github/appium/ruby_lib_core/Appium/Core/Driver) to catch up with available capabilities.
@@ -148,6 +148,13 @@ module Appium
148
148
 
149
149
  private
150
150
 
151
+ # Preserve the response until Element initialization, including for script results.
152
+ # Selenium calls this immediately before constructing an element. Keep nil for
153
+ # non-element hashes so ordinary script results and shadow roots stay intact.
154
+ def element_id_from(response)
155
+ response if super
156
+ end
157
+
151
158
  def selenium_bridge_accepts_url?
152
159
  ::Selenium::WebDriver::Remote::Bridge.instance_method(:initialize).parameters.any? do |_, name|
153
160
  name == :url
@@ -134,7 +134,7 @@ module Appium
134
134
  return [normalized_host] if ip_literal?(normalized_host)
135
135
 
136
136
  Timeout.timeout(DNS_RESOLVE_TIMEOUT_SECONDS) do
137
- Socket.getaddrinfo(normalized_host, nil).map { |entry| entry[3] }.uniq
137
+ Socket.getaddrinfo(normalized_host, nil).map { |entry| entry[3].to_s }.uniq
138
138
  end
139
139
  rescue Timeout::Error
140
140
  ::Appium::Logger.warn("DNS resolution for '#{host}' timed out after #{DNS_RESOLVE_TIMEOUT_SECONDS}s")
@@ -17,6 +17,86 @@ module Appium
17
17
  # Implement useful features for element.
18
18
  # Patch for Selenium Webdriver.
19
19
  class Element < ::Selenium::WebDriver::Element
20
+ # Attributes returned with an element response. This object has no bridge:
21
+ # reading it never sends a command or refreshes the returned values.
22
+ class Cache
23
+ attr_reader :attributes
24
+
25
+ def initialize(attributes = {})
26
+ @attributes = attributes.dup.freeze
27
+ end
28
+
29
+ # Normalize standard response fields; arbitrary attribute/... values stay raw.
30
+ # Missing attributes return nil. The original values remain in attributes.
31
+ def attribute(name)
32
+ key = attribute_key(name)
33
+ value = @attributes[key]
34
+ case name.to_s
35
+ when 'enabled', 'displayed', 'selected'
36
+ return true if value == 'true'
37
+ return false if value == 'false'
38
+ when 'rect'
39
+ return ::Selenium::WebDriver::Rectangle.new(value['x'], value['y'], value['width'], value['height']) if value.is_a?(Hash)
40
+ end
41
+ value
42
+ end
43
+
44
+ alias [] attribute
45
+
46
+ def enabled?
47
+ attribute('enabled')
48
+ end
49
+
50
+ alias enabled enabled?
51
+
52
+ def displayed?
53
+ attribute('displayed')
54
+ end
55
+
56
+ alias displayed displayed?
57
+
58
+ def selected?
59
+ attribute('selected')
60
+ end
61
+
62
+ alias selected selected?
63
+
64
+ def rect
65
+ attribute('rect')
66
+ end
67
+
68
+ def location
69
+ rectangle = rect
70
+ ::Selenium::WebDriver::Point.new(rectangle.x, rectangle.y) if rectangle
71
+ end
72
+
73
+ def size
74
+ rectangle = rect
75
+ ::Selenium::WebDriver::Dimension.new(rectangle.width, rectangle.height) if rectangle
76
+ end
77
+
78
+ def tag_name
79
+ attribute('name')
80
+ end
81
+
82
+ def method_missing(name, *args, &block)
83
+ return super unless args.empty? && block.nil? && respond_to_missing?(name)
84
+
85
+ attribute(name.to_s.delete_suffix('?').tr('_', '-'))
86
+ end
87
+
88
+ def respond_to_missing?(name, include_private = false)
89
+ @attributes.key?(attribute_key(name.to_s.delete_suffix('?').tr('_', '-'))) || super
90
+ end
91
+
92
+ private
93
+
94
+ def attribute_key(name)
95
+ key = name.to_s
96
+ @attributes.key?("attribute/#{key}") ? "attribute/#{key}" : key
97
+ end
98
+ end
99
+
20
100
  include ::Appium::Core::Base::TakesScreenshot
21
101
 
22
102
  # steep:ignore:start
@@ -32,6 +112,24 @@ module Appium
32
112
  #
33
113
  attr_reader :id
34
114
 
115
+ def initialize(bridge, id, cached = nil)
116
+ if id.is_a?(Hash)
117
+ # Preserve any extra attributes included in the element response.
118
+ cached = Cache.new(id.except('ELEMENT', ELEMENT_KEY))
119
+ id = id['ELEMENT'] || id[ELEMENT_KEY]
120
+ end
121
+ super(bridge, id)
122
+ @cached = cached
123
+ end
124
+
125
+ # Snapshot from elementResponseAttributes with shouldUseCompactResponses=false.
126
+ # Normal element calls still query the server and do not update this snapshot.
127
+ # Standard fields use Element API types; cached.attributes holds server values.
128
+ # @return [Appium::Core::Element::Cache]
129
+ def cached
130
+ @cached ||= Cache.new
131
+ end
132
+
35
133
  # Returns the value of attributes like below. Read each platform to know more details.
36
134
  #
37
135
  # uiautomator2: https://github.com/appium/appium-uiautomator2-server/blob/203cc7e57ce477f3cff5d95b135d1b3450a6033a/app/src/main/java/io/appium/uiautomator2/utils/Attribute.java#L19
@@ -29,7 +29,7 @@ module Appium
29
29
  @delegate.find_element_by how, what, parent
30
30
  end
31
31
 
32
- ::Appium::Core::Element.new self, e.ref.last
32
+ ::Appium::Core::Element.new self, e.ref.last, e.cached
33
33
  end
34
34
 
35
35
  def find_elements_by(how, what, parent = nil)
@@ -37,7 +37,7 @@ module Appium
37
37
  @delegate.find_elements_by(how, what, parent)
38
38
  end
39
39
 
40
- es.map { |e| ::Appium::Core::Element.new self, e.ref.last }
40
+ es.map { |e| ::Appium::Core::Element.new self, e.ref.last, e.cached }
41
41
  end
42
42
 
43
43
  private
@@ -14,7 +14,7 @@
14
14
 
15
15
  module Appium
16
16
  module Core
17
- VERSION = '13.1.3' unless defined? ::Appium::Core::VERSION
18
- DATE = '2026-09-13' unless defined? ::Appium::Core::DATE # x-release-please-date
17
+ VERSION = '13.2.0' unless defined? ::Appium::Core::VERSION
18
+ DATE = '2026-10-26' unless defined? ::Appium::Core::DATE # x-release-please-date
19
19
  end
20
20
  end
@@ -3,6 +3,8 @@ module Selenium
3
3
  class Element
4
4
  ELEMENT_KEY: ::String
5
5
 
6
+ def initialize: (untyped bridge, untyped id) -> void
7
+
6
8
  def inspect: () -> untyped
7
9
 
8
10
  def ==: (untyped other) -> bool
@@ -105,6 +105,8 @@ module Appium
105
105
 
106
106
  private
107
107
 
108
+ def element_id_from: (untyped response) -> untyped
109
+
108
110
  def selenium_bridge_accepts_url?: () -> bool
109
111
 
110
112
  def camel_case: (untyped str_or_sym) -> untyped
@@ -70,6 +70,18 @@ module Appium
70
70
 
71
71
  W3C_KEYS: Hash[String | Symbol, String]
72
72
 
73
+ DNS_RESOLVE_TIMEOUT_SECONDS: Integer
74
+
75
+ LOOPBACK_RANGES: Array[IPAddr]
76
+
77
+ LINK_LOCAL_RANGES: Array[IPAddr]
78
+
79
+ UNSPECIFIED_RANGES: Array[IPAddr]
80
+
81
+ MULTICAST_RANGES: Array[IPAddr]
82
+
83
+ DISALLOWED_RANGES: Array[IPAddr]
84
+
73
85
  attr_reader protocol: String
74
86
 
75
87
  attr_reader host: String
@@ -2,9 +2,37 @@ module Appium
2
2
  module Core
3
3
  # Element class inheriting from Selenium::WebDriver::Element
4
4
  class Element < ::Selenium::WebDriver::Element
5
+ class Cache
6
+ attr_reader attributes: Hash[String, untyped]
7
+
8
+ def initialize: (?Hash[String, untyped] attributes) -> void
9
+ def attribute: (String | Symbol name) -> untyped
10
+ alias [] attribute
11
+ def enabled?: () -> bool?
12
+ alias enabled enabled?
13
+ def displayed?: () -> bool?
14
+ alias displayed displayed?
15
+ def selected?: () -> bool?
16
+ alias selected selected?
17
+ def rect: () -> untyped
18
+ def location: () -> untyped
19
+ def size: () -> untyped
20
+ def tag_name: () -> String?
21
+ def method_missing: (Symbol name, *untyped args) ?{ (?) -> untyped } -> untyped
22
+ def respond_to_missing?: (Symbol name, ?bool include_private) -> bool
23
+
24
+ private
25
+
26
+ def attribute_key: (String | Symbol name) -> String
27
+ end
28
+
5
29
  include ::Appium::Core::Base::TakesScreenshot
6
30
 
7
- def initialize: (untyped bridge, untyped id) -> void
31
+ @cached: Cache?
32
+
33
+ def initialize: (untyped bridge, untyped id, ?Cache? cached) -> void
34
+
35
+ def cached: () -> Cache
8
36
 
9
37
  attr_reader id: Array[untyped]
10
38
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appium_lib_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.1.3
4
+ version: 13.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuaki MATSUO
@@ -251,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
251
  - !ruby/object:Gem::Version
252
252
  version: '0'
253
253
  requirements: []
254
- rubygems_version: 4.0.16
254
+ rubygems_version: 4.0.20
255
255
  specification_version: 4
256
256
  summary: Minimal Ruby library for Appium.
257
257
  test_files: []