appium_lib_core 4.1.0 → 9.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +352 -270
  3. data/README.md +68 -16
  4. data/Rakefile +8 -20
  5. data/Steepfile +11 -0
  6. data/appium_lib_core.gemspec +13 -15
  7. data/bin/console +0 -4
  8. data/lib/appium_lib_core/android/device/auth_finger_print.rb +4 -1
  9. data/lib/appium_lib_core/android/device/clipboard.rb +4 -2
  10. data/lib/appium_lib_core/android/device/emulator.rb +11 -5
  11. data/lib/appium_lib_core/android/device/network.rb +10 -0
  12. data/lib/appium_lib_core/android/device/performance.rb +3 -0
  13. data/lib/appium_lib_core/android/device/screen.rb +5 -1
  14. data/lib/appium_lib_core/android/device.rb +83 -20
  15. data/lib/appium_lib_core/common/base/bridge.rb +238 -95
  16. data/lib/appium_lib_core/common/base/capabilities.rb +21 -8
  17. data/lib/appium_lib_core/common/{command/mjsonwp.rb → base/device_ime.rb} +33 -12
  18. data/lib/appium_lib_core/common/base/driver.rb +263 -334
  19. data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
  20. data/lib/appium_lib_core/common/base/has_location.rb +80 -0
  21. data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
  22. data/lib/appium_lib_core/common/base/http_default.rb +22 -38
  23. data/lib/appium_lib_core/{ios/uiautomation/bridge.rb → common/base/remote_status.rb} +9 -8
  24. data/lib/appium_lib_core/common/base/rotable.rb +62 -0
  25. data/lib/appium_lib_core/common/base/screenshot.rb +10 -10
  26. data/lib/appium_lib_core/common/base/search_context.rb +98 -172
  27. data/lib/appium_lib_core/common/base.rb +1 -5
  28. data/lib/appium_lib_core/common/command.rb +244 -4
  29. data/lib/appium_lib_core/common/device/app_management.rb +2 -26
  30. data/lib/appium_lib_core/common/device/context.rb +1 -5
  31. data/lib/appium_lib_core/common/device/image_comparison.rb +27 -10
  32. data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
  33. data/lib/appium_lib_core/common/device/{touch_actions.rb → orientation.rb} +6 -10
  34. data/lib/appium_lib_core/common/device/screen_record.rb +8 -2
  35. data/lib/appium_lib_core/common/error.rb +5 -5
  36. data/lib/appium_lib_core/common/log.rb +5 -4
  37. data/lib/appium_lib_core/common/wait.rb +38 -6
  38. data/lib/appium_lib_core/device.rb +3 -9
  39. data/lib/appium_lib_core/driver.rb +207 -164
  40. data/lib/appium_lib_core/{patch.rb → element.rb} +64 -26
  41. data/lib/appium_lib_core/ios/device/clipboard.rb +4 -2
  42. data/lib/appium_lib_core/ios/xcuitest/device.rb +2 -0
  43. data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
  44. data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
  45. data/lib/appium_lib_core/mac2/device.rb +92 -0
  46. data/lib/appium_lib_core/{ios.rb → mac2.rb} +2 -5
  47. data/lib/appium_lib_core/support/event_firing_bridge.rb +57 -0
  48. data/lib/appium_lib_core/version.rb +2 -2
  49. data/lib/appium_lib_core.rb +23 -10
  50. data/rbs_collection.lock.yaml +252 -0
  51. data/rbs_collection.yaml +15 -0
  52. data/sig/gems/selenium/abstract_event_listener.rbs +8 -0
  53. data/sig/gems/selenium/capabilities.rbs +8 -0
  54. data/sig/gems/selenium/common.rbs +10 -0
  55. data/sig/gems/selenium/default.rbs +10 -0
  56. data/sig/gems/selenium/driver.rbs +7 -0
  57. data/sig/gems/selenium/has_session_id.rbs +8 -0
  58. data/sig/gems/selenium/has_web_storage.rbs +8 -0
  59. data/sig/gems/selenium/uploads_files.rbs +8 -0
  60. data/sig/lib/appium_lib_core/common/base/capabilities.rbs +9 -0
  61. data/sig/lib/appium_lib_core/common/base/driver.rbs +167 -0
  62. data/sig/lib/appium_lib_core/common/base/driver_settings.rbs +15 -0
  63. data/sig/lib/appium_lib_core/common/base/has_location.rbs +13 -0
  64. data/sig/lib/appium_lib_core/common/base/has_network_connection.rbs +19 -0
  65. data/sig/lib/appium_lib_core/common/base/http_default.rbs +38 -0
  66. data/sig/lib/appium_lib_core/common/base/platform.rbs +7 -0
  67. data/sig/lib/appium_lib_core/common/base/remote_status.rbs +9 -0
  68. data/sig/lib/appium_lib_core/common/base/rotable.rbs +17 -0
  69. data/sig/lib/appium_lib_core/common/base/screenshot.rbs +19 -0
  70. data/sig/lib/appium_lib_core/common/device/battery_status.rbs +13 -0
  71. data/sig/lib/appium_lib_core/common/wait.rbs +31 -0
  72. data/sig/lib/appium_lib_core/device.rbs +21 -0
  73. data/sig/lib/appium_lib_core/driver.rbs +200 -0
  74. data/sig/lib/appium_lib_core/ios/xcuitest/device/battery.rbs +15 -0
  75. data/sig/lib/appium_lib_core/version.rbs +7 -0
  76. data/sig/lib/appium_lib_core.rbs +8 -0
  77. metadata +88 -111
  78. data/.github/ISSUE_TEMPLATE/issue-report.md +0 -29
  79. data/.github/contributing.md +0 -26
  80. data/.github/issue_template.md +0 -20
  81. data/.github/workflows/unittest.yml +0 -68
  82. data/.gitignore +0 -18
  83. data/.rubocop.yml +0 -58
  84. data/azure-pipelines.yml +0 -15
  85. data/ci-jobs/functional/android_setup.yml +0 -3
  86. data/ci-jobs/functional/ios_setup.yml +0 -7
  87. data/ci-jobs/functional/publish_test_result.yml +0 -18
  88. data/ci-jobs/functional/run_appium.yml +0 -25
  89. data/ci-jobs/functional/start-emulator.sh +0 -26
  90. data/ci-jobs/functional_test.yml +0 -298
  91. data/docs/mobile_command.md +0 -34
  92. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
  93. data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
  94. data/lib/appium_lib_core/common/command/common.rb +0 -110
  95. data/lib/appium_lib_core/common/command/w3c.rb +0 -56
  96. data/lib/appium_lib_core/common/device/value.rb +0 -52
  97. data/lib/appium_lib_core/common/touch_action/multi_touch.rb +0 -56
  98. data/lib/appium_lib_core/common/touch_action/touch_actions.rb +0 -203
  99. data/lib/appium_lib_core/ios/uiautomation/device.rb +0 -44
  100. data/lib/appium_lib_core/ios/uiautomation/patch.rb +0 -34
  101. data/release_notes.md +0 -816
  102. data/script/commands.rb +0 -200
