appium_lib_core 4.1.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +8 -0
  3. data/.github/workflows/codeql-analysis.yml +70 -0
  4. data/.github/workflows/unittest.yml +8 -9
  5. data/.rubocop.yml +95 -1
  6. data/CHANGELOG.md +108 -275
  7. data/README.md +11 -6
  8. data/Rakefile +4 -0
  9. data/appium_lib_core.gemspec +4 -7
  10. data/bin/console +0 -4
  11. data/ci-jobs/functional/run_appium.yml +3 -3
  12. data/ci-jobs/functional_test.yml +3 -3
  13. data/docs/mobile_command.md +2 -2
  14. data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
  15. data/lib/appium_lib_core/android/device.rb +4 -4
  16. data/lib/appium_lib_core/common/base/bridge.rb +301 -90
  17. data/lib/appium_lib_core/common/base/capabilities.rb +10 -3
  18. data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
  19. data/lib/appium_lib_core/common/base/driver.rb +198 -184
  20. data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
  21. data/lib/appium_lib_core/common/base/has_location.rb +80 -0
  22. data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
  23. data/lib/appium_lib_core/common/base/http_default.rb +1 -3
  24. data/lib/appium_lib_core/common/base/remote_status.rb +31 -0
  25. data/lib/appium_lib_core/common/base/rotable.rb +54 -0
  26. data/lib/appium_lib_core/common/base/screenshot.rb +6 -6
  27. data/lib/appium_lib_core/common/base/search_context.rb +19 -4
  28. data/lib/appium_lib_core/common/base.rb +1 -3
  29. data/lib/appium_lib_core/common/command.rb +257 -4
  30. data/lib/appium_lib_core/common/device/app_management.rb +2 -14
  31. data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
  32. data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
  33. data/lib/appium_lib_core/common/{command/mjsonwp.rb → device/orientation.rb} +14 -11
  34. data/lib/appium_lib_core/common/device/touch_actions.rb +2 -0
  35. data/lib/appium_lib_core/common/device/value.rb +6 -6
  36. data/lib/appium_lib_core/common/error.rb +4 -1
  37. data/lib/appium_lib_core/common/log.rb +4 -1
  38. data/lib/appium_lib_core/common/touch_action/multi_touch.rb +19 -0
  39. data/lib/appium_lib_core/common/touch_action/touch_actions.rb +16 -2
  40. data/lib/appium_lib_core/common/wait.rb +38 -6
  41. data/lib/appium_lib_core/device.rb +1 -5
  42. data/lib/appium_lib_core/driver.rb +30 -46
  43. data/lib/appium_lib_core/{patch.rb → element.rb} +66 -9
  44. data/lib/appium_lib_core/ios/uiautomation/patch.rb +1 -1
  45. data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
  46. data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
  47. data/lib/appium_lib_core/mac2/device.rb +92 -0
  48. data/lib/appium_lib_core/mac2.rb +17 -0
  49. data/lib/appium_lib_core/version.rb +2 -2
  50. data/lib/appium_lib_core.rb +2 -5
  51. data/release_notes.md +148 -0
  52. data/script/commands.rb +3 -37
  53. metadata +27 -68
  54. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
  55. data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
  56. data/lib/appium_lib_core/common/command/common.rb +0 -110
  57. data/lib/appium_lib_core/common/command/w3c.rb +0 -56
@@ -16,52 +16,45 @@ module Appium
16
16
  module Core
17
17
  class Base
18
18
  class Bridge < ::Selenium::WebDriver::Remote::Bridge
19
+ include Device::DeviceLock
20
+ include Device::Keyboard
21
+ include Device::ImeActions
22
+ include Device::Setting
23
+ include Device::Context
24
+ include Device::Value
25
+ include Device::FileManagement
26
+ include Device::KeyEvent
27
+ include Device::ImageComparison
28
+ include Device::AppManagement
29
+ include Device::AppState
30
+ include Device::ScreenRecord::Command
31
+ include Device::Device
32
+ include Device::TouchActions
33
+ include Device::ExecuteDriver
34
+ include Device::Orientation
35
+
19
36
  # Prefix for extra capability defined by W3C
20
37
  APPIUM_PREFIX = 'appium:'
