appium_lib 9.17.0 → 9.18.0
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/.rubocop.yml +2 -0
- data/.travis.yml +5 -5
- data/CHANGELOG.md +10 -0
- data/appium_lib.gemspec +2 -2
- data/docs/android_docs.md +447 -191
- data/docs/ios_docs.md +263 -251
- data/lib/appium_lib/android/element/button.rb +1 -3
- data/lib/appium_lib/android/espresso.rb +3 -1
- data/lib/appium_lib/android/espresso/bridge.rb +2 -0
- data/lib/appium_lib/android/espresso/element.rb +11 -0
- data/lib/appium_lib/android/espresso/element/button.rb +124 -0
- data/lib/appium_lib/android/espresso/element/generic.rb +61 -0
- data/lib/appium_lib/android/espresso/helper.rb +39 -0
- data/lib/appium_lib/driver.rb +23 -3
- data/lib/appium_lib/version.rb +2 -2
- data/release_notes.md +7 -0
- metadata +10 -6
|
@@ -14,6 +14,7 @@ module Appium
|
|
|
14
14
|
index = value
|
|
15
15
|
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
|
16
16
|
|
|
17
|
+
# 1 indexed
|
|
17
18
|
return find_element :uiautomator, _button_visible_selectors(index: index)
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -74,7 +75,6 @@ module Appium
|
|
|
74
75
|
elements.first
|
|
75
76
|
end
|
|
76
77
|
|
|
77
|
-
# @private
|
|
78
78
|
def _button_visible_selectors(opts = {})
|
|
79
79
|
button_index = opts.fetch :button_index, false
|
|
80
80
|
image_button_index = opts.fetch :image_button_index, false
|
|
@@ -88,14 +88,12 @@ module Appium
|
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
# @private
|
|
92
91
|
def _button_exact_string(value)
|
|
93
92
|
button = string_visible_exact Button, value
|
|
94
93
|
image_button = string_visible_exact ImageButton, value
|
|
95
94
|
button + image_button
|
|
96
95
|
end
|
|
97
96
|
|
|
98
|
-
# @private
|
|
99
97
|
def _button_contains_string(value)
|
|
100
98
|
button = string_visible_contains Button, value
|
|
101
99
|
image_button = string_visible_contains ImageButton, value
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
require_relative 'espresso/helper'
|
|
2
|
+
require_relative 'espresso/element'
|
|
1
3
|
require_relative 'espresso/bridge'
|
|
2
4
|
|
|
3
5
|
module Appium
|
|
4
6
|
module Android
|
|
5
7
|
module Espresso
|
|
6
8
|
# parent
|
|
7
|
-
end # module
|
|
9
|
+
end # module Espresso
|
|
8
10
|
end # module Android
|
|
9
11
|
end # module Appium
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
module Appium
|
|
2
|
+
module Android
|
|
3
|
+
module Espresso
|
|
4
|
+
module Element
|
|
5
|
+
# Find the first button that contains value or by index.
|
|
6
|
+
# @param value [String, Integer] the value to exactly match.
|
|
7
|
+
# If int then the button at that index is returned.
|
|
8
|
+
# @return [Button]
|
|
9
|
+
def button(value)
|
|
10
|
+
# Don't use ele_index because that only works on one element type.
|
|
11
|
+
# Android needs to combine button and image button to match iOS.
|
|
12
|
+
if value.is_a? Numeric
|
|
13
|
+
index = value
|
|
14
|
+
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
|
15
|
+
|
|
16
|
+
# zero index
|
|
17
|
+
_button_visible_selectors_xpath(index: index - 1)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
i = find_elements :xpath, _button_contains_string_xpath(Button, value)
|
|
21
|
+
e = find_elements :xpath, _button_contains_string_xpath(ImageButton, value)
|
|
22
|
+
|
|
23
|
+
raise_no_such_element_if_empty(i + e)
|
|
24
|
+
|
|
25
|
+
(i + e)[0]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Find all buttons containing value.
|
|
29
|
+
# If value is omitted, all buttons are returned.
|
|
30
|
+
# @param value [String] the value to search for
|
|
31
|
+
# @return [Array<Button>]
|
|
32
|
+
def buttons(value = false)
|
|
33
|
+
return _button_visible_selectors_xpath unless value
|
|
34
|
+
|
|
35
|
+
i = find_elements :xpath, _button_contains_string_xpath(Button, value)
|
|
36
|
+
e = find_elements :xpath, _button_contains_string_xpath(ImageButton, value)
|
|
37
|
+
i + e
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Find the first button.
|
|
41
|
+
# @return [Button]
|
|
42
|
+
def first_button
|
|
43
|
+
_button_visible_selectors_xpath(button_index: 0, image_button_index: 0)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Find the last button.
|
|
47
|
+
# @return [Button]
|
|
48
|
+
def last_button
|
|
49
|
+
# uiautomator index doesn't support last
|
|
50
|
+
# and it's 0 indexed
|
|
51
|
+
button_index = tags(::Appium::Android::Button).length
|
|
52
|
+
button_index -= 1 if button_index > 0
|
|
53
|
+
image_button_index = tags(::Appium::Android::ImageButton).length
|
|
54
|
+
image_button_index -= 1 if image_button_index > 0
|
|
55
|
+
|
|
56
|
+
_button_visible_selectors_xpath(button_index: button_index,
|
|
57
|
+
image_button_index: image_button_index)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Find the first button that exactly matches value.
|
|
61
|
+
# @param value [String] the value to match exactly
|
|
62
|
+
# @return [Button]
|
|
63
|
+
def button_exact(value)
|
|
64
|
+
i = find_elements :xpath, _button_exact_string_xpath(Button, value)
|
|
65
|
+
e = find_elements :xpath, _button_exact_string_xpath(ImageButton, value)
|
|
66
|
+
|
|
67
|
+
raise_no_such_element_if_empty(i + e)
|
|
68
|
+
|
|
69
|
+
(i + e)[0]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Find all buttons that exactly match value.
|
|
73
|
+
# @param value [String] the value to match exactly
|
|
74
|
+
# @return [Array<Button>]
|
|
75
|
+
def buttons_exact(value)
|
|
76
|
+
i = find_elements :xpath, _button_exact_string_xpath(Button, value)
|
|
77
|
+
e = find_elements :xpath, _button_exact_string_xpath(ImageButton, value)
|
|
78
|
+
i + e
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# @private
|
|
84
|
+
def raise_no_such_element_if_empty(elements)
|
|
85
|
+
raise _no_such_element if elements.empty?
|
|
86
|
+
|
|
87
|
+
elements.first
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def _button_visible_selectors_xpath(opts = {})
|
|
91
|
+
button_index = opts.fetch :button_index, false
|
|
92
|
+
image_button_index = opts.fetch :image_button_index, false
|
|
93
|
+
|
|
94
|
+
index = opts.fetch :index, false
|
|
95
|
+
|
|
96
|
+
b = find_elements :xpath, "//#{Button}"
|
|
97
|
+
i = find_elements :xpath, "//#{ImageButton}"
|
|
98
|
+
|
|
99
|
+
if index
|
|
100
|
+
raise_no_such_element_if_empty(b + i)
|
|
101
|
+
(b + i)[index]
|
|
102
|
+
elsif button_index && image_button_index
|
|
103
|
+
raise_no_such_element_if_empty(b + i)
|
|
104
|
+
b_index = button_index + image_button_index
|
|
105
|
+
(b + i)[b_index]
|
|
106
|
+
else
|
|
107
|
+
b + i
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def _button_exact_string_xpath(class_name, value)
|
|
112
|
+
r_id = resource_id(value, " or @resource-id='#{value}'")
|
|
113
|
+
"//#{class_name}[@text='#{value}' or @content-desc='#{value}'#{r_id}]"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def _button_contains_string_xpath(class_name, value)
|
|
117
|
+
r_id = resource_id(value, " or @resource-id='#{value}'")
|
|
118
|
+
"//#{class_name}[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
|
|
119
|
+
" or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')#{r_id}]"
|
|
120
|
+
end
|
|
121
|
+
end # module Element
|
|
122
|
+
end # module Espresso
|
|
123
|
+
end # module Android
|
|
124
|
+
end # module Appium
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Appium
|
|
2
|
+
module Android
|
|
3
|
+
module Espresso
|
|
4
|
+
module Element
|
|
5
|
+
# Scroll to the first element containing target text or description.
|
|
6
|
+
# Scroll happens upto 30 times in centre of device width.
|
|
7
|
+
# @param text [String] the text or resourceId to search for in the text value and content description
|
|
8
|
+
# @return [Element] the element scrolled to
|
|
9
|
+
def scroll_to(text)
|
|
10
|
+
err = nil
|
|
11
|
+
w_s = window_rect
|
|
12
|
+
|
|
13
|
+
(1..30).each do |_count|
|
|
14
|
+
begin
|
|
15
|
+
action
|
|
16
|
+
.move_to_location(w_s.width / 2, (w_s.height * 2) / 5) # pointer based magic number
|
|
17
|
+
.pointer_down(:left)
|
|
18
|
+
.move_to_location(0, w_s.height / 5)
|
|
19
|
+
.release
|
|
20
|
+
.perform
|
|
21
|
+
sleep 1 # we must wait finish scrolling
|
|
22
|
+
|
|
23
|
+
return text(text)
|
|
24
|
+
rescue StandardError => e
|
|
25
|
+
err = e
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
raise err
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Scroll to the first element with the exact target text or description.
|
|
33
|
+
# Scroll happens upto 30 times in centre of device width.
|
|
34
|
+
# @param text [String] the text or resourceId to search for in the text value and content description
|
|
35
|
+
# @return [Element] the element scrolled to
|
|
36
|
+
def scroll_to_exact(text)
|
|
37
|
+
err = nil
|
|
38
|
+
w_s = window_rect
|
|
39
|
+
|
|
40
|
+
(1..30).each do |_count|
|
|
41
|
+
begin
|
|
42
|
+
action
|
|
43
|
+
.move_to_location(w_s.width / 2, (w_s.height * 2) / 5) # pointer based magic number
|
|
44
|
+
.pointer_down(:left)
|
|
45
|
+
.move_to_location(0, w_s.height / 5)
|
|
46
|
+
.release
|
|
47
|
+
.perform
|
|
48
|
+
sleep 1 # we must wait finish scrolling
|
|
49
|
+
|
|
50
|
+
return text_exact(text)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
err = e
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
raise err
|
|
57
|
+
end
|
|
58
|
+
end # module Element
|
|
59
|
+
end # module Espresso
|
|
60
|
+
end # module Android
|
|
61
|
+
end # module Appium
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Appium
|
|
2
|
+
module Android
|
|
3
|
+
module Espresso
|
|
4
|
+
module Helper
|
|
5
|
+
# Find the first element that contains value
|
|
6
|
+
# @param class_name [String] the class name for the element
|
|
7
|
+
# @param value [String] the value to search for
|
|
8
|
+
# @return [Element]
|
|
9
|
+
def complex_find_contains(class_name, value)
|
|
10
|
+
find_element :xpath, string_visible_contains_xpath(class_name, value)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Find all elements containing value
|
|
14
|
+
# @param class_name [String] the class name for the element
|
|
15
|
+
# @param value [String] the value to search for
|
|
16
|
+
# @return [Array<Element>]
|
|
17
|
+
def complex_finds_contains(class_name, value)
|
|
18
|
+
find_elements :xpath, string_visible_contains_xpath(class_name, value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Find the first element exactly matching value
|
|
22
|
+
# @param class_name [String] the class name for the element
|
|
23
|
+
# @param value [String] the value to search for
|
|
24
|
+
# @return [Element]
|
|
25
|
+
def complex_find_exact(class_name, value)
|
|
26
|
+
find_element :xpath, string_visible_exact_xpath(class_name, value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Find all elements exactly matching value
|
|
30
|
+
# @param class_name [String] the class name for the element
|
|
31
|
+
# @param value [String] the value to search for
|
|
32
|
+
# @return [Element]
|
|
33
|
+
def complex_finds_exact(class_name, value)
|
|
34
|
+
find_elements :xpath, string_visible_exact_xpath(class_name, value)
|
|
35
|
+
end
|
|
36
|
+
end # module Helper
|
|
37
|
+
end # module Espresso
|
|
38
|
+
end # module Android
|
|
39
|
+
end # module Appium
|
data/lib/appium_lib/driver.rb
CHANGED
|
@@ -209,6 +209,8 @@ module Appium
|
|
|
209
209
|
case automation_name
|
|
210
210
|
when :uiautomator2
|
|
211
211
|
::Appium::Android::Uiautomator2::Bridge.for(self)
|
|
212
|
+
when :espresso
|
|
213
|
+
::Appium::Android::Espresso::Bridge.for(self)
|
|
212
214
|
else # default and UiAutomator
|
|
213
215
|
::Appium::Android::Bridge.for(self)
|
|
214
216
|
end
|
|
@@ -226,8 +228,11 @@ module Appium
|
|
|
226
228
|
# no windows specific extentions
|
|
227
229
|
Appium::Logger.debug('windows')
|
|
228
230
|
when :tizen
|
|
229
|
-
#
|
|
231
|
+
# https://github.com/Samsung/appium-tizen-driver
|
|
230
232
|
Appium::Logger.debug('tizen')
|
|
233
|
+
when :youiengine
|
|
234
|
+
# https://github.com/YOU-i-Labs/appium-youiengine-driver
|
|
235
|
+
Appium::Logger.debug('YouiEngine')
|
|
231
236
|
else
|
|
232
237
|
Appium::Logger.warn('no device matched')
|
|
233
238
|
end
|
|
@@ -334,12 +339,12 @@ module Appium
|
|
|
334
339
|
# element = find_element(:id, "some id")
|
|
335
340
|
# action.click(element).perform # The `click` is a part of `PointerActions`
|
|
336
341
|
#
|
|
337
|
-
def action
|
|
342
|
+
def action
|
|
338
343
|
if @driver.dialect != :w3c
|
|
339
344
|
::Appium::Logger.info('Calls TouchAction instead of W3C actions for MJSONWP module')
|
|
340
345
|
TouchAction.new($driver || @driver)
|
|
341
346
|
else
|
|
342
|
-
@driver.action
|
|
347
|
+
@driver.action
|
|
343
348
|
end
|
|
344
349
|
end
|
|
345
350
|
|
|
@@ -475,6 +480,21 @@ module Appium
|
|
|
475
480
|
@driver.window_size
|
|
476
481
|
end
|
|
477
482
|
|
|
483
|
+
# Get the device window's rect.
|
|
484
|
+
# @return [Selenium::WebDriver::Rectangle]
|
|
485
|
+
#
|
|
486
|
+
# @example
|
|
487
|
+
#
|
|
488
|
+
# size = @driver.window_size
|
|
489
|
+
# size.width #=> Integer
|
|
490
|
+
# size.height #=> Integer
|
|
491
|
+
# size.x #=> Integer
|
|
492
|
+
# size.y #=> Integer
|
|
493
|
+
#
|
|
494
|
+
def window_rect
|
|
495
|
+
@driver.window_rect
|
|
496
|
+
end
|
|
497
|
+
|
|
478
498
|
# Creates a new global driver and quits the old one if it exists.
|
|
479
499
|
# You can customise http_client as the following
|
|
480
500
|
#
|
data/lib/appium_lib/version.rb
CHANGED
|
@@ -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
|
-
DATE = '
|
|
3
|
+
VERSION = '9.18.0'.freeze unless defined? ::Appium::VERSION
|
|
4
|
+
DATE = '2019-01-13'.freeze unless defined? ::Appium::DATE
|
|
5
5
|
end
|
data/release_notes.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
#### v9.18.0 2019-01-13
|
|
2
|
+
|
|
3
|
+
- [32f3272](https://github.com/appium/ruby_lib/commit/32f327239055362ef630979d5975d0fac64d94c6) Release 9.18.0
|
|
4
|
+
- [e0f3683](https://github.com/appium/ruby_lib/commit/e0f36830edf0c33617efa50907c44b4ddc58702d) Enhance espresso adaptation for text, button, finds wrappers (#844)
|
|
5
|
+
- [fb49333](https://github.com/appium/ruby_lib/commit/fb49333c46a7b612920d05d2f9ebc51fd7bfdb20) Add ruby 260 (#843)
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
#### v9.17.0 2018-12-15
|
|
2
9
|
|
|
3
10
|
- [84f71e4](https://github.com/appium/ruby_lib/commit/84f71e47b86a2f7a1de71c13888adce68622a35b) Release 9.17.0
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appium_lib
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.
|
|
4
|
+
version: 9.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- code@bootstraponline.com
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2019-01-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: appium_lib_core
|
|
@@ -17,14 +17,14 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - "~>"
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: '2.
|
|
20
|
+
version: '2.3'
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - "~>"
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: '2.
|
|
27
|
+
version: '2.3'
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: nokogiri
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -155,14 +155,14 @@ dependencies:
|
|
|
155
155
|
requirements:
|
|
156
156
|
- - "~>"
|
|
157
157
|
- !ruby/object:Gem::Version
|
|
158
|
-
version: 0.
|
|
158
|
+
version: 0.61.0
|
|
159
159
|
type: :development
|
|
160
160
|
prerelease: false
|
|
161
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
162
162
|
requirements:
|
|
163
163
|
- - "~>"
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: 0.
|
|
165
|
+
version: 0.61.0
|
|
166
166
|
- !ruby/object:Gem::Dependency
|
|
167
167
|
name: spec
|
|
168
168
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -238,6 +238,10 @@ files:
|
|
|
238
238
|
- lib/appium_lib/android/element/textfield.rb
|
|
239
239
|
- lib/appium_lib/android/espresso.rb
|
|
240
240
|
- lib/appium_lib/android/espresso/bridge.rb
|
|
241
|
+
- lib/appium_lib/android/espresso/element.rb
|
|
242
|
+
- lib/appium_lib/android/espresso/element/button.rb
|
|
243
|
+
- lib/appium_lib/android/espresso/element/generic.rb
|
|
244
|
+
- lib/appium_lib/android/espresso/helper.rb
|
|
241
245
|
- lib/appium_lib/android/uiautomator2.rb
|
|
242
246
|
- lib/appium_lib/android/uiautomator2/bridge.rb
|
|
243
247
|
- lib/appium_lib/android/uiautomator2/element.rb
|