appium_lib_core 4.1.0 → 5.0.0.rc6

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +8 -0
  3. data/.github/workflows/unittest.yml +8 -9
  4. data/.rubocop.yml +89 -1
  5. data/CHANGELOG.md +64 -277
  6. data/README.md +7 -6
  7. data/Rakefile +4 -0
  8. data/appium_lib_core.gemspec +4 -4
  9. data/ci-jobs/functional/run_appium.yml +3 -3
  10. data/ci-jobs/functional_test.yml +3 -3
  11. data/docs/mobile_command.md +2 -2
  12. data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
  13. data/lib/appium_lib_core/android/device.rb +4 -4
  14. data/lib/appium_lib_core/common/base/bridge.rb +297 -90
  15. data/lib/appium_lib_core/common/base/capabilities.rb +10 -3
  16. data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
  17. data/lib/appium_lib_core/common/base/driver.rb +148 -128
  18. data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
  19. data/lib/appium_lib_core/common/base/has_location.rb +80 -0
  20. data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
  21. data/lib/appium_lib_core/common/base/http_default.rb +1 -3
  22. data/lib/appium_lib_core/common/base/remote_status.rb +31 -0
  23. data/lib/appium_lib_core/common/base/rotable.rb +54 -0
  24. data/lib/appium_lib_core/common/base/screenshot.rb +6 -6
  25. data/lib/appium_lib_core/common/base/search_context.rb +11 -4
  26. data/lib/appium_lib_core/common/base.rb +1 -3
  27. data/lib/appium_lib_core/common/command.rb +259 -4
  28. data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
  29. data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
  30. data/lib/appium_lib_core/common/{command/mjsonwp.rb → device/orientation.rb} +14 -11
  31. data/lib/appium_lib_core/common/device/value.rb +6 -6
  32. data/lib/appium_lib_core/common/error.rb +4 -1
  33. data/lib/appium_lib_core/common/log.rb +4 -1
  34. data/lib/appium_lib_core/common/touch_action/touch_actions.rb +1 -1
  35. data/lib/appium_lib_core/common/wait.rb +42 -10
  36. data/lib/appium_lib_core/device.rb +1 -5
  37. data/lib/appium_lib_core/driver.rb +27 -46
  38. data/lib/appium_lib_core/{patch.rb → element.rb} +66 -9
  39. data/lib/appium_lib_core/ios/uiautomation/patch.rb +1 -1
  40. data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
  41. data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
  42. data/lib/appium_lib_core/mac2/device.rb +92 -0
  43. data/lib/appium_lib_core/mac2.rb +17 -0
  44. data/lib/appium_lib_core/version.rb +2 -2
  45. data/lib/appium_lib_core.rb +2 -5
  46. data/release_notes.md +92 -0
  47. data/script/commands.rb +3 -37
  48. metadata +28 -28
  49. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
  50. data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
  51. data/lib/appium_lib_core/common/command/common.rb +0 -110
  52. data/lib/appium_lib_core/common/command/w3c.rb +0 -56
@@ -19,10 +19,17 @@ module Appium
19
19
  # @private
20
20
  # @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
21
21
  # this client sends capabilities to Appium server as JSON format.
22
- # @return [::Selenium::WebDriver::Remote::W3C::Capabilities] Return instance of Appium::Core::Base::Capabilities
23
- # inherited ::Selenium::WebDriver::Remote::W3C::Capabilities
22
+ # @return [::Selenium::WebDriver::Remote::Capabilities] Return instance of Appium::Core::Base::Capabilities
23
+ # inherited ::Selenium::WebDriver::Remote::Capabilities
24
24
  def self.create_capabilities(opts_caps = {})
25
- ::Selenium::WebDriver::Remote::W3C::Capabilities.new(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.
32
+ ::Selenium::WebDriver::Remote::Capabilities.new(opts_caps)
26
33
  end
27
34
  end
28
35
  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,8 +13,15 @@
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'
24
+ require_relative '../wait'
18
25
 
19
26
  module Appium
20
27
  module Core
@@ -22,42 +29,49 @@ module Appium
22
29
  class Driver < ::Selenium::WebDriver::Driver
23
30
  include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
24
31
  include ::Selenium::WebDriver::DriverExtensions::HasSessionId
25
- include ::Selenium::WebDriver::DriverExtensions::Rotatable
26
32
  include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
27
33
  include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
28
34
 
35
+ include ::Appium::Core::Base::Rotatable
29
36
  include ::Appium::Core::Base::SearchContext
30
- include ::Appium::Core::Base::TakeScreenshot
37
+ include ::Appium::Core::Base::TakesScreenshot
38
+ include ::Appium::Core::Base::HasRemoteStatus
39
+ include ::Appium::Core::Base::HasLocation
40
+ include ::Appium::Core::Base::HasNetworkConnection
41
+
42
+ include ::Appium::Core::Waitable
43
+
44
+ private
31
45
 
32
46
  # Private API.
33
47
  # Do not use this for general use. Used by flutter driver to get bridge for creating a new element
34
48
  attr_reader :bridge
35
49
 
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)
50
+ def initialize(bridge: nil, listener: nil, **opts)
51
+ super
50
52
  end