@@ -15,53 +15,78 @@
15
15
  module Appium
16
16
  module Core
17
17
  class Base
18
+ class LocatorConverter
19
+ def convert(how, what)
20
+ [how, what]
21
+ end
22
+ end # LocatorConverter
23
+
18
24
  class Bridge < ::Selenium::WebDriver::Remote::Bridge
25
+ include Device::DeviceLock
26
+ include Device::Keyboard
27
+ include Device::ImeActions
28
+ include Device::Setting
29
+ include Device::Context
30
+ include Device::FileManagement
31
+ include Device::KeyEvent
32
+ include Device::ImageComparison
33
+ include Device::AppManagement
34
+ include Device::AppState
35
+ include Device::ScreenRecord::Command
36
+ include Device::Device
37
+ include Device::ExecuteDriver
38
+ include Device::Orientation
39
+
40
+ Bridge.locator_converter = LocatorConverter.new
41
+
19
42
  # Prefix for extra capability defined by W3C
20
43
  APPIUM_PREFIX = 'appium:'
21
44
 
22
- # TODO: Remove the forceMjsonwp after Appium server won't need it
23
- FORCE_MJSONWP = :forceMjsonwp
45
+ # No 'browserName' means the session is native appium connection
46
+ APPIUM_NATIVE_BROWSER_NAME = 'appium'
24
47
 
