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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +8 -0
  3. data/.github/workflows/unittest.yml +2 -2
  4. data/CHANGELOG.md +43 -277
  5. data/README.md +2 -1
  6. data/appium_lib_core.gemspec +4 -4
  7. data/ci-jobs/functional/run_appium.yml +2 -2
  8. data/ci-jobs/functional_test.yml +1 -1
  9. data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
  10. data/lib/appium_lib_core/android/device.rb +4 -4
  11. data/lib/appium_lib_core/common/base/bridge.rb +284 -89
  12. data/lib/appium_lib_core/common/base/capabilities.rb +3 -3
  13. data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
  14. data/lib/appium_lib_core/common/base/driver.rb +157 -88
  15. data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
  16. data/lib/appium_lib_core/common/base/has_location.rb +73 -0
  17. data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
  18. data/lib/appium_lib_core/common/base/http_default.rb +1 -3
  19. data/lib/appium_lib_core/common/base/remote_status.rb +31 -0
  20. data/lib/appium_lib_core/common/base/rotable.rb +54 -0
  21. data/lib/appium_lib_core/common/base/screenshot.rb +1 -1
  22. data/lib/appium_lib_core/common/base/search_context.rb +11 -4
  23. data/lib/appium_lib_core/common/base.rb +1 -3
  24. data/lib/appium_lib_core/common/command.rb +259 -4
  25. data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
  26. data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
  27. data/lib/appium_lib_core/common/{command/mjsonwp.rb → device/orientation.rb} +14 -11
  28. data/lib/appium_lib_core/common/error.rb +4 -1
  29. data/lib/appium_lib_core/common/log.rb +4 -1
  30. data/lib/appium_lib_core/device.rb +1 -5
  31. data/lib/appium_lib_core/driver.rb +17 -13
  32. data/lib/appium_lib_core/{patch.rb → element.rb} +53 -5
  33. data/lib/appium_lib_core/ios/uiautomation/patch.rb +1 -1
  34. data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
  35. data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
  36. data/lib/appium_lib_core/mac2/device.rb +92 -0
  37. data/lib/appium_lib_core/mac2.rb +17 -0
  38. data/lib/appium_lib_core/version.rb +2 -2
  39. data/lib/appium_lib_core.rb +2 -5
  40. data/release_notes.md +73 -0
  41. data/script/commands.rb +3 -37
  42. metadata +30 -30
  43. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
  44. data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
  45. data/lib/appium_lib_core/common/command/common.rb +0 -110
  46. data/lib/appium_lib_core/common/command/w3c.rb +0 -56
@@ -13,8 +13,14 @@
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'
20
+ require_relative 'rotable'
21
+ require_relative 'remote_status'
22
+ require_relative 'has_location'
23
+ require_relative 'has_network_connection'
18
24
 
19
25
  module Appium
20
26
  module Core
@@ -22,42 +28,69 @@ module Appium
22
28
  class Driver < ::Selenium::WebDriver::Driver
23
29
  include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
24
30
  include ::Selenium::WebDriver::DriverExtensions::HasSessionId
25
- include ::Selenium::WebDriver::DriverExtensions::Rotatable
26
31
  include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
27
32
  include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
28
33
 
34
+ include ::Appium::Core::Base::Rotatable
29
35
  include ::Appium::Core::Base::SearchContext
30
- include ::Appium::Core::Base::TakeScreenshot
36
+ include ::Appium::Core::Base::TakesScreenshot
37
+ include ::Appium::Core::Base::HasRemoteStatus
38
+ include ::Appium::Core::Base::HasLocation
39
+ include ::Appium::Core::Base::HasNetworkConnection
40
+
41
+ private
31
42
 
32
43
  # Private API.
33
44
  # Do not use this for general use. Used by flutter driver to get bridge for creating a new element
34
45
  attr_reader :bridge
35
46
 
36
- def initialize(opts = {})
37
- listener = opts.delete(:listener)
38
- @bridge = ::Appium::Core::Base::Bridge.handshake(**opts)
39
- if @bridge.dialect == :oss # MJSONWP
40
- extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
41
- extend ::Selenium::WebDriver::DriverExtensions::HasLocation
42
- extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
43
- elsif @bridge.dialect == :w3c
44
- # TODO: Only for Appium. Ideally, we'd like to remove the below like selenium-webdriver
45
- extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
46
- extend ::Selenium::WebDriver::DriverExtensions::HasLocation
47
- extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
48
- end
49
- super(@bridge, listener: listener)
47
+ def initialize(bridge: nil, listener: nil, **opts)
48
+ super
50
49
  end