51
53
 
52
- # Get the dialect value
53
- # @return [:oss|:w3c]
54
- def dialect
55
- @bridge.dialect
54
+ # Create a proper bridge instance.
55
+ #
56
+ # @return [::Appium::Core::Base::Bridge]
57
+ #
58
+ def create_bridge(**opts)
59
+ capabilities = opts.delete(:capabilities)
60
+ bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
61
+ raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
62
+
63
+ bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
64
+
65
+ bridge.create_session(capabilities)
66
+ bridge
56
67
  end
57
68
 
69
+ public
70
+
58
71
  # Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path.
59
72
  # After this method, +@bridge.http+ will be a new instance following them instead of +server_url+ which is
60
73
  # set before creating session.
74
+ # If +@bridge.http+ did not have +update_sending_request_to+ method, this method returns immediately.
61
75
  #
62
76
  # @example
63
77
  #
@@ -66,10 +80,95 @@ module Appium
66
80
  # driver.manage.timeouts.implicit_wait = 10 # @bridge.http is for 'https://example2.com:9000/wd/hub/'
67
81
  #
68
82
  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)
83
+ unless @bridge.http&.class&.method_defined? :update_sending_request_to
84
+ ::Appium::Logger.warn "#{@bridge.http&.class} has no 'update_sending_request_to'. " \
85
+ 'It keeps current connection target.'
86
+ return
87
+ end
88
+
89
+ @bridge.http&.update_sending_request_to(scheme: protocol,
90
+ host: host,
91
+ port: port,
92
+ path: path)
93
+ end
94
+
95
+ AVAILABLE_METHODS = [
96
+ :get, :head, :post, :put, :delete,
97
+ :connect, :options, :trace, :patch
98
+ ].freeze
99
+ # Define a new custom method to the driver so that you can define your own method for
100
+ # drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
101
+ # to define custom commands that are not part of W3C spec.
102
+ #
103
+ # @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
104
+ # @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
105
+ # +:session_id+ is the placeholder of 'session id'.
106
+ # Other place holders can be specified with +:+ prefix like +:id+.
107
+ # Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
108
+ # @param [Symbol] name The name of method that is called as the driver instance method.
109
+ # @param [Proc] block The block to involve as the method.
110
+ # Please define a method that has the same +name+ with arguments you want.
111
+ # The method must has +execute+ method. tHe +execute+ is calls the +url+
112
+ # with the given parameters.
113
+ # The first argument should be +name+ as symbol.
114
+ # The second argument should be hash. If keys in the hash matches +:+ prefix
115
+ # string in the given url, the matched string in the given url will be
116
+ # values in the hash.
117
+ # The third argument should be hash. The hash will be the request body.
118
+ # Please read examples below for more details.
119
+ # @raise [ArgumentError] If the given +method+ is invalid value.
120
+ #
121
+ # @example
122
+ #
123
+ # @driver.add_command(
124
+ # method: :get,
125
+ # url: 'session/:session_id/path/to/custom/url',
126
+ # name: :test_command
127
+ # )
128
+ # # Send a GET request to 'session/<session id>/path/to/custom/url'
129
+ # @driver.test_command
130
+ #
131
+ #
132
+ # @driver.add_command(
133
+ # method: :post,
134
+ # url: 'session/:session_id/path/to/custom/url',
135
+ # name: :test_command
136
+ # ) do
137
+ # def test_command(argument)
138
+ # execute(:test_command, {}, { dummy: argument })
139
+ # end
140
+ # end
141
+ # # Send a POST request to 'session/<session id>/path/to/custom/url'
142
+ # # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
143
+ # # ':session_id' in the given 'url' is replaced with current 'session id'.
144
+ # @driver.test_command(1)
145
+ #
146
+ #
147
+ # @driver.add_command(
148
+ # method: :post,
149
+ # url: 'session/:session_id/element/:id/custom/action',
150
+ # name: :test_action_command
151
+ # ) do
152
+ # def test_action_command(element_id, action)
153
+ # execute(:test_action_command, {id: element_id}, { dummy_action: action })
154
+ # end
155
+ # end
156
+ # # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
157
+ # # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
158
+ # # ':session_id' in the given url is replaced with current 'session id'.
159
+ # # ':id' in the given url is replaced with the given 'element_id'.
160
+ # e = @driver.find_element :accessibility_id, 'an element'
161
+ # @driver.test_action_command(e.id, 'action')
162
+ #
163
+ def add_command(method:, url:, name:, &block)
164
+ unless AVAILABLE_METHODS.include? method
165
+ raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}"
166
+ end
167
+
168
+ # TODO: Remove this logger before Appium 2.0 release
169
+ ::Appium::Logger.info '[Experimental] this method is experimental for Appium 2.0. This interface may change.'
170
+
171
+ @bridge.add_command method: method, url: url, name: name, &block
73
172
  end