25
- # Almost same as self.handshake in ::Selenium::WebDriver::Remote::Bridge
48
+ attr_reader :available_commands
49
+
50
+ def browser
51
+ @browser ||= begin
52
+ name = @capabilities&.browser_name
53
+ name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
54
+ rescue KeyError
55
+ APPIUM_NATIVE_BROWSER_NAME
56
+ end
57
+ end
58
+
59
+ # Appium only.
60
+ # Attach to an existing session.
26
61
  #
27
- # Implements protocol handshake which:
62
+ # @param [String] The session id to attach to.
63
+ # @param [String] platform_name The platform name to keep in the dummy capabilities
64
+ # @param [String] platform_name The automation name to keep in the dummy capabilities
65
+ # @return [::Appium::Core::Base::Capabilities]
28
66
  #
29
- # 1. Creates session with driver.
30
- # 2. Sniffs response.
31
- # 3. Based on the response, understands which dialect we should use.
67
+ # @example
32
68
  #
33
- # @return [Bridge::MJSONWP, Bridge::W3C]
69
+ # new_driver = ::Appium::Core::Driver.attach_to(
70
+ # driver.session_id,
71
+ # url: 'http://127.0.0.1:4723/wd/hub', automation_name: 'UiAutomator2', platform_name: 'Android'
72
+ # )
34
73
  #
35
- def self.handshake(**opts)
36
- desired_capabilities = opts.delete(:desired_capabilities) { ::Selenium::WebDriver::Remote::Capabilities.new }
37
-
38
- if desired_capabilities.is_a?(Symbol)
39
- unless ::Selenium::WebDriver::Remote::Capabilities.respond_to?(desired_capabilities)
40
- raise ::Selenium::WebDriver::Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
41
- end
42
-
43
- desired_capabilities = ::Selenium::WebDriver::Remote::Capabilities.__send__(desired_capabilities)
44
- end
45
-
46
- bridge = new(opts)
47
- capabilities = bridge.create_session(desired_capabilities)
48
-
49
- case bridge.dialect
50
- when :oss # for MJSONWP
51
- Bridge::MJSONWP.new(capabilities, bridge.session_id, **opts)
52
- when :w3c
53
- Bridge::W3C.new(capabilities, bridge.session_id, **opts)
54
- else
55
- raise CoreError, 'cannot understand dialect'
56
- end
74
+ def attach_to(session_id, platform_name, automation_name)
75
+ @available_commands = ::Appium::Core::Commands::COMMANDS.dup
76
+ @session_id = session_id
77
+
78
+ # generate a dummy capabilities instance which only has the given platformName and automationName
79
+ @capabilities = ::Appium::Core::Base::Capabilities.new(
80
+ 'platformName' => platform_name,
81
+ 'automationName' => automation_name
82
+ )
57
83
  end
58
84
 
59
85
  # Override
60
- # Creates session handling both OSS and W3C dialects.
61
- # Copy from Selenium::WebDriver::Remote::Bridge to keep using +merged_capabilities+ for Appium
86
+ # Creates session handling.
62
87
  #
63
- # @param [::Selenium::WebDriver::Remote::W3C::Capabilities, Hash] desired_capabilities A capability
64
- # @return [::Selenium::WebDriver::Remote::Capabilities, ::Selenium::WebDriver::Remote::W3C::Capabilities]
88
+ # @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
89
+ # @return [::Appium::Core::Base::Capabilities]
65
90
  #
66
91
  # @example
67
92
  #
@@ -79,44 +104,31 @@ module Appium
79
104
  # }
80
105
  # }
81
106
  # core = ::Appium::Core.for(caps)
82
- # driver = core.start_driver #=> driver.dialect == :w3c if the Appium server support W3C.
107
+ # driver = core.start_driver
83
108
  #
84
- def create_session(desired_capabilities)
85
- response = execute(:new_session, {}, merged_capabilities(desired_capabilities))
109
+ def create_session(capabilities)
110
+ @available_commands = ::Appium::Core::Commands::COMMANDS.dup
86
111
 
87
- @session_id = response['sessionId']
88
- oss_status = response['status'] # for compatibility with Appium 1.7.1-
89
- value = response['value']
90
-
91
- if value.is_a?(Hash) # include for W3C format
92
- @session_id = value['sessionId'] if value.key?('sessionId')
93
-
94
- if value.key?('capabilities')
95
- value = value['capabilities']
96
- elsif value.key?('value')
97
- value = value['value']
98
- end
99
- end
112
+ always_match = add_appium_prefix(capabilities)
113
+ response = execute(:new_session, {}, { capabilities: { alwaysMatch: always_match, firstMatch: [{}] } })
100
114
 
