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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53abadd3b91fdcaac0c23f62bbc83b0e21ea08a50da28394a504d6839d36d2e7
4
- data.tar.gz: 9bc2cda2b1fa8be1d602cd7ab9943594f9b4a1fce0ea5a4527491563c3687fd2
3
+ metadata.gz: 3eba36b9dee77259cd1a14dd0e03c3a140a0e4bcb014d3d7d277ca9d4c47e011
4
+ data.tar.gz: 511a0a3fa46c55f078185c8d25262ec4c6b5d281be628a2217df1d90fd58d331
5
5
  SHA512:
6
- metadata.gz: 313ae53035edd0273b8d122325c77d031a186c5a9f60b57956ad0f204165cc8ca60420ce2a910dc28d9e0b5000fa9131262fbe4a2b796e4e4d7bd09d9e40e941
7
- data.tar.gz: deb1d0d9c9aba7cc7a9b6040dbdbcf76896d5a0ce786a8ac419b436a11a90e1960893e2f6683a78efee7d3a8044d5eb19414d527123778cebd088a437b6a4215
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.beta1]
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.5.0] - 2021-03-14
23
+ ## [4.7.0] - 2021-07-17
20
24
 
21
25
  ### Enhancements
22
- - Add `speed` argument for `Appium::Core::Base::Driver#set_location` since Appium 1.21.0
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
- ### Bug fixes
28
+ ## [4.6.0] - 2021-06-03
26
29
 
27
- ### Deprecations
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']
@@ -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.beta2'
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.12.1'
34
- spec.add_development_dependency 'rubocop', '1.12.0'
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'
@@ -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 wix/brew/applesimutils
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
@@ -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
- @driver.execute_script 'mobile: scrollToPage', { element: el.ref, scrollToPage: -100 }
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, "finger_id should be integer between 1 to 10. Not #{finger_id}"
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
- # Returns 'unknown' if no specific browser name
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
- 'unknown'
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] desired_capabilities A capability
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(desired_capabilities)
74
- caps = add_appium_prefix(desired_capabilities)
75
- response = execute(:new_session, {}, { capabilities: { firstMatch: [caps] } })
77
+ def create_session(capabilities)
78
+ @available_commands = ::Appium::Core::Commands::COMMANDS.dup
76
79
 
77
- @session_id = response['sessionId']
78
- capabilities = response['capabilities']
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.__send__(:capabilities) unless capabilities.is_a?(Hash)
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
- ::Appium::Core::Commands::COMMANDS[command]
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
- execute :is_element_displayed, id: element.ref
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
- execute :get_element_attribute, id: element.ref, name: name
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, parent = nil)
218
- how, what = convert_locators(how, what)
232
+ def find_element_by(how, what, parent_ref = [])
233
+ how, what = convert_locator(how, what)
219
234
 
220
- id = if parent
221
- execute :find_child_element, { id: parent }, { using: how, value: what }
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, parent = nil)
231
- how, what = convert_locators(how, what)
252
+ def find_elements_by(how, what, parent_ref = [])
253
+ how, what = convert_locator(how, what)
232
254
 
233
- ids = if parent
234
- execute :find_child_elements, { id: parent }, { using: how, value: what }
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 take_viewport_screenshot
345
+ def viewport_screenshot
317
346
  execute_script('mobile: viewportScreenshot')
318
347
  end
319
348
 
320
- def take_element_screenshot(element)
321
- execute :take_element_screenshot, id: element.ref
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 Client
345
- # TODO: Only for Appium. Ideally, we'd like to keep the selenium-webdriver
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
- # Almost same as self.handshake in ::Selenium::WebDriver::Remote::Bridge
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
- opts[:url] ||= service_url(opts)
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
- @driver_settings ||= DriverSettings.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
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
- @device_ime ||= DeviceIME.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
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
- # # {:proxy=>nil,
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
- # # {:proxy=>nil,
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 @since Appium 1.21.0.
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
- @bridge.set_location loc.latitude, loc.longitude, loc.altitude, speed: Float(speed)
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.take_element_screenshot(element)
88
+ bridge.element_screenshot element_id
88
89
  when :png
89
- bridge.take_element_screenshot(element).unpack('m')[0]
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.take_viewport_screenshot
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
- raise ArgumentError, "cannot find element by #{how.inspect}. Available finders are #{FINDERS.keys}." unless by
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
- raise ArgumentError, "expected #{arg.inspect}:#{arg.class} to respond to #shift" unless arg.respond_to?(:shift)
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(element, *value)
21
- execute :set_immediate_value, { id: element.ref }, generate_value_and_text(value)
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(element, *value)
25
- execute :replace_value, { id: element.ref }, generate_value_and_text(value)
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 error
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
- raise ArgumentError('log_event should be Hash like { vendor: "appium", event: "funEvent"}') unless log_event.is_a?(Hash)
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
- args[:element] = args[:element].ref if args.key? :element
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:' or 'desired_capabilities:' is also available instead of 'caps:'.
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
- # # 'desired_capabilities:' or 'capabilities:' is also available instead of 'caps:'. Either is fine.
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
- # desired_capabilities: {
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
- desired_capabilities: @caps,
374
- url: @custom_url)
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
- # FIXME: Remove 'desired_capabilities' in the next major Selenium update
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
- # FIXME: Remove 'desired_capabilities' in the next major Selenium update
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
- # @driver.immediate_value 'hello'
62
+ # element.immediate_value 'hello'
63
63
  #
64
64
  def immediate_value(*value)
65
- @bridge.set_immediate_value(self, *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
- # @driver.replace_value 'hello'
72
+ # element.replace_value 'hello'
73
73
  #
74
74
  def replace_value(*value)
75
- @bridge.replace_value(self, *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.take_element_screenshot(self)
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.take_element_screenshot(self)
126
+ bridge.element_screenshot @id
127
127
  when :png
128
- bridge.take_element_screenshot(self).unpack('m')[0]
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.beta2' unless defined? ::Appium::Core::VERSION
18
- DATE = '2021-04-13' unless defined? ::Appium::Core::DATE
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
@@ -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.beta2
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-04-13 00:00:00.000000000 Z
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.beta2
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.beta2
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.12.1
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.12.1
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.0
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.0
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.1.2
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: []