appium_lib_core 5.0.0.beta3 → 5.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d181fc3278538381590906e61508d9a2200e59f531ba60204e69a5703adc4c7
4
- data.tar.gz: a599869012ce5c6644686fe08faa3f56da739aad5f8c9d429495b4791a51c113
3
+ metadata.gz: 007f4811a4dfb2fa4592354eb4e736482436e72e155b51958156025fda15f0be
4
+ data.tar.gz: 2197f6bd36999883b43673da670e43032569bd2eb75860753d8e8a1b2461a467
5
5
  SHA512:
6
- metadata.gz: 3cde51ee7eba948cba06c82f6bb3e3d496fb8f7d68c0d9f92c9e76de86909df27bfe1ec312e7ed8e58225fcaa09b46b317977a530d431e24455d5e1cd349646a
7
- data.tar.gz: bbd2c4940a57a8e8e601fbe01d13d5d67bb42c5ca7ff36fde5ea94d7099784df4e3afe74a4cdf2400cb0d16d5e37b74971d88054b381498743cd04d6abeb99fe
6
+ metadata.gz: f586786cec414da935ae88599866a199c9350715a7cb71f41fb47dfe8f9eef8e4e81043349d0d5619662f53ea56279ec196a95f7594ab73ff8f8bcf0ffc30699
7
+ data.tar.gz: 792b6474ab0a6b5096c6cd20a467af3f2fe480bf3459fcdb2d8ae5791a4cbd5efdd50b369b9fe610fa032d49e77000f4628272f8f9bf1bc51fd5918d4e3be55c
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.beta3'
25
+ spec.add_runtime_dependency 'selenium-webdriver', '4.0.0.rc3'
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)
@@ -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
@@ -40,7 +40,7 @@ module Appium
40
40
 
41
41
  def initialize(appium_lib_opts)
42
42
  @custom_url = appium_lib_opts.fetch :server_url, nil
43
- @default_wait = appium_lib_opts.fetch :wait, Driver::DEFAULT_IMPLICIT_WAIT
43
+ @default_wait = appium_lib_opts.fetch :wait, nil
44
44
  @enable_idempotency_header = appium_lib_opts.fetch :enable_idempotency_header, true
45
45
 
46
46
  # bump current session id into a particular file
@@ -135,11 +135,9 @@ module Appium
135
135
  attr_reader :export_session_path
136
136
 
137
137
  # Default wait time for elements to appear in Appium server side.
138
- # Defaults to {::Appium::Core::Driver::DEFAULT_IMPLICIT_WAIT}.<br>
139
138
  # Provide <code>{ appium_lib: { wait: 30 } }</code> to {::Appium::Core.for}
140
139
  # @return [Integer]
141
140
  attr_reader :default_wait
142
- DEFAULT_IMPLICIT_WAIT = 0
143
141
 
144
142
  # Appium's server port. 4723 is by default. Defaults to {::Appium::Core::Driver::DEFAULT_APPIUM_PORT}.<br>
145
143
  # Provide <code>{ appium_lib: { port: 8080 } }</code> to {::Appium::Core.for}.
@@ -187,8 +185,6 @@ module Appium
187
185
  # @option opts [Hash] :caps Appium capabilities.
188
186
  # @option opts [Hash] :capabilities The same as :caps.
189
187
  # 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
188
  # @option opts [Appium::Core::Options] :appium_lib Capabilities affect only ruby client
193
189
  # @option opts [String] :url The same as :custom_url in :appium_lib.
194
190
  # This param is for compatibility with Selenium WebDriver format
@@ -199,10 +195,8 @@ module Appium
199
195
  #
200
196
  # # format 1
201
197
  # @core = Appium::Core.for caps: {...}, appium_lib: {...}
202
- # # format 2. 'capabilities:' or 'desired_capabilities:' is also available instead of 'caps:'.
198
+ # # format 2. 'capabilities:' is also available instead of 'caps:'.
203
199
  # @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
200
  #
207
201
  #
208
202
  # require 'rubygems'
@@ -230,7 +224,7 @@ module Appium
230
224
  # @core.start_driver # Connect to 'http://127.0.0.1:8080/wd/hub' because of 'port: 8080'
231
225
  #
232
226
  # # Start iOS driver with .zip file over HTTP
233
- # # 'desired_capabilities:' or 'capabilities:' is also available instead of 'caps:'. Either is fine.
227
+ # # 'capabilities:' is also available instead of 'caps:'. Either is fine.
234
228
  # opts = {
235
229
  # capabilities: {
236
230
  # platformName: :ios,
@@ -254,7 +248,7 @@ module Appium
254
248
  # # Start iOS driver as another format. 'url' is available like below
255
249
  # opts = {
256
250
  # url: "http://custom-host:8080/wd/hub.com",
257
- # desired_capabilities: {
251
+ # capabilities: {
258
252
  # platformName: :ios,
259
253
  # platformVersion: '11.0',
260
254
  # deviceName: 'iPhone Simulator',
@@ -367,11 +361,10 @@ module Appium
367
361
  end
368
362
 
369
363
  begin
370
- # included https://github.com/SeleniumHQ/selenium/blob/43f8b3f66e7e01124eff6a5805269ee441f65707/rb/lib/selenium/webdriver/remote/driver.rb#L29
371
364
  @driver = ::Appium::Core::Base::Driver.new(listener: @listener,
372
365
  http_client: @http_client,
373
- desired_capabilities: @caps,
374
- url: @custom_url)
366
+ capabilities: @caps, # ::Selenium::WebDriver::Remote::Capabilities
367
+ url: @custom_url)
375
368
 
376
369
  if @direct_connect
377
370
  d_c = DirectConnections.new(@driver.capabilities)
@@ -412,6 +405,8 @@ module Appium
412
405
 
413
406
  # Ignore setting default wait if the target driver has no implementation
414
407
  def set_implicit_wait_by_default(wait)
408
+ return if @default_wait.nil?
409
+
415
410
  @driver.manage.timeouts.implicit_wait = wait
416
411
  rescue ::Selenium::WebDriver::Error::UnknownError => e
417
412
  unless e.message.include?('The operation requested is not yet implemented')
@@ -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.beta3' unless defined? ::Appium::Core::VERSION
18
- DATE = '2021-04-15' unless defined? ::Appium::Core::DATE
17
+ VERSION = '5.0.0.rc3' unless defined? ::Appium::Core::VERSION
18
+ DATE = '2021-10-10' 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.beta3
4
+ version: 5.0.0.rc3
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-15 00:00:00.000000000 Z
11
+ date: 2021-10-11 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.beta3
19
+ version: 4.0.0.rc3
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.beta3
26
+ version: 4.0.0.rc3
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: []