115
+ @session_id = response['sessionId']
101
116
  raise ::Selenium::WebDriver::Error::WebDriverError, 'no sessionId in returned payload' unless @session_id
102
117
 
103
- json_create(oss_status, value)
118
+ @capabilities = json_create(response['capabilities'])
104
119
  end
105
120
 
106
121
  # Append +appium:+ prefix for Appium following W3C spec
107
122
  # https://www.w3.org/TR/webdriver/#dfn-validate-capabilities
108
123
  #
109
- # @param [::Selenium::WebDriver::Remote::W3C::Capabilities, Hash] capabilities A capability
110
- # @return [::Selenium::WebDriver::Remote::W3C::Capabilities]
124
+ # @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
125
+ # @return [::Appium::Core::Base::Capabilities]
111
126
  def add_appium_prefix(capabilities)
112
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
127
+ w3c_capabilities = ::Appium::Core::Base::Capabilities.new
113
128
 
114
- capabilities = capabilities.__send__(:capabilities) unless capabilities.is_a?(Hash)
129
+ capabilities = capabilities.send(:capabilities) unless capabilities.is_a?(Hash)
115
130
 
116
131
  capabilities.each do |name, value|
117
- next if value.nil?
118
- next if value.is_a?(String) && value.empty?
119
-
120
132
  capability_name = name.to_s
121
133
  w3c_name = extension_prefix?(capability_name) ? name : "#{APPIUM_PREFIX}#{capability_name}"
122
134
 
@@ -128,61 +140,192 @@ module Appium
128
140
 
129
141
  private
130
142
 
131
- def camel_case(str)
132
- str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
143
+ def camel_case(str_or_sym)
144
+ str_or_sym.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
133
145
  end
134
146
 
135
147
  def extension_prefix?(capability_name)
136
- snake_cased_capability_names = ::Selenium::WebDriver::Remote::W3C::Capabilities::KNOWN.map(&:to_s)
148
+ snake_cased_capability_names = ::Appium::Core::Base::Capabilities::KNOWN.map(&:to_s)
137
149
  camel_cased_capability_names = snake_cased_capability_names.map { |v| camel_case(v) }
138
150
 
151
+ # Check 'EXTENSION_CAPABILITY_PATTERN'
139
152
  snake_cased_capability_names.include?(capability_name) ||
140
153
  camel_cased_capability_names.include?(capability_name) ||
141
- capability_name.match(::Selenium::WebDriver::Remote::W3C::Capabilities::EXTENSION_CAPABILITY_PATTERN)
142
- end
143
-
144
- def json_create(oss_status, value)
145
- if oss_status
146
- ::Selenium::WebDriver.logger.info 'Detected OSS dialect.'
147
- @dialect = :oss
148
- ::Selenium::WebDriver::Remote::Capabilities.json_create(value)
149
- else
150
- ::Selenium::WebDriver.logger.info 'Detected W3C dialect.'
151
- @dialect = :w3c
152
- ::Selenium::WebDriver::Remote::W3C::Capabilities.json_create(value)
153
- end
154
+ capability_name.match(':')
154
155
  end
155
156
 
156
- def delete_force_mjsonwp(capabilities)
157
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
157
+ def json_create(value)
158
+ ::Appium::Core::Base::Capabilities.json_create(value)
159
+ end
158
160
 
159
- capabilities = capabilities.__send__(:capabilities) unless capabilities.is_a?(Hash)
160
- capabilities.each do |name, value|
161
- next if value.nil?
162
- next if value.is_a?(String) && value.empty?
163
- next if name == FORCE_MJSONWP
161
+ public
162
+
163
+ # command for Appium 2.0.
164
+
165
+ # Example:
166
+ # driver.add_command(name: :available_contexts, method: :get, url: 'session/:session_id/contexts') do
167
+ # execute(:available_contexts, {}) || []
168
+ # end
169
+ # Then,
170
+ # driver.available_contexts #=> ["NATIVE_APP"]
171
+
172
+ # def add_command(method:, url:, name:, &block)
173
+ # Bridge.add_command name, method, url, &block
174
+ # end
175
+
176
+ def add_command(method:, url:, name:, &block)
177
+ ::Appium::Logger.info "Overriding the method '#{name}' for '#{url}'" if @available_commands.key? name
164
178
 
