appium_lib 9.4.7 → 9.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/docs/android_docs.md +264 -229
- data/docs/ios_docs.md +294 -264
- data/lib/appium_lib/android/client_xpath.rb +4 -0
- data/lib/appium_lib/common/command.rb +1 -0
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/common/wait.rb +53 -40
- data/lib/appium_lib/device/device.rb +24 -4
- data/lib/appium_lib/ios/helper.rb +19 -27
- data/release_notes.md +7 -0
- metadata +2 -2
|
@@ -33,11 +33,15 @@ module Appium
|
|
|
33
33
|
_nodeset_to_uiselector nodes: nodes, first: first
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# @deprecated Please use :uiautomator or :xpath strategy directly
|
|
36
37
|
def client_xpath(xpath)
|
|
38
|
+
warn '[DEPRECATION] client_xpath will be removed. Please use :uiautomator or :xpath strategy directly.'
|
|
37
39
|
find_element :uiautomator, _client_xpath(xpath: xpath, first: true)
|
|
38
40
|
end
|
|
39
41
|
|
|
42
|
+
# @deprecated Please use :uiautomator or :xpath strategy directly
|
|
40
43
|
def client_xpaths(xpath)
|
|
44
|
+
warn '[DEPRECATION] client_xpaths will be removed. Please use :uiautomator or :xpath strategy directly.'
|
|
41
45
|
find_elements :uiautomator, _client_xpath(xpath: xpath, first: false)
|
|
42
46
|
end
|
|
43
47
|
end
|
|
@@ -13,6 +13,7 @@ module Appium
|
|
|
13
13
|
open_notifications: [:post, 'session/:session_id/appium/device/open_notifications'.freeze],
|
|
14
14
|
toggle_airplane_mode: [:post, 'session/:session_id/appium/device/toggle_airplane_mode'.freeze],
|
|
15
15
|
current_activity: [:get, 'session/:session_id/appium/device/current_activity'.freeze],
|
|
16
|
+
current_package: [:get, 'session/:session_id/appium/device/current_package'.freeze],
|
|
16
17
|
get_system_bars: [:get, 'session/:session_id/appium/device/system_bars'.freeze],
|
|
17
18
|
get_display_density: [:get, 'session/:session_id/appium/device/display_density'.freeze],
|
|
18
19
|
is_keyboard_shown: [:get, 'session/:session_id/appium/device/is_keyboard_shown'.freeze],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Appium
|
|
2
2
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
|
3
|
-
VERSION = '9.4.
|
|
4
|
-
DATE = '2017-06-
|
|
3
|
+
VERSION = '9.4.8'.freeze unless defined? ::Appium::VERSION
|
|
4
|
+
DATE = '2017-06-24'.freeze unless defined? ::Appium::DATE
|
|
5
5
|
end
|
|
@@ -1,47 +1,50 @@
|
|
|
1
1
|
module Appium
|
|
2
2
|
module Common
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
class Wait < ::Selenium::WebDriver::Wait
|
|
4
|
+
def initialize(opts = {})
|
|
5
|
+
valid_keys = [:timeout, :interval, :message, :ignore, :return_if_true]
|
|
6
|
+
invalid_keys = []
|
|
7
|
+
opts.keys.each { |key| invalid_keys << key unless valid_keys.include?(key) }
|
|
8
|
+
# [:one, :two] => :one, :two
|
|
9
|
+
raise "Invalid keys #{invalid_keys.to_s[1..-2]}. Valid keys are #{valid_keys.to_s[1..-2]}" unless invalid_keys.empty?
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
opts.keys.each { |key| invalid_keys << key unless valid_keys.include?(key) }
|
|
13
|
-
# [:one, :two] => :one, :two
|
|
14
|
-
raise "Invalid keys #{invalid_keys.to_s[1..-2]}. Valid keys are #{valid_keys.to_s[1..-2]}" unless invalid_keys.empty?
|
|
15
|
-
|
|
16
|
-
timeout = opts.fetch(:timeout, @appium_wait_timeout)
|
|
17
|
-
interval = opts.fetch(:interval, @appium_wait_interval)
|
|
18
|
-
message = opts[:message]
|
|
19
|
-
ignored = Array(opts[:ignore] || ::Exception)
|
|
20
|
-
return_if_true = opts[:return_if_true]
|
|
21
|
-
|
|
22
|
-
end_time = Time.now + timeout
|
|
23
|
-
last_error = nil
|
|
24
|
-
|
|
25
|
-
until Time.now > end_time
|
|
26
|
-
begin
|
|
27
|
-
return yield unless return_if_true
|
|
28
|
-
|
|
29
|
-
result = yield
|
|
30
|
-
return result if result
|
|
31
|
-
rescue ::Errno::ECONNREFUSED => e
|
|
32
|
-
raise e
|
|
33
|
-
rescue *ignored => last_error # rubocop:disable Lint/HandleExceptions
|
|
34
|
-
# swallowed
|
|
35
|
-
end
|
|
11
|
+
@timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
|
|
12
|
+
@interval = opts.fetch(:interval, DEFAULT_INTERVAL)
|
|
13
|
+
@message = opts[:message]
|
|
14
|
+
@ignored = Array(opts[:ignore] || ::Exception)
|
|
15
|
+
@return_if_true = opts[:return_if_true]
|
|
36
16
|
|
|
37
|
-
|
|
17
|
+
super(timeout: @timeout, interval: @interval, message: @message, ignore: @ignored)
|
|
38
18
|
end
|
|
39
19
|
|
|
40
|
-
|
|
20
|
+
# Wait code from the selenium Ruby gem
|
|
21
|
+
# https://github.com/SeleniumHQ/selenium/blob/cf501dda3f0ed12233de51ce8170c0e8090f0c20/rb/lib/selenium/webdriver/common/wait.rb
|
|
22
|
+
# @override
|
|
23
|
+
def until
|
|
24
|
+
end_time = Time.now + @timeout
|
|
25
|
+
last_error = nil
|
|
26
|
+
|
|
27
|
+
until Time.now > end_time
|
|
28
|
+
begin
|
|
29
|
+
return yield unless @return_if_true
|
|
30
|
+
|
|
31
|
+
result = yield
|
|
32
|
+
return result if result
|
|
33
|
+
rescue ::Errno::ECONNREFUSED => e
|
|
34
|
+
raise e
|
|
35
|
+
rescue *@ignored => last_error # rubocop:disable Lint/HandleExceptions
|
|
36
|
+
# swallowed
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
sleep @interval
|
|
40
|
+
end
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
msg = @message ? @message.dup : "timed out after #{@timeout} seconds"
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
msg << " (#{last_error.message})" if last_error
|
|
45
|
+
|
|
46
|
+
raise Selenium::WebDriver::Error::TimeOutError, msg
|
|
47
|
+
end
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
# process opts before calling _generic_wait
|
|
@@ -66,9 +69,14 @@ module Appium
|
|
|
66
69
|
# @option opts [Numeric] :interval Seconds to sleep between polls. Set default by `appium_wait_interval` (0.5).
|
|
67
70
|
# @option opts [String] :message Exception message if timed out.
|
|
68
71
|
# @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Exception)
|
|
69
|
-
def wait_true(opts = {}
|
|
72
|
+
def wait_true(opts = {})
|
|
70
73
|
opts = _process_wait_opts(opts).merge(return_if_true: true)
|
|
71
|
-
|
|
74
|
+
|
|
75
|
+
opts[:timeout] ||= @appium_wait_timeout
|
|
76
|
+
opts[:interval] ||= @appium_wait_interval
|
|
77
|
+
|
|
78
|
+
wait = ::Appium::Common::Wait.new opts
|
|
79
|
+
wait.until { yield }
|
|
72
80
|
end
|
|
73
81
|
|
|
74
82
|
# Check every interval seconds to see if yield doesn't raise an exception.
|
|
@@ -84,9 +92,14 @@ module Appium
|
|
|
84
92
|
# @option opts [Numeric] :interval Seconds to sleep between polls. Set default by `appium_wait_interval` (0.5).
|
|
85
93
|
# @option opts [String] :message Exception message if timed out.
|
|
86
94
|
# @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Exception)
|
|
87
|
-
def wait(opts = {}
|
|
95
|
+
def wait(opts = {})
|
|
88
96
|
opts = _process_wait_opts(opts).merge(return_if_true: false)
|
|
89
|
-
|
|
97
|
+
|
|
98
|
+
opts[:timeout] ||= @appium_wait_timeout
|
|
99
|
+
opts[:interval] ||= @appium_wait_interval
|
|
100
|
+
|
|
101
|
+
wait = ::Appium::Common::Wait.new opts
|
|
102
|
+
wait.until { yield }
|
|
90
103
|
end
|
|
91
104
|
end # module Common
|
|
92
105
|
end # module Appium
|
|
@@ -22,6 +22,20 @@ module Appium
|
|
|
22
22
|
# ```
|
|
23
23
|
|
|
24
24
|
# @!method current_activity
|
|
25
|
+
# Get current activity name
|
|
26
|
+
# @return [String] An activity name
|
|
27
|
+
#
|
|
28
|
+
# ```ruby
|
|
29
|
+
# current_activity # '.ApiDemos'
|
|
30
|
+
# ```
|
|
31
|
+
|
|
32
|
+
# @!method current_package
|
|
33
|
+
# Get current package name
|
|
34
|
+
# @return [String] A package name
|
|
35
|
+
#
|
|
36
|
+
# ```ruby
|
|
37
|
+
# current_package # 'com.example.android.apis'
|
|
38
|
+
# ```
|
|
25
39
|
|
|
26
40
|
# @!method get_system_bars
|
|
27
41
|
# Get system bar's information
|
|
@@ -583,14 +597,20 @@ module Appium
|
|
|
583
597
|
# @param context (String) The context to switch to for the duration of the block.
|
|
584
598
|
#
|
|
585
599
|
# ```ruby
|
|
586
|
-
# within_context('NATIVE_APP') do
|
|
587
|
-
# find_element
|
|
600
|
+
# result = within_context('NATIVE_APP') do
|
|
601
|
+
# find_element :tag, "button"
|
|
602
|
+
# end # The result of `find_element :tag, "button"`
|
|
588
603
|
# ```
|
|
589
604
|
def within_context(context)
|
|
590
605
|
existing_context = current_context
|
|
591
606
|
set_context context
|
|
592
|
-
|
|
593
|
-
|
|
607
|
+
if block_given?
|
|
608
|
+
result = yield
|
|
609
|
+
set_context existing_context
|
|
610
|
+
result
|
|
611
|
+
else
|
|
612
|
+
set_context existing_context
|
|
613
|
+
end
|
|
594
614
|
end
|
|
595
615
|
|
|
596
616
|
# Change to the default context. This is equivalent to `set_context nil`.
|
|
@@ -6,31 +6,32 @@ module Appium
|
|
|
6
6
|
def start_element(type, attrs = [])
|
|
7
7
|
return if filter && !filter.eql?(type)
|
|
8
8
|
page = attrs.inject({}) do |hash, attr|
|
|
9
|
-
hash[attr[0]] = attr[1] if %w(name label value hint).include?(attr[0])
|
|
9
|
+
hash[attr[0]] = attr[1] if %w(name label value hint visible).include?(attr[0])
|
|
10
10
|
hash
|
|
11
11
|
end
|
|
12
|
-
_print_attr(type, page['name'], page['label'], page['value'], page['hint'])
|
|
12
|
+
_print_attr(type, page['name'], page['label'], page['value'], page['hint'], page['visible'])
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def _print_attr(type, name, label, value, hint)
|
|
15
|
+
def _print_attr(type, name, label, value, hint, visible) # rubocop:disable Metrics/ParameterLists
|
|
16
16
|
if name == label && name == value
|
|
17
|
-
puts type.to_s if name || label || value || hint
|
|
17
|
+
puts type.to_s if name || label || value || hint || visible
|
|
18
18
|
puts " name, label, value: #{name}" if name
|
|
19
19
|
elsif name == label
|
|
20
|
-
puts type.to_s if name || label || value || hint
|
|
20
|
+
puts type.to_s if name || label || value || hint || visible
|
|
21
21
|
puts " name, label: #{name}" if name
|
|
22
22
|
puts " value: #{value}" if value
|
|
23
23
|
elsif name == value
|
|
24
|
-
puts type.to_s if name || label || value || hint
|
|
24
|
+
puts type.to_s if name || label || value || hint || visible
|
|
25
25
|
puts " name, value: #{name}" if name
|
|
26
26
|
puts " label: #{label}" if label
|
|
27
27
|
else
|
|
28
|
-
puts type.to_s if name || label || value || hint
|
|
28
|
+
puts type.to_s if name || label || value || hint || visible
|
|
29
29
|
puts " name: #{name}" if name
|
|
30
30
|
puts " label: #{label}" if label
|
|
31
31
|
puts " value: #{value}" if value
|
|
32
32
|
end
|
|
33
33
|
puts " hint: #{hint}" if hint
|
|
34
|
+
puts " visible: #{visible}" if visible
|
|
34
35
|
end
|
|
35
36
|
end
|
|
36
37
|
# iOS only. On Android uiautomator always returns an empty string for EditText password.
|
|
@@ -50,7 +51,10 @@ module Appium
|
|
|
50
51
|
# @option element [Object] the element to search. omit to search everything
|
|
51
52
|
# @option class_name [String,Symbol] the class name to filter on. case insensitive include match.
|
|
52
53
|
# @return [String]
|
|
54
|
+
# @deprecated
|
|
53
55
|
def get_page(element = source_window(0), class_name = nil)
|
|
56
|
+
warn '[DEPRECATION] get_page will be removed. Please use page or source instead.'
|
|
57
|
+
|
|
54
58
|
lazy_load_strings # populate @strings_xml
|
|
55
59
|
class_name = class_name.to_s.downcase
|
|
56
60
|
|
|
@@ -85,10 +89,10 @@ module Appium
|
|
|
85
89
|
type = fix_space element['type']
|
|
86
90
|
|
|
87
91
|
# if class_name is set, mark non-matches as invisible
|
|
88
|
-
visible = (type.downcase.include?
|
|
92
|
+
visible = (type.downcase.include? class_name).to_s if class_name
|
|
89
93
|
if visible && visible == 'true'
|
|
90
94
|
|
|
91
|
-
_print_attr(type, name, label, value, hint)
|
|
95
|
+
_print_attr(type, name, label, value, hint, visible)
|
|
92
96
|
|
|
93
97
|
# there may be many ids with the same value.
|
|
94
98
|
# output all exact matches.
|
|
@@ -128,22 +132,16 @@ module Appium
|
|
|
128
132
|
#
|
|
129
133
|
# ```ruby
|
|
130
134
|
# page class: :UIAButton # filter on buttons
|
|
131
|
-
# page window: 1 # show source for window 1
|
|
132
135
|
# page class: :UIAButton, window: 1
|
|
133
136
|
# ```
|
|
134
137
|
#
|
|
135
|
-
# @option
|
|
138
|
+
# @option visible [Symbol] visible value to filter on
|
|
136
139
|
# @option class [Symbol] class name to filter on
|
|
137
140
|
#
|
|
138
141
|
# @return [void]
|
|
139
142
|
def page(opts = {})
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
class_name = opts.fetch :class, nil
|
|
143
|
-
else
|
|
144
|
-
window_number = -1
|
|
145
|
-
class_name = opts
|
|
146
|
-
end
|
|
143
|
+
class_name = opts.is_a?(Hash) ? opts.fetch(:class, nil) : opts
|
|
144
|
+
|
|
147
145
|
# current_context may be nil which breaks start_with
|
|
148
146
|
if current_context && current_context.start_with?('WEBVIEW')
|
|
149
147
|
s = get_source
|
|
@@ -153,8 +151,7 @@ module Appium
|
|
|
153
151
|
parser.parse s
|
|
154
152
|
parser.document.result
|
|
155
153
|
else
|
|
156
|
-
|
|
157
|
-
s = source_window(window_number || 0)
|
|
154
|
+
s = source_window
|
|
158
155
|
parser = Nokogiri::XML::SAX::Parser.new(UITestElementsPrinter.new)
|
|
159
156
|
if class_name
|
|
160
157
|
parser.document.filter = class_name.is_a?(Symbol) ? class_name.to_s : class_name
|
|
@@ -165,14 +162,9 @@ module Appium
|
|
|
165
162
|
end
|
|
166
163
|
|
|
167
164
|
# Gets the JSON source of window number
|
|
168
|
-
# @param [Integer] _window_number The int index of the target window
|
|
169
165
|
# @return [JSON]
|
|
170
|
-
def source_window(
|
|
171
|
-
|
|
172
|
-
# appium 1.0 still returns JSON when getTree() is invoked so this
|
|
173
|
-
# doesn't need to change to XML. If getTree() is removed then
|
|
174
|
-
# source_window will need to parse the elements of getTreeForXML()\
|
|
175
|
-
# https://github.com/appium/appium-uiauto/blob/247eb71383fa1a087ff8f8fc96fac25025731f3f/uiauto/appium/element.js#L145
|
|
166
|
+
def source_window(window_number = nil)
|
|
167
|
+
warn '[DEPRECATION] The argument window_number will be removed. Plesse remove window_number' unless window_number
|
|
176
168
|
get_source
|
|
177
169
|
end
|
|
178
170
|
|
data/release_notes.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
#### v9.4.7 2017-06-11
|
|
2
|
+
|
|
3
|
+
- [ef9efbd](https://github.com/appium/ruby_lib/commit/ef9efbd6d3fadfaebaa4245bed40d28aec33be32) [Release 9 4 7 (#601)](https://github.com/appium/ruby_lib/issues/601)
|
|
4
|
+
- [29f031a](https://github.com/appium/ruby_lib/commit/29f031a0b8d180289cfd8a9de4216300916cd5cc) [Ignore server version check for grid (#600)](https://github.com/appium/ruby_lib/issues/600)
|
|
5
|
+
- [1b7a4b4](https://github.com/appium/ruby_lib/commit/1b7a4b45074761141d25b1461d0c23672889905d) [Update CHANGELOG.md (#597)](https://github.com/appium/ruby_lib/issues/597)
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
#### v9.4.6 2017-05-25
|
|
2
9
|
|
|
3
10
|
- [a44ea77](https://github.com/appium/ruby_lib/commit/a44ea770287407ba9b488e25e259884676c89709) [Release 9 4 6 (#593)](https://github.com/appium/ruby_lib/issues/593)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appium_lib
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.4.
|
|
4
|
+
version: 9.4.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- code@bootstraponline.com
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-06-
|
|
11
|
+
date: 2017-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: selenium-webdriver
|