21
38
 
22
- # TODO: Remove the forceMjsonwp after Appium server won't need it
23
- FORCE_MJSONWP = :forceMjsonwp
24
-
25
- # Almost same as self.handshake in ::Selenium::WebDriver::Remote::Bridge
26
- #
27
- # Implements protocol handshake which:
28
- #
29
- # 1. Creates session with driver.
30
- # 2. Sniffs response.
31
- # 3. Based on the response, understands which dialect we should use.
32
- #
33
- # @return [Bridge::MJSONWP, Bridge::W3C]
34
- #
35
- def self.handshake(**opts)
36
- desired_capabilities = opts.delete(:desired_capabilities) { ::Selenium::WebDriver::Remote::Capabilities.new }
39
+ # No 'browserName' means the session is native appium connection
40
+ APPIUM_NATIVE_BROWSER_NAME = 'appium'
37
41
 
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
+ attr_reader :available_commands
42
43
 
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'
44
+ def browser
45
+ @browser ||= begin
46
+ name = @capabilities.browser_name
47
+ name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
48
+ rescue KeyError
49
+ APPIUM_NATIVE_BROWSER_NAME
56
50
  end
57
51
  end
58
52
 
59
53
  # Override
60
- # Creates session handling both OSS and W3C dialects.
61
- # Copy from Selenium::WebDriver::Remote::Bridge to keep using +merged_capabilities+ for Appium
54
+ # Creates session handling.
62
55
  #
63
- # @param [::Selenium::WebDriver::Remote::W3C::Capabilities, Hash] desired_capabilities A capability
64
- # @return [::Selenium::WebDriver::Remote::Capabilities, ::Selenium::WebDriver::Remote::W3C::Capabilities]
56
+ # @param [::Selenium::WebDriver::Remote::Capabilities, Hash] capabilities A capability
57
+ # @return [::Selenium::WebDriver::Remote::Capabilities]
65
58
  #
66
59
  # @example
67
60
  #
@@ -79,39 +72,29 @@ module Appium
79
72
  # }
80
73
  # }
81
74
  # core = ::Appium::Core.for(caps)
82
- # driver = core.start_driver #=> driver.dialect == :w3c if the Appium server support W3C.
75
+ # driver = core.start_driver
83
76
  #
84
- def create_session(desired_capabilities)
85
- response = execute(:new_session, {}, merged_capabilities(desired_capabilities))
86
-
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')
77
+ def create_session(capabilities)
78
+ @available_commands = ::Appium::Core::Commands::COMMANDS.dup
93
79
 
94
- if value.key?('capabilities')
95
- value = value['capabilities']
96
- elsif value.key?('value')
97
- value = value['value']
98
- end
99
- end
80
+ always_match = add_appium_prefix(capabilities)
81
+ response = execute(:new_session, {}, { capabilities: { alwaysMatch: always_match, firstMatch: [{}] } })
100
82
 
83
+ @session_id = response['sessionId']
101
84
  raise ::Selenium::WebDriver::Error::WebDriverError, 'no sessionId in returned payload' unless @session_id
102
85
 
103
- json_create(oss_status, value)
86
+ @capabilities = json_create(response['capabilities'])
104
87
  end
105
88
 
106
89
  # Append +appium:+ prefix for Appium following W3C spec
107
90
  # https://www.w3.org/TR/webdriver/#dfn-validate-capabilities
108
91
  #
109
- # @param [::Selenium::WebDriver::Remote::W3C::Capabilities, Hash] capabilities A capability
110
- # @return [::Selenium::WebDriver::Remote::W3C::Capabilities]
92
+ # @param [::Selenium::WebDriver::Remote::Capabilities, Hash] capabilities A capability
93
+ # @return [::Selenium::WebDriver::Remote::Capabilities]
111
94
  def add_appium_prefix(capabilities)
112
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
95
+ w3c_capabilities = ::Selenium::WebDriver::Remote::Capabilities.new
113
96
 
114
- capabilities = capabilities.__send__(:capabilities) unless capabilities.is_a?(Hash)
97
+ capabilities = capabilities.send(:capabilities) unless capabilities.is_a?(Hash)
115
98
 
