appium_lib_core 5.0.0.beta2 → 5.0.0.rc2
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 +15 -6
- data/README.md +2 -1
- data/Rakefile +4 -0
- data/appium_lib_core.gemspec +3 -3
- data/ci-jobs/functional_test.yml +1 -1
- data/docs/mobile_command.md +3 -2
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
- data/lib/appium_lib_core/common/base/bridge.rb +66 -30
- data/lib/appium_lib_core/common/base/capabilities.rb +7 -0
- data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
- data/lib/appium_lib_core/common/base/driver.rb +93 -110
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +11 -4
- data/lib/appium_lib_core/common/base/has_network_connection.rb +1 -1
- data/lib/appium_lib_core/common/base/rotable.rb +1 -1
- data/lib/appium_lib_core/common/base/screenshot.rb +4 -3
- data/lib/appium_lib_core/common/base/search_context.rb +9 -4
- data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
- data/lib/appium_lib_core/common/device/value.rb +4 -4
- 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/common/touch_action/touch_actions.rb +4 -1
- data/lib/appium_lib_core/driver.rb +7 -16
- data/lib/appium_lib_core/element.rb +7 -7
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core.rb +1 -1
- data/release_notes.md +23 -0
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eba36b9dee77259cd1a14dd0e03c3a140a0e4bcb014d3d7d277ca9d4c47e011
|
4
|
+
data.tar.gz: 511a0a3fa46c55f078185c8d25262ec4c6b5d281be628a2217df1d90fd58d331
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47a0de22452cdfa19f9e9aa71dd1b29bedc17c0b431860c7db5bbccb4f50ff83e08db3103caa5ad9e40aaf526518c072ee32563a7139d126222c63d52375048e
|
7
|
+
data.tar.gz: 868a920d5221fba2e9e9e3c583a7e5c81cd00bbdf19680ef4795ae23cb71ea773fdce24889935574190a82d888f8ba7f99f1e98e3f86ddd3dab344710598675a
|
data/CHANGELOG.md
CHANGED
@@ -5,27 +5,36 @@ Read `release_notes.md` for commit level details.
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
7
|
### Enhancements
|
8
|
+
- Allow to override an existing method by `Appium::Core::Base::Driver#add_command` since Appium drivers/plugins allow to override them
|
8
9
|
|
9
10
|
### Bug fixes
|
10
11
|
|
11
12
|
### Deprecations
|
12
13
|
|
13
|
-
## [5.0.0.
|
14
|
+
## [5.0.0.beta]
|
14
15
|
|
15
16
|
- Update base selenium webdriver version to `4.0.0.beta2`
|
16
17
|
- Support only W3C spec
|
17
18
|
- Support Ruby 2.5+
|
19
|
+
- Raises `::Appium::Core::Error::ArgumentError` instead of `ArgumentError` for this library specific argument errors
|
20
|
+
- Removed `desired_capabilities` from capabilities. Please use `capabilities` instead.
|
21
|
+
- `element.ref` returns not only element id. It returns an array like `[:driver, id]`. You should do `_, element_id = element.ref` to get the element id
|
18
22
|
|
19
|
-
## [4.
|
23
|
+
## [4.7.0] - 2021-07-17
|
20
24
|
|
21
25
|
### Enhancements
|
22
|
-
- Add `
|
23
|
-
- Add `multiple` and `match_neighbour_threshold` arguments for `Appium::Core::Base::Driver#find_image_occurrence`
|
26
|
+
- Add `satellites` option in `Appium::Core::Base::Driver#set_location`
|
24
27
|
|
25
|
-
|
28
|
+
## [4.6.0] - 2021-06-03
|
26
29
|
|
27
|
-
###
|
30
|
+
### Enhancements
|
31
|
+
- Add `Appium::Core::Base::Driver#add_command` to allow you to add your own command
|
28
32
|
|
33
|
+
## [4.5.0] - 2021-03-14
|
34
|
+
|
35
|
+
### Enhancements
|
36
|
+
- Add `speed` argument for `Appium::Core::Base::Driver#set_location` since Appium 1.21.0
|
37
|
+
- Add `multiple` and `match_neighbour_threshold` arguments for `Appium::Core::Base::Driver#find_image_occurrence`
|
29
38
|
|
30
39
|
## [4.4.1(4.4.0)] - 2021-02-15(2021-02-13)
|
31
40
|
|
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/Rakefile
CHANGED
@@ -38,6 +38,7 @@ namespace :test do
|
|
38
38
|
namespace :unit do
|
39
39
|
desc('Run all iOS related unit tests in test directory')
|
40
40
|
Rake::TestTask.new(:ios) do |t|
|
41
|
+
ENV['UNIT_TEST'] = '1'
|
41
42
|
t.libs << 'test'
|
42
43
|
t.libs << 'lib'
|
43
44
|
t.test_files = FileList['test/unit/ios/**/*_test.rb']
|
@@ -45,6 +46,7 @@ namespace :test do
|
|
45
46
|
|
46
47
|
desc('Run all Android related unit tests in test directory')
|
47
48
|
Rake::TestTask.new(:android) do |t|
|
49
|
+
ENV['UNIT_TEST'] = '1'
|
48
50
|
t.libs << 'test'
|
49
51
|
t.libs << 'lib'
|
50
52
|
t.test_files = FileList['test/unit/android/**/*_test.rb']
|
@@ -52,6 +54,7 @@ namespace :test do
|
|
52
54
|
|
53
55
|
desc('Run all common related unit tests in test directory')
|
54
56
|
Rake::TestTask.new(:common) do |t|
|
57
|
+
ENV['UNIT_TEST'] = '1'
|
55
58
|
t.libs << 'test'
|
56
59
|
t.libs << 'lib'
|
57
60
|
t.test_files = FileList['test/unit/common/**/*_test.rb']
|
@@ -59,6 +62,7 @@ namespace :test do
|
|
59
62
|
|
60
63
|
desc('Run all Windows related unit tests in test directory')
|
61
64
|
Rake::TestTask.new(:windows) do |t|
|
65
|
+
ENV['UNIT_TEST'] = '1'
|
62
66
|
t.libs << 'test'
|
63
67
|
t.libs << 'lib'
|
64
68
|
t.test_files = FileList['test/unit/windows/**/*_test.rb']
|
data/appium_lib_core.gemspec
CHANGED
@@ -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', '4.0.0.
|
25
|
+
spec.add_runtime_dependency 'selenium-webdriver', '4.0.0.rc2'
|
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.12.
|
33
|
+
spec.add_development_dependency 'webmock', '~> 3.14.0'
|
34
|
+
spec.add_development_dependency 'rubocop', '1.12.1'
|
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'
|
data/ci-jobs/functional_test.yml
CHANGED
@@ -103,7 +103,7 @@ jobs:
|
|
103
103
|
- template: ./functional/ios_setup.yml
|
104
104
|
parameters:
|
105
105
|
xcodeVersion: ${{ parameters.xcodeForIOS }}
|
106
|
-
- script: brew install ffmpeg && brew tap wix/brew && brew install
|
106
|
+
- script: brew install ffmpeg && brew tap wix/brew && brew install applesimutils
|
107
107
|
displayName: Install ffmpeg and applesimutils
|
108
108
|
- template: ./functional/run_appium.yml
|
109
109
|
- script: bundle exec rake test:func:ios TESTS=test/functional/ios/ios/mjpeg_server_test.rb,test/functional/ios/ios/mobile_commands_test.rb
|
data/docs/mobile_command.md
CHANGED
@@ -9,7 +9,7 @@ We can invoke them via `execute_script` command with `mobile:` arguments.
|
|
9
9
|
- https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android
|
10
10
|
- iOS:
|
11
11
|
- https://github.com/appium/appium/tree/master/docs/en/writing-running-appium/ios
|
12
|
-
|
12
|
+
|
13
13
|
|
14
14
|
```ruby
|
15
15
|
# Android shell : https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android/android-shell.md
|
@@ -28,7 +28,8 @@ To handle it, we would recommend you to handle the error based on the error mess
|
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
error = assert_raises ::Selenium::WebDriver::Error::UnknownError do
|
31
|
-
|
31
|
+
_, element_id = el.ref
|
32
|
+
@driver.execute_script 'mobile: scrollToPage', { element: element_id, scrollToPage: -100 }
|
32
33
|
end
|
33
34
|
assert error.message.include? 'be a non-negative integer'
|
34
35
|
```
|
@@ -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 })
|
@@ -36,20 +36,24 @@ module Appium
|
|
36
36
|
# Prefix for extra capability defined by W3C
|
37
37
|
APPIUM_PREFIX = 'appium:'
|
38
38
|
|
39
|
-
#
|
39
|
+
# No 'browserName' means the session is native appium connection
|
40
|
+
APPIUM_NATIVE_BROWSER_NAME = 'appium'
|
41
|
+
|
42
|
+
attr_reader :available_commands
|
43
|
+
|
40
44
|
def browser
|
41
45
|
@browser ||= begin
|
42
46
|
name = @capabilities.browser_name
|
43
47
|
name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
|
44
48
|
rescue KeyError
|
45
|
-
|
49
|
+
APPIUM_NATIVE_BROWSER_NAME
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
53
|
# Override
|
50
54
|
# Creates session handling both OSS and W3C dialects.
|
51
55
|
#
|
52
|
-
# @param [::Selenium::WebDriver::Remote::Capabilities, Hash]
|
56
|
+
# @param [::Selenium::WebDriver::Remote::Capabilities, Hash] capabilities A capability
|
53
57
|
# @return [::Selenium::WebDriver::Remote::Capabilities]
|
54
58
|
#
|
55
59
|
# @example
|
@@ -70,16 +74,16 @@ module Appium
|
|
70
74
|
# core = ::Appium::Core.for(caps)
|
71
75
|
# driver = core.start_driver
|
72
76
|
#
|
73
|
-
def create_session(
|
74
|
-
|
75
|
-
response = execute(:new_session, {}, { capabilities: { firstMatch: [caps] } })
|
77
|
+
def create_session(capabilities)
|
78
|
+
@available_commands = ::Appium::Core::Commands::COMMANDS.dup
|
76
79
|
|
77
|
-
|
78
|
-
|
80
|
+
caps = add_appium_prefix(capabilities)
|
81
|
+
response = execute(:new_session, {}, { capabilities: { alwaysMatch: caps, firstMatch: [] } })
|
79
82
|
|
83
|
+
@session_id = response['sessionId']
|
80
84
|
raise ::Selenium::WebDriver::Error::WebDriverError, 'no sessionId in returned payload' unless @session_id
|
81
85
|
|
82
|
-
@capabilities = json_create(capabilities)
|
86
|
+
@capabilities = json_create(response['capabilities'])
|
83
87
|
end
|
84
88
|
|
85
89
|
# Append +appium:+ prefix for Appium following W3C spec
|
@@ -90,7 +94,7 @@ module Appium
|
|
90
94
|
def add_appium_prefix(capabilities)
|
91
95
|
w3c_capabilities = ::Selenium::WebDriver::Remote::Capabilities.new
|
92
96
|
|
93
|
-
capabilities = capabilities.
|
97
|
+
capabilities = capabilities.send(:capabilities) unless capabilities.is_a?(Hash)
|
94
98
|
|
95
99
|
capabilities.each do |name, value|
|
96
100
|
next if value.nil?
|
@@ -127,8 +131,17 @@ module Appium
|
|
127
131
|
|
128
132
|
public
|
129
133
|
|
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
|
+
|
130
143
|
def commands(command)
|
131
|
-
|
144
|
+
@available_commands[command]
|
132
145
|
end
|
133
146
|
|
134
147
|
# Returns all available sessions on the Appium server instance
|
@@ -194,7 +207,8 @@ module Appium
|
|
194
207
|
# For W3C
|
195
208
|
# https://github.com/SeleniumHQ/selenium/commit/b618499adcc3a9f667590652c5757c0caa703289
|
196
209
|
# execute_atom :isDisplayed, element
|
197
|
-
|
210
|
+
_, element_id = element.ref
|
211
|
+
execute :is_element_displayed, id: element_id
|
198
212
|
end
|
199
213
|
|
200
214
|
# For Appium
|
@@ -202,7 +216,8 @@ module Appium
|
|
202
216
|
def element_attribute(element, name)
|
203
217
|
# For W3C in Selenium Client
|
204
218
|
# execute_atom :getAttribute, element, name
|
205
|
-
|
219
|
+
_, element_id = element.ref
|
220
|
+
execute :get_element_attribute, id: element_id, name: name
|
206
221
|
end
|
207
222
|
|
208
223
|
# For Appium
|
@@ -214,26 +229,39 @@ module Appium
|
|
214
229
|
|
215
230
|
# For Appium
|
216
231
|
# override
|
217
|
-
def find_element_by(how, what,
|
218
|
-
how, what =
|
232
|
+
def find_element_by(how, what, parent_ref = [])
|
233
|
+
how, what = convert_locator(how, what)
|
219
234
|
|
220
|
-
|
221
|
-
|
235
|
+
return execute_atom(:findElements, Support::RelativeLocator.new(what).as_json).first if how == 'relative'
|
236
|
+
|
237
|
+
parent_type, parent_id = parent_ref
|
238
|
+
id = case parent_type
|
239
|
+
when :element
|
240
|
+
execute :find_child_element, { id: parent_id }, { using: how, value: what.to_s }
|
241
|
+
when :shadow_root
|
242
|
+
execute :find_shadow_child_element, { id: parent_id }, { using: how, value: what.to_s }
|
222
243
|
else
|
223
|
-
execute :find_element, {}, { using: how, value: what }
|
244
|
+
execute :find_element, {}, { using: how, value: what.to_s }
|
224
245
|
end
|
246
|
+
|
225
247
|
::Appium::Core::Element.new self, element_id_from(id)
|
226
248
|
end
|
227
249
|
|
228
250
|
# For Appium
|
229
251
|
# override
|
230
|
-
def find_elements_by(how, what,
|
231
|
-
how, what =
|
252
|
+
def find_elements_by(how, what, parent_ref = [])
|
253
|
+
how, what = convert_locator(how, what)
|
232
254
|
|
233
|
-
|
234
|
-
|
255
|
+
return execute_atom :findElements, Support::RelativeLocator.new(what).as_json if how == 'relative'
|
256
|
+
|
257
|
+
parent_type, parent_id = parent_ref
|
258
|
+
ids = case parent_type
|
259
|
+
when :element
|
260
|
+
execute :find_child_elements, { id: parent_id }, { using: how, value: what.to_s }
|
261
|
+
when :shadow_root
|
262
|
+
execute :find_shadow_child_elements, { id: parent_id }, { using: how, value: what.to_s }
|
235
263
|
else
|
236
|
-
execute :find_elements, {}, { using: how, value: what }
|
264
|
+
execute :find_elements, {}, { using: how, value: what.to_s }
|
237
265
|
end
|
238
266
|
|
239
267
|
ids.map { |id| ::Appium::Core::Element.new self, element_id_from(id) }
|
@@ -270,9 +298,10 @@ module Appium
|
|
270
298
|
|
271
299
|
# For Appium
|
272
300
|
# No implementation for W3C webdriver module
|
273
|
-
def set_location(lat, lon, alt = 0.0, speed: nil)
|
301
|
+
def set_location(lat, lon, alt = 0.0, speed: nil, satellites: nil)
|
274
302
|
loc = { latitude: lat, longitude: lon, altitude: alt }
|
275
303
|
loc[:speed] = speed unless speed.nil?
|
304
|
+
loc[:satellites] = satellites unless satellites.nil?
|
276
305
|
execute :set_location, {}, { location: loc }
|
277
306
|
end
|
278
307
|
|
@@ -313,12 +342,12 @@ module Appium
|
|
313
342
|
execute :get_log_events, {}, args
|
314
343
|
end
|
315
344
|
|
316
|
-
def
|
345
|
+
def viewport_screenshot
|
317
346
|
execute_script('mobile: viewportScreenshot')
|
318
347
|
end
|
319
348
|
|
320
|
-
def
|
321
|
-
execute :take_element_screenshot, id:
|
349
|
+
def element_screenshot(element_id)
|
350
|
+
execute :take_element_screenshot, id: element_id
|
322
351
|
end
|
323
352
|
|
324
353
|
private
|
@@ -341,9 +370,8 @@ module Appium
|
|
341
370
|
id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
|
342
371
|
end
|
343
372
|
|
344
|
-
# Don't convert locators for Appium
|
345
|
-
|
346
|
-
def convert_locators(how, what)
|
373
|
+
# Don't convert locators for Appium in native context
|
374
|
+
def convert_locator(how, what)
|
347
375
|
# case how
|
348
376
|
# when 'class name'
|
349
377
|
# how = 'css selector'
|
@@ -357,6 +385,14 @@ module Appium
|
|
357
385
|
# when 'tag name'
|
358
386
|
# how = 'css selector'
|
359
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
|
+
|
360
396
|
[how, what]
|
361
397
|
end
|
362
398
|
end # class Bridge
|
@@ -22,6 +22,13 @@ module Appium
|
|
22
22
|
# @return [::Selenium::WebDriver::Remote::Capabilities] Return instance of Appium::Core::Base::Capabilities
|
23
23
|
# inherited ::Selenium::WebDriver::Remote::Capabilities
|
24
24
|
def self.create_capabilities(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.
|
25
32
|
::Selenium::WebDriver::Remote::Capabilities.new(opts_caps)
|
26
33
|
end
|
27
34
|
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
|
@@ -13,6 +13,8 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require 'base64'
|
16
|
+
require_relative 'device_ime'
|
17
|
+
require_relative 'driver_settings'
|
16
18
|
require_relative 'search_context'
|
17
19
|
require_relative 'screenshot'
|
18
20
|
require_relative 'rotable'
|
@@ -42,8 +44,10 @@ module Appium
|
|
42
44
|
# Do not use this for general use. Used by flutter driver to get bridge for creating a new element
|
43
45
|
attr_reader :bridge
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
+
def initialize(bridge: nil, listener: nil, **opts)
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
47
51
|
# Implements protocol handshake which:
|
48
52
|
#
|
49
53
|
# 1. Creates session with driver.
|
@@ -53,26 +57,9 @@ module Appium
|
|
53
57
|
# @return [::Appium::Core::Base::Bridge]
|
54
58
|
#
|
55
59
|
def create_bridge(**opts)
|
56
|
-
|
57
|
-
caps = opts.delete(:capabilities)
|
58
|
-
# NOTE: This is deprecated
|
59
|
-
cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
|
60
|
-
|
61
|
-
desired_capabilities = opts.delete(:desired_capabilities)
|
62
|
-
if desired_capabilities
|
63
|
-
if desired_capabilities.is_a?(Hash)
|
64
|
-
desired_capabilities = ::Selenium::WebDriver::Remote::Capabilities(desired_capabilities)
|
65
|
-
end
|
66
|
-
cap_array << desired_capabilities
|
67
|
-
end
|
68
|
-
|
69
|
-
options = opts.delete(:options)
|
70
|
-
cap_array << options if options
|
71
|
-
|
72
|
-
capabilities = generate_capabilities(cap_array)
|
73
|
-
|
60
|
+
capabilities = opts.delete(:capabilities)
|
74
61
|
bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
|
75
|
-
raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
62
|
+
raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
76
63
|
|
77
64
|
bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
|
78
65
|
|
@@ -106,6 +93,86 @@ module Appium
|
|
106
93
|
path: path)
|
107
94
|
end
|
108
95
|
|
96
|
+
AVAILABLE_METHODS = [
|
97
|
+
:get, :head, :post, :put, :delete,
|
98
|
+
:connect, :options, :trace, :patch
|
99
|
+
].freeze
|
100
|
+
# Define a new custom method to the driver so that you can define your own method for
|
101
|
+
# drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
|
102
|
+
# to define custom commands that are not part of W3C spec.
|
103
|
+
#
|
104
|
+
# @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
|
105
|
+
# @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
|
106
|
+
# +:session_id+ is the placeholder of 'session id'.
|
107
|
+
# Other place holders can be specified with +:+ prefix like +:id+.
|
108
|
+
# Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
|
109
|
+
# @param [Symbol] name The name of method that is called as the driver instance method.
|
110
|
+
# @param [Proc] block The block to involve as the method.
|
111
|
+
# Please define a method that has the same +name+ with arguments you want.
|
112
|
+
# The method must has +execute+ method. tHe +execute+ is calls the +url+
|
113
|
+
# with the given parameters.
|
114
|
+
# The first argument should be +name+ as symbol.
|
115
|
+
# The second argument should be hash. If keys in the hash matches +:+ prefix
|
116
|
+
# string in the given url, the matched string in the given url will be
|
117
|
+
# values in the hash.
|
118
|
+
# The third argument should be hash. The hash will be the request body.
|
119
|
+
# Please read examples below for more details.
|
120
|
+
# @raise [ArgumentError] If the given +method+ is invalid value.
|
121
|
+
#
|
122
|
+
# @example
|
123
|
+
#
|
124
|
+
# @driver.add_command(
|
125
|
+
# method: :get,
|
126
|
+
# url: 'session/:session_id/path/to/custom/url',
|
127
|
+
# name: :test_command
|
128
|
+
# )
|
129
|
+
# # Send a GET request to 'session/<session id>/path/to/custom/url'
|
130
|
+
# @driver.test_command
|
131
|
+
#
|
132
|
+
#
|
133
|
+
# @driver.add_command(
|
134
|
+
# method: :post,
|
135
|
+
# url: 'session/:session_id/path/to/custom/url',
|
136
|
+
# name: :test_command
|
137
|
+
# ) do
|
138
|
+
# def test_command(argument)
|
139
|
+
# execute(:test_command, {}, { dummy: argument })
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
# # Send a POST request to 'session/<session id>/path/to/custom/url'
|
143
|
+
# # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
|
144
|
+
# # ':session_id' in the given 'url' is replaced with current 'session id'.
|
145
|
+
# @driver.test_command(1)
|
146
|
+
#
|
147
|
+
#
|
148
|
+
# @driver.add_command(
|
149
|
+
# method: :post,
|
150
|
+
# url: 'session/:session_id/element/:id/custom/action',
|
151
|
+
# name: :test_action_command
|
152
|
+
# ) do
|
153
|
+
# def test_action_command(element_id, action)
|
154
|
+
# execute(:test_action_command, {id: element_id}, { dummy_action: action })
|
155
|
+
# end
|
156
|
+
# end
|
157
|
+
# # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
|
158
|
+
# # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
|
159
|
+
# # ':session_id' in the given url is replaced with current 'session id'.
|
160
|
+
# # ':id' in the given url is replaced with the given 'element_id'.
|
161
|
+
# e = @driver.find_element :accessibility_id, 'an element'
|
162
|
+
# _, element_id = e.ref
|
163
|
+
# @driver.test_action_command(element_id, 'action')
|
164
|
+
#
|
165
|
+
def add_command(method:, url:, name:, &block)
|
166
|
+
unless AVAILABLE_METHODS.include? method
|
167
|
+
raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}"
|
168
|
+
end
|
169
|
+
|
170
|
+
# TODO: Remove this logger before Appium 2.0 release
|
171
|
+
::Appium::Logger.info '[Experimental] this method is experimental for Appium 2.0. This interface may change.'
|
172
|
+
|
173
|
+
@bridge.add_command method: method, url: url, name: name, &block
|
174
|
+
end
|
175
|
+
|
109
176
|
### Methods for Appium
|
110
177
|
|
111
178
|
# Lock the device
|
@@ -188,36 +255,6 @@ module Appium
|
|
188
255
|
end
|
189
256
|
alias type send_keys
|
190
257
|
|
191
|
-
class DriverSettings
|
192
|
-
# @private this class is private
|
193
|
-
def initialize(bridge)
|
194
|
-
@bridge = bridge
|
195
|
-
end
|
196
|
-
|
197
|
-
# Get appium Settings for current test session.
|
198
|
-
#
|
199
|
-
# @example
|
200
|
-
#
|
201
|
-
# @driver.settings.get
|
202
|
-
#
|
203
|
-
def get
|
204
|
-
@bridge.get_settings
|
205
|
-
end
|
206
|
-
|
207
|
-
# Update Appium Settings for current test session
|
208
|
-
#
|
209
|
-
# @param [Hash] settings Settings to update, keys are settings, values to value to set each setting to
|
210
|
-
#
|
211
|
-
# @example
|
212
|
-
#
|
213
|
-
# @driver.settings.update({'allowInvisibleElements': true})
|
214
|
-
#
|
215
|
-
def update(settings)
|
216
|
-
@bridge.update_settings(settings)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
private_constant :DriverSettings
|
220
|
-
|
221
258
|
# Returns an instance of DriverSettings to call get/update.
|
222
259
|
#
|
223
260
|
# @example
|
@@ -226,7 +263,7 @@ module Appium
|
|
226
263
|
# @driver.settings.update('allowInvisibleElements': true)
|
227
264
|
#
|
228
265
|
def settings
|
229
|
-
@
|
266
|
+
@settings ||= DriverSettings.new(@bridge)
|
230
267
|
end
|
231
268
|
|
232
269
|
# Get appium Settings for current test session.
|
@@ -257,34 +294,6 @@ module Appium
|
|
257
294
|
end
|
258
295
|
alias update_settings settings=
|
259
296
|
|
260
|
-
class DeviceIME
|
261
|
-
# @private this class is private
|
262
|
-
def initialize(bridge)
|
263
|
-
@bridge = bridge
|
264
|
-
end
|
265
|
-
|
266
|
-
def activate(ime_name)
|
267
|
-
@bridge.ime_activate(ime_name)
|
268
|
-
end
|
269
|
-
|
270
|
-
def available_engines
|
271
|
-
@bridge.ime_available_engines
|
272
|
-
end
|
273
|
-
|
274
|
-
def active_engine
|
275
|
-
@bridge.ime_active_engine
|
276
|
-
end
|
277
|
-
|
278
|
-
def activated?
|
279
|
-
@bridge.ime_activated
|
280
|
-
end
|
281
|
-
|
282
|
-
def deactivate
|
283
|
-
@bridge.ime_deactivate
|
284
|
-
end
|
285
|
-
end
|
286
|
-
private_constant :DeviceIME
|
287
|
-
|
288
297
|
# Returns an instance of DeviceIME
|
289
298
|
#
|
290
299
|
# @return [Appium::Core::Base::Driver::DeviceIME]
|
@@ -298,7 +307,7 @@ module Appium
|
|
298
307
|
# @driver.ime.deactivate #=> Deactivate current IME engine
|
299
308
|
#
|
300
309
|
def ime
|
301
|
-
@
|
310
|
+
@ime ||= DeviceIME.new(@bridge)
|
302
311
|
end
|
303
312
|
|
304
313
|
# Android only. Make an engine that is available active.
|
@@ -418,30 +427,6 @@ module Appium
|
|
418
427
|
end
|
419
428
|
alias set_context context=
|
420
429
|
|
421
|
-
# Set the value to element directly
|
422
|
-
#
|
423
|
-
# @example
|
424
|
-
#
|
425
|
-
# @driver.set_immediate_value element, 'hello'
|
426
|
-
#
|
427
|
-
def set_immediate_value(element, *value)
|
428
|
-
::Appium::Logger.warn '[DEPRECATION] driver#set_immediate_value(element, *value) is deprecated. ' \
|
429
|
-
'Use Element#immediate_value(*value) instead'
|
430
|
-
@bridge.set_immediate_value(element, *value)
|
431
|
-
end
|
432
|
-
|
433
|
-
# Replace the value to element directly
|
434
|
-
#
|
435
|
-
# @example
|
436
|
-
#
|
437
|
-
# @driver.replace_value element, 'hello'
|
438
|
-
#
|
439
|
-
def replace_value(element, *value)
|
440
|
-
::Appium::Logger.warn '[DEPRECATION] driver#replace_value(element, *value) is deprecated. ' \
|
441
|
-
'Use Element#replace_value(*value) instead'
|
442
|
-
@bridge.replace_value(element, *value)
|
443
|
-
end
|
444
|
-
|
445
430
|
# Place a file in a specific location on the device.
|
446
431
|
# On iOS, the server should have ifuse libraries installed and configured properly for this feature to work on
|
447
432
|
# real devices.
|
@@ -861,7 +846,7 @@ module Appium
|
|
861
846
|
# @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
|
862
847
|
#
|
863
848
|
def perform_actions(data)
|
864
|
-
raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
849
|
+
raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
865
850
|
|
866
851
|
@bridge.send_actions data.map(&:encode).compact
|
867
852
|
data.each(&:clear_actions)
|
@@ -939,8 +924,7 @@ module Appium
|
|
939
924
|
# #=> uiautomator2
|
940
925
|
# # <Selenium::WebDriver::Remote::Capabilities:0x007fa38dae1360
|
941
926
|
# # @capabilities=
|
942
|
-
# # {:
|
943
|
-
# # :browser_name=>nil,
|
927
|
+
# # {:browser_name=>nil,
|
944
928
|
# # :browser_version=>nil,
|
945
929
|
# # :platform_name=>"android",
|
946
930
|
# # :page_load_strategy=>nil,
|
@@ -989,8 +973,7 @@ module Appium
|
|
989
973
|
# #=> XCUITest
|
990
974
|
# # <Selenium::WebDriver::Remote::Capabilities:0x007fb15dc01370
|
991
975
|
# # @capabilities=
|
992
|
-
# # {:
|
993
|
-
# # :browser_name=>"UICatalog",
|
976
|
+
# # {:browser_name=>"UICatalog",
|
994
977
|
# # :browser_version=>nil,
|
995
978
|
# # :platform_name=>"ios",
|
996
979
|
# # :page_load_strategy=>nil,
|
@@ -0,0 +1,51 @@
|
|
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 DriverSettings
|
22
|
+
# @private this class is private
|
23
|
+
def initialize(bridge)
|
24
|
+
@bridge = bridge
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get appium Settings for current test session.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
#
|
31
|
+
# @driver.settings.get
|
32
|
+
#
|
33
|
+
def get
|
34
|
+
@bridge.get_settings
|
35
|
+
end
|
36
|
+
|
37
|
+
# Update Appium Settings for current test session
|
38
|
+
#
|
39
|
+
# @param [Hash] settings Settings to update, keys are settings, values to value to set each setting to
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
#
|
43
|
+
# @driver.settings.update({'allowInvisibleElements': true})
|
44
|
+
#
|
45
|
+
def update(settings)
|
46
|
+
@bridge.update_settings(settings)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -52,19 +52,26 @@ module Appium
|
|
52
52
|
# @param [String, Number] latitude Set the latitude.
|
53
53
|
# @param [String, Number] longitude Set the longitude.
|
54
54
|
# @param [String, Number] altitude Set the altitude.
|
55
|
-
# @param [String, Number] speed Set the speed to apply the location on Android real devices
|
55
|
+
# @param [String, Number] speed Set the speed to apply the location on Android real devices
|
56
|
+
# in meters/second @since Appium 1.21.0 and in knots for emulators @since Appium 1.22.0.
|
57
|
+
# @param [String, Number] satellites Sets the count of geo satellites being tracked in range 1..12 @since Appium 1.22.0.
|
58
|
+
# This number is respected on Emulators.
|
56
59
|
# @param [::Selenium::WebDriver::Location]
|
57
60
|
#
|
58
61
|
# @example
|
59
62
|
#
|
60
63
|
# driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
|
61
64
|
#
|
62
|
-
def set_location(latitude, longitude, altitude, speed: nil)
|
63
|
-
if speed.nil?
|
65
|
+
def set_location(latitude, longitude, altitude, speed: nil, satellites: nil)
|
66
|
+
if speed.nil? && satellites.nil?
|
64
67
|
self.location = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
|
65
68
|
else
|
66
69
|
loc = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
|
67
|
-
|
70
|
+
|
71
|
+
speed = Float(speed) unless speed.nil?
|
72
|
+
satellites = Integer(satellites) unless satellites.nil?
|
73
|
+
|
74
|
+
@bridge.set_location loc.latitude, loc.longitude, loc.altitude, speed: speed, satellites: satellites
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
@@ -30,7 +30,7 @@ module Appium
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def network_connection_type=(connection_type)
|
33
|
-
raise ArgumentError, 'Invalid connection type' unless valid_type? connection_type
|
33
|
+
raise ::Appium::Core::Error::ArgumentError, 'Invalid connection type' unless valid_type? connection_type
|
34
34
|
|
35
35
|
connection_value = type_to_values[connection_type]
|
36
36
|
|
@@ -30,7 +30,7 @@ module Appium
|
|
30
30
|
#
|
31
31
|
def rotation=(orientation)
|
32
32
|
unless ORIENTATIONS.include?(orientation)
|
33
|
-
raise ArgumentError, "expected #{ORIENTATIONS.inspect}, got #{orientation.inspect}"
|
33
|
+
raise ::Appium::Core::Error::ArgumentError, "expected #{ORIENTATIONS.inspect}, got #{orientation.inspect}"
|
34
34
|
end
|
35
35
|
|
36
36
|
bridge.screen_orientation = orientation.to_s.upcase
|
@@ -82,11 +82,12 @@ module Appium
|
|
82
82
|
# @@driver.element_screenshot_as element, :base64 #=> "iVBORw0KGgoAAAANSUhEUgAABDgAAAB+CAIAAABOPDa6AAAAAX"
|
83
83
|
#
|
84
84
|
def element_screenshot_as(element, format)
|
85
|
+
_, element_id = element.ref
|
85
86
|
case format
|
86
87
|
when :base64
|
87
|
-
bridge.
|
88
|
+
bridge.element_screenshot element_id
|
88
89
|
when :png
|
89
|
-
bridge.
|
90
|
+
bridge.element_screenshot(element_id).unpack('m')[0]
|
90
91
|
else
|
91
92
|
raise Core::Error::UnsupportedOperationError, "unsupported format: #{format.inspect}"
|
92
93
|
end
|
@@ -106,7 +107,7 @@ module Appium
|
|
106
107
|
::Appium::Logger.warn 'name used for saved screenshot does not match file type. '\
|
107
108
|
'It should end with .png extension'
|
108
109
|
end
|
109
|
-
viewport_screenshot_encode64 = bridge.
|
110
|
+
viewport_screenshot_encode64 = bridge.viewport_screenshot
|
110
111
|
File.open(png_path, 'wb') { |f| f << viewport_screenshot_encode64.unpack('m')[0] }
|
111
112
|
end
|
112
113
|
end
|
@@ -159,7 +159,10 @@ module Appium
|
|
159
159
|
|
160
160
|
def _set_by_from_finders(how)
|
161
161
|
by = FINDERS[how.to_sym]
|
162
|
-
|
162
|
+
unless by
|
163
|
+
raise ::Appium::Core::Error::ArgumentError,
|
164
|
+
"cannot find element by #{how.inspect}. Available finders are #{FINDERS.keys}."
|
165
|
+
end
|
163
166
|
|
164
167
|
by
|
165
168
|
end
|
@@ -171,16 +174,18 @@ module Appium
|
|
171
174
|
when 1
|
172
175
|
arg = args.first
|
173
176
|
|
174
|
-
|
177
|
+
unless arg.respond_to?(:shift)
|
178
|
+
raise ::Appium::Core::Error::ArgumentError, "expected #{arg.inspect}:#{arg.class} to respond to #shift"
|
179
|
+
end
|
175
180
|
|
176
181
|
# this will be a single-entry hash, so use #shift over #first or #[]
|
177
182
|
arr = arg.dup.shift
|
178
183
|
|
179
|
-
raise ArgumentError, "expected #{arr.inspect} to have 2 elements" unless arr.size == 2
|
184
|
+
raise ::Appium::Core::Error::ArgumentError, "expected #{arr.inspect} to have 2 elements" unless arr.size == 2
|
180
185
|
|
181
186
|
arr
|
182
187
|
else
|
183
|
-
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
|
188
|
+
raise ::Appium::Core::Error::ArgumentError, "wrong number of arguments (#{args.size} for 2)"
|
184
189
|
end
|
185
190
|
end
|
186
191
|
end # module SearchContext
|
@@ -25,8 +25,8 @@ module Appium
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def press_keycode(key, metastate: [], flags: [])
|
28
|
-
raise ArgumentError, 'flags should be Array' unless flags.is_a? Array
|
29
|
-
raise ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
|
28
|
+
raise ::Appium::Core::Error::ArgumentError, 'flags should be Array' unless flags.is_a? Array
|
29
|
+
raise ::Appium::Core::Error::ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
|
30
30
|
|
31
31
|
args = { keycode: key }
|
32
32
|
args[:metastate] = metastate.reduce(0) { |acc, meta| acc | meta } unless metastate.empty?
|
@@ -36,8 +36,8 @@ module Appium
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def long_press_keycode(key, metastate: [], flags: [])
|
39
|
-
raise ArgumentError, 'flags should be Array' unless flags.is_a? Array
|
40
|
-
raise ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
|
39
|
+
raise ::Appium::Core::Error::ArgumentError, 'flags should be Array' unless flags.is_a? Array
|
40
|
+
raise ::Appium::Core::Error::ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
|
41
41
|
|
42
42
|
args = { keycode: key }
|
43
43
|
args[:metastate] = metastate.reduce(0) { |acc, meta| acc | meta } unless metastate.empty?
|
@@ -17,12 +17,12 @@ module Appium
|
|
17
17
|
class Base
|
18
18
|
module Device
|
19
19
|
module Value
|
20
|
-
def set_immediate_value(
|
21
|
-
execute :set_immediate_value, { id:
|
20
|
+
def set_immediate_value(element_id, *value)
|
21
|
+
execute :set_immediate_value, { id: element_id }, generate_value_and_text(value)
|
22
22
|
end
|
23
23
|
|
24
|
-
def replace_value(
|
25
|
-
execute :replace_value, { id:
|
24
|
+
def replace_value(element_id, *value)
|
25
|
+
execute :replace_value, { id: element_id }, generate_value_and_text(value)
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
@@ -27,8 +27,11 @@ module Appium
|
|
27
27
|
|
28
28
|
class UnsupportedOperationError < CoreError; end
|
29
29
|
|
30
|
-
# Server side
|
30
|
+
# Server side errors
|
31
31
|
class ServerError < CoreError; end
|
32
|
+
|
33
|
+
# ruby_lib_core library specific errors
|
34
|
+
class ArgumentError < CoreError; end
|
32
35
|
end
|
33
36
|
end
|
34
37
|
end
|
@@ -65,7 +65,10 @@ module Appium
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def event=(log_event)
|
68
|
-
|
68
|
+
unless log_event.is_a?(Hash)
|
69
|
+
raise ::Appium::Core::Error::ArgumentError,
|
70
|
+
'log_event should be Hash like { vendor: "appium", event: "funEvent"}'
|
71
|
+
end
|
69
72
|
|
70
73
|
event vendor: log_event[:vendor], event: log_event[:event]
|
71
74
|
end
|
@@ -195,7 +195,10 @@ module Appium
|
|
195
195
|
end
|
196
196
|
|
197
197
|
def args_with_ele_ref(args)
|
198
|
-
|
198
|
+
if args.key? :element
|
199
|
+
_, element_id = args[:element].ref
|
200
|
+
args[:element] = element_id
|
201
|
+
end
|
199
202
|
args
|
200
203
|
end
|
201
204
|
end # class TouchAction
|
@@ -187,8 +187,6 @@ module Appium
|
|
187
187
|
# @option opts [Hash] :caps Appium capabilities.
|
188
188
|
# @option opts [Hash] :capabilities The same as :caps.
|
189
189
|
# This param is for compatibility with Selenium WebDriver format
|
190
|
-
# @option opts [Hash] :desired_capabilities The same as :caps.
|
191
|
-
# This param is for compatibility with Selenium WebDriver format
|
192
190
|
# @option opts [Appium::Core::Options] :appium_lib Capabilities affect only ruby client
|
193
191
|
# @option opts [String] :url The same as :custom_url in :appium_lib.
|
194
192
|
# This param is for compatibility with Selenium WebDriver format
|
@@ -199,10 +197,8 @@ module Appium
|
|
199
197
|
#
|
200
198
|
# # format 1
|
201
199
|
# @core = Appium::Core.for caps: {...}, appium_lib: {...}
|
202
|
-
# # format 2. 'capabilities:'
|
200
|
+
# # format 2. 'capabilities:' is also available instead of 'caps:'.
|
203
201
|
# @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", capabilities: {...}, appium_lib: {...}
|
204
|
-
# # format 3. 'appium_lib: {...}' can be blank
|
205
|
-
# @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", desired_capabilities: {...}
|
206
202
|
#
|
207
203
|
#
|
208
204
|
# require 'rubygems'
|
@@ -230,7 +226,7 @@ module Appium
|
|
230
226
|
# @core.start_driver # Connect to 'http://127.0.0.1:8080/wd/hub' because of 'port: 8080'
|
231
227
|
#
|
232
228
|
# # Start iOS driver with .zip file over HTTP
|
233
|
-
# #
|
229
|
+
# # 'capabilities:' is also available instead of 'caps:'. Either is fine.
|
234
230
|
# opts = {
|
235
231
|
# capabilities: {
|
236
232
|
# platformName: :ios,
|
@@ -254,7 +250,7 @@ module Appium
|
|
254
250
|
# # Start iOS driver as another format. 'url' is available like below
|
255
251
|
# opts = {
|
256
252
|
# url: "http://custom-host:8080/wd/hub.com",
|
257
|
-
#
|
253
|
+
# capabilities: {
|
258
254
|
# platformName: :ios,
|
259
255
|
# platformVersion: '11.0',
|
260
256
|
# deviceName: 'iPhone Simulator',
|
@@ -367,11 +363,10 @@ module Appium
|
|
367
363
|
end
|
368
364
|
|
369
365
|
begin
|
370
|
-
# included https://github.com/SeleniumHQ/selenium/blob/43f8b3f66e7e01124eff6a5805269ee441f65707/rb/lib/selenium/webdriver/remote/driver.rb#L29
|
371
366
|
@driver = ::Appium::Core::Base::Driver.new(listener: @listener,
|
372
367
|
http_client: @http_client,
|
373
|
-
|
374
|
-
|
368
|
+
capabilities: @caps, # ::Selenium::WebDriver::Remote::Capabilities
|
369
|
+
url: @custom_url)
|
375
370
|
|
376
371
|
if @direct_connect
|
377
372
|
d_c = DirectConnections.new(@driver.capabilities)
|
@@ -568,10 +563,7 @@ module Appium
|
|
568
563
|
def validate_keys(opts)
|
569
564
|
flatten_ops = flatten_hash_keys(opts)
|
570
565
|
|
571
|
-
|
572
|
-
unless opts.member?(:caps) || opts.member?(:capabilities) || opts.member?(:desired_capabilities)
|
573
|
-
raise Error::NoCapabilityError
|
574
|
-
end
|
566
|
+
raise Error::NoCapabilityError unless opts.member?(:caps) || opts.member?(:capabilities)
|
575
567
|
|
576
568
|
if !opts.member?(:appium_lib) && flatten_ops.member?(:appium_lib)
|
577
569
|
raise Error::CapabilityStructureError, 'Please check the value of appium_lib in the capability'
|
@@ -592,8 +584,7 @@ module Appium
|
|
592
584
|
|
593
585
|
# @private
|
594
586
|
def get_caps(opts)
|
595
|
-
|
596
|
-
Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || opts[:desired_capabilities] || {})
|
587
|
+
Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || {})
|
597
588
|
end
|
598
589
|
|
599
590
|
# @private
|
@@ -59,20 +59,20 @@ module Appium
|
|
59
59
|
#
|
60
60
|
# @example
|
61
61
|
#
|
62
|
-
#
|
62
|
+
# element.immediate_value 'hello'
|
63
63
|
#
|
64
64
|
def immediate_value(*value)
|
65
|
-
@bridge.set_immediate_value
|
65
|
+
@bridge.set_immediate_value @id, *value
|
66
66
|
end
|
67
67
|
|
68
68
|
# Replace the value to element directly
|
69
69
|
#
|
70
70
|
# @example
|
71
71
|
#
|
72
|
-
#
|
72
|
+
# element.replace_value 'hello'
|
73
73
|
#
|
74
74
|
def replace_value(*value)
|
75
|
-
@bridge.replace_value
|
75
|
+
@bridge.replace_value @id, *value
|
76
76
|
end
|
77
77
|
|
78
78
|
# For use with location_rel.
|
@@ -108,7 +108,7 @@ module Appium
|
|
108
108
|
# element.screenshot #=> "iVBORw0KGgoAAAANSUhEUgAABDgAAAB+CAIAAABOPDa6AAAAAX"
|
109
109
|
#
|
110
110
|
def screenshot
|
111
|
-
bridge.
|
111
|
+
bridge.element_screenshot @id
|
112
112
|
end
|
113
113
|
|
114
114
|
# Return an element screenshot in the given format
|
@@ -123,9 +123,9 @@ module Appium
|
|
123
123
|
def screenshot_as(format)
|
124
124
|
case format
|
125
125
|
when :base64
|
126
|
-
bridge.
|
126
|
+
bridge.element_screenshot @id
|
127
127
|
when :png
|
128
|
-
bridge.
|
128
|
+
bridge.element_screenshot(@id).unpack('m')[0]
|
129
129
|
else
|
130
130
|
raise Core::Error::UnsupportedOperationError, "unsupported format: #{format.inspect}"
|
131
131
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
module Appium
|
16
16
|
module Core
|
17
|
-
VERSION = '5.0.0.
|
18
|
-
DATE = '2021-
|
17
|
+
VERSION = '5.0.0.rc2' unless defined? ::Appium::Core::VERSION
|
18
|
+
DATE = '2021-10-01' unless defined? ::Appium::Core::DATE
|
19
19
|
end
|
20
20
|
end
|
data/lib/appium_lib_core.rb
CHANGED
@@ -27,7 +27,7 @@ module Appium
|
|
27
27
|
# https://github.com/rails/docrails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/activesupport/lib/active_support/core_ext/hash/keys.rb#L84
|
28
28
|
# @param [Hash] hash Hash value to make symbolise
|
29
29
|
def self.symbolize_keys(hash)
|
30
|
-
raise ArgumentError, 'symbolize_keys requires a hash' unless hash.is_a? Hash
|
30
|
+
raise ::Appium::Core::Error::ArgumentError, 'symbolize_keys requires a hash' unless hash.is_a? Hash
|
31
31
|
|
32
32
|
hash.each_with_object({}) do |pair, acc|
|
33
33
|
key = begin
|
data/release_notes.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
#### v4.7.0 2021-07-17
|
2
|
+
|
3
|
+
- [0059974](https://github.com/appium/ruby_lib_core/commit/0059974b0b1d79a822db84d8b0169e8393e00ef9) Release 4.7.0
|
4
|
+
- [0f93a52](https://github.com/appium/ruby_lib_core/commit/0f93a52bbdc44bf916c9b974fe9fd09d48e5ff39) test: add more example and test (#328)
|
5
|
+
- [9e37b3b](https://github.com/appium/ruby_lib_core/commit/9e37b3bc15f72f7c0117a49945a3fe482598f374) feat: add satellites for Android emulators (#327)
|
6
|
+
- [3063a73](https://github.com/appium/ruby_lib_core/commit/3063a73fa291dc378daa53b7df2e4b0b8a6f03d2) ci: calls quit_driver to ensure close the previous session
|
7
|
+
- [43fb9e7](https://github.com/appium/ruby_lib_core/commit/43fb9e77f5492a92f4f8c5a5bda71be9c3a9e2c8) chore: tweak naming in an internal variable
|
8
|
+
|
9
|
+
|
10
|
+
#### v4.6.0 2021-06-03
|
11
|
+
|
12
|
+
- [0dacfab](https://github.com/appium/ruby_lib_core/commit/0dacfab1256e1447e1f7a5974dfcf48ee0a72b9d) Release 4.6.0
|
13
|
+
- [b9f015d](https://github.com/appium/ruby_lib_core/commit/b9f015d7dea14964a0733f2385ebcff68da1e18e) feat: allow to add commands dynamically (#325)
|
14
|
+
- [3de96ee](https://github.com/appium/ruby_lib_core/commit/3de96eea133ccbcbc5c4d77adc7d67c065a5a38c) chore(deps-dev): update webmock requirement from ~> 3.12.1 to ~> 3.13.0 (#324)
|
15
|
+
- [f1a9e79](https://github.com/appium/ruby_lib_core/commit/f1a9e79f3bd4d134e125fc2ed9adcf3d085afc9a) docs: address func test code as working example
|
16
|
+
- [eb85b1b](https://github.com/appium/ruby_lib_core/commit/eb85b1b26623436cb0aae95a00fef7bc2d795520) remove ; in a test
|
17
|
+
- [1632637](https://github.com/appium/ruby_lib_core/commit/1632637fd872c0b80dfb97b8514ada6a7164eebf) chore(deps-dev): update rubocop requirement from = 1.11.0 to = 1.12.0 (#321)
|
18
|
+
- [b9e47aa](https://github.com/appium/ruby_lib_core/commit/b9e47aa9b02f060ffa91e8410ab97dc87d3640a4) docs: add docstring
|
19
|
+
- [954a2fe](https://github.com/appium/ruby_lib_core/commit/954a2feebb768a55b496a2614d9e4dd8b702fc1e) chore(deps-dev): update rubocop requirement from = 1.8.1 to = 1.11.0 (#316)
|
20
|
+
- [a5b9651](https://github.com/appium/ruby_lib_core/commit/a5b9651aa349c10bd9759fedac6f09e27012a5e5) chore(deps-dev): update webmock requirement from ~> 3.11.0 to ~> 3.12.1 (#319)
|
21
|
+
- [485c096](https://github.com/appium/ruby_lib_core/commit/485c096273178aa5e21f28d93545fd127cbb8735) test: add assertion
|
22
|
+
|
23
|
+
|
1
24
|
#### v4.5.0 2021-03-14
|
2
25
|
|
3
26
|
- [656230e](https://github.com/appium/ruby_lib_core/commit/656230e688ed86414c06efaa73bce7359933cc91) Release 4.5.0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appium_lib_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0.
|
4
|
+
version: 5.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kazuaki MATSUO
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: selenium-webdriver
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.0.0.
|
19
|
+
version: 4.0.0.rc2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.0.0.
|
26
|
+
version: 4.0.0.rc2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: faye-websocket
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,28 +114,28 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 3.
|
117
|
+
version: 3.14.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 3.
|
124
|
+
version: 3.14.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rubocop
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - '='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 1.12.
|
131
|
+
version: 1.12.1
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 1.12.
|
138
|
+
version: 1.12.1
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: appium_thor
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -257,7 +257,9 @@ files:
|
|
257
257
|
- lib/appium_lib_core/common/base.rb
|
258
258
|
- lib/appium_lib_core/common/base/bridge.rb
|
259
259
|
- lib/appium_lib_core/common/base/capabilities.rb
|
260
|
+
- lib/appium_lib_core/common/base/device_ime.rb
|
260
261
|
- lib/appium_lib_core/common/base/driver.rb
|
262
|
+
- lib/appium_lib_core/common/base/driver_settings.rb
|
261
263
|
- lib/appium_lib_core/common/base/has_location.rb
|
262
264
|
- lib/appium_lib_core/common/base/has_network_connection.rb
|
263
265
|
- lib/appium_lib_core/common/base/http_default.rb
|
@@ -323,7 +325,7 @@ homepage: https://github.com/appium/ruby_lib_core/
|
|
323
325
|
licenses:
|
324
326
|
- Apache-2.0
|
325
327
|
metadata: {}
|
326
|
-
post_install_message:
|
328
|
+
post_install_message:
|
327
329
|
rdoc_options: []
|
328
330
|
require_paths:
|
329
331
|
- lib
|
@@ -338,8 +340,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
338
340
|
- !ruby/object:Gem::Version
|
339
341
|
version: 1.3.1
|
340
342
|
requirements: []
|
341
|
-
rubygems_version: 3.
|
342
|
-
signing_key:
|
343
|
+
rubygems_version: 3.2.15
|
344
|
+
signing_key:
|
343
345
|
specification_version: 4
|
344
346
|
summary: Minimal Ruby library for Appium.
|
345
347
|
test_files: []
|