appium_lib_core 4.1.0 → 5.0.0.beta4
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/.github/dependabot.yml +8 -0
- data/.github/workflows/unittest.yml +2 -2
- data/CHANGELOG.md +43 -277
- data/README.md +2 -1
- data/appium_lib_core.gemspec +4 -4
- data/ci-jobs/functional/run_appium.yml +2 -2
- data/ci-jobs/functional_test.yml +1 -1
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
- data/lib/appium_lib_core/android/device.rb +4 -4
- data/lib/appium_lib_core/common/base/bridge.rb +284 -89
- data/lib/appium_lib_core/common/base/capabilities.rb +3 -3
- data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
- data/lib/appium_lib_core/common/base/driver.rb +157 -88
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +73 -0
- data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
- data/lib/appium_lib_core/common/base/http_default.rb +1 -3
- data/lib/appium_lib_core/common/base/remote_status.rb +31 -0
- data/lib/appium_lib_core/common/base/rotable.rb +54 -0
- data/lib/appium_lib_core/common/base/screenshot.rb +1 -1
- data/lib/appium_lib_core/common/base/search_context.rb +11 -4
- 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/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/error.rb +4 -1
- data/lib/appium_lib_core/common/log.rb +4 -1
- data/lib/appium_lib_core/device.rb +1 -5
- data/lib/appium_lib_core/driver.rb +17 -13
- data/lib/appium_lib_core/{patch.rb → element.rb} +53 -5
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +1 -1
- 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/mac2.rb +17 -0
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core.rb +2 -5
- data/release_notes.md +73 -0
- data/script/commands.rb +3 -37
- metadata +30 -30
- 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/README.md
CHANGED
@@ -11,6 +11,7 @@ This library wraps [selenium-webdriver](https://github.com/SeleniumHQ/selenium/w
|
|
11
11
|
# Documentation
|
12
12
|
|
13
13
|
- http://www.rubydoc.info/github/appium/ruby_lib_core
|
14
|
+
- You can find working API examples in test code, [test/functional](test/functional)
|
14
15
|
|
15
16
|
# Related library
|
16
17
|
- https://github.com/appium/ruby_lib
|
@@ -120,7 +121,7 @@ $ IGNORE_VERSION_SKIP=true CI=true bundle exec rake test:func:android
|
|
120
121
|
$ ruby test.rb
|
121
122
|
```
|
122
123
|
|
123
|
-
More examples are in [test/functional](test/functional)
|
124
|
+
More examples are in [test/functional](test/functional)
|
124
125
|
|
125
126
|
### Capabilities
|
126
127
|
|
data/appium_lib_core.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'appium_lib_core/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.required_ruby_version = '>= 2.
|
7
|
+
spec.required_ruby_version = '>= 2.5'
|
8
8
|
|
9
9
|
spec.name = 'appium_lib_core'
|
10
10
|
spec.version = Appium::Core::VERSION
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
|
-
spec.add_runtime_dependency 'selenium-webdriver', '
|
25
|
+
spec.add_runtime_dependency 'selenium-webdriver', '4.0.0.beta4'
|
26
26
|
spec.add_runtime_dependency 'faye-websocket', '~> 0.11.0'
|
27
27
|
|
28
28
|
spec.add_development_dependency 'bundler', '>= 1.14'
|
@@ -30,8 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency 'yard', '~> 0.9.11'
|
31
31
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
32
32
|
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
33
|
-
spec.add_development_dependency 'webmock', '~> 3.
|
34
|
-
spec.add_development_dependency 'rubocop', '1.
|
33
|
+
spec.add_development_dependency 'webmock', '~> 3.13.0'
|
34
|
+
spec.add_development_dependency 'rubocop', '1.12.0'
|
35
35
|
spec.add_development_dependency 'appium_thor', '~> 1.0'
|
36
36
|
spec.add_development_dependency 'pry'
|
37
37
|
spec.add_development_dependency 'pry-byebug'
|
@@ -1,8 +1,8 @@
|
|
1
1
|
steps:
|
2
2
|
- task: NodeTool@0
|
3
3
|
inputs:
|
4
|
-
versionSpec:
|
5
|
-
displayName: Install Node
|
4
|
+
versionSpec: 12.x
|
5
|
+
displayName: Install Node 12.x
|
6
6
|
- script: npm install -g appium@${APPIUM_VERSION}
|
7
7
|
displayName: Install appium beta
|
8
8
|
- script: npm install -g mjpeg-consumer
|
data/ci-jobs/functional_test.yml
CHANGED
@@ -4,7 +4,7 @@ parameters:
|
|
4
4
|
vmImageForIOS: 'macOS-10.15' # Not sure the reason, but macOS 10.14 instance raises no info.plist error
|
5
5
|
xcodeForIOS: 12.2
|
6
6
|
xcodeForTVOS: 12.2
|
7
|
-
androidSDK: 30
|
7
|
+
androidSDK: 29 # API Level 30 emulators are more unstable than 29
|
8
8
|
appiumVersion: 'beta'
|
9
9
|
ignoreVersionSkip: true
|
10
10
|
CI: true
|
@@ -21,7 +21,8 @@ module Appium
|
|
21
21
|
::Appium::Core::Device.add_endpoint_method(:finger_print) do
|
22
22
|
def finger_print(finger_id)
|
23
23
|
unless (1..10).cover? finger_id.to_i
|
24
|
-
raise ArgumentError,
|
24
|
+
raise ::Appium::Core::Error::ArgumentError,
|
25
|
+
"finger_id should be integer between 1 to 10. Not #{finger_id}"
|
25
26
|
end
|
26
27
|
|
27
28
|
execute(:finger_print, {}, { fingerprintId: finger_id.to_i })
|
@@ -290,16 +290,16 @@ module Appium
|
|
290
290
|
# @driver.finger_print 1
|
291
291
|
#
|
292
292
|
|
293
|
-
# @!method execute_cdp(cmd, params)
|
293
|
+
# @!method execute_cdp(cmd, **params)
|
294
294
|
# Execute Chrome Devtools protocol commands
|
295
295
|
# https://chromedevtools.github.io/devtools-protocol
|
296
296
|
#
|
297
297
|
# @param [String] cmd The name of command
|
298
|
-
# @
|
298
|
+
# @option params The parameter for the command as keyword options.
|
299
299
|
#
|
300
300
|
# @example
|
301
301
|
#
|
302
|
-
# @driver.execute_cdp 'Page.captureScreenshot',
|
302
|
+
# @driver.execute_cdp 'Page.captureScreenshot', quality: 50, format: 'jpeg'
|
303
303
|
# @driver.execute_cdp 'Page.getResourceTree'
|
304
304
|
#
|
305
305
|
|
@@ -415,7 +415,7 @@ module Appium
|
|
415
415
|
# SeleniumWebdriver could already define this method
|
416
416
|
return if method_defined? :execute_cdp
|
417
417
|
|
418
|
-
def execute_cdp(cmd, params
|
418
|
+
def execute_cdp(cmd, **params)
|
419
419
|
execute :chrome_send_command, {}, { cmd: cmd, params: params }
|
420
420
|
end
|
421
421
|
end
|
@@ -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
|
-
#
|
23
|
-
|
39
|
+
# No 'browserName' means the session is native appium connection
|
40
|
+
APPIUM_NATIVE_BROWSER_NAME = 'appium'
|
24
41
|
|
25
|
-
|
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 }
|
42
|
+
attr_reader :available_commands
|
37
43
|
|
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'
|
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
54
|
# Creates session handling both OSS and W3C dialects.
|
61
|
-
# Copy from Selenium::WebDriver::Remote::Bridge to keep using +merged_capabilities+ for Appium
|
62
55
|
#
|
63
|
-
# @param [::Selenium::WebDriver::Remote::
|
64
|
-
# @return [::Selenium::WebDriver::Remote::Capabilities
|
56
|
+
# @param [::Selenium::WebDriver::Remote::Capabilities, Hash] desired_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
|
75
|
+
# driver = core.start_driver
|
83
76
|
#
|
84
|
-
def create_session(
|
85
|
-
|
77
|
+
def create_session(capabilities)
|
78
|
+
@available_commands = ::Appium::Core::Commands::COMMANDS.dup
|
86
79
|
|
87
|
-
|
88
|
-
|
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
|
80
|
+
caps = add_appium_prefix(capabilities)
|
81
|
+
response = execute(:new_session, {}, { capabilities: { firstMatch: [caps] } })
|
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(
|
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::
|
110
|
-
# @return [::Selenium::WebDriver::Remote::
|
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::
|
95
|
+
w3c_capabilities = ::Selenium::WebDriver::Remote::Capabilities.new
|
113
96
|
|
114
|
-
capabilities = capabilities.
|
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,268 @@ module Appium
|
|
133
116
|
end
|
134
117
|
|
135
118
|
def extension_prefix?(capability_name)
|
136
|
-
snake_cased_capability_names = ::Selenium::WebDriver::Remote::
|
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(
|
125
|
+
capability_name.match(':')
|
142
126
|
end
|
143
127
|
|
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
|
128
|
+
def json_create(value)
|
129
|
+
::Selenium::WebDriver::Remote::Capabilities.json_create(value)
|
154
130
|
end
|
155
131
|
|
156
|
-
|
157
|
-
w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
|
132
|
+
public
|
158
133
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
134
|
+
# command for Appium 2.0.
|
135
|
+
def add_command(method:, url:, name:, &block)
|
136
|
+
raise ::Appium::Core::Error::ArgumentError, "#{name} is already defined" 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
|
+
# 'mouse' action is by default in the Ruby client. Appium server force the +mouse+ action to +touch+ once in
|
163
|
+
# the server side. So we don't consider the case.
|
164
|
+
#
|
165
|
+
# @example
|
166
|
+
#
|
167
|
+
# element = @driver.find_element(:id, "some id")
|
168
|
+
# @driver.action.click(element).perform # The 'click' is a part of 'PointerActions'
|
169
|
+
#
|
170
|
+
def action(async = false)
|
171
|
+
# Used for default duration of each touch actions
|
172
|
+
# Override from 250 milliseconds to 50 milliseconds
|
173
|
+
action_builder = super
|
174
|
+
action_builder.default_move_duration = 0.05
|
175
|
+
action_builder
|
176
|
+
end
|
177
|
+
|
178
|
+
# Port from MJSONWP
|
179
|
+
def get_timeouts
|
180
|
+
execute :get_timeouts
|
181
|
+
end
|
182
|
+
|
183
|
+
# Port from MJSONWP
|
184
|
+
def session_capabilities
|
185
|
+
::Selenium::WebDriver::Remote::Capabilities.json_create execute(:get_capabilities)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Port from MJSONWP
|
189
|
+
def send_keys_to_active_element(key)
|
190
|
+
text = ::Selenium::WebDriver::Keys.encode(key).join('')
|
191
|
+
execute :send_keys_to_active_element, {}, { value: text.split(//) }
|
192
|
+
end
|
164
193
|
|
165
|
-
|
194
|
+
# For Appium
|
195
|
+
# override
|
196
|
+
def page_source
|
197
|
+
# For W3C
|
198
|
+
# execute_script('var source = document.documentElement.outerHTML;' \
|
199
|
+
# 'if (!source) { source = new XMLSerializer().serializeToString(document); }' \
|
200
|
+
# 'return source;')
|
201
|
+
execute :get_page_source
|
202
|
+
end
|
203
|
+
|
204
|
+
# For Appium
|
205
|
+
# override
|
206
|
+
def element_displayed?(element)
|
207
|
+
# For W3C
|
208
|
+
# https://github.com/SeleniumHQ/selenium/commit/b618499adcc3a9f667590652c5757c0caa703289
|
209
|
+
# execute_atom :isDisplayed, element
|
210
|
+
execute :is_element_displayed, id: element.ref
|
211
|
+
end
|
212
|
+
|
213
|
+
# For Appium
|
214
|
+
# override
|
215
|
+
def element_attribute(element, name)
|
216
|
+
# For W3C in Selenium Client
|
217
|
+
# execute_atom :getAttribute, element, name
|
218
|
+
execute :get_element_attribute, id: element.ref, name: name
|
219
|
+
end
|
220
|
+
|
221
|
+
# For Appium
|
222
|
+
# override
|
223
|
+
def active_element
|
224
|
+
::Appium::Core::Element.new self, element_id_from(execute(:get_active_element))
|
225
|
+
end
|
226
|
+
alias switch_to_active_element active_element
|
227
|
+
|
228
|
+
# For Appium
|
229
|
+
# override
|
230
|
+
def find_element_by(how, what, parent = nil)
|
231
|
+
how, what = convert_locator(how, what)
|
232
|
+
|
233
|
+
id = if parent
|
234
|
+
execute :find_child_element, { id: parent }, { using: how, value: what }
|
235
|
+
else
|
236
|
+
execute :find_element, {}, { using: how, value: what }
|
237
|
+
end
|
238
|
+
::Appium::Core::Element.new self, element_id_from(id)
|
239
|
+
end
|
240
|
+
|
241
|
+
# For Appium
|
242
|
+
# override
|
243
|
+
def find_elements_by(how, what, parent = nil)
|
244
|
+
how, what = convert_locator(how, what)
|
245
|
+
|
246
|
+
ids = if parent
|
247
|
+
execute :find_child_elements, { id: parent }, { using: how, value: what }
|
248
|
+
else
|
249
|
+
execute :find_elements, {}, { using: how, value: what }
|
250
|
+
end
|
251
|
+
|
252
|
+
ids.map { |id| ::Appium::Core::Element.new self, element_id_from(id) }
|
253
|
+
end
|
254
|
+
|
255
|
+
# For Appium
|
256
|
+
# @param [Hash] id The id which can get as a response from server
|
257
|
+
# @return [::Appium::Core::Element]
|
258
|
+
def convert_to_element(id)
|
259
|
+
::Appium::Core::Element.new self, element_id_from(id)
|
260
|
+
end
|
261
|
+
|
262
|
+
# For Appium
|
263
|
+
# override
|
264
|
+
# called in 'extend DriverExtensions::HasNetworkConnection'
|
265
|
+
def network_connection
|
266
|
+
execute :get_network_connection
|
267
|
+
end
|
268
|
+
|
269
|
+
# For Appium
|
270
|
+
# override
|
271
|
+
# called in 'extend DriverExtensions::HasNetworkConnection'
|
272
|
+
def network_connection=(type)
|
273
|
+
execute :set_network_connection, {}, { parameters: { type: type } }
|
274
|
+
end
|
275
|
+
|
276
|
+
# For Appium
|
277
|
+
# No implementation for W3C webdriver module
|
278
|
+
# called in 'extend DriverExtensions::HasLocation'
|
279
|
+
def location
|
280
|
+
obj = execute(:get_location) || {}
|
281
|
+
::Selenium::WebDriver::Location.new obj['latitude'], obj['longitude'], obj['altitude']
|
282
|
+
end
|
283
|
+
|
284
|
+
# For Appium
|
285
|
+
# No implementation for W3C webdriver module
|
286
|
+
def set_location(lat, lon, alt = 0.0, speed: nil)
|
287
|
+
loc = { latitude: lat, longitude: lon, altitude: alt }
|
288
|
+
loc[:speed] = speed unless speed.nil?
|
289
|
+
execute :set_location, {}, { location: loc }
|
290
|
+
end
|
291
|
+
|
292
|
+
#
|
293
|
+
# logs
|
294
|
+
#
|
295
|
+
# For Appium
|
296
|
+
# No implementation for W3C webdriver module
|
297
|
+
def available_log_types
|
298
|
+
types = execute :get_available_log_types
|
299
|
+
Array(types).map(&:to_sym)
|
300
|
+
end
|
301
|
+
|
302
|
+
# For Appium
|
303
|
+
# No implementation for W3C webdriver module
|
304
|
+
def log(type)
|
305
|
+
data = execute :get_log, {}, { type: type.to_s }
|
306
|
+
|
307
|
+
Array(data).map do |l|
|
308
|
+
begin
|
309
|
+
::Selenium::WebDriver::LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
|
310
|
+
rescue KeyError
|
311
|
+
next
|
312
|
+
end
|
166
313
|
end
|
314
|
+
end
|
167
315
|
|
168
|
-
|
316
|
+
# For Appium
|
317
|
+
def log_event(vendor, event)
|
318
|
+
execute :post_log_event, {}, { vendor: vendor, event: event }
|
319
|
+
end
|
320
|
+
|
321
|
+
# For Appium
|
322
|
+
def log_events(type = nil)
|
323
|
+
args = {}
|
324
|
+
args['type'] = type unless type.nil?
|
325
|
+
|
326
|
+
execute :get_log_events, {}, args
|
327
|
+
end
|
328
|
+
|
329
|
+
def take_viewport_screenshot
|
330
|
+
execute_script('mobile: viewportScreenshot')
|
169
331
|
end
|
170
332
|
|
171
|
-
def
|
172
|
-
|
173
|
-
|
333
|
+
def take_element_screenshot(element)
|
334
|
+
execute :take_element_screenshot, id: element.ref
|
335
|
+
end
|
336
|
+
|
337
|
+
private
|
174
338
|
|
175
|
-
|
339
|
+
def unwrap_script_result(arg)
|
340
|
+
case arg
|
341
|
+
when Array
|
342
|
+
arg.map { |e| unwrap_script_result(e) }
|
343
|
+
when Hash
|
344
|
+
element_id = element_id_from(arg)
|
345
|
+
return ::Appium::Core::Element.new(self, element_id) if element_id
|
176
346
|
|
177
|
-
|
178
|
-
|
347
|
+
arg.each { |k, v| arg[k] = unwrap_script_result(v) }
|
348
|
+
else
|
349
|
+
arg
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def element_id_from(id)
|
354
|
+
id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
|
355
|
+
end
|
179
356
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
}
|
357
|
+
# Don't convert locators for Appium in native context
|
358
|
+
def convert_locator(how, what)
|
359
|
+
# case how
|
360
|
+
# when 'class name'
|
361
|
+
# how = 'css selector'
|
362
|
+
# what = ".#{escape_css(what)}"
|
363
|
+
# when 'id'
|
364
|
+
# how = 'css selector'
|
365
|
+
# what = "##{escape_css(what)}"
|
366
|
+
# when 'name'
|
367
|
+
# how = 'css selector'
|
368
|
+
# what = "*[name='#{escape_css(what)}']"
|
369
|
+
# when 'tag name'
|
370
|
+
# how = 'css selector'
|
371
|
+
# end
|
372
|
+
#
|
373
|
+
# if what.is_a?(Hash)
|
374
|
+
# what = what.each_with_object({}) do |(h, w), hash|
|
375
|
+
# h, w = convert_locator(h.to_s, w)
|
376
|
+
# hash[h] = w
|
377
|
+
# end
|
378
|
+
# end
|
379
|
+
|
380
|
+
[how, what]
|
186
381
|
end
|
187
382
|
end # class Bridge
|
188
383
|
end # class Base
|
@@ -19,10 +19,10 @@ 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::
|
23
|
-
# inherited ::Selenium::WebDriver::Remote::
|
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::
|
25
|
+
::Selenium::WebDriver::Remote::Capabilities.new(opts_caps)
|
26
26
|
end
|
27
27
|
end
|
28
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
|