116
99
  capabilities.each do |name, value|
117
100
  next if value.nil?
@@ -133,56 +116,284 @@ module Appium
133
116
  end
134
117
 
135
118
  def extension_prefix?(capability_name)
136
- snake_cased_capability_names = ::Selenium::WebDriver::Remote::W3C::Capabilities::KNOWN.map(&:to_s)
119
+ snake_cased_capability_names = ::Selenium::WebDriver::Remote::Capabilities::KNOWN.map(&:to_s)
137
120
  camel_cased_capability_names = snake_cased_capability_names.map { |v| camel_case(v) }
138
121
 
122
+ # Check 'EXTENSION_CAPABILITY_PATTERN'
139
123
  snake_cased_capability_names.include?(capability_name) ||
140
124
  camel_cased_capability_names.include?(capability_name) ||
141
- capability_name.match(::Selenium::WebDriver::Remote::W3C::Capabilities::EXTENSION_CAPABILITY_PATTERN)
125
+ capability_name.match(':')
142
126
  end
143
127
 
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
128
+ def json_create(value)
129
+ ::Selenium::WebDriver::Remote::Capabilities.json_create(value)
154
130
  end
155
131
 
156
- def delete_force_mjsonwp(capabilities)
157
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
132
+ public
158
133
 
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
134
+ # command for Appium 2.0.
135
+ def add_command(method:, url:, name:, &block)
136
+ ::Appium::Logger.info "Overriding the method '#{name}' for '#{url}'" if @available_commands.key? name
137
+
138
+ @available_commands[name] = [method, url]
139
+
140
+ ::Appium::Core::Device.add_endpoint_method name, &block
141
+ end
142
+
143
+ def commands(command)
144
+ @available_commands[command]
145
+ end
146
+
147
+ # Returns all available sessions on the Appium server instance
148
+ def sessions
149
+ execute :get_all_sessions
150
+ end
151
+
152
+ def status
153
+ execute :status
154
+ end
155
+
156
+ # Perform touch actions for W3C module.
157
+ # Generate +touch+ pointer action here and users can use this via +driver.action+
158
+ # - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/W3CActionBuilder.html
159
+ # - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/PointerActions.html
160
+ # - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/KeyActions.html
161
+ #
162
+ # The pointer type is 'touch' by default in the Appium Ruby client. (The selenium one is 'mouse')
163
+ #
164
+ # @example
165
+ #
166
+ # element = @driver.find_element(:id, "some id")
167
+ # @driver.action.click(element).perform # The 'click' is a part of 'PointerActions'
168
+ #
169
+ def action(async = false)
170
+ action_builder = ::Selenium::WebDriver::ActionBuilder.new(
171
+ self,
172
+ ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'touch'),
173
+ ::Selenium::WebDriver::Interactions.key('keyboard'),
174
+ async
175
+ )
176
+ # Used for default duration of each touch actions.
177
+ # Override from 250 milliseconds to 50 milliseconds in PointerActions included by ::Selenium::WebDriver::ActionBuilder
178
+ action_builder.default_move_duration = 0.05
179
+ action_builder
180
+ end
181
+
182
+ # Port from MJSONWP
183
+ def get_timeouts
184
+ execute :get_timeouts
185
+ end
186
+
187
+ # Port from MJSONWP
188
+ def session_capabilities
189
+ ::Selenium::WebDriver::Remote::Capabilities.json_create execute(:get_capabilities)
190
+ end
191
+
192
+ # Port from MJSONWP
193
+ def send_keys_to_active_element(key)
194
+ text = ::Selenium::WebDriver::Keys.encode(key).join
195
+ execute :send_keys_to_active_element, {}, { value: text.chars }
196
+ end
197
+
198
+ # For Appium
199
+ # override
200
+ def page_source
201
+ # For W3C
202
+ # execute_script('var source = document.documentElement.outerHTML;' \
203
+ # 'if (!source) { source = new XMLSerializer().serializeToString(document); }' \
204
+ # 'return source;')
205
+ execute :get_page_source
206
+ end
207
+
208
+ # For Appium
209
+ # override
210
+ def element_displayed?(element)
211
+ # For W3C
212
+ # https://github.com/SeleniumHQ/selenium/commit/b618499adcc3a9f667590652c5757c0caa703289
213
+ # execute_atom :isDisplayed, element
214
+ execute :is_element_displayed, id: element.id
215
+ end
216
+
217
+ # For Appium
218
+ # override
219
+ def element_attribute(element, name)
220
+ # For W3C in Selenium Client
221
+ # execute_atom :getAttribute, element, name
222
+ execute :get_element_attribute, id: element.id, name: name
223
+ end
224
+
225
+ # For Appium
226
+ # override
227
+ def active_element
228
+ ::Appium::Core::Element.new self, element_id_from(execute(:get_active_element))
229
+ end
230
+ alias switch_to_active_element active_element
231
+
232
+ # For Appium
233
+ # override
234
+ def find_element_by(how, what, parent_ref = [])
235
+ how, what = convert_locator(how, what)
236
+
237
+ return execute_atom(:findElements, Support::RelativeLocator.new(what).as_json).first if how == 'relative'
238
+
239
+ parent_type, parent_id = parent_ref
240
+ id = case parent_type
241
+ when :element
242
+ execute :find_child_element, { id: parent_id }, { using: how, value: what.to_s }
243
+ when :shadow_root
244
+ execute :find_shadow_child_element, { id: parent_id }, { using: how, value: what.to_s }
245
+ else
246
+ execute :find_element, {}, { using: how, value: what.to_s }
247
+ end
248
+
249
+ ::Appium::Core::Element.new self, element_id_from(id)
250
+ end
251
+
252
+ # For Appium
253
+ # override
254
+ def find_elements_by(how, what, parent_ref = [])
255
+ how, what = convert_locator(how, what)
256
+
257
+ return execute_atom :findElements, Support::RelativeLocator.new(what).as_json if how == 'relative'
258
+
259
+ parent_type, parent_id = parent_ref
260
+ ids = case parent_type
261
+ when :element
262
+ execute :find_child_elements, { id: parent_id }, { using: how, value: what.to_s }
263
+ when :shadow_root
264
+ execute :find_shadow_child_elements, { id: parent_id }, { using: how, value: what.to_s }
265
+ else
266
+ execute :find_elements, {}, { using: how, value: what.to_s }
267
+ end
164
268
 