165
- w3c_capabilities[name] = value
179
+ @available_commands[name] = [method, url]
180
+
181
+ ::Appium::Core::Device.add_endpoint_method name, &block
182
+ end
183
+
184
+ def commands(command)
185
+ @available_commands[command] || Bridge.extra_commands[command]
186
+ end
187
+
188
+ def status
189
+ execute :status
190
+ end
191
+
192
+ # Perform 'touch' actions for W3C module.
193
+ # Generate +touch+ pointer action here and users can use this via +driver.action+
194
+ # - https://www.selenium.dev/documentation/webdriver/actions_api/
195
+ # - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/ActionBuilder.html
196
+ # - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/PointerActions.html
197
+ # - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/KeyActions.html
198
+ #
199
+ # The pointer type is 'touch' by default in the Appium Ruby client.
200
+ #
201
+ # @example
202
+ #
203
+ # element = @driver.find_element(:id, "some id")
204
+ # @driver.action.click(element).perform # The 'click' is a part of 'PointerActions'
205
+ #
206
+ def action(_deprecated_async = nil, async: false, devices: nil)
207
+ ::Selenium::WebDriver::ActionBuilder.new(
208
+ self,
209
+ devices: devices || [::Selenium::WebDriver::Interactions.pointer(:touch, name: 'touch')],
210
+ async: async,
211
+ duration: 50 # milliseconds
212
+ )
213
+ end
214
+
215
+ # Port from MJSONWP
216
+ def get_timeouts
217
+ execute :get_timeouts
218
+ end
219
+
220
+ # For Appium
221
+ # override
222
+ def element_displayed?(element)
223
+ # For W3C
224
+ # https://github.com/SeleniumHQ/selenium/commit/b618499adcc3a9f667590652c5757c0caa703289
225
+ # execute_atom :isDisplayed, element
226
+ execute :is_element_displayed, id: element.id
227
+ end
228
+
229
+ # For Appium
230
+ # override
231
+ def element_attribute(element, name)
232
+ # For W3C in Selenium Client
233
+ # execute_atom :getAttribute, element, name.
234
+ # 'dom_attribute' in the WebDriver Selenium.
235
+ execute :get_element_attribute, id: element.id, name: name
236
+ end
237
+
238
+ # For Appium
239
+ alias switch_to_active_element active_element
240
+
241
+ # For Appium
242
+ # @param [Hash] id The id which can get as a response from server
243
+ # @return [::Appium::Core::Element]
244
+ def convert_to_element(id)
245
+ ::Appium::Core::Element.new self, element_id_from(id)
246
+ end
247
+
248
+ # For Appium
249
+ # override
250
+ # called in 'extend DriverExtensions::HasNetworkConnection'
251
+ def network_connection
252
+ execute :get_network_connection
253
+ end
254
+
255
+ # For Appium
256
+ # override
257
+ # called in 'extend DriverExtensions::HasNetworkConnection'
258
+ def network_connection=(type)
259
+ execute :set_network_connection, {}, { parameters: { type: type } }
260
+ end
261
+
262
+ # For Appium
263
+ # No implementation for W3C webdriver module
264
+ # called in 'extend DriverExtensions::HasLocation'
265
+ def location
266
+ obj = execute(:get_location) || {}
267
+ ::Appium::Location.new obj['latitude'], obj['longitude'], obj['altitude']
268
+ end
269
+
270
+ # For Appium
271
+ # No implementation for W3C webdriver module
272
+ def set_location(lat, lon, alt = 0.0, speed: nil, satellites: nil)
273
+ loc = { latitude: lat, longitude: lon, altitude: alt }
274
+ loc[:speed] = speed unless speed.nil?
275
+ loc[:satellites] = satellites unless satellites.nil?
276
+ execute :set_location, {}, { location: loc }
277
+ end
278
+
279
+ #
280
+ # logs
281
+ #
282
+ # For Appium
283
+ # No implementation for W3C webdriver module
284
+ def available_log_types
285
+ types = execute :get_available_log_types
286
+ Array(types).map(&:to_sym)
287
+ end
288
+
289
+ # For Appium
290
+ # No implementation for W3C webdriver module
291
+ def log(type)
292
+ data = execute :get_log, {}, { type: type.to_s }
293
+
294
+ Array(data).map do |l|
295
+ ::Selenium::WebDriver::LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
296
+ rescue KeyError
297
+ next
166
298
  end