51
50
 
52
- # Get the dialect value
53
- # @return [:oss|:w3c]
54
- def dialect
55
- @bridge.dialect
51
+ # Implements protocol handshake which:
52
+ #
53
+ # 1. Creates session with driver.
54
+ # 2. Sniffs response.
55
+ # 3. Based on the response, understands which dialect we should use.
56
+ #
57
+ # @return [::Appium::Core::Base::Bridge]
58
+ #
59
+ def create_bridge(**opts)
60
+ # TODO: probably Appium does not need this.
61
+ opts[:url] ||= service_url(opts)
62
+ caps = opts.delete(:capabilities)
63
+ # NOTE: This is deprecated
64
+ cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
65
+
66
+ desired_capabilities = opts.delete(:desired_capabilities)
67
+ if desired_capabilities
68
+ if desired_capabilities.is_a?(Hash)
69
+ desired_capabilities = ::Selenium::WebDriver::Remote::Capabilities(desired_capabilities)
70
+ end
71
+ cap_array << desired_capabilities
72
+ end
73
+
74
+ options = opts.delete(:options)
75
+ cap_array << options if options
76
+
77
+ capabilities = generate_capabilities(cap_array)
78
+
79
+ bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
80
+ raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
81
+
82
+ bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
83
+
84
+ bridge.create_session(capabilities)
85
+ bridge
56
86
  end
57
87
 
88
+ public
89
+
58
90
  # Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path.
59
91
  # After this method, +@bridge.http+ will be a new instance following them instead of +server_url+ which is
60
92
  # set before creating session.
93
+ # If +@bridge.http+ did not have +update_sending_request_to+ method, this method returns immediately.
61
94
  #
62
95
  # @example
63
96
  #
@@ -66,10 +99,85 @@ module Appium
66
99
  # driver.manage.timeouts.implicit_wait = 10 # @bridge.http is for 'https://example2.com:9000/wd/hub/'
67
100
  #
68
101
  def update_sending_request_to(protocol:, host:, port:, path:)
69
- @bridge.http.update_sending_request_to(scheme: protocol,
70
- host: host,
71
- port: port,
72
- path: path)
102
+ unless @bridge.http&.class&.method_defined? :update_sending_request_to
103
+ ::Appium::Logger.warn "#{@bridge.http&.class} has no 'update_sending_request_to'. " \
104
+ 'It keeps current connection target.'
105
+ return
106
+ end
107
+
108
+ @bridge.http&.update_sending_request_to(scheme: protocol,
109
+ host: host,
110
+ port: port,
111
+ path: path)
112
+ end
113
+
114
+ AVAILABLE_METHODS = [
115
+ :get, :head, :post, :put, :delete,
116
+ :connect, :options, :trace, :patch
117
+ ].freeze
118
+ # Define a new custom method to the driver so that you can define your own method for
119
+ # drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
120
+ # to define custom commands that are not part of W3C spec.
121
+ #
122
+ # @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
123
+ # @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
124
+ # +:session_id+ is the placeholder of 'session id'.
125
+ # Other place holders can be specified with +:+ prefix like +:id+.
126
+ # Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
127
+ # @param [Symbol] name The name of method that is called as the driver instance method.
128
+ # @param [Proc] block The block to involve as the method
129
+ # @raise [ArgumentError] If the given +name+ is already defined or +method+ are invalid value.
130
+ #
131
+ # @example
132
+ #
133
+ # @driver.add_command(
134
+ # method: :get,
135
+ # url: 'session/:session_id/path/to/custom/url',
136
+ # name: :test_command
137
+ # )
138
+ # # Send a GET request to 'session/<session id>/path/to/custom/url'
139
+ # @driver.test_command
140
+ #
141
+ #
142
+ # @driver.add_command(
143
+ # method: :post,
144
+ # url: 'session/:session_id/path/to/custom/url',
145
+ # name: :test_command
146
+ # ) do
147
+ # def test_command(argument)
148
+ # execute(:test_command, {}, { dummy: argument })
149
+ # end
150
+ # end
151
+ # # Send a POST request to 'session/<session id>/path/to/custom/url'
152
+ # # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
153
+ # # ':session_id' in the given 'url' is replaced with current 'session id'.
154
+ # @driver.test_command(1)
155
+ #
156
+ # @driver.add_command(
157
+ # method: :post,
158
+ # url: 'session/:session_id/element/:id/custom/action',
159
+ # name: :test_action_command
160
+ # ) do
161
+ # def test_action_command(element_id, action)
162
+ # execute(:test_action_command, {id: element_id}, { dummy_action: action })
163
+ # end
164
+ # end
165
+ # # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
166
+ # # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
167
+ # # ':session_id' in the given url is replaced with current 'session id'.
168
+ # # ':id' in the given url is replaced with the given 'element_id'.
169
+ # e = @driver.find_element :accessibility_id, 'an element'
170
+ # @driver.test_action_command(e.ref, 'action')
171
+ #
172
+ def add_command(method:, url:, name:, &block)
173
+ unless AVAILABLE_METHODS.include? method
174
+ raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}"
175
+ end
176
+
177
+ # TODO: Remove this logger before Appium 2.0 release
178
+ ::Appium::Logger.info '[Experimental] this method is experimental for Appium 2.0. This interface may change.'
179
+
180
+ @bridge.add_command method: method, url: url, name: name, &block
73
181
  end