165
- w3c_capabilities[name] = value
269
+ ids.map { |id| ::Appium::Core::Element.new self, element_id_from(id) }
270
+ end
271
+
272
+ # For Appium
273
+ # @param [Hash] id The id which can get as a response from server
274
+ # @return [::Appium::Core::Element]
275
+ def convert_to_element(id)
276
+ ::Appium::Core::Element.new self, element_id_from(id)
277
+ end
278
+
279
+ # For Appium
280
+ # override
281
+ # called in 'extend DriverExtensions::HasNetworkConnection'
282
+ def network_connection
283
+ execute :get_network_connection
284
+ end
285
+
286
+ # For Appium
287
+ # override
288
+ # called in 'extend DriverExtensions::HasNetworkConnection'
289
+ def network_connection=(type)
290
+ execute :set_network_connection, {}, { parameters: { type: type } }
291
+ end
292
+
293
+ # For Appium
294
+ # No implementation for W3C webdriver module
295
+ # called in 'extend DriverExtensions::HasLocation'
296
+ def location
297
+ obj = execute(:get_location) || {}
298
+ ::Selenium::WebDriver::Location.new obj['latitude'], obj['longitude'], obj['altitude']
299
+ end
300
+
301
+ # For Appium
302
+ # No implementation for W3C webdriver module
303
+ def set_location(lat, lon, alt = 0.0, speed: nil, satellites: nil)
304
+ loc = { latitude: lat, longitude: lon, altitude: alt }
305
+ loc[:speed] = speed unless speed.nil?
306
+ loc[:satellites] = satellites unless satellites.nil?
307
+ execute :set_location, {}, { location: loc }
308
+ end
309
+
310
+ #
311
+ # logs
312
+ #
313
+ # For Appium
314
+ # No implementation for W3C webdriver module
315
+ def available_log_types
316
+ types = execute :get_available_log_types
317
+ Array(types).map(&:to_sym)
318
+ end
319
+
320
+ # For Appium
321
+ # No implementation for W3C webdriver module
322
+ def log(type)
323
+ data = execute :get_log, {}, { type: type.to_s }
324
+
325
+ Array(data).map do |l|
326
+ ::Selenium::WebDriver::LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
327
+ rescue KeyError
328
+ next
166
329
  end
