appium_lib_core 13.1.0 → 13.1.2

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -3
  3. data/README.md +8 -21
  4. data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -2
  5. data/lib/appium_lib_core/android/device/clipboard.rb +3 -3
  6. data/lib/appium_lib_core/android/device/emulator.rb +8 -8
  7. data/lib/appium_lib_core/android/device/performance.rb +3 -3
  8. data/lib/appium_lib_core/android/device/screen.rb +3 -3
  9. data/lib/appium_lib_core/android/device.rb +15 -15
  10. data/lib/appium_lib_core/android/uiautomator2/device/battery.rb +2 -2
  11. data/lib/appium_lib_core/android/uiautomator2/device.rb +2 -2
  12. data/lib/appium_lib_core/common/base/driver.rb +4 -2
  13. data/lib/appium_lib_core/common/base/http_default.rb +2 -0
  14. data/lib/appium_lib_core/common/device/context.rb +3 -5
  15. data/lib/appium_lib_core/device.rb +4 -4
  16. data/lib/appium_lib_core/driver.rb +15 -8
  17. data/lib/appium_lib_core/ios/device/clipboard.rb +3 -3
  18. data/lib/appium_lib_core/ios/device.rb +4 -4
  19. data/lib/appium_lib_core/ios/xcuitest/device/battery.rb +2 -2
  20. data/lib/appium_lib_core/ios/xcuitest/device/performance.rb +3 -3
  21. data/lib/appium_lib_core/ios/xcuitest/device/screen.rb +2 -2
  22. data/lib/appium_lib_core/ios/xcuitest/device.rb +6 -6
  23. data/lib/appium_lib_core/mac2/device/screen.rb +2 -2
  24. data/lib/appium_lib_core/mac2/device.rb +2 -2
  25. data/lib/appium_lib_core/version.rb +2 -2
  26. data/lib/appium_lib_core/windows/device/screen.rb +2 -2
  27. data/lib/appium_lib_core/windows/device.rb +2 -2
  28. data/sig/lib/appium_lib_core/android/device/auth_finger_print.rbs +1 -1
  29. data/sig/lib/appium_lib_core/android/device/clipboard.rbs +1 -1
  30. data/sig/lib/appium_lib_core/android/device/emulator.rbs +1 -1
  31. data/sig/lib/appium_lib_core/android/device/performance.rbs +1 -1
  32. data/sig/lib/appium_lib_core/android/device/screen.rbs +1 -1
  33. data/sig/lib/appium_lib_core/android/uiautomator2/device/battery.rbs +1 -1
  34. data/sig/lib/appium_lib_core/device.rbs +2 -2
  35. data/sig/lib/appium_lib_core/driver.rbs +1 -0
  36. data/sig/lib/appium_lib_core/ios/device/clipboard.rbs +1 -1
  37. data/sig/lib/appium_lib_core/ios/xcuitest/device/battery.rbs +1 -1
  38. data/sig/lib/appium_lib_core/ios/xcuitest/device/performance.rbs +1 -1
  39. data/sig/lib/appium_lib_core/ios/xcuitest/device/screen.rbs +1 -1
  40. data/sig/lib/appium_lib_core/mac2/device/screen.rbs +1 -1
  41. data/sig/lib/appium_lib_core/windows/device/screen.rbs +1 -1
  42. metadata +9 -13
  43. data/Gemfile +0 -15
  44. data/Rakefile +0 -120
  45. data/Steepfile +0 -11
  46. data/Thorfile +0 -7
  47. data/appium_lib_core.gemspec +0 -27
  48. data/bin/console +0 -10
  49. data/bin/setup +0 -8
  50. data/rbs_collection.lock.yaml +0 -304
  51. data/rbs_collection.yaml +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7e61d3b24b0cbc11f24bc4121579d06457518e89c2377ea2b0b6979ab211c0e
4
- data.tar.gz: 898eaf12eaabb2d2541f0a6681e19bc5e8bf8e9ccaf5fb21b8582e062562a65d
3
+ metadata.gz: 721f441be394116dee549716bf6060b0cc45ef8a32740b2b492a8eee53f0b972
4
+ data.tar.gz: 841386effd79fb19da19320cfdd55b7512a373d3440e2cc1f5ca8ba33006ba2b
5
5
  SHA512:
6
- metadata.gz: 1be7dd5d017840bd5c0c06ccc9599ef3c6fcbfb85ba73b16e4608bb4a13f4ae4985756c006fd4423a09493d53b16892b41beecb179997b7898c9dfc215c9ba47
7
- data.tar.gz: 25bae6774144c8c58e37c676891680a949fc1b3c35c172f2d8068df38a758182d165bfac00e09902f609c0a16cd30999a2c32fd74628c2aad8f293e412008206
6
+ metadata.gz: 7963b059664bc6af4b475cf16ca746b3a768a1c1e3dfa99691f1995df66bec9c0ce4c369169c77d1e6dc412398ab6a5c41637ebe2d562573ccfa73155cd2cc9f
7
+ data.tar.gz: 2a5e89ec360b89bec0f6ea0461b269af1b5b7c7a1d68b1647ff520d2ee5c18479a21702691d743bf8173cd93c70770eba23f94c92e3957d5758e57081ed3f7a6
data/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
- Read `release_notes.md` for commit level details.
3
+ New entries are generated by Release Please. Historical commit-level details through 13.1.0 remain in `release_notes.md`.
4
+
5
+ ## [13.1.2](https://github.com/appium/ruby_lib_core/compare/v13.1.1...v13.1.2) (2026-09-13)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * tweak release files and metadatas ([5b2f239](https://github.com/appium/ruby_lib_core/commit/5b2f239def3dd17b8caf114bdafe0df16e70071d))
11
+
12
+ ## [13.1.1](https://github.com/appium/ruby_lib_core/compare/v13.1.0...v13.1.1) (2026-09-13)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * isolate platform commands and correct session regressions ([#703](https://github.com/appium/ruby_lib_core/issues/703)) ([03d2661](https://github.com/appium/ruby_lib_core/commit/03d2661c821d8195c909aadfabd0ab5d86335b9d))
4
18
 
5
19
  ## [13.1.0] - 2026-07-13
6
20
  - Compatible with selenium 4.46
@@ -387,8 +401,6 @@ Read `release_notes.md` for commit level details.
387
401
  - [test/functional/common_w3c_actions.rb](test/functional/common_w3c_actions.rb)
388
402
  - https://www.selenium.dev/documentation/support_packages/mouse_and_keyboard_actions_in_detail/
389
403
  - https://www.youtube.com/watch?v=oAJ7jwMNFVU