74
173
 
75
174
  ### Methods for Appium
@@ -138,38 +237,6 @@ module Appium
138
237
  end
139
238
  alias is_keyboard_shown keyboard_shown?
140
239
 
141
- # [DEPRECATION]
142
- # Send keys for a current active element
143
- # @param [String] key Input text
144
- #
145
- # @example
146
- #
147
- # @driver.send_keys 'happy testing!'
148
- #
149
- def send_keys(*key)
150
- ::Appium::Logger.warn(
151
- '[DEPRECATION] Driver#send_keys is deprecated in W3C spec. Use driver.action.<command>.perform instead'
152
- )
153
- @bridge.send_keys_to_active_element(key)
154
- end
155
- alias type send_keys
156
-
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
240
  # Returns an instance of DriverSettings to call get/update.
174
241
  #
175
242
  # @example
@@ -178,7 +245,7 @@ module Appium
178
245
  # @driver.settings.update('allowInvisibleElements': true)
179
246
  #
180
247
  def settings
181
- @driver_settings ||= DriverSettings.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
248
+ @settings ||= DriverSettings.new(@bridge)
182
249
  end
183
250
 
184
251
  # Get appium Settings for current test session.
@@ -200,8 +267,8 @@ module Appium
200
267
  #
201
268
  # @example
202
269
  #
203
- # @driver.update_settings('allowInvisibleElements': true)
204
- # @driver.settings.update('allowInvisibleElements': true)
270
+ # @driver.update_settings({ 'allowInvisibleElements': true })
271
+ # @driver.settings.update({ 'allowInvisibleElements': true })
205
272
  # @driver.settings = { 'allowInvisibleElements': true }
206
273
  #
207
274
  def settings=(value)
@@ -209,36 +276,10 @@ module Appium
209
276
  end
210
277
  alias update_settings settings=
211
278
 
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
279
  # Returns an instance of DeviceIME
241
280
  #
281
+ # @return [Appium::Core::Base::Driver::DeviceIME]
282
+ #
242
283
  # @example
243
284
  #
244
285
  # @driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'
@@ -248,7 +289,7 @@ module Appium
248
289
  # @driver.ime.deactivate #=> Deactivate current IME engine
249
290
  #
250
291
  def ime
251
- @device_ime ||= DeviceIME.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
292
+ @ime ||= DeviceIME.new(@bridge)
252
293
  end
253
294
 
254
295
  # Android only. Make an engine that is available active.
@@ -289,6 +330,8 @@ module Appium
289
330
  # @!method ime_activated
290
331
  # Android only. Indicates whether IME input is active at the moment (not if it is available).
291
332
  #
333
+ # @return [Boolean]
334
+ #
292
335
  # @example
293
336
  #
294
337
  # @driver.ime_activated #=> True if IME is activated
@@ -366,30 +409,6 @@ module Appium
366
409
  end
367
410
  alias set_context context=
368
411
 
369
- # Set the value to element directly
370
- #
371
- # @example
372
- #
373
- # @driver.set_immediate_value element, 'hello'
374
- #
375
- def set_immediate_value(element, *value)
376
- ::Appium::Logger.warn '[DEPRECATION] driver#set_immediate_value(element, *value) is deprecated. ' \
377
- 'Use Element#immediate_value(*value) instead'
378
- @bridge.set_immediate_value(element, *value)
379
- end
380
-
381
- # Replace the value to element directly
382
- #
383
- # @example
384
- #
385
- # @driver.replace_value element, 'hello'
386
- #
387
- def replace_value(element, *value)
388
- ::Appium::Logger.warn '[DEPRECATION] driver#replace_value(element, *value) is deprecated. ' \
389
- 'Use Element#replace_value(*value) instead'
390
- @bridge.replace_value(element, *value)
391
- end
392
-
393
412
  # Place a file in a specific location on the device.
394
413
  # On iOS, the server should have ifuse libraries installed and configured properly for this feature to work on
395
414
  # real devices.
@@ -809,7 +828,7 @@ module Appium
809
828
  # @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
810
829
  #
811
830
  def perform_actions(data)