330
+ end
167
331
 
168
- w3c_capabilities
332
+ # For Appium
333
+ def log_event(vendor, event)
334
+ execute :post_log_event, {}, { vendor: vendor, event: event }
169
335
  end
170
336
 
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?
337
+ # For Appium
338
+ def log_events(type = nil)
339
+ args = {}
340
+ args['type'] = type unless type.nil?
174
341
 
175
- ::Appium::Logger.warn "'forceMjsonwp' no longer works. Sending both W3C and MJSONWP capabilities" if force_mjsonwp
342
+ execute :get_log_events, {}, args
343
+ end
344
+
345
+ def viewport_screenshot
346
+ execute_script('mobile: viewportScreenshot')
347
+ end
176
348
 
177
- new_caps = add_appium_prefix(desired_capabilities)
178
- w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.from_oss(new_caps)
349
+ def element_screenshot(element_id)
350
+ execute :take_element_screenshot, id: element_id
351
+ end
352
+
353
+ private
354
+
355
+ def unwrap_script_result(arg)
356
+ case arg
357
+ when Array
358
+ arg.map { |e| unwrap_script_result(e) }
359
+ when Hash
360
+ element_id = element_id_from(arg)
361
+ return ::Appium::Core::Element.new(self, element_id) if element_id
362
+
363
+ arg.each { |k, v| arg[k] = unwrap_script_result(v) }
364
+ else
365
+ arg
366
+ end
367
+ end
368
+
369
+ def element_id_from(id)
370
+ id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
371
+ end
179
372
 
180
- {
181
- desiredCapabilities: desired_capabilities,
182
- capabilities: {
183
- firstMatch: [w3c_capabilities]
184
- }
185
- }
373
+ # Don't convert locators for Appium in native context
374
+ def convert_locator(how, what)
375
+ # case how
376
+ # when 'class name'
377
+ # how = 'css selector'
378
+ # what = ".#{escape_css(what)}"
379
+ # when 'id'
380
+ # how = 'css selector'
381
+ # what = "##{escape_css(what)}"
382
+ # when 'name'
383
+ # how = 'css selector'
384
+ # what = "*[name='#{escape_css(what)}']"
385
+ # when 'tag name'
386
+ # how = 'css selector'
387
+ # end
388
+ #
389
+ # if what.is_a?(Hash)
390
+ # what = what.each_with_object({}) do |(h, w), hash|
391
+ # h, w = convert_locator(h.to_s, w)
392
+ # hash[h] = w
393
+ # end
394
+ # end
395
+
396
+ [how, what]
186
397
  end
187
398
  end # class Bridge
188
399
  end # class Base
@@ -19,10 +19,17 @@ module Appium
19
19
  # @private
20
20
  # @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
21
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
22
+ # @return [::Selenium::WebDriver::Remote::Capabilities] Return instance of Appium::Core::Base::Capabilities
23
+ # inherited ::Selenium::WebDriver::Remote::Capabilities
24
24
  def self.create_capabilities(opts_caps = {})
25
- ::Selenium::WebDriver::Remote::W3C::Capabilities.new(opts_caps)
25
+ # TODO: Move to 'Options' way instead of 'Capabilities'.
26
+ # Selenium 5 will have Options instead of 'Capabilities'.
27
+ # https://github.com/SeleniumHQ/selenium/blob/trunk/rb/lib/selenium/webdriver/common/options.rb
28
+ # Then, Ruby client also shoud move to the Options way.
29
+ # Appium's capabilities could change by depending on Appium versions. So it does not have
30
+ # standard options like chrome and firefox etc. So, the implementation should differ from
31
+ # other browsers. But here should inherit `Options` to follow Selenium.
32
+ ::Selenium::WebDriver::Remote::Capabilities.new(opts_caps)
26
33
  end
27
34
  end
28
35
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Appium
16
+ module Core
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