299
+ end
167
300
 
168
- w3c_capabilities
301
+ # For Appium
302
+ def log_event(vendor, event)
303
+ execute :post_log_event, {}, { vendor: vendor, event: event }
169
304
  end
170
305
 
171
- def merged_capabilities(desired_capabilities)
172
- force_mjsonwp = desired_capabilities[FORCE_MJSONWP]
173
- desired_capabilities = delete_force_mjsonwp(desired_capabilities) unless force_mjsonwp.nil?
306
+ # For Appium
307
+ def log_events(type = nil)
308
+ args = {}
309
+ args['type'] = type unless type.nil?
174
310
 
175
- ::Appium::Logger.warn "'forceMjsonwp' no longer works. Sending both W3C and MJSONWP capabilities" if force_mjsonwp
311
+ execute :get_log_events, {}, args
312
+ end
313
+
314
+ def viewport_screenshot
315
+ execute_script('mobile: viewportScreenshot')
316
+ end
176
317
 
177
- new_caps = add_appium_prefix(desired_capabilities)
178
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.from_oss(new_caps)
318
+ def element_screenshot(element_id)
319
+ execute :take_element_screenshot, id: element_id
320
+ end
179
321
 
180
- {
181
- desiredCapabilities: desired_capabilities,
182
- capabilities: {
183
- firstMatch: [w3c_capabilities]
184
- }
185
- }
322
+ # for selenium-webdriver compatibility in chrome browser session.
323
+ # This may be needed in selenium-webdriver 4.8 or over? (around the version)
324
+ # when a session starts browserName: 'chrome' for bridge.
325
+ # This method is not only for Android, but also chrome desktop browser as well.
326
+ # So this bridge itself does not restrict the target module.
327
+ def send_command(command_params)
328
+ execute :chrome_send_command, {}, command_params
186
329
  end
187
330
  end # class Bridge
188
331
  end # class Base
@@ -15,14 +15,27 @@
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::W3C::Capabilities] Return instance of Appium::Core::Base::Capabilities
23
- # inherited ::Selenium::WebDriver::Remote::W3C::Capabilities
24
- def self.create_capabilities(opts_caps = {})
25
- ::Selenium::WebDriver::Remote::W3C::Capabilities.new(opts_caps)
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.
26
+
27
+ # Method override
28
+ # FIXME: when we drop "symbolize_keys", this can be removed.
29
+ def convert_key(key)
30
+ case key
31
+ when String
32
+ key.to_s
33
+ when Symbol
34
+ # here do not convert to camel case
35
+ key.to_s
36
+ else
37
+ raise ::Appium::Core::Error::ArgumentError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
38
+ end
26
39
  end
27
40
  end
28
41
  end
@@ -14,15 +14,36 @@
14
14
 
15
15
  module Appium
16
16
  module Core
17
- module Commands
18
- module MJSONWP
19
- COMMANDS = ::Appium::Core::Commands::COMMANDS.merge(::Appium::Core::Base::Commands::OSS).merge(
20
- {
21
- # W3C already has.
22
- take_element_screenshot: [:get, 'session/:session_id/element/:id/screenshot']
23
- }
24
- ).freeze
25
- end # module MJSONWP
26
- end # module Commands
27
- end # module Core
28
- end # Appium
17
+ class Base
18
+ #
19
+ # @api private
20
+ #
21
+ class DeviceIME
22
+ # @private this class is private
23
+ def initialize(bridge)
24
+ @bridge = bridge
25
+ end
26
+
27
+ def activate(ime_name)
28
+ @bridge.ime_activate(ime_name)
29
+ end
30
+
31
+ def available_engines
32
+ @bridge.ime_available_engines
33
+ end
34
+
35
+ def active_engine
36
+ @bridge.ime_active_engine
37
+ end
38
+
39
+ def activated?
40
+ @bridge.ime_activated
41
+ end
42
+
43
+ def deactivate
44
+ @bridge.ime_deactivate
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end