390
- - https://appiumpro.com/editions/30-ios-specific-touch-action-methods
391
- - https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api
392
404
  - `launch_app`, `close_app` and `reset`. Please read [issues#15807](https://github.com/appium/appium/issues/15807) for more details.
393
405
  - `activate_app` or a new session request can be alternatives of `launch_app`
394
406
  - `terminate_app` or close the session request can be alternatives of `close_app`
data/README.md CHANGED
@@ -114,21 +114,10 @@ $ IGNORE_VERSION_SKIP=true CI=true bundle exec rake test:func:android
114
114
  opts = {
115
115
  capabilities: { # Append capabilities
116
116
  platformName: 'ios',
117
- platformVersion: '15.8.3',
117
+ platformVersion: '26.0',
118
118
  deviceName: 'iPhone 17',
119
119
  # app: '/path/to/MyiOS.app', # Without 'app' capability, an appium session starts with the home screen
120
- automationName: 'XCUITest',
121
- # "appium:bundleId":"com.apple.mobilesafari",
122
- # "usePreinstalledWDA": true,
123
- useNewWDA: false,
124
- browserName: 'Safari',
125
- # "webDriverAgentUrl": "http://192.168.4.47:8100",
126
- "udid": "00008020-000E5CDA0A23002E",
127
- 'xcodeOrgId': '47PCFA586Q',
128
- 'xcodeSigningId': 'iPhone Developer',
129
- 'updatedWDABundleId': 'com.kazucocoa.wda',
130
- allowProvisioningDeviceRegistration: true,
131
- # 'appium:skipLogCapture': true
120
+ automationName: 'XCUITest'
132
121
  },
133
122
  appium_lib: {
134
123
  wait: 30
@@ -198,10 +187,10 @@ class CustomListener < ::Selenium::WebDriver::Support::AbstractEventListener
198
187
  end
199
188
  capabilities: {
200
189
  platformName: :ios,
201
- platformVersion: '11.0',
202
- deviceName: 'iPhone Simulator',
190
+ platformVersion: '26',
191
+ deviceName: 'iPhone',
203
192
  automationName: 'XCUITest',
204
- app: '/path/to/MyiOS.app'
193
+ browser: 'safari'
205
194
  }
206
195
  appium_lib: {
207
196
  listener: CustomListener.new
@@ -215,12 +204,10 @@ appium_lib: {
215
204
  - https://android.googlesource.com/platform/development/+/master/samples/ApiDemos
216
205
 
217
206
  # Release
218
- Use [appium_thor](https://github.com/appium/appium_thor) to release this gem.
207
+ Releases are prepared automatically by Release Please. Review and merge the release
208
+ PR; GitHub Actions then validates and publishes the gem using RubyGems Trusted
209
+ Publishing. See [RELEASING.md](RELEASING.md) for setup, version overrides, and recovery.
219
210
 
220
- ```bash
221
- $ thor bump # bumpy,
222
- $ thor release
223
- ```
224
211
 
225
212
  # Contribution
226
213
  1. Fork it ( https://github.com/appium/ruby_lib_core/fork )
@@ -17,8 +17,8 @@ module Appium
17
17
  module Android
18
18
  module Device
19
19
  module Authentication
20
- def self.add_methods
21
- ::Appium::Core::Device.add_endpoint_method(:finger_print) do
20
+ def self.add_methods(target)
21
+ ::Appium::Core::Device.add_endpoint_method(:finger_print, bridge: target.bridge_extensions) do
22
22
  def finger_print(finger_id)
23
23
  unless (1..10).cover? finger_id.to_i
24
24
  raise ::Appium::Core::Error::ArgumentError,
@@ -19,8 +19,8 @@ module Appium
19
19
  module Android
20
20
  module Device
21
21
  module Clipboard
22
- def self.add_methods
23
- ::Appium::Core::Device.add_endpoint_method(:get_clipboard) do
22
+ def self.add_methods(target)
23
+ ::Appium::Core::Device.add_endpoint_method(:get_clipboard, bridge: target.bridge_extensions) do
24
24
  def get_clipboard(content_type: :plaintext)
25
25
  unless ::Appium::Core::Base::Device::Clipboard::CONTENT_TYPE.member?(content_type)
26
26
  raise ::Appium::Core::Error::ArgumentError,
@@ -34,7 +34,7 @@ module Appium
34
34
  end
35
35
  end
36
36
 
37
- ::Appium::Core::Device.add_endpoint_method(:set_clipboard) do
37
+ ::Appium::Core::Device.add_endpoint_method(:set_clipboard, bridge: target.bridge_extensions) do
38
38
  def set_clipboard(content:, content_type: :plaintext, label: nil)
39
39
  unless ::Appium::Core::Base::Device::Clipboard::CONTENT_TYPE.member?(content_type)
40
40
  raise ::Appium::Core::Error::ArgumentError,
@@ -112,14 +112,14 @@ module Appium
112
112
  ## self.emulator_commands
113
113
  ####
114
114
 
115
- def self.add_methods
116
- ::Appium::Core::Device.add_endpoint_method(:send_sms) do
115
+ def self.add_methods(target)
116
+ ::Appium::Core::Device.add_endpoint_method(:send_sms, bridge: target.bridge_extensions) do
117
117
  def send_sms(phone_number:, message:)
118
118
  execute_script 'mobile:sendSms', { phoneNumber: phone_number, message: message }
119
119
  end
120
120
  end
121
121
 
122
- ::Appium::Core::Device.add_endpoint_method(:gsm_call) do
122
+ ::Appium::Core::Device.add_endpoint_method(:gsm_call, bridge: target.bridge_extensions) do
123
123
  def gsm_call(phone_number:, action:)
124
124
  raise ::Appium::Core::Error::ArgumentError, "action: should be member of #{GSM_CALL_ACTIONS}. Not #{action}." unless GSM_CALL_ACTIONS.member? action.to_sym
125
125
 
@@ -127,7 +127,7 @@ module Appium
127
127
  end
128
128
  end
129
129
 
130
- ::Appium::Core::Device.add_endpoint_method(:gsm_signal) do
130
+ ::Appium::Core::Device.add_endpoint_method(:gsm_signal, bridge: target.bridge_extensions) do
131
131
  def gsm_signal(signal_strength)
132
132
  if GSM_SIGNALS[signal_strength.to_sym].nil?
133
133
  raise ::Appium::Core::Error::ArgumentError,
@@ -138,7 +138,7 @@ module Appium
138
138
  end
139
139
  end
140
140
 
141
- ::Appium::Core::Device.add_endpoint_method(:gsm_voice) do
141
+ ::Appium::Core::Device.add_endpoint_method(:gsm_voice, bridge: target.bridge_extensions) do
142
142
  def gsm_voice(state)
143
143
  raise ::Appium::Core::Error::ArgumentError, "The state should be member of #{GSM_VOICE_STATES}. Not #{state}." unless GSM_VOICE_STATES.member? state.to_sym
144
144
 
@@ -146,7 +146,7 @@ module Appium
146
146
  end
147
147
  end
148
148
 
149
- ::Appium::Core::Device.add_endpoint_method(:set_network_speed) do
149
+ ::Appium::Core::Device.add_endpoint_method(:set_network_speed, bridge: target.bridge_extensions) do
150
150
  def set_network_speed(netspeed)
151
151
  unless NET_SPEED.member? netspeed.to_sym
152
152
  raise ::Appium::Core::Error::ArgumentError,
@@ -157,7 +157,7 @@ module Appium
157
157
  end
158
158
  end
159
159
 
160
- ::Appium::Core::Device.add_endpoint_method(:set_power_capacity) do
160
+ ::Appium::Core::Device.add_endpoint_method(:set_power_capacity, bridge: target.bridge_extensions) do
161
161
  def set_power_capacity(percent)
162
162
  ::Appium::Logger.warn "The percent should be between 0 and 100. Not #{percent}." unless (0..100).member? percent
163
163
 
@@ -165,7 +165,7 @@ module Appium
165
165
  end
166
166
  end
167
167
 
168
- ::Appium::Core::Device.add_endpoint_method(:set_power_ac) do
168
+ ::Appium::Core::Device.add_endpoint_method(:set_power_ac, bridge: target.bridge_extensions) do
169
169
  def set_power_ac(state)
170
170
  raise ::Appium::Core::Error::ArgumentError, "The state should be member of #{POWER_AC_STATE}. Not #{state}." unless POWER_AC_STATE.member? state.to_sym
171
171
 
@@ -17,14 +17,14 @@ module Appium
17
17
  module Android
18
18
  module Device
19
19
  module Performance
20
- def self.add_methods
21
- ::Appium::Core::Device.add_endpoint_method(:get_performance_data_types) do
20
+ def self.add_methods(target)
21
+ ::Appium::Core::Device.add_endpoint_method(:get_performance_data_types, bridge: target.bridge_extensions) do
22
22
  def get_performance_data_types
23
23
  execute_script 'mobile:getPerformanceDataTypes', {}
24
24
  end
25
25
  end
26
26
 
27
- ::Appium::Core::Device.add_endpoint_method(:get_performance_data) do
27
+ ::Appium::Core::Device.add_endpoint_method(:get_performance_data, bridge: target.bridge_extensions) do
28
28
  def get_performance_data(package_name:, data_type:)
29
29
  execute_script 'mobile:getPerformanceData', { packageName: package_name, dataType: data_type }
30
30
  end
@@ -17,14 +17,14 @@ module Appium
17
17
  module Android
18
18
  module Device
19
19
  module Screen
20
- def self.add_methods
21
- ::Appium::Core::Device.add_endpoint_method(:get_display_density) do
20
+ def self.add_methods(target)
21
+ ::Appium::Core::Device.add_endpoint_method(:get_display_density, bridge: target.bridge_extensions) do
22
22
  def get_display_density
23
23
  execute_script 'mobile:getDisplayDensity', {}
24
24
  end
25
25
  end
26
26
 
27
- ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
27
+ ::Appium::Core::Device.add_endpoint_method(:start_recording_screen, bridge: target.bridge_extensions) do
28
28
  def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
29
29
  file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil,
30
30
  video_size: nil, time_limit: '180', bit_rate: nil, bug_report: nil)
@@ -243,60 +243,60 @@ module Appium
243
243
  ####
244
244
 
245
245
  class << self
246
- def extended(_mod)
246
+ def extended(target)
247
247
  ::Appium::Core::Device.extend_webdriver_with_forwardable
248
248
 
249
- ::Appium::Core::Device.add_endpoint_method(:open_notifications) do
249
+ ::Appium::Core::Device.add_endpoint_method(:open_notifications, bridge: target.bridge_extensions) do
250
250
  def open_notifications
251
251
  execute_script 'mobile:openNotifications', {}
252
252
  end
253
253
  end
254
254
 
255
- ::Appium::Core::Device.add_endpoint_method(:current_activity) do
255
+ ::Appium::Core::Device.add_endpoint_method(:current_activity, bridge: target.bridge_extensions) do
256
256
  def current_activity
257
257
  execute_script 'mobile:getCurrentActivity', {}
258
258
  end
259
259
  end
260
260
 
261
- ::Appium::Core::Device.add_endpoint_method(:current_package) do
261
+ ::Appium::Core::Device.add_endpoint_method(:current_package, bridge: target.bridge_extensions) do
262
262
  def current_package
263
263
  execute_script 'mobile:getCurrentPackage', {}
264
264
  end
265
265
  end
266
266
 
267
- ::Appium::Core::Device.add_endpoint_method(:get_system_bars) do
267
+ ::Appium::Core::Device.add_endpoint_method(:get_system_bars, bridge: target.bridge_extensions) do
268
268
  def get_system_bars
269
269
  execute_script 'mobile:getSystemBars', {}
270
270
  end
271
271
  end
272
272
  # as alias to get_system_bars
273
- ::Appium::Core::Device.add_endpoint_method(:system_bars) do
273
+ ::Appium::Core::Device.add_endpoint_method(:system_bars, bridge: target.bridge_extensions) do
274
274
  def system_bars
275
275
  execute_script 'mobile:getSystemBars', {}
276
276
  end
277
277
  end
278
278
 
279
- ::Appium::Core::Device.add_endpoint_method(:toggle_location_services) do
279
+ ::Appium::Core::Device.add_endpoint_method(:toggle_location_services, bridge: target.bridge_extensions) do
280
280
  def toggle_location_services
281
281
  execute_script 'mobile:toggleGps', {}
282
282
  end
283
283
  end
284
284
 
285
285
  # Android, Override included method in bridge
286
- ::Appium::Core::Device.add_endpoint_method(:hide_keyboard) do
286
+ ::Appium::Core::Device.add_endpoint_method(:hide_keyboard, bridge: target.bridge_extensions) do
287
287
  def hide_keyboard(_close_key = nil)
288
288
  execute_script 'mobile:hideKeyboard', {}
289
289
  end
290
290
  end
291
291
 
292
292
  # Android, Override included method in bridge
293
- ::Appium::Core::Device.add_endpoint_method(:background_app) do
293
+ ::Appium::Core::Device.add_endpoint_method(:background_app, bridge: target.bridge_extensions) do
294
294
  def background_app(duration = 0)
295
295
  execute_script 'mobile:backgroundApp', { seconds: duration }
296
296
  end
297
297
  end
298
298
 
299
- ::Appium::Core::Device.add_endpoint_method(:execute_cdp) do
299
+ ::Appium::Core::Device.add_endpoint_method(:execute_cdp, bridge: target.bridge_extensions) do
300
300
  # SeleniumWebdriver could already define this method
301
301
  return if method_defined? :execute_cdp
302
302
 
@@ -305,11 +305,11 @@ module Appium
305
305
  end
306
306
  end
307
307
 
308
- Screen.add_methods
309
- Performance.add_methods
310
- Clipboard.add_methods
311
- Emulator.add_methods
312
- Authentication.add_methods
308
+ Screen.add_methods(target)
309
+ Performance.add_methods(target)
310
+ Clipboard.add_methods(target)
311
+ Emulator.add_methods(target)
312
+ Authentication.add_methods(target)
313
313
  end
314
314
  end
315
315
  end # module Device
@@ -18,8 +18,8 @@ module Appium
18
18
  module Uiautomator2
19
19
  module Device
20
20
  module Battery
21
- def self.add_methods
22
- ::Appium::Core::Device.add_endpoint_method(:battery_info) do
21
+ def self.add_methods(target)
22
+ ::Appium::Core::Device.add_endpoint_method(:battery_info, bridge: target.bridge_extensions) do
23
23
  def battery_info
24
24
  response = execute_script 'mobile: batteryInfo', {}
25
25
 
@@ -42,8 +42,8 @@ module Appium
42
42
  ####
43
43
 
44
44
  class << self
45
- def extended(_mod)
46
- Battery.add_methods
45
+ def extended(target)
46
+ Battery.add_methods(target)
47
47
  end
48
48
  end # class << self
49
49
  end # module Device
@@ -49,8 +49,8 @@ module Appium
49
49
  original_opts = opts.dup
50
50
 
51
51
  # For ::Appium::Core::Waitable
52
- @wait_timeout = opts.delete(:wait_timeout)
53
- @wait_interval = opts.delete(:wait_interval)
52
+ @wait_timeout = opts.delete(:wait_timeout) || ::Appium::Core::Wait::DEFAULT_TIMEOUT
53
+ @wait_interval = opts.delete(:wait_interval) || ::Appium::Core::Wait::DEFAULT_INTERVAL
54
54
 
55
55
  # Selenium WebDriver attributes
56
56
  @devtools = nil
@@ -76,6 +76,7 @@ module Appium
76
76
  def create_bridge(**opts)
77
77
  # for a new session request
78
78
  capabilities = opts.delete(:capabilities)
79
+ bridge_extensions = opts.delete(:bridge_extensions)
79
80
  bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
80
81
 
81
82
  # for attaching to an existing session
@@ -89,6 +90,7 @@ module Appium
89
90
  bridge_clzz = @has_bidi ? ::Appium::Core::Base::BiDiBridge : ::Appium::Core::Base::Bridge
90
91
  # steep:ignore:start
91
92
  bridge = bridge_clzz.new(**bridge_opts)
93
+ bridge.extend(bridge_extensions) if bridge_extensions
92
94
  # steep:ignore:end
93
95
 
94
96
  if session_id.nil?
@@ -69,6 +69,8 @@ module Appium
69
69
  path = "/#{path}" unless path.start_with?('/')
70
70
  path = "#{path}/" unless path.end_with?('/')
71
71
 
72
+ host = "[#{host}]" if host.include?(':') && !host.start_with?('[')
73
+
72
74
  @http = nil
73
75
  self.server_url = URI.parse "#{scheme}://#{host}:#{port}#{path}"
74
76
  end
@@ -20,11 +20,9 @@ module Appium
20
20
  def within_context(context)
21
21
  existing_context = current_context
22
22
  set_context context
23
- if block_given?
24
- result = yield
25
- set_context existing_context
26
- result
27
- else
23
+ begin
24
+ yield if block_given?
25
+ ensure
28
26
  set_context existing_context
29
27
  end
30
28
  end
@@ -26,8 +26,8 @@ module Appium
26
26
 
27
27
  # @private
28
28
  # Define method in Bridges
29
- def add_endpoint_method(method, &block)
30
- block_given? ? create_bridge_command(method, &block) : create_bridge_command(method)
29
+ def add_endpoint_method(method, bridge: ::Appium::Core::Base::Bridge, &block)
30
+ create_bridge_command(method, bridge: bridge, &block)
31
31
 
32
32
  delegate_driver_method method
33
33
  delegate_from_appium_driver method
@@ -56,8 +56,8 @@ module Appium
56
56
  ::Appium::Core::Base::Driver.class_eval { def_delegator :@bridge, method }
57
57
  end
58
58
 
59
- def create_bridge_command(method, &block)
60
- ::Appium::Core::Base::Bridge.class_eval do
59
+ def create_bridge_command(method, bridge:, &block)
60
+ bridge.class_eval do
61
61
  undef_method method if method_defined? method
62
62
  block_given? ? class_eval(&block) : define_method(method) { execute method }
63
63
  end
@@ -160,6 +160,10 @@ module Appium
160
160
  class Driver
161
161
  include Waitable
162
162
 
163
+ # @private Platform-specific methods for this driver
164
+ # @return [Module]
165
+ attr_reader :bridge_extensions
166
+
163
167
  # Selenium webdriver capabilities, but the value is provided capabilities basis.
164
168
  # @return [Core::Base::Capabilities]
165
169
  attr_reader :caps
@@ -388,6 +392,7 @@ module Appium
388
392
 
389
393
  # @private
390
394
  def initialize
395
+ @bridge_extensions = Module.new
391
396
  @delegate_target = self # for testing purpose
392
397
  @automation_name = nil # initialise before 'set_automation_name'
393
398
  end
@@ -473,6 +478,7 @@ module Appium
473
478
  begin
474
479
  @driver = ::Appium::Core::Base::Driver.new(listener: @listener,
475
480
  http_client: @http_client,
481
+ bridge_extensions: @bridge_extensions,
476
482
  capabilities: @caps, # ::Appium::Core::Base::Capabilities
477
483
  url: @custom_url,
478
484
  wait_timeout: @wait_timeout,
@@ -531,6 +537,7 @@ module Appium
531
537
  @driver = ::Appium::Core::Base::Driver.new(http_client: @http_client,
532
538
  url: @custom_url,
533
539
  listener: @listener,
540
+ bridge_extensions: @bridge_extensions,
534
541
  existing_session_id: session_id,
535
542
  automation_name: automation_name,
536
543
  platform_name: platform_name)
@@ -693,23 +700,23 @@ module Appium
693
700
  # The path can be local, HTTP/S, Windows Share and other path like 'sauce-storage:'.
694
701
  # Use @caps[:app] without modifications if the path isn't HTTP/S or local path.
695
702
  def set_app_path
696
- # FIXME: maybe `:app` should check `app` as well.
697
703
  return unless @caps
698
704
 
699
705
  app = get_app # for steep reason
700
- return unless app && app.empty?
706
+ return if app.nil? || app.empty?
701
707
 
702
708
  uri_regex = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER # steep:ignore
703
709
  return if app =~ uri_regex.make_regexp
704
710
 
705
711
  # steep:ignore
706
712
  app_path = File.expand_path(app)
707
- @caps['app'] = if File.exist? app_path
708
- app_path
709
- else
710
- ::Appium::Logger.warn("Use #{app} directly since #{app_path} does not exist.")
711
- app
712
- end
713
+ app_key = [:app, 'app', :'appium:app', 'appium:app'].find { |key| @caps[key] }
714
+ @caps[app_key] = if File.exist? app_path
715
+ app_path
716
+ else
717
+ ::Appium::Logger.warn("Use #{app} directly since #{app_path} does not exist.")
718
+ app
719
+ end
713
720
  end
714
721
 
715
722
  # @private
@@ -19,8 +19,8 @@ module Appium
19
19
  module Ios
20
20
  module Device
21
21
  module Clipboard
22
- def self.add_methods
23
- ::Appium::Core::Device.add_endpoint_method(:get_clipboard) do
22
+ def self.add_methods(target)
23
+ ::Appium::Core::Device.add_endpoint_method(:get_clipboard, bridge: target.bridge_extensions) do
24
24
  def get_clipboard(content_type: :plaintext)
25
25
  unless ::Appium::Core::Base::Device::Clipboard::CONTENT_TYPE.member?(content_type)
26
26
  raise ::Appium::Core::Error::ArgumentError,
@@ -34,7 +34,7 @@ module Appium
34
34
  end
35
35
  end
36
36
 
37
- ::Appium::Core::Device.add_endpoint_method(:set_clipboard) do
37
+ ::Appium::Core::Device.add_endpoint_method(:set_clipboard, bridge: target.bridge_extensions) do
38
38
  def set_clipboard(content:, content_type: :plaintext)
39
39
  unless ::Appium::Core::Base::Device::Clipboard::CONTENT_TYPE.member?(content_type)
40
40
  raise ::Appium::Core::Error::ArgumentError,
@@ -70,22 +70,22 @@ module Appium
70
70
  ####
71
71
 
72
72
  class << self
73
- def extended(_mod)
73
+ def extended(target)
74
74
  ::Appium::Core::Device.extend_webdriver_with_forwardable
75
75
 
76
- ::Appium::Core::Device.add_endpoint_method(:touch_id) do
76
+ ::Appium::Core::Device.add_endpoint_method(:touch_id, bridge: target.bridge_extensions) do
77
77
  def touch_id(match = true)
78
78
  execute_script 'mobile:sendBiometricMatch', { 'type': 'touch_id', match: match }
79
79
  end
80
80
  end
81
81
 
82
- ::Appium::Core::Device.add_endpoint_method(:toggle_touch_id_enrollment) do
82
+ ::Appium::Core::Device.add_endpoint_method(:toggle_touch_id_enrollment, bridge: target.bridge_extensions) do
83
83
  def toggle_touch_id_enrollment(enabled = true)
84
84
  execute_script 'mobile:enrollBiometric', { 'isEnabled': enabled }
85
85
  end
86
86
  end
87
87
 
88
- Clipboard.add_methods
88
+ Clipboard.add_methods(target)
89
89
  end
90
90
  end
91
91
  end # module Device
@@ -18,8 +18,8 @@ module Appium
18
18
  module Xcuitest
19
19
  module Device
20
20
  module Battery
21
- def self.add_methods
22
- ::Appium::Core::Device.add_endpoint_method(:battery_info) do
21
+ def self.add_methods(target)
22
+ ::Appium::Core::Device.add_endpoint_method(:battery_info, bridge: target.bridge_extensions) do
23
23
  def battery_info
24
24
  response = execute_script 'mobile: batteryInfo', {}
25
25
 
@@ -18,8 +18,8 @@ module Appium
18
18
  module Xcuitest
19
19
  module Device
20
20
  module Performance
21
- def self.add_methods
22
- ::Appium::Core::Device.add_endpoint_method(:start_performance_record) do
21
+ def self.add_methods(target)
22
+ ::Appium::Core::Device.add_endpoint_method(:start_performance_record, bridge: target.bridge_extensions) do
23
23
  def start_performance_record(timeout: 300_000, profile_name: 'Activity Monitor', pid: nil)
24
24
  option = {}
25
25
  option[:timeout] = timeout
@@ -30,7 +30,7 @@ module Appium
30
30
  end
31
31
  end
32
32
 
33
- ::Appium::Core::Device.add_endpoint_method(:get_performance_record) do
33
+ ::Appium::Core::Device.add_endpoint_method(:get_performance_record, bridge: target.bridge_extensions) do
34
34
  def get_performance_record(save_file_path: './performance', profile_name: 'Activity Monitor',
35
35
  remote_path: nil, user: nil, pass: nil, method: 'PUT',
36
36
  file_field_name: nil, form_fields: nil, headers: nil)
@@ -18,8 +18,8 @@ module Appium
18
18
  module Xcuitest
19
19
  module Device
20
20
  module Screen
21
- def self.add_methods
22
- ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
21
+ def self.add_methods(target)
22
+ ::Appium::Core::Device.add_endpoint_method(:start_recording_screen, bridge: target.bridge_extensions) do
23
23
  def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
24
24
  file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil,
25
25
  video_type: 'mjpeg', time_limit: '180', video_quality: nil,
@@ -170,9 +170,9 @@ module Appium
170
170
  ####
171
171
 
172
172
  class << self
173
- def extended(_mod)
173
+ def extended(target)
174
174
  # Xcuitest, Override included method in bridge
175
- ::Appium::Core::Device.add_endpoint_method(:hide_keyboard) do
175
+ ::Appium::Core::Device.add_endpoint_method(:hide_keyboard, bridge: target.bridge_extensions) do
176
176
  def hide_keyboard(close_key = nil)
177
177
  option = {}
178
178
 
@@ -183,15 +183,15 @@ module Appium
183
183
  end
184
184
 
185
185
  # Xcuitest, Override included method in bridge
186
- ::Appium::Core::Device.add_endpoint_method(:background_app) do
186
+ ::Appium::Core::Device.add_endpoint_method(:background_app, bridge: target.bridge_extensions) do
187
187
  def background_app(duration = 0)
188
188
  execute_script 'mobile:backgroundApp', { seconds: duration }
189
189
  end
190
190
  end
191
191
 
192
- Performance.add_methods
193
- Screen.add_methods
194
- Battery.add_methods
192
+ Performance.add_methods(target)
193
+ Screen.add_methods(target)
194
+ Battery.add_methods(target)
195
195
  end
196
196
  end # class << self
197
197
  end # module Device
@@ -17,8 +17,8 @@ module Appium
17
17
  module Mac2
18
18
  module Device
19
19
  module Screen
20
- def self.add_methods
21
- ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
20
+ def self.add_methods(target)
21
+ ::Appium::Core::Device.add_endpoint_method(:start_recording_screen, bridge: target.bridge_extensions) do
22
22
  def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
23
23
  file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil,
24
24
  fps: nil, preset: nil, video_filter: nil, time_limit: nil,
@@ -77,8 +77,8 @@ module Appium
77
77
  ####
78
78
 
79
79
  class << self
80
- def extended(_mod)
81
- Screen.add_methods
80
+ def extended(target)
81
+ Screen.add_methods(target)
82
82
  end
83
83
  end # class << self
84
84
  end # module Device
@@ -14,7 +14,7 @@
14
14
 
15
15
  module Appium
16
16
  module Core
17
- VERSION = '13.1.0' unless defined? ::Appium::Core::VERSION
18
- DATE = '2026-07-13' unless defined? ::Appium::Core::DATE
17
+ VERSION = '13.1.2' unless defined? ::Appium::Core::VERSION
18
+ DATE = '2026-09-13' unless defined? ::Appium::Core::DATE # x-release-please-date
19
19
  end
20
20
  end