appium_lib_core 4.1.0 → 7.1.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 +4 -4
- data/CHANGELOG.md +250 -271
- data/README.md +65 -15
- data/Rakefile +4 -0
- data/appium_lib_core.gemspec +5 -8
- data/bin/console +0 -4
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
- data/lib/appium_lib_core/android/device.rb +45 -4
- data/lib/appium_lib_core/common/base/bridge.rb +320 -90
- data/lib/appium_lib_core/common/base/capabilities.rb +8 -9
- data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
- data/lib/appium_lib_core/common/base/driver.rb +232 -191
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +80 -0
- data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
- data/lib/appium_lib_core/common/base/http_default.rb +15 -38
- data/lib/appium_lib_core/{ios/uiautomation/bridge.rb → common/base/remote_status.rb} +9 -8
- data/lib/appium_lib_core/common/base/rotable.rb +62 -0
- data/lib/appium_lib_core/common/base/screenshot.rb +8 -8
- data/lib/appium_lib_core/common/base/search_context.rb +20 -6
- data/lib/appium_lib_core/common/base.rb +1 -3
- data/lib/appium_lib_core/common/command.rb +259 -4
- data/lib/appium_lib_core/common/device/app_management.rb +8 -14
- data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
- data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
- data/lib/appium_lib_core/common/{command/mjsonwp.rb → device/orientation.rb} +14 -11
- data/lib/appium_lib_core/common/device/touch_actions.rb +2 -0
- data/lib/appium_lib_core/common/device/value.rb +6 -8
- data/lib/appium_lib_core/common/error.rb +4 -5
- data/lib/appium_lib_core/common/log.rb +4 -1
- data/lib/appium_lib_core/common/touch_action/multi_touch.rb +19 -0
- data/lib/appium_lib_core/common/touch_action/touch_actions.rb +16 -2
- data/lib/appium_lib_core/common/wait.rb +38 -6
- data/lib/appium_lib_core/device.rb +1 -5
- data/lib/appium_lib_core/driver.rb +194 -108
- data/lib/appium_lib_core/{patch.rb → element.rb} +66 -9
- data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
- data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
- data/lib/appium_lib_core/mac2/device.rb +92 -0
- data/lib/appium_lib_core/{ios.rb → mac2.rb} +2 -5
- data/lib/appium_lib_core/support/event_firing_bridge.rb +57 -0
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core/windows/device/app_management.rb +38 -0
- data/lib/appium_lib_core/windows/device.rb +2 -0
- data/lib/appium_lib_core.rb +21 -10
- metadata +31 -86
- data/.github/ISSUE_TEMPLATE/issue-report.md +0 -29
- data/.github/contributing.md +0 -26
- data/.github/issue_template.md +0 -20
- data/.github/workflows/unittest.yml +0 -68
- data/.gitignore +0 -18
- data/.rubocop.yml +0 -58
- data/azure-pipelines.yml +0 -15
- data/ci-jobs/functional/android_setup.yml +0 -3
- data/ci-jobs/functional/ios_setup.yml +0 -7
- data/ci-jobs/functional/publish_test_result.yml +0 -18
- data/ci-jobs/functional/run_appium.yml +0 -25
- data/ci-jobs/functional/start-emulator.sh +0 -26
- data/ci-jobs/functional_test.yml +0 -298
- data/docs/mobile_command.md +0 -34
- data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
- data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
- data/lib/appium_lib_core/common/command/common.rb +0 -110
- data/lib/appium_lib_core/common/command/w3c.rb +0 -56
- data/lib/appium_lib_core/ios/uiautomation/device.rb +0 -44
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +0 -34
- data/release_notes.md +0 -816
- data/script/commands.rb +0 -200
@@ -16,52 +16,71 @@ 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
|
-
#
|
23
|
-
|
39
|
+
# No 'browserName' means the session is native appium connection
|
40
|
+
APPIUM_NATIVE_BROWSER_NAME = 'appium'
|
41
|
+
|
42
|
+
attr_reader :available_commands
|
43
|
+
|
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
|
50
|
+
end
|
51
|
+
end
|
24
52
|
|
25
|
-
#
|
53
|
+
# Appium only.
|
54
|
+
# Attach to an existing session.
|
26
55
|
#
|
27
|
-
#
|
56
|
+
# @param [String] The session id to attach to.
|
57
|
+
# @param [String] platform_name The platform name to keep in the dummy capabilities
|
58
|
+
# @param [String] platform_name The automation name to keep in the dummy capabilities
|
59
|
+
# @return [::Appium::Core::Base::Capabilities]
|
28
60
|
#
|
29
|
-
#
|
30
|
-
# 2. Sniffs response.
|
31
|
-
# 3. Based on the response, understands which dialect we should use.
|
61
|
+
# @example
|
32
62
|
#
|
33
|
-
#
|
63
|
+
# new_driver = ::Appium::Core::Driver.attach_to(
|
64
|
+
# driver.session_id,
|
65
|
+
# url: 'http://127.0.0.1:4723/wd/hub', automation_name: 'UiAutomator2', platform_name: 'Android'
|
66
|
+
# )
|
34
67
|
#
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
68
|
+
def attach_to(session_id, platform_name, automation_name)
|
69
|
+
@available_commands = ::Appium::Core::Commands::COMMANDS.dup
|
70
|
+
@session_id = session_id
|
71
|
+
|
72
|
+
# generate a dummy capabilities instance which only has the given platformName and automationName
|
73
|
+
@capabilities = ::Appium::Core::Base::Capabilities.new(
|
74
|
+
'platformName' => platform_name,
|
75
|
+
'automationName' => automation_name
|
76
|
+
)
|
57
77
|
end
|
58
78
|
|
59
79
|
# Override
|
60
|
-
# Creates session handling
|
61
|
-
# Copy from Selenium::WebDriver::Remote::Bridge to keep using +merged_capabilities+ for Appium
|
80
|
+
# Creates session handling.
|
62
81
|
#
|
63
|
-
# @param [::
|
64
|
-
# @return [::
|
82
|
+
# @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
|
83
|
+
# @return [::Appium::Core::Base::Capabilities]
|
65
84
|
#
|
66
85
|
# @example
|
67
86
|
#
|
@@ -79,39 +98,29 @@ module Appium
|
|
79
98
|
# }
|
80
99
|
# }
|
81
100
|
# core = ::Appium::Core.for(caps)
|
82
|
-
# driver = core.start_driver
|
101
|
+
# driver = core.start_driver
|
83
102
|
#
|
84
|
-
def create_session(
|
85
|
-
|
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')
|
103
|
+
def create_session(capabilities)
|
104
|
+
@available_commands = ::Appium::Core::Commands::COMMANDS.dup
|
93
105
|
|
94
|
-
|
95
|
-
|
96
|
-
elsif value.key?('value')
|
97
|
-
value = value['value']
|
98
|
-
end
|
99
|
-
end
|
106
|
+
always_match = add_appium_prefix(capabilities)
|
107
|
+
response = execute(:new_session, {}, { capabilities: { alwaysMatch: always_match, firstMatch: [{}] } })
|
100
108
|
|
109
|
+
@session_id = response['sessionId']
|
101
110
|
raise ::Selenium::WebDriver::Error::WebDriverError, 'no sessionId in returned payload' unless @session_id
|
102
111
|
|
103
|
-
json_create(
|
112
|
+
@capabilities = json_create(response['capabilities'])
|
104
113
|
end
|
105
114
|
|
106
115
|
# Append +appium:+ prefix for Appium following W3C spec
|
107
116
|
# https://www.w3.org/TR/webdriver/#dfn-validate-capabilities
|
108
117
|
#
|
109
|
-
# @param [::
|
110
|
-
# @return [::
|
118
|
+
# @param [::Appium::Core::Base::Capabilities, Hash] capabilities A capability
|
119
|
+
# @return [::Appium::Core::Base::Capabilities]
|
111
120
|
def add_appium_prefix(capabilities)
|
112
|
-
w3c_capabilities = ::
|
121
|
+
w3c_capabilities = ::Appium::Core::Base::Capabilities.new
|
113
122
|
|
114
|
-
capabilities = capabilities.
|
123
|
+
capabilities = capabilities.send(:capabilities) unless capabilities.is_a?(Hash)
|
115
124
|
|
116
125
|
capabilities.each do |name, value|
|
117
126
|
next if value.nil?
|
@@ -128,61 +137,282 @@ module Appium
|
|
128
137
|
|
129
138
|
private
|
130
139
|
|
131
|
-
def camel_case(
|
132
|
-
|
140
|
+
def camel_case(str_or_sym)
|
141
|
+
str_or_sym.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
133
142
|
end
|
134
143
|
|
135
144
|
def extension_prefix?(capability_name)
|
136
|
-
snake_cased_capability_names = ::
|
145
|
+
snake_cased_capability_names = ::Appium::Core::Base::Capabilities::KNOWN.map(&:to_s)
|
137
146
|
camel_cased_capability_names = snake_cased_capability_names.map { |v| camel_case(v) }
|
138
147
|
|
148
|
+
# Check 'EXTENSION_CAPABILITY_PATTERN'
|
139
149
|
snake_cased_capability_names.include?(capability_name) ||
|
140
150
|
camel_cased_capability_names.include?(capability_name) ||
|
141
|
-
capability_name.match(
|
151
|
+
capability_name.match(':')
|
142
152
|
end
|
143
153
|
|
144
|
-
def json_create(
|
145
|
-
|
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
|
+
def json_create(value)
|
155
|
+
::Appium::Core::Base::Capabilities.json_create(value)
|
154
156
|
end
|
155
157
|
|
156
|
-
|
157
|
-
w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
|
158
|
+
public
|
158
159
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
160
|
+
# command for Appium 2.0.
|
161
|
+
def add_command(method:, url:, name:, &block)
|
162
|
+
::Appium::Logger.info "Overriding the method '#{name}' for '#{url}'" if @available_commands.key? name
|
163
|
+
|
164
|
+
@available_commands[name] = [method, url]
|
165
|
+
|
166
|
+
::Appium::Core::Device.add_endpoint_method name, &block
|
167
|
+
end
|
168
|
+
|
169
|
+
def commands(command)
|
170
|
+
@available_commands[command]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Returns all available sessions on the Appium server instance
|
174
|
+
def sessions
|
175
|
+
execute :get_all_sessions
|
176
|
+
end
|
177
|
+
|
178
|
+
def status
|
179
|
+
execute :status
|
180
|
+
end
|
181
|
+
|
182
|
+
# Perform 'touch' actions for W3C module.
|
183
|
+
# Generate +touch+ pointer action here and users can use this via +driver.action+
|
184
|
+
# - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/W3CActionBuilder.html
|
185
|
+
# - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/PointerActions.html
|
186
|
+
# - https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/KeyActions.html
|
187
|
+
#
|
188
|
+
# The pointer type is 'touch' by default in the Appium Ruby client.
|
189
|
+
#
|
190
|
+
# @example
|
191
|
+
#
|
192
|
+
# element = @driver.find_element(:id, "some id")
|
193
|
+
# @driver.action.click(element).perform # The 'click' is a part of 'PointerActions'
|
194
|
+
#
|
195
|
+
def action(_deprecated_async = nil, async: false, devices: nil)
|
196
|
+
::Selenium::WebDriver::ActionBuilder.new(
|
197
|
+
self,
|
198
|
+
devices: devices || [::Selenium::WebDriver::Interactions.pointer(:touch, name: 'touch')],
|
199
|
+
async: async,
|
200
|
+
duration: 50 # milliseconds
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Port from MJSONWP
|
205
|
+
def get_timeouts
|
206
|
+
execute :get_timeouts
|
207
|
+
end
|
208
|
+
|
209
|
+
# Port from MJSONWP
|
210
|
+
def session_capabilities
|
211
|
+
::Appium::Core::Base::Capabilities.json_create execute(:get_capabilities)
|
212
|
+
end
|
213
|
+
|
214
|
+
# For Appium
|
215
|
+
# override
|
216
|
+
def element_displayed?(element)
|
217
|
+
# For W3C
|
218
|
+
# https://github.com/SeleniumHQ/selenium/commit/b618499adcc3a9f667590652c5757c0caa703289
|
219
|
+
# execute_atom :isDisplayed, element
|
220
|
+
execute :is_element_displayed, id: element.id
|
221
|
+
end
|
222
|
+
|
223
|
+
# For Appium
|
224
|
+
# override
|
225
|
+
def element_attribute(element, name)
|
226
|
+
# For W3C in Selenium Client
|
227
|
+
# execute_atom :getAttribute, element, name.
|
228
|
+
# 'dom_attribute' in the WebDriver Selenium.
|
229
|
+
execute :get_element_attribute, id: element.id, name: name
|
230
|
+
end
|
231
|
+
|
232
|
+
# For Appium
|
233
|
+
# override
|
234
|
+
def active_element
|
235
|
+
::Appium::Core::Element.new self, element_id_from(execute(:get_active_element))
|
236
|
+
end
|
237
|
+
alias switch_to_active_element active_element
|
238
|
+
|
239
|
+
# For Appium
|
240
|
+
# override
|
241
|
+
def find_element_by(how, what, parent_ref = [])
|
242
|
+
how, what = convert_locator(how, what)
|
243
|
+
|
244
|
+
return execute_atom(:findElements, Support::RelativeLocator.new(what).as_json).first if how == 'relative'
|
245
|
+
|
246
|
+
parent_type, parent_id = parent_ref
|
247
|
+
id = case parent_type
|
248
|
+
when :element
|
249
|
+
execute :find_child_element, { id: parent_id }, { using: how, value: what.to_s }
|
250
|
+
when :shadow_root
|
251
|
+
execute :find_shadow_child_element, { id: parent_id }, { using: how, value: what.to_s }
|
252
|
+
else
|
253
|
+
execute :find_element, {}, { using: how, value: what.to_s }
|
254
|
+
end
|
255
|
+
|
256
|
+
::Appium::Core::Element.new self, element_id_from(id)
|
257
|
+
end
|
258
|
+
|
259
|
+
# For Appium
|
260
|
+
# override
|
261
|
+
def find_elements_by(how, what, parent_ref = [])
|
262
|
+
how, what = convert_locator(how, what)
|
263
|
+
|
264
|
+
return execute_atom :findElements, Support::RelativeLocator.new(what).as_json if how == 'relative'
|
265
|
+
|
266
|
+
parent_type, parent_id = parent_ref
|
267
|
+
ids = case parent_type
|
268
|
+
when :element
|
269
|
+
execute :find_child_elements, { id: parent_id }, { using: how, value: what.to_s }
|
270
|
+
when :shadow_root
|
271
|
+
execute :find_shadow_child_elements, { id: parent_id }, { using: how, value: what.to_s }
|
272
|
+
else
|
273
|
+
execute :find_elements, {}, { using: how, value: what.to_s }
|
274
|
+
end
|
275
|
+
|
276
|
+
ids.map { |id| ::Appium::Core::Element.new self, element_id_from(id) }
|
277
|
+
end
|
278
|
+
|
279
|
+
# For Appium
|
280
|
+
# @param [Hash] id The id which can get as a response from server
|
281
|
+
# @return [::Appium::Core::Element]
|
282
|
+
def convert_to_element(id)
|
283
|
+
::Appium::Core::Element.new self, element_id_from(id)
|
284
|
+
end
|
285
|
+
|
286
|
+
# For Appium
|
287
|
+
# override
|
288
|
+
# called in 'extend DriverExtensions::HasNetworkConnection'
|
289
|
+
def network_connection
|
290
|
+
execute :get_network_connection
|
291
|
+
end
|
292
|
+
|
293
|
+
# For Appium
|
294
|
+
# override
|
295
|
+
# called in 'extend DriverExtensions::HasNetworkConnection'
|
296
|
+
def network_connection=(type)
|
297
|
+
execute :set_network_connection, {}, { parameters: { type: type } }
|
298
|
+
end
|
299
|
+
|
300
|
+
# For Appium
|
301
|
+
# No implementation for W3C webdriver module
|
302
|
+
# called in 'extend DriverExtensions::HasLocation'
|
303
|
+
def location
|
304
|
+
obj = execute(:get_location) || {}
|
305
|
+
::Appium::Location.new obj['latitude'], obj['longitude'], obj['altitude']
|
306
|
+
end
|
307
|
+
|
308
|
+
# For Appium
|
309
|
+
# No implementation for W3C webdriver module
|
310
|
+
def set_location(lat, lon, alt = 0.0, speed: nil, satellites: nil)
|
311
|
+
loc = { latitude: lat, longitude: lon, altitude: alt }
|
312
|
+
loc[:speed] = speed unless speed.nil?
|
313
|
+
loc[:satellites] = satellites unless satellites.nil?
|
314
|
+
execute :set_location, {}, { location: loc }
|
315
|
+
end
|
316
|
+
|
317
|
+
#
|
318
|
+
# logs
|
319
|
+
#
|
320
|
+
# For Appium
|
321
|
+
# No implementation for W3C webdriver module
|
322
|
+
def available_log_types
|
323
|
+
types = execute :get_available_log_types
|
324
|
+
Array(types).map(&:to_sym)
|
325
|
+
end
|
164
326
|
|
165
|
-
|
327
|
+
# For Appium
|
328
|
+
# No implementation for W3C webdriver module
|
329
|
+
def log(type)
|
330
|
+
data = execute :get_log, {}, { type: type.to_s }
|
331
|
+
|
332
|
+
Array(data).map do |l|
|
333
|
+
::Selenium::WebDriver::LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
|
334
|
+
rescue KeyError
|
335
|
+
next
|
166
336
|
end
|
337
|
+
end
|
167
338
|
|
168
|
-
|
339
|
+
# For Appium
|
340
|
+
def log_event(vendor, event)
|
341
|
+
execute :post_log_event, {}, { vendor: vendor, event: event }
|
342
|
+
end
|
343
|
+
|
344
|
+
# For Appium
|
345
|
+
def log_events(type = nil)
|
346
|
+
args = {}
|
347
|
+
args['type'] = type unless type.nil?
|
348
|
+
|
349
|
+
execute :get_log_events, {}, args
|
350
|
+
end
|
351
|
+
|
352
|
+
def viewport_screenshot
|
353
|
+
execute_script('mobile: viewportScreenshot')
|
169
354
|
end
|
170
355
|
|
171
|
-
def
|
172
|
-
|
173
|
-
|
356
|
+
def element_screenshot(element_id)
|
357
|
+
execute :take_element_screenshot, id: element_id
|
358
|
+
end
|
359
|
+
|
360
|
+
# for selenium-webdriver compatibility in chrome browser session.
|
361
|
+
# This may be needed in selenium-webdriver 4.8 or over? (around the version)
|
362
|
+
# when a session starts browserName: 'chrome' for bridge.
|
363
|
+
# This method is not only for Android, but also chrome desktop browser as well.
|
364
|
+
# So this bridge itself does not restrict the target module.
|
365
|
+
def send_command(command_params)
|
366
|
+
execute :chrome_send_command, {}, command_params
|
367
|
+
end
|
368
|
+
|
369
|
+
private
|
370
|
+
|
371
|
+
def unwrap_script_result(arg)
|
372
|
+
case arg
|
373
|
+
when Array
|
374
|
+
arg.map { |e| unwrap_script_result(e) }
|
375
|
+
when Hash
|
376
|
+
element_id = element_id_from(arg)
|
377
|
+
return ::Appium::Core::Element.new(self, element_id) if element_id
|
174
378
|
|
175
|
-
|
379
|
+
shadow_root_id = shadow_root_id_from(arg)
|
380
|
+
return ::Selenium::WebDriver::Remote::ShadowRoot.new self, shadow_root_id if shadow_root_id
|
176
381
|
|
177
|
-
|
178
|
-
|
382
|
+
arg.each { |k, v| arg[k] = unwrap_script_result(v) }
|
383
|
+
else
|
384
|
+
arg
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
def element_id_from(id)
|
389
|
+
id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
|
390
|
+
end
|
179
391
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
}
|
392
|
+
# Don't convert locators for Appium in native context
|
393
|
+
def convert_locator(how, what)
|
394
|
+
# case how
|
395
|
+
# when 'class name'
|
396
|
+
# how = 'css selector'
|
397
|
+
# what = ".#{escape_css(what)}"
|
398
|
+
# when 'id'
|
399
|
+
# how = 'css selector'
|
400
|
+
# what = "##{escape_css(what)}"
|
401
|
+
# when 'name'
|
402
|
+
# how = 'css selector'
|
403
|
+
# what = "*[name='#{escape_css(what)}']"
|
404
|
+
# when 'tag name'
|
405
|
+
# how = 'css selector'
|
406
|
+
# end
|
407
|
+
#
|
408
|
+
# if what.is_a?(Hash)
|
409
|
+
# what = what.each_with_object({}) do |(h, w), hash|
|
410
|
+
# h, w = convert_locator(h.to_s, w)
|
411
|
+
# hash[h] = w
|
412
|
+
# end
|
413
|
+
# end
|
414
|
+
|
415
|
+
[how, what]
|
186
416
|
end
|
187
417
|
end # class Bridge
|
188
418
|
end # class Base
|
@@ -15,15 +15,14 @@
|
|
15
15
|
module Appium
|
16
16
|
module Core
|
17
17
|
class Base
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
end
|
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.
|
27
26
|
end
|
28
27
|
end
|
29
28
|
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
|