74
182
 
75
183
  ### Methods for Appium
@@ -154,22 +262,6 @@ module Appium
154
262
  end
155
263
  alias type send_keys
156
264
 
157
- class DriverSettings
158
- # @private this class is private
159
- def initialize(bridge)
160
- @bridge = bridge
161
- end
162
-
163
- def get
164
- @bridge.get_settings
165
- end
166
-
167
- def update(settings)
168
- @bridge.update_settings(settings)
169
- end
170
- end
171
- private_constant :DriverSettings
172
-
173
265
  # Returns an instance of DriverSettings to call get/update.
174
266
  #
175
267
  # @example
@@ -178,7 +270,7 @@ module Appium
178
270
  # @driver.settings.update('allowInvisibleElements': true)
179
271
  #
180
272
  def settings
181
- @driver_settings ||= DriverSettings.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
273
+ @settings ||= DriverSettings.new(@bridge)
182
274
  end
183
275
 
184
276
  # Get appium Settings for current test session.
@@ -200,8 +292,8 @@ module Appium
200
292
  #
201
293
  # @example
202
294
  #
203
- # @driver.update_settings('allowInvisibleElements': true)
204
- # @driver.settings.update('allowInvisibleElements': true)
295
+ # @driver.update_settings({ 'allowInvisibleElements': true })
296
+ # @driver.settings.update({ 'allowInvisibleElements': true })
205
297
  # @driver.settings = { 'allowInvisibleElements': true }
206
298
  #
207
299
  def settings=(value)
@@ -209,36 +301,10 @@ module Appium
209
301
  end
210
302
  alias update_settings settings=
211
303
 
212
- class DeviceIME
213
- # @private this class is private
214
- def initialize(bridge)
215
- @bridge = bridge
216
- end
217
-
218
- def activate(ime_name)
219
- @bridge.ime_activate(ime_name)
220
- end
221
-
222
- def available_engines
223
- @bridge.ime_available_engines
224
- end
225
-
226
- def active_engine
227
- @bridge.ime_active_engine
228
- end
229
-
230
- def activated?
231
- @bridge.ime_activated
232
- end
233
-
234
- def deactivate
235
- @bridge.ime_deactivate
236
- end
237
- end
238
- private_constant :DeviceIME
239
-
240
304
  # Returns an instance of DeviceIME
241
305
  #
306
+ # @return [Appium::Core::Base::Driver::DeviceIME]
307
+ #
242
308
  # @example
243
309
  #
244
310
  # @driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'
@@ -248,7 +314,7 @@ module Appium
248
314
  # @driver.ime.deactivate #=> Deactivate current IME engine
249
315
  #
250
316
  def ime
251
- @device_ime ||= DeviceIME.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
317
+ @ime ||= DeviceIME.new(@bridge)
252
318
  end
253
319
 
254
320
  # Android only. Make an engine that is available active.
@@ -289,6 +355,8 @@ module Appium
289
355
  # @!method ime_activated
290
356
  # Android only. Indicates whether IME input is active at the moment (not if it is available).
291
357
  #
358
+ # @return [Boolean]
359
+ #
292
360
  # @example
293
361
  #
294
362
  # @driver.ime_activated #=> True if IME is activated
@@ -809,7 +877,7 @@ module Appium
809
877
  # @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
810
878
  #
811
879
  def perform_actions(data)
812
- raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
880
+ raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
813
881
 
814
882
  @bridge.send_actions data.map(&:encode).compact
815
883
  data.each(&:clear_actions)
@@ -853,7 +921,7 @@ module Appium
853
921
  end
854
922
 
855
923
  # Get the device window's logs.
856
- # @return [String]
924
+ # @return [Appium::Core::Logs]
857
925
  #
