appium_lib_core 4.1.0 → 5.0.2
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/codeql-analysis.yml +70 -0
- data/.github/workflows/unittest.yml +8 -9
- data/.rubocop.yml +95 -1
- data/CHANGELOG.md +94 -276
- data/README.md +11 -6
- data/Rakefile +4 -0
- data/appium_lib_core.gemspec +4 -7
- data/bin/console +0 -4
- data/ci-jobs/functional/run_appium.yml +3 -3
- data/ci-jobs/functional_test.yml +3 -3
- data/docs/mobile_command.md +2 -2
- 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 +297 -90
- data/lib/appium_lib_core/common/base/capabilities.rb +10 -3
- data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
- data/lib/appium_lib_core/common/base/driver.rb +183 -171
- 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 +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 +6 -6
- data/lib/appium_lib_core/common/base/search_context.rb +19 -4
- data/lib/appium_lib_core/common/base.rb +1 -3
- data/lib/appium_lib_core/common/command.rb +257 -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/device/touch_actions.rb +2 -0
- data/lib/appium_lib_core/common/device/value.rb +6 -6
- 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/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 +30 -46
- data/lib/appium_lib_core/{patch.rb → element.rb} +66 -9
- 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 +132 -0
- data/script/commands.rb +3 -37
- metadata +27 -68
- 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
@@ -47,7 +47,7 @@ module Appium
|
|
47
47
|
# not available in the default OpenCV installation and have to be enabled manually
|
48
48
|
# before library compilation. The default detector name is 'ORB'.
|
49
49
|
# @param [String] match_func The name of the matching function. The default one is 'BruteForce'.
|
50
|
-
# @param [String] good_matches_factor The maximum count of "good" matches (e. g. with minimal distances).
|
50
|
+
# @param [String, nil] good_matches_factor The maximum count of "good" matches (e. g. with minimal distances).
|
51
51
|
# The default one is nil.
|
52
52
|
# @param [Bool] visualize Makes the endpoint to return an image, which contains the visualized result of
|
53
53
|
# the corresponding picture matching operation. This option is disabled by default.
|
@@ -94,7 +94,12 @@ module Appium
|
|
94
94
|
# are supported.
|
95
95
|
# @param [Bool] visualize Makes the endpoint to return an image, which contains the visualized result of
|
96
96
|
# the corresponding picture matching operation. This option is disabled by default.
|
97
|
-
# @param [Float] threshold [0.5] At what normalized threshold to reject
|
97
|
+
# @param [Float, nil] threshold [0.5] At what normalized threshold to reject
|
98
|
+
# @param [bool, nil] multiple Whether to enable the support of multiple image occurrences @since Appium 1.21.0.
|
99
|
+
# @param [integer, nil] match_neighbour_threshold The pixel distance between matches we consider to be part of
|
100
|
+
# the same template match @since Appium 1.21.0.
|
101
|
+
# This option is only considered if multiple matches mode is enabled.
|
102
|
+
# 10 pixels by default.
|
98
103
|
#
|
99
104
|
# @example
|
100
105
|
# @driver.find_image_occurrence full_image: "image data 1", partial_image: "image data 2"
|
@@ -102,12 +107,15 @@ module Appium
|
|
102
107
|
# visual = @@driver.find_image_occurrence full_image: image1, partial_image: image2, visualize: true
|
103
108
|
# File.write 'find_result_visual.png', Base64.decode64(visual['visualization']) # if the image is PNG
|
104
109
|
#
|
105
|
-
def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil
|
110
|
+
def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
|
111
|
+
multiple: nil, match_neighbour_threshold: nil)
|
106
112
|
raise "visualize should be #{MATCH_TEMPLATE[:visualize]}" unless MATCH_TEMPLATE[:visualize].member?(visualize)
|
107
113
|
|
108
114
|
options = {}
|
109
115
|
options[:visualize] = visualize
|
110
116
|
options[:threshold] = threshold unless threshold.nil?
|
117
|
+
options[:multiple] = multiple unless multiple.nil?
|
118
|
+
options[:matchNeighbourThreshold] = match_neighbour_threshold unless match_neighbour_threshold.nil?
|
111
119
|
|
112
120
|
compare_images(mode: :matchTemplate, first_image: full_image, second_image: partial_image, options: options)
|
113
121
|
end
|
@@ -144,7 +152,7 @@ module Appium
|
|
144
152
|
# +:matchFeatures is by default.
|
145
153
|
# @param [String] first_image An image data. All image formats, that OpenCV library itself accepts, are supported.
|
146
154
|
# @param [String] second_image An image data. All image formats, that OpenCV library itself accepts, are supported.
|
147
|
-
# @param [Hash] options The content of this dictionary depends on the actual +mode+ value.
|
155
|
+
# @param [Hash, nil] options The content of this dictionary depends on the actual +mode+ value.
|
148
156
|
# See the documentation on +appium-support+ module for more details.
|
149
157
|
# @return [Hash] The content of the resulting dictionary depends on the actual +mode+ and +options+ values.
|
150
158
|
# See the documentation on +appium-support+ module for more details.
|
@@ -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?
|
@@ -14,15 +14,18 @@
|
|
14
14
|
|
15
15
|
module Appium
|
16
16
|
module Core
|
17
|
-
|
18
|
-
module
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
class Base
|
18
|
+
module Device
|
19
|
+
module Orientation
|
20
|
+
def screen_orientation=(orientation)
|
21
|
+
execute :set_screen_orientation, {}, { orientation: orientation }
|
22
|
+
end
|
23
|
+
|
24
|
+
def screen_orientation
|
25
|
+
execute :get_screen_orientation
|
26
|
+
end
|
27
|
+
end # module Orientation
|
28
|
+
end # module Device
|
29
|
+
end # class Base
|
27
30
|
end # module Core
|
28
|
-
end # Appium
|
31
|
+
end # module Appium
|
@@ -20,11 +20,13 @@ module Appium
|
|
20
20
|
class Base
|
21
21
|
module Device
|
22
22
|
module TouchActions
|
23
|
+
# @deprecated Use W3C actions instead
|
23
24
|
def touch_actions(actions)
|
24
25
|
actions = { actions: [actions].flatten }
|
25
26
|
execute :touch_actions, {}, actions
|
26
27
|
end
|
27
28
|
|
29
|
+
# @deprecated Use W3C actions instead
|
28
30
|
def multi_touch(actions)
|
29
31
|
execute :multi_touch, {}, actions: actions
|
30
32
|
end
|
@@ -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
|
@@ -39,11 +39,11 @@ module Appium
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Keep .split(//) for backward compatibility for now
|
42
|
-
text = keys.join
|
42
|
+
text = keys.join
|
43
43
|
|
44
44
|
# FIXME: further work for W3C. Over appium 1.15.0 or later
|
45
45
|
# { value: text.split(//), text: text }
|
46
|
-
{ value: text.
|
46
|
+
{ value: text.chars }
|
47
47
|
end
|
48
48
|
end # module Value
|
49
49
|
end # module Device
|
@@ -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
|
@@ -14,6 +14,9 @@
|
|
14
14
|
|
15
15
|
module Appium
|
16
16
|
module Core
|
17
|
+
#
|
18
|
+
# @deprecated Use W3C actions instead
|
19
|
+
#
|
17
20
|
# MultiTouch actions allow for multiple touches to happen at the same time,
|
18
21
|
# for instance, to simulate multiple finger swipes.
|
19
22
|
#
|
@@ -21,6 +24,18 @@ module Appium
|
|
21
24
|
# add to a new MultiTouch action. When ready, call +prepare()+ and all
|
22
25
|
# actions will be executed simultaneously.
|
23
26
|
#
|
27
|
+
# Consider to use W3C spec touch action like the followings.
|
28
|
+
# https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/PointerActions.html
|
29
|
+
# https://github.com/appium/ruby_lib_core/blob/master/test/functional/android/webdriver/w3c_actions_test.rb
|
30
|
+
# https://github.com/appium/ruby_lib_core/blob/master/test/functional/ios/webdriver/w3c_actions_test.rb
|
31
|
+
#
|
32
|
+
# About W3C actions
|
33
|
+
# https://www.youtube.com/watch?v=oAJ7jwMNFVU
|
34
|
+
# https://appiumpro.com/editions/30-ios-specific-touch-action-methods
|
35
|
+
# https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api
|
36
|
+
#
|
37
|
+
# Functional test code in ruby_lib_core repository also helps.
|
38
|
+
#
|
24
39
|
# @example
|
25
40
|
#
|
26
41
|
# @driver = Appium::Core.for(opts).start_driver
|
@@ -36,6 +51,10 @@ module Appium
|
|
36
51
|
attr_reader :driver
|
37
52
|
|
38
53
|
def initialize(driver)
|
54
|
+
::Appium::Logger.warn(
|
55
|
+
'[DEPRECATION] Appium::Core::MultiTouch is deprecated in W3C spec. Use W3C actions instead'
|
56
|
+
)
|
57
|
+
|
39
58
|
@actions = []
|
40
59
|
@driver = driver
|
41
60
|
end
|
@@ -14,16 +14,26 @@
|
|
14
14
|
|
15
15
|
module Appium
|
16
16
|
module Core
|
17
|
+
#
|
18
|
+
# @deprecated Use W3C actions instead
|
19
|
+
#
|
17
20
|
# Perform a series of gestures, one after another. Gestures are chained
|
18
21
|
# together and only performed when +perform()+ is called. Default is conducted by global driver.
|
19
22
|
#
|
20
23
|
# Each method returns the object itself, so calls can be chained.
|
21
24
|
#
|
22
25
|
# Consider to use W3C spec touch action like the followings.
|
23
|
-
# https://
|
26
|
+
# https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/PointerActions.html
|
24
27
|
# https://github.com/appium/ruby_lib_core/blob/master/test/functional/android/webdriver/w3c_actions_test.rb
|
25
28
|
# https://github.com/appium/ruby_lib_core/blob/master/test/functional/ios/webdriver/w3c_actions_test.rb
|
26
29
|
#
|
30
|
+
# About W3C actions
|
31
|
+
# https://www.youtube.com/watch?v=oAJ7jwMNFVU
|
32
|
+
# https://appiumpro.com/editions/30-ios-specific-touch-action-methods
|
33
|
+
# https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api
|
34
|
+
#
|
35
|
+
# Functional test code in ruby_lib_core repository also helps.
|
36
|
+
#
|
27
37
|
# @example
|
28
38
|
#
|
29
39
|
# @driver = Appium::Core.for(opts).start_driver
|
@@ -39,6 +49,10 @@ module Appium
|
|
39
49
|
attr_reader :actions, :driver
|
40
50
|
|
41
51
|
def initialize(driver)
|
52
|
+
::Appium::Logger.warn(
|
53
|
+
'[DEPRECATION] Appium::Core::TouchAction is deprecated in W3C spec. Use W3C actions instead'
|
54
|
+
)
|
55
|
+
|
42
56
|
@actions = []
|
43
57
|
@driver = driver
|
44
58
|
end
|
@@ -195,7 +209,7 @@ module Appium
|
|
195
209
|
end
|
196
210
|
|
197
211
|
def args_with_ele_ref(args)
|
198
|
-
args[:element] = args[:element].
|
212
|
+
args[:element] = args[:element].id if args.key? :element
|
199
213
|
args
|
200
214
|
end
|
201
215
|
end # class TouchAction
|
@@ -38,6 +38,8 @@ module Appium
|
|
38
38
|
#
|
39
39
|
# result = Appium::Core::Wait.until { @driver.find_element(:id, 'something') }
|
40
40
|
#
|
41
|
+
# result = Appium::Core::Wait.until(timeout: 30, message: 'timeout') { @driver.find_element(:id, 'something') }
|
42
|
+
#
|
41
43
|
# result = Appium::Core::Wait.until(object: 'some object') { |object|
|
42
44
|
# @driver.find_element(:id, object)
|
43
45
|
# }
|
@@ -82,6 +84,8 @@ module Appium
|
|
82
84
|
#
|
83
85
|
# Appium::Core::Wait.until_true { @driver.find_element(:id, 'something') }
|
84
86
|
#
|
87
|
+
# Appium::Core::Wait.until_true(timeout: 30) { @driver.find_element(:id, 'something') }
|
88
|
+
#
|
85
89
|
# Appium::Core::Wait.until_true(object: 'some object') { |object|
|
86
90
|
# @driver.find_element(:id, object)
|
87
91
|
# }
|
@@ -133,17 +137,31 @@ module Appium
|
|
133
137
|
# @param [String] message Exception message if timed out.
|
134
138
|
# @param [Array, Exception] ignored Exceptions to ignore while polling (default: Exception)
|
135
139
|
#
|
136
|
-
# @example
|
140
|
+
# @example With core instance
|
137
141
|
#
|
138
142
|
# @core.wait_true { @driver.find_element :accessibility_id, 'something' }
|
143
|
+
# @core.wait_true(timeout: 30, interval: 2) { @driver.find_element :accessibility_id, 'something' }
|
144
|
+
#
|
145
|
+
# @core.wait_until_true { @driver.find_element :accessibility_id, 'something' }
|
146
|
+
# @core.wait_until_true(timeout: 30, interval: 2) { @driver.find_element :accessibility_id, 'something' }
|
147
|
+
#
|
148
|
+
# @example With driver instance
|
149
|
+
#
|
150
|
+
# @driver.wait_true { |d| d.find_element :accessibility_id, 'something' }
|
151
|
+
# @driver.wait_true(timeout: 30, interval: 2) { |d| driver.find_element :accessibility_id, 'something' }
|
139
152
|
#
|
140
|
-
|
153
|
+
# @driver.wait_until_true { |d| d.find_element :accessibility_id, 'something' }
|
154
|
+
# @driver.wait_until_true(timeout: 30, interval: 2) { |d| driver.find_element :accessibility_id, 'something' }
|
155
|
+
#
|
156
|
+
def wait_until_true(timeout: nil, interval: nil, message: nil, ignored: nil, &block)
|
141
157
|
Wait.until_true(timeout: timeout || @wait_timeout,
|
142
158
|
interval: interval || @wait_interval,
|
143
159
|
message: message,
|
144
160
|
ignored: ignored,
|
145
|
-
object: self
|
161
|
+
object: self,
|
162
|
+
&block)
|
146
163
|
end
|
164
|
+
alias wait_true wait_until_true
|
147
165
|
|
148
166
|
# Check every interval seconds to see if yield doesn't raise an exception.
|
149
167
|
# Give up after timeout seconds.
|
@@ -155,17 +173,31 @@ module Appium
|
|
155
173
|
# @param [String] message Exception message if timed out.
|
156
174
|
# @param [Array, Exception] ignored Exceptions to ignore while polling (default: Exception)
|
157
175
|
#
|
158
|
-
# @example
|
176
|
+
# @example With core instance
|
159
177
|
#
|
160
178
|
# @core.wait { @driver.find_element :accessibility_id, 'something' }
|
179
|
+
# @core.wait(timeout: 30, interval: 2) { @driver.find_element :accessibility_id, 'something' }
|
180
|
+
#
|
181
|
+
# @core.wait_until { @driver.find_element :accessibility_id, 'something' }
|
182
|
+
# @core.wait_until(timeout: 30, interval: 2) { @driver.find_element :accessibility_id, 'something' }
|
183
|
+
#
|
184
|
+
# @example With driver instance
|
185
|
+
#
|
186
|
+
# @driver.wait { @driver.find_element :accessibility_id, 'something' }
|
187
|
+
# @driver.wait(timeout: 30, interval: 2) { @driver.find_element :accessibility_id, 'something' }
|
188
|
+
#
|
189
|
+
# @driver.wait_until { |d| d.find_element :accessibility_id, 'something' }
|
190
|
+
# @driver.wait_until(timeout: 30, interval: 2) { |d| d.find_element :accessibility_id, 'something' }
|
161
191
|
#
|
162
|
-
def
|
192
|
+
def wait_until(timeout: nil, interval: nil, message: nil, ignored: nil, &block)
|
163
193
|
Wait.until(timeout: timeout || @wait_timeout,
|
164
194
|
interval: interval || @wait_interval,
|
165
195
|
message: message,
|
166
196
|
ignored: ignored,
|
167
|
-
object: self
|
197
|
+
object: self,
|
198
|
+
&block)
|
168
199
|
end
|
200
|
+
alias wait wait_until
|
169
201
|
end
|
170
202
|
end # module Core
|
171
203
|
end # module Appium
|
@@ -79,11 +79,7 @@ module Appium
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def create_bridge_command(method, &block)
|
82
|
-
::Appium::Core::Base::Bridge
|
83
|
-
undef_method method if method_defined? method
|
84
|
-
block_given? ? class_eval(&block) : define_method(method) { execute method }
|
85
|
-
end
|
86
|
-
::Appium::Core::Base::Bridge::W3C.class_eval do
|
82
|
+
::Appium::Core::Base::Bridge.class_eval do
|
87
83
|
undef_method method if method_defined? method
|
88
84
|
block_given? ? class_eval(&block) : define_method(method) { execute method }
|
89
85
|
end
|
@@ -27,6 +27,8 @@ module Appium
|
|
27
27
|
autoload :Xcuitest, 'appium_lib_core/ios_xcuitest'
|
28
28
|
end
|
29
29
|
|
30
|
+
autoload :Mac2, 'appium_lib_core/mac2'
|
31
|
+
|
30
32
|
autoload :Windows, 'appium_lib_core/windows'
|
31
33
|
|
32
34
|
# This options affects only client side as <code>:appium_lib</code> key.<br>
|
@@ -38,18 +40,18 @@ module Appium
|
|
38
40
|
|
39
41
|
def initialize(appium_lib_opts)
|
40
42
|
@custom_url = appium_lib_opts.fetch :server_url, nil
|
41
|
-
@default_wait = appium_lib_opts.fetch :wait,
|
43
|
+
@default_wait = appium_lib_opts.fetch :wait, nil
|
42
44
|
@enable_idempotency_header = appium_lib_opts.fetch :enable_idempotency_header, true
|
43
45
|
|
44
46
|
# bump current session id into a particular file
|
45
47
|
@export_session = appium_lib_opts.fetch :export_session, false
|
46
48
|
@export_session_path = appium_lib_opts.fetch :export_session_path, default_tmp_appium_lib_session
|
47
49
|
|
48
|
-
@direct_connect = appium_lib_opts.fetch :direct_connect,
|
50
|
+
@direct_connect = appium_lib_opts.fetch :direct_connect, true
|
49
51
|
|
50
52
|
@port = appium_lib_opts.fetch :port, Driver::DEFAULT_APPIUM_PORT
|
51
53
|
|
52
|
-
# timeout and interval used in ::Appium::
|
54
|
+
# timeout and interval used in ::Appium::Commn.wait/wait_true
|
53
55
|
@wait_timeout = appium_lib_opts.fetch :wait_timeout, ::Appium::Core::Wait::DEFAULT_TIMEOUT
|
54
56
|
@wait_interval = appium_lib_opts.fetch :wait_interval, ::Appium::Core::Wait::DEFAULT_INTERVAL
|
55
57
|
|
@@ -133,11 +135,9 @@ module Appium
|
|
133
135
|
attr_reader :export_session_path
|
134
136
|
|
135
137
|
# Default wait time for elements to appear in Appium server side.
|
136
|
-
# Defaults to {::Appium::Core::Driver::DEFAULT_IMPLICIT_WAIT}.<br>
|
137
138
|
# Provide <code>{ appium_lib: { wait: 30 } }</code> to {::Appium::Core.for}
|
138
139
|
# @return [Integer]
|
139
140
|
attr_reader :default_wait
|
140
|
-
DEFAULT_IMPLICIT_WAIT = 0
|
141
141
|
|
142
142
|
# Appium's server port. 4723 is by default. Defaults to {::Appium::Core::Driver::DEFAULT_APPIUM_PORT}.<br>
|
143
143
|
# Provide <code>{ appium_lib: { port: 8080 } }</code> to {::Appium::Core.for}.
|
@@ -175,7 +175,7 @@ module Appium
|
|
175
175
|
# - <code>directConnectPort</code>
|
176
176
|
# - <code>directConnectPath</code>
|
177
177
|
#
|
178
|
-
# Ignore them if this parameter is <code>false</code>. Defaults to
|
178
|
+
# Ignore them if this parameter is <code>false</code>. Defaults to true.
|
179
179
|
#
|
180
180
|
# @return [Bool]
|
181
181
|
attr_reader :direct_connect
|
@@ -185,8 +185,6 @@ module Appium
|
|
185
185
|
# @option opts [Hash] :caps Appium capabilities.
|
186
186
|
# @option opts [Hash] :capabilities The same as :caps.
|
187
187
|
# This param is for compatibility with Selenium WebDriver format
|
188
|
-
# @option opts [Hash] :desired_capabilities The same as :caps.
|
189
|
-
# This param is for compatibility with Selenium WebDriver format
|
190
188
|
# @option opts [Appium::Core::Options] :appium_lib Capabilities affect only ruby client
|
191
189
|
# @option opts [String] :url The same as :custom_url in :appium_lib.
|
192
190
|
# This param is for compatibility with Selenium WebDriver format
|
@@ -197,10 +195,8 @@ module Appium
|
|
197
195
|
#
|
198
196
|
# # format 1
|
199
197
|
# @core = Appium::Core.for caps: {...}, appium_lib: {...}
|
200
|
-
# # format 2. 'capabilities:'
|
198
|
+
# # format 2. 'capabilities:' is also available instead of 'caps:'.
|
201
199
|
# @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", capabilities: {...}, appium_lib: {...}
|
202
|
-
# # format 3. 'appium_lib: {...}' can be blank
|
203
|
-
# @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", desired_capabilities: {...}
|
204
200
|
#
|
205
201
|
#
|
206
202
|
# require 'rubygems'
|
@@ -228,7 +224,7 @@ module Appium
|
|
228
224
|
# @core.start_driver # Connect to 'http://127.0.0.1:8080/wd/hub' because of 'port: 8080'
|
229
225
|
#
|
230
226
|
# # Start iOS driver with .zip file over HTTP
|
231
|
-
# #
|
227
|
+
# # 'capabilities:' is also available instead of 'caps:'. Either is fine.
|
232
228
|
# opts = {
|
233
229
|
# capabilities: {
|
234
230
|
# platformName: :ios,
|
@@ -252,7 +248,7 @@ module Appium
|
|
252
248
|
# # Start iOS driver as another format. 'url' is available like below
|
253
249
|
# opts = {
|
254
250
|
# url: "http://custom-host:8080/wd/hub.com",
|
255
|
-
#
|
251
|
+
# capabilities: {
|
256
252
|
# platformName: :ios,
|
257
253
|
# platformVersion: '11.0',
|
258
254
|
# deviceName: 'iPhone Simulator',
|
@@ -324,7 +320,7 @@ module Appium
|
|
324
320
|
#
|
325
321
|
# # Start iOS driver
|
326
322
|
# opts = {
|
327
|
-
#
|
323
|
+
# capabilities: {
|
328
324
|
# platformName: :ios,
|
329
325
|
# platformVersion: '11.0',
|
330
326
|
# deviceName: 'iPhone Simulator',
|
@@ -365,11 +361,13 @@ module Appium
|
|
365
361
|
end
|
366
362
|
|
367
363
|
begin
|
368
|
-
|
369
|
-
|
370
|
-
|
364
|
+
@driver = ::Appium::Core::Base::Driver.new(listener: @listener,
|
365
|
+
http_client: @http_client,
|
366
|
+
capabilities: @caps, # ::Selenium::WebDriver::Remote::Capabilities
|
371
367
|
url: @custom_url,
|
372
|
-
|
368
|
+
wait_timeout: @wait_timeout,
|
369
|
+
wait_interval: @wait_interval,
|
370
|
+
automation_name: @automation_name)
|
373
371
|
|
374
372
|
if @direct_connect
|
375
373
|
d_c = DirectConnections.new(@driver.capabilities)
|
@@ -410,6 +408,8 @@ module Appium
|
|
410
408
|
|
411
409
|
# Ignore setting default wait if the target driver has no implementation
|
412
410
|
def set_implicit_wait_by_default(wait)
|
411
|
+
return if @default_wait.nil?
|
412
|
+
|
413
413
|
@driver.manage.timeouts.implicit_wait = wait
|
414
414
|
rescue ::Selenium::WebDriver::Error::UnknownError => e
|
415
415
|
unless e.message.include?('The operation requested is not yet implemented')
|
@@ -435,7 +435,8 @@ module Appium
|
|
435
435
|
nil
|
436
436
|
end
|
437
437
|
|
438
|
-
# Returns the server's version info
|
438
|
+
# Returns the server's version info. This method calls +driver.remote_status+ internally
|
439
|
+
#
|
439
440
|
# @return [Hash]
|
440
441
|
#
|
441
442
|
# @example
|
@@ -449,18 +450,20 @@ module Appium
|
|
449
450
|
# }
|
450
451
|
# }
|
451
452
|
#
|
452
|
-
# Returns blank hash
|
453
|
+
# Returns blank hash in a case +driver.remote_status+ got an error
|
454
|
+
# such as Selenium Grid. It returns 500 error against 'remote_status'.
|
453
455
|
#
|
454
456
|
# @example
|
455
457
|
#
|
456
458
|
# @core.appium_server_version #=> {}
|
457
459
|
#
|
458
460
|
def appium_server_version
|
459
|
-
@driver.
|
460
|
-
rescue Selenium::WebDriver::Error::ServerError => e
|
461
|
-
raise ::Appium::Core::Error::ServerError unless e.message.include?('status code 500')
|
461
|
+
return {} if @driver.nil?
|
462
462
|
|
463
|
-
|
463
|
+
@driver.remote_status
|
464
|
+
rescue StandardError
|
465
|
+
# Ignore error case in a case the target appium server
|
466
|
+
# does not support `/status` API.
|
464
467
|
{}
|
465
468
|
end
|
466
469
|
|
@@ -476,21 +479,6 @@ module Appium
|
|
476
479
|
p_version.split('.').map(&:to_i)
|
477
480
|
end
|
478
481
|
|
479
|
-
# Takes a png screenshot and saves to the target path.
|
480
|
-
#
|
481
|
-
# @param png_save_path [String] the full path to save the png
|
482
|
-
# @return [File]
|
483
|
-
#
|
484
|
-
# @example
|
485
|
-
#
|
486
|
-
# @core.screenshot '/tmp/hi.png' #=> nil
|
487
|
-
# # same as '@driver.save_screenshot png_save_path'
|
488
|
-
#
|
489
|
-
def screenshot(png_save_path)
|
490
|
-
::Appium::Logger.warn '[DEPRECATION] screenshot will be removed. Please use driver.save_screenshot instead.'
|
491
|
-
@driver.save_screenshot png_save_path
|
492
|
-
end
|
493
|
-
|
494
482
|
private
|
495
483
|
|
496
484
|
# @private
|
@@ -526,7 +514,7 @@ module Appium
|
|
526
514
|
when :gecko
|
527
515
|
::Appium::Logger.debug('Gecko Driver for macOS')
|
528
516
|
when :mac2
|
529
|
-
::Appium::
|
517
|
+
::Appium::Core::Mac2::Bridge.for self
|
530
518
|
else
|
531
519
|
# no Mac specific extentions
|
532
520
|
::Appium::Logger.debug('macOS Native')
|
@@ -563,10 +551,7 @@ module Appium
|
|
563
551
|
def validate_keys(opts)
|
564
552
|
flatten_ops = flatten_hash_keys(opts)
|
565
553
|
|
566
|
-
|
567
|
-
unless opts.member?(:caps) || opts.member?(:capabilities) || opts.member?(:desired_capabilities)
|
568
|
-
raise Error::NoCapabilityError
|
569
|
-
end
|
554
|
+
raise Error::NoCapabilityError unless opts.member?(:caps) || opts.member?(:capabilities)
|
570
555
|
|
571
556
|
if !opts.member?(:appium_lib) && flatten_ops.member?(:appium_lib)
|
572
557
|
raise Error::CapabilityStructureError, 'Please check the value of appium_lib in the capability'
|
@@ -587,8 +572,7 @@ module Appium
|
|
587
572
|
|
588
573
|
# @private
|
589
574
|
def get_caps(opts)
|
590
|
-
|
591
|
-
Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || opts[:desired_capabilities] || {})
|
575
|
+
Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || {})
|
592
576
|
end
|
593
577
|
|
594
578
|
# @private
|