812
- raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
831
+ raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
813
832
 
814
833
  @bridge.send_actions data.map(&:encode).compact
815
834
  data.each(&:clear_actions)
@@ -853,7 +872,7 @@ module Appium
853
872
  end
854
873
 
855
874
  # Get the device window's logs.
856
- # @return [String]
875
+ # @return [Appium::Core::Logs]
857
876
  #
858
877
  # @example
859
878
  #
@@ -879,16 +898,15 @@ module Appium
879
898
  # Retrieve the capabilities of the specified session.
880
899
  # It's almost same as +@driver.capabilities+ but you can get more details.
881
900
  #
882
- # @return [Selenium::WebDriver::Remote::Capabilities]
901
+ # @return [Selenium::WebDriver::Remote::Capabilities, Selenium::WebDriver::Remote::Capabilities]
883
902
  #
884
903
  # @example
885
904
  # @driver.session_capabilities
886
905
  #
887
906
  # #=> uiautomator2
888
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fa38dae1360
907
+ # # <Selenium::WebDriver::Remote::Capabilities:0x007fa38dae1360
889
908
  # # @capabilities=
890
- # # {:proxy=>nil,
891
- # # :browser_name=>nil,
909
+ # # {:browser_name=>nil,
892
910
  # # :browser_version=>nil,
893
911
  # # :platform_name=>"android",
894
912
  # # :page_load_strategy=>nil,
@@ -935,10 +953,9 @@ module Appium
935
953
  # # "viewportRect"=>{"left"=>0, "top"=>63, "width"=>1080, "height"=>1731}}>
936
954
  # #
937
955
  # #=> XCUITest
938
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fb15dc01370
956
+ # # <Selenium::WebDriver::Remote::Capabilities:0x007fb15dc01370
939
957
  # # @capabilities=
940
- # # {:proxy=>nil,
941
- # # :browser_name=>"UICatalog",
958
+ # # {:browser_name=>"UICatalog",
942
959
  # # :browser_version=>nil,
943
960
  # # :platform_name=>"ios",
944
961
  # # :page_load_strategy=>nil,
@@ -992,11 +1009,14 @@ module Appium
992
1009
  visualize: visualize)
993
1010
  end
994
1011
 
995
- def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil)
1012
+ def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
1013
+ multiple: nil, match_neighbour_threshold: nil)
996
1014
  @bridge.find_image_occurrence(full_image: full_image,
997
1015
  partial_image: partial_image,
998
1016
  visualize: visualize,
999
- threshold: threshold)
1017
+ threshold: threshold,
1018
+ multiple: multiple,
1019
+ match_neighbour_threshold: match_neighbour_threshold)
1000
1020
  end
1001
1021
 
1002
1022
  def get_images_similarity(first_image:, second_image:, visualize: false)
@@ -1016,7 +1036,7 @@ module Appium
1016
1036
  #
1017
1037
  # @param [String] img_path A path to a partial image you'd like to find
1018
1038
  #
1019
- # @return [::Selenium::WebDriver::Element]
1039
+ # @return [::Appium::Core::Element]
1020
1040
  #
1021
1041
  # @example
1022
1042
  #
@@ -1038,7 +1058,7 @@ module Appium
1038
1058
  #
1039
1059
  # @param [String] img_path A path to a partial image you'd like to find
1040
1060
  #
1041
- # @return [::Selenium::WebDriver::Element]
1061
+ # @return [Array<Selenium::WebDriver::Element>]
1042
1062
  #
1043
1063
  # @example
1044
1064
  #
@@ -1086,14 +1106,14 @@ module Appium
1086
1106
  @bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
1087
1107
  end
1088
1108
 
1089
- # Convert vanilla element response to ::Selenium::WebDriver::Element
1109
+ # Convert vanilla element response to ::Appium::Core::Element
1090
1110
  #
1091
1111
  # @param [Hash] id The id which can get as a response from server
1092
- # @return [::Selenium::WebDriver::Element]
1112
+ # @return [::Appium::Core::Element]
1093
1113
  #
1094
1114
  # @example
1095
1115
  # response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
1096
- # ele = @driver.convert_to_element(response) #=> ::Selenium::WebDriver::Element
1116
+ # ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
1097
1117
  # ele.rect #=> Can get the rect of the element
1098
1118
  #
1099
1119
  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,80 @@
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
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.
59
+ # @param [::Selenium::WebDriver::Location]
60
+ #
61
+ # @example
62
+ #
63
+ # driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
64
+ #
65
+ def set_location(latitude, longitude, altitude, speed: nil, satellites: nil)
66
+ if speed.nil? && satellites.nil?
67
+ self.location = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
68
+ else
69
+ loc = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
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
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ 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