858
926
  # @example
859
927
  #
@@ -879,16 +947,15 @@ module Appium
879
947
  # Retrieve the capabilities of the specified session.
880
948
  # It's almost same as +@driver.capabilities+ but you can get more details.
881
949
  #
882
- # @return [Selenium::WebDriver::Remote::Capabilities]
950
+ # @return [Selenium::WebDriver::Remote::Capabilities, Selenium::WebDriver::Remote::Capabilities]
883
951
  #
884
952
  # @example
885
953
  # @driver.session_capabilities
886
954
  #
887
955
  # #=> uiautomator2
888
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fa38dae1360
956
+ # # <Selenium::WebDriver::Remote::Capabilities:0x007fa38dae1360
889
957
  # # @capabilities=
890
- # # {:proxy=>nil,
891
- # # :browser_name=>nil,
958
+ # # {:browser_name=>nil,
892
959
  # # :browser_version=>nil,
893
960
  # # :platform_name=>"android",
894
961
  # # :page_load_strategy=>nil,
@@ -935,10 +1002,9 @@ module Appium
935
1002
  # # "viewportRect"=>{"left"=>0, "top"=>63, "width"=>1080, "height"=>1731}}>
936
1003
  # #
937
1004
  # #=> XCUITest
938
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fb15dc01370
1005
+ # # <Selenium::WebDriver::Remote::Capabilities:0x007fb15dc01370
939
1006
  # # @capabilities=
940
- # # {:proxy=>nil,
941
- # # :browser_name=>"UICatalog",
1007
+ # # {:browser_name=>"UICatalog",
942
1008
  # # :browser_version=>nil,
943
1009
  # # :platform_name=>"ios",
944
1010
  # # :page_load_strategy=>nil,
@@ -992,11 +1058,14 @@ module Appium
992
1058
  visualize: visualize)
993
1059
  end
994
1060
 
995
- def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil)
1061
+ def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
1062
+ multiple: nil, match_neighbour_threshold: nil)
996
1063
  @bridge.find_image_occurrence(full_image: full_image,
997
1064
  partial_image: partial_image,
998
1065
  visualize: visualize,
999
- threshold: threshold)
1066
+ threshold: threshold,
1067
+ multiple: multiple,
1068
+ match_neighbour_threshold: match_neighbour_threshold)
1000
1069
  end
1001
1070
 
1002
1071
  def get_images_similarity(first_image:, second_image:, visualize: false)
@@ -1016,7 +1085,7 @@ module Appium
1016
1085
  #
1017
1086
  # @param [String] img_path A path to a partial image you'd like to find
1018
1087
  #
1019
- # @return [::Selenium::WebDriver::Element]
1088
+ # @return [::Appium::Core::Element]
1020
1089
  #
1021
1090
  # @example
1022
1091
  #
@@ -1038,7 +1107,7 @@ module Appium
1038
1107
  #
1039
1108
  # @param [String] img_path A path to a partial image you'd like to find
1040
1109
  #
1041
- # @return [::Selenium::WebDriver::Element]
1110
+ # @return [Array<Selenium::WebDriver::Element>]
1042
1111
  #
1043
1112
  # @example
1044
1113
  #
@@ -1086,14 +1155,14 @@ module Appium
1086
1155
  @bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
1087
1156
  end
1088
1157
 
1089
- # Convert vanilla element response to ::Selenium::WebDriver::Element
1158
+ # Convert vanilla element response to ::Appium::Core::Element
1090
1159
  #
1091
1160
  # @param [Hash] id The id which can get as a response from server
1092
- # @return [::Selenium::WebDriver::Element]
1161
+ # @return [::Appium::Core::Element]
1093
1162
  #
1094
1163
  # @example
1095
1164
  # response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
1096
- # ele = @driver.convert_to_element(response) #=> ::Selenium::WebDriver::Element
1165
+ # ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
1097
1166
  # ele.rect #=> Can get the rect of the element
1098
1167
  #
1099
1168
  def convert_to_element(id)
@@ -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
@@ -0,0 +1,73 @@
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
+ module HasLocation
22
+ # Get the location of the device.
23
+ #
24
+ # @return [::Selenium::WebDriver::Location]
25
+ #
26
+ # @example
27
+ #
28
+ # driver.location #=> ::Selenium::WebDriver::Location.new(10, 10, 10)
29
+ #
30
+ def location
31
+ @bridge.location
32
+ end
33
+
34
+ # Set the location of the device.
35
+ #
36
+ # @param [::Selenium::WebDriver::Location] location Set the location.
37
+ #
38
+ # @example
39
+ #
40
+ # driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
41
+ #
42
+ def location=(location)
43
+ unless location.is_a?(::Selenium::WebDriver::Location)
44
+ raise TypeError, "expected #{::Selenium::WebDriver::Location}, got #{location.inspect}:#{location.class}"
45
+ end
46
+
47
+ @bridge.set_location location.latitude, location.longitude, location.altitude
48
+ end
49
+
50
+ # Set the location of the device.
51
+ #
52
+ # @param [String, Number] latitude Set the latitude.
53
+ # @param [String, Number] longitude Set the longitude.
54
+ # @param [String, Number] altitude Set the altitude.
55
+ # @param [String, Number] speed Set the speed to apply the location on Android real devices @since Appium 1.21.0.
56
+ # @param [::Selenium::WebDriver::Location]
57
+ #
58
+ # @example
59
+ #
60
+ # driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
61
+ #
62
+ def set_location(latitude, longitude, altitude, speed: nil)
63
+ if speed.nil?
64
+ self.location = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
65
+ else
66
+ loc = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
67
+ @bridge.set_location loc.latitude, loc.longitude, loc.altitude, speed: Float(speed)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,56 @@
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
+ module HasNetworkConnection
22
+ def network_connection_type
23
+ connection_value = @bridge.network_connection
24
+
25
+ connection_type = values_to_type[connection_value]
26
+
27
+ # In case the connection type is not recognized return the
28
+ # connection value.
29
+ connection_type || connection_value
30
+ end
31
+
32
+ def network_connection_type=(connection_type)
33
+ raise ::Appium::Core::Error::ArgumentError, 'Invalid connection type' unless valid_type? connection_type
34
+
35
+ connection_value = type_to_values[connection_type]
36
+
37
+ @bridge.network_connection = connection_value
38
+ end
39
+
40
+ private
41
+
42
+ def type_to_values
43
+ { airplane_mode: 1, wifi: 2, data: 4, all: 6, none: 0 }
44
+ end
45
+
46
+ def values_to_type
47
+ type_to_values.invert
48
+ end
49
+
50
+ def valid_type?(type)
51
+ type_to_values.keys.include? type
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -55,8 +55,6 @@ module Appium
55
55
  def update_sending_request_to(scheme:, host:, port:, path:)
56
56
  return @server_url unless validate_url_param(scheme, host, port, path)
57
57
 
58
- ::Appium::Logger.debug("[experimental] This feature, #{__method__}, is an experimental")
59
-
60
58
  # Add / if 'path' does not have it
61
59
  path = path.start_with?('/') ? path : "/#{path}"
62
60
  path = path.end_with?('/') ? path : "#{path}/"
@@ -71,7 +69,7 @@ module Appium
71
69
  return true unless [scheme, host, port, path].include?(nil)
72
70
 
73
71
  message = "Given parameters are scheme: '#{scheme}', host: '#{host}', port: '#{port}', path: '#{path}'"
74
- ::Appium::Logger.warn(message)
72
+ ::Appium::Logger.debug(message)
75
73
  false
76
74
  end
77
75
 
@@ -0,0 +1,31 @@
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
+
22
+ module HasRemoteStatus
23
+ # Selenium binding has this ability only in Remote Binding,
24
+ # so this library has this method by own for safe.
25
+ def remote_status
26
+ bridge.status
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,54 @@
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
+
22
+ module Rotatable
23
+ ORIENTATIONS = %i[landscape portrait].freeze
24
+
25
+ #
26
+ # Change the screen orientation
27
+ #
28
+ # @param [:landscape, :portrait] orientation
29
+ #
30
+ #
31
+ def rotation=(orientation)
32
+ unless ORIENTATIONS.include?(orientation)
33
+ raise ::Appium::Core::Error::ArgumentError, "expected #{ORIENTATIONS.inspect}, got #{orientation.inspect}"
34
+ end
35
+
36
+ bridge.screen_orientation = orientation.to_s.upcase
37
+ end
38
+ alias rotate rotation=
39
+
40
+ #
41
+ # Get the current screen orientation
42
+ #
43
+ # @return [:landscape, :portrait] orientation
44
+ #
45
+ # @api public
46
+ #
47
+
48
+ def orientation
49
+ bridge.screen_orientation.to_sym.downcase
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -15,7 +15,7 @@
15
15
  module Appium
16
16
  module Core
17
17
  class Base
18
- module TakeScreenshot
18
+ module TakesScreenshot
19
19
  #
20
20
  # Save a PNG screenshot to the given path
21
21
  #