appium_lib 0.24.1 → 1.0.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/Rakefile +17 -8
- data/android_tests/Gemfile +1 -0
- data/android_tests/LICENSE-2.0.txt +202 -0
- data/android_tests/Rakefile +61 -0
- data/android_tests/api.apk +0 -0
- data/android_tests/appium.txt +3 -0
- data/android_tests/flaky.txt +1 -0
- data/android_tests/lib/android/specs/android/dynamic.rb +5 -0
- data/android_tests/lib/android/specs/android/element/alert.rb +41 -0
- data/android_tests/lib/android/specs/android/element/button.rb +55 -0
- data/android_tests/lib/android/specs/android/element/generic.rb +48 -0
- data/android_tests/lib/android/specs/android/element/text.rb +39 -0
- data/android_tests/lib/android/specs/android/element/textfield.rb +60 -0
- data/android_tests/lib/android/specs/android/helper.rb +80 -0
- data/android_tests/lib/android/specs/android/patch.rb +14 -0
- data/android_tests/lib/android/specs/common/device.rb +117 -0
- data/android_tests/lib/android/specs/common/element/window.rb +9 -0
- data/android_tests/lib/android/specs/common/helper.rb +112 -0
- data/android_tests/lib/android/specs/common/patch.rb +69 -0
- data/android_tests/lib/android/specs/common/version.rb +9 -0
- data/android_tests/lib/android/specs/driver.rb +174 -0
- data/android_tests/lib/format.rb +49 -0
- data/android_tests/lib/run.rb +72 -0
- data/android_tests/readme.md +27 -0
- data/appium_lib.gemspec +8 -5
- data/docs/android_docs.md +1052 -716
- data/docs/ios_docs.md +657 -834
- data/docs_gen/make_docs.rb +1 -3
- data/ios_tests/Gemfile +1 -0
- data/ios_tests/LICENSE-2.0.txt +202 -0
- data/ios_tests/Rakefile +47 -0
- data/ios_tests/UICatalog.app.zip +0 -0
- data/ios_tests/UICatalog.app/12-6AM.png +0 -0
- data/ios_tests/UICatalog.app/12-6PM.png +0 -0
- data/ios_tests/UICatalog.app/6-12AM.png +0 -0
- data/ios_tests/UICatalog.app/6-12PM.png +0 -0
- data/ios_tests/UICatalog.app/Default-568h@2x.png +0 -0
- data/ios_tests/UICatalog.app/Default@2x.png +0 -0
- data/ios_tests/UICatalog.app/Info.plist +0 -0
- data/ios_tests/UICatalog.app/PkgInfo +1 -0
- data/ios_tests/UICatalog.app/UIButton_custom.png +0 -0
- data/ios_tests/UICatalog.app/UICatalog +0 -0
- data/ios_tests/UICatalog.app/blueButton.png +0 -0
- data/ios_tests/UICatalog.app/bookmarkImage.png +0 -0
- data/ios_tests/UICatalog.app/bookmarkImageHighlighted.png +0 -0
- data/ios_tests/UICatalog.app/divider.png +0 -0
- data/ios_tests/UICatalog.app/en.lproj/AlertsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ButtonsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ControlsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ImagesViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/Localizable.strings +0 -0
- data/ios_tests/UICatalog.app/en.lproj/MainWindow.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/PickerViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/SearchBarController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/SegmentViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TextFieldController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TextViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ToolbarViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TransitionViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/WebViewController.nib +0 -0
- data/ios_tests/UICatalog.app/orangeslide.png +0 -0
- data/ios_tests/UICatalog.app/scene1.jpg +0 -0
- data/ios_tests/UICatalog.app/scene2.jpg +0 -0
- data/ios_tests/UICatalog.app/scene3.jpg +0 -0
- data/ios_tests/UICatalog.app/scene4.jpg +0 -0
- data/ios_tests/UICatalog.app/scene5.jpg +0 -0
- data/ios_tests/UICatalog.app/searchBarBackground.png +0 -0
- data/ios_tests/UICatalog.app/segment_check.png +0 -0
- data/ios_tests/UICatalog.app/segment_search.png +0 -0
- data/ios_tests/UICatalog.app/segment_tools.png +0 -0
- data/ios_tests/UICatalog.app/segmentedBackground.png +0 -0
- data/ios_tests/UICatalog.app/slider_ball.png +0 -0
- data/ios_tests/UICatalog.app/toolbarBackground.png +0 -0
- data/ios_tests/UICatalog.app/whiteButton.png +0 -0
- data/ios_tests/UICatalog.app/yellowslide.png +0 -0
- data/ios_tests/appium.txt +3 -0
- data/ios_tests/flaky.txt +1 -0
- data/ios_tests/lib/format.rb +25 -0
- data/ios_tests/lib/ios/specs/common/element/window.rb +15 -0
- data/ios_tests/lib/ios/specs/common/helper.rb +204 -0
- data/ios_tests/lib/ios/specs/common/patch.rb +50 -0
- data/ios_tests/lib/ios/specs/common/version.rb +17 -0
- data/ios_tests/lib/ios/specs/device/device.rb +82 -0
- data/ios_tests/lib/ios/specs/device/multi_touch.rb +12 -0
- data/ios_tests/lib/ios/specs/device/touch_actions.rb +15 -0
- data/ios_tests/lib/ios/specs/driver.rb +203 -0
- data/ios_tests/lib/ios/specs/ios/element/alert.rb +48 -0
- data/ios_tests/lib/ios/specs/ios/element/button.rb +58 -0
- data/ios_tests/lib/ios/specs/ios/element/generic.rb +35 -0
- data/ios_tests/lib/ios/specs/ios/element/text.rb +54 -0
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +123 -0
- data/ios_tests/lib/ios/specs/ios/helper.rb +27 -0
- data/ios_tests/lib/ios/specs/ios/patch.rb +30 -0
- data/ios_tests/lib/run.rb +106 -0
- data/ios_tests/readme.md +30 -0
- data/ios_tests/upload/sauce_storage.rb +64 -0
- data/ios_tests/upload/upload.rb +6 -0
- data/lib/appium_lib.rb +4 -14
- data/lib/appium_lib/android/dynamic.rb +30 -32
- data/lib/appium_lib/android/element/alert.rb +34 -33
- data/lib/appium_lib/android/element/button.rb +91 -0
- data/lib/appium_lib/android/element/generic.rb +51 -146
- data/lib/appium_lib/android/element/text.rb +54 -0
- data/lib/appium_lib/android/element/textfield.rb +46 -41
- data/lib/appium_lib/android/helper.rb +248 -417
- data/lib/appium_lib/android/mobile_methods.rb +17 -0
- data/lib/appium_lib/android/patch.rb +9 -8
- data/lib/appium_lib/awesome_print/ostruct.rb +33 -0
- data/lib/appium_lib/common/element/window.rb +9 -8
- data/lib/appium_lib/common/helper.rb +182 -243
- data/lib/appium_lib/common/patch.rb +65 -79
- data/lib/appium_lib/common/version.rb +2 -3
- data/lib/appium_lib/device/device.rb +339 -0
- data/lib/appium_lib/device/multi_touch.rb +94 -0
- data/lib/appium_lib/device/touch_actions.rb +142 -0
- data/lib/appium_lib/driver.rb +217 -306
- data/lib/appium_lib/ios/element/alert.rb +16 -92
- data/lib/appium_lib/ios/element/button.rb +55 -0
- data/lib/appium_lib/ios/element/generic.rb +27 -160
- data/lib/appium_lib/ios/element/text.rb +54 -0
- data/lib/appium_lib/ios/element/textfield.rb +78 -65
- data/lib/appium_lib/ios/helper.rb +300 -190
- data/lib/appium_lib/ios/mobile_methods.rb +17 -0
- data/lib/appium_lib/ios/patch.rb +55 -41
- data/lib/appium_lib/logger.rb +13 -0
- data/lib/appium_lib/rails/duplicable.rb +116 -0
- data/readme.md +6 -1
- data/release_notes.md +118 -0
- metadata +170 -12
- data/lib/appium_lib/common/element/button.rb +0 -83
- data/lib/appium_lib/common/element/text.rb +0 -61
data/lib/appium_lib.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
require 'Forwardable' unless defined? Forwardable
|
|
2
|
+
require_relative 'appium_lib/rails/duplicable'
|
|
2
3
|
|
|
3
4
|
$driver = nil
|
|
4
5
|
|
|
@@ -19,16 +20,5 @@ def self.method_missing method, *args, &block
|
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def self.add_to_path file, path=false
|
|
25
|
-
path = path ? "../#{path}/" : '..'
|
|
26
|
-
path = File.expand_path path, file
|
|
27
|
-
|
|
28
|
-
$:.unshift path unless $:.include? path
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
add_to_path __FILE__
|
|
32
|
-
|
|
33
|
-
require_relative 'appium_lib/driver'
|
|
34
|
-
end
|
|
23
|
+
require_relative 'appium_lib/logger'
|
|
24
|
+
require_relative 'appium_lib/driver'
|
|
@@ -1,45 +1,43 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
1
|
module Appium
|
|
4
2
|
class Driver
|
|
5
3
|
@@map = {
|
|
6
|
-
1
|
|
7
|
-
2
|
|
8
|
-
3
|
|
9
|
-
4
|
|
10
|
-
5
|
|
11
|
-
6
|
|
12
|
-
7
|
|
13
|
-
8
|
|
14
|
-
9
|
|
15
|
-
10
|
|
16
|
-
11
|
|
17
|
-
12
|
|
18
|
-
13
|
|
19
|
-
14
|
|
20
|
-
15
|
|
21
|
-
16
|
|
4
|
+
1 => ['text(String text)', 'SELECTOR_TEXT', 1],
|
|
5
|
+
2 => ['textStartsWith(String text)', 'SELECTOR_START_TEXT', 2],
|
|
6
|
+
3 => ['textContains(String text)', 'SELECTOR_CONTAINS_TEXT', 3],
|
|
7
|
+
4 => ['className(String className)', 'SELECTOR_CLASS', 4],
|
|
8
|
+
5 => ['description(String desc)', 'SELECTOR_DESCRIPTION', 5],
|
|
9
|
+
6 => ['descriptionStartsWith(String desc)', 'SELECTOR_START_DESCRIPTION', 6],
|
|
10
|
+
7 => ['descriptionContains(String desc)', 'SELECTOR_CONTAINS_DESCRIPTION', 7],
|
|
11
|
+
8 => ['index(final int index)', 'SELECTOR_INDEX', 8],
|
|
12
|
+
9 => ['instance(final int instance)', 'SELECTOR_INSTANCE', 9],
|
|
13
|
+
10 => ['enabled(boolean val)', 'SELECTOR_ENABLED', 10],
|
|
14
|
+
11 => ['focused(boolean val)', 'SELECTOR_FOCUSED', 11],
|
|
15
|
+
12 => ['focusable(boolean val)', 'SELECTOR_FOCUSABLE', 12],
|
|
16
|
+
13 => ['scrollable(boolean val)', 'SELECTOR_SCROLLABLE', 13],
|
|
17
|
+
14 => ['clickable(boolean val)', 'SELECTOR_CLICKABLE', 14],
|
|
18
|
+
15 => ['checked(boolean val)', 'SELECTOR_CHECKED', 15],
|
|
19
|
+
16 => ['selected(boolean val)', 'SELECTOR_SELECTED', 16],
|
|
22
20
|
# // SELECTOR_ID = 17; // nothing.
|
|
23
|
-
18
|
|
21
|
+
18 => ['packageName(String name)', 'SELECTOR_PACKAGE_NAME', 18],
|
|
24
22
|
# // SELECTOR_CHILD = 19; // childSelector(UiSelector selector)
|
|
25
23
|
# // SELECTOR_CONTAINER = 20; // containerSelector(UiSelector selector)
|
|
26
24
|
# // SELECTOR_PATTERN = 21; // ! private ! patternSelector(UiSelector selector)
|
|
27
25
|
# // SELECTOR_PARENT = 22; // fromParent(UiSelector selector)
|
|
28
26
|
# // SELECTOR_COUNT = 23; // nothing.
|
|
29
|
-
24
|
|
30
|
-
25
|
|
31
|
-
26
|
|
32
|
-
27
|
|
33
|
-
28
|
|
27
|
+
24 => ['longClickable(boolean val)', 'SELECTOR_LONG_CLICKABLE', 24],
|
|
28
|
+
25 => ['textMatches(String regex)', 'SELECTOR_TEXT_REGEX', 25],
|
|
29
|
+
26 => ['classNameMatches(String regex)', 'SELECTOR_CLASS_REGEX', 26],
|
|
30
|
+
27 => ['descriptionMatches(String regex)', 'SELECTOR_DESCRIPTION_REGEX', 27],
|
|
31
|
+
28 => ['packageNameMatches(String regex)', 'SELECTOR_PACKAGE_NAME_REGEX', 28],
|
|
34
32
|
# // start internal methods at 100
|
|
35
|
-
100 => [
|
|
36
|
-
|
|
33
|
+
100 => ['getStringAttribute("name")', 'GET_NAME', 100]
|
|
34
|
+
}
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
# @private
|
|
37
|
+
def dynamic_code_to_string code, value=false
|
|
38
|
+
result = @@map[code].first
|
|
39
|
+
return result unless value
|
|
40
|
+
result.split('(').first + "( \"#{value}\" )"
|
|
41
|
+
end
|
|
44
42
|
end # class Driver
|
|
45
43
|
end # module Appium
|
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
module Appium
|
|
2
|
+
module Android
|
|
3
|
+
# Click the first alert button that contains value or by index.
|
|
4
|
+
# @param value [Integer, String] either an integer index of the button or the button's name
|
|
5
|
+
# @return [void]
|
|
6
|
+
def alert_click value
|
|
7
|
+
button(value).click
|
|
8
|
+
end
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
# Accept the alert.
|
|
11
|
+
# The last button is considered "accept."
|
|
12
|
+
# @return [void]
|
|
13
|
+
def alert_accept
|
|
14
|
+
last_button.click
|
|
15
|
+
end
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
# Get the text of the alert's accept button.
|
|
18
|
+
# The last button is considered "accept."
|
|
19
|
+
# @return [String]
|
|
20
|
+
def alert_accept_text
|
|
21
|
+
last_button.text
|
|
22
|
+
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
# Dismiss the alert.
|
|
25
|
+
# The first button is considered "dismiss."
|
|
26
|
+
# @return [void]
|
|
27
|
+
def alert_dismiss
|
|
28
|
+
first_button.click
|
|
29
|
+
end
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
end # module
|
|
31
|
+
# Get the text of the alert's dismiss button.
|
|
32
|
+
# The first button is considered "dismiss."
|
|
33
|
+
# @return [String]
|
|
34
|
+
def alert_dismiss_text
|
|
35
|
+
first_button.text
|
|
36
|
+
end
|
|
37
|
+
end # module Android
|
|
38
|
+
end # module Appium
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# UIAButton methods
|
|
2
|
+
module Appium
|
|
3
|
+
module Android
|
|
4
|
+
Button = 'android.widget.Button'
|
|
5
|
+
ImageButton = 'android.widget.ImageButton'
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# @private
|
|
10
|
+
def _button_visible_string opts={}
|
|
11
|
+
index = opts.fetch :index, false
|
|
12
|
+
if index
|
|
13
|
+
%Q(//#{Button}[#{index}] | //#{ImageButton}[#{index}])
|
|
14
|
+
else
|
|
15
|
+
%Q(//#{Button} | //#{ImageButton})
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @private
|
|
20
|
+
def _button_exact_string value
|
|
21
|
+
button = string_visible_exact Button, value
|
|
22
|
+
image_button = string_visible_exact ImageButton, value
|
|
23
|
+
"#{button} | #{image_button}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @private
|
|
27
|
+
def _button_contains_string value
|
|
28
|
+
button = string_visible_contains Button, value
|
|
29
|
+
image_button = string_visible_contains ImageButton, value
|
|
30
|
+
"#{button} | #{image_button}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
public
|
|
34
|
+
|
|
35
|
+
# Find the first button that contains value or by index.
|
|
36
|
+
# @param value [String, Integer] the value to exactly match.
|
|
37
|
+
# If int then the button at that index is returned.
|
|
38
|
+
# @return [Button]
|
|
39
|
+
def button value
|
|
40
|
+
# Don't use ele_index because that only works on one element type.
|
|
41
|
+
# Android needs to combine button and image button to match iOS.
|
|
42
|
+
if value.is_a? Numeric
|
|
43
|
+
index = value
|
|
44
|
+
raise "#{index} is not a valid xpath index. Must be >= 1" if index <= 0
|
|
45
|
+
|
|
46
|
+
return xpath _button_visible_string index: index
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
xpath _button_contains_string value
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Find all buttons containing value
|
|
53
|
+
# @param value [String] the value to search for
|
|
54
|
+
# @return [Array<Button>]
|
|
55
|
+
def buttons value
|
|
56
|
+
xpaths _button_contains_string value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Find the first button.
|
|
60
|
+
# @return [Button]
|
|
61
|
+
def first_button
|
|
62
|
+
xpath _button_visible_string
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Find the last button.
|
|
66
|
+
# @return [Button]
|
|
67
|
+
def last_button
|
|
68
|
+
xpath _button_visible_string index: 'last()'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Find the first button that exactly matches value.
|
|
72
|
+
# @param value [String] the value to match exactly
|
|
73
|
+
# @return [Button]
|
|
74
|
+
def button_exact value
|
|
75
|
+
xpath _button_exact_string value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Find all buttons that exactly match value.
|
|
79
|
+
# @param value [String] the value to match exactly
|
|
80
|
+
# @return [Array<Button>]
|
|
81
|
+
def buttons_exact value
|
|
82
|
+
xpaths _button_exact_string value
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Find all buttons.
|
|
86
|
+
# @return [Array<Button>]
|
|
87
|
+
def e_buttons
|
|
88
|
+
xpaths _button_visible_string
|
|
89
|
+
end
|
|
90
|
+
end # module Android
|
|
91
|
+
end # module Appium
|
|
@@ -1,153 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
find_element :name by default uses a partial case insensitive match.
|
|
10
|
-
On iOS the default is an exact name match.
|
|
11
|
-
|
|
12
|
-
```javascript
|
|
13
|
-
// iOS version
|
|
14
|
-
// https://github.com/appium/ruby_lib/blob/37bb4e90b29e5adb4438b287b6387a504c94b5c4/lib/appium_lib/element/ios/generic.rb#L23
|
|
15
|
-
var search = "name contains[c] '#{text}' || label contains[c] '#{text}' || value contains[c] '#{text}'";
|
|
16
|
-
var a = w.secureTextFields().firstWithPredicate(search);
|
|
17
|
-
if ( isNil(a) ) {
|
|
18
|
-
a = w.textFields().firstWithPredicate(search);
|
|
19
|
-
if ( isNil(a) ) {
|
|
20
|
-
a = w.buttons().firstWithPredicate(search);
|
|
21
|
-
if ( isNil(a) ) {
|
|
22
|
-
a = w.elements().firstWithPredicate(search);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Android considers both a textfield and a secure textfield to be "EditText".
|
|
29
|
-
Name (the content desc) is searched first and then we search for value (text).
|
|
30
|
-
There's no label in Android.
|
|
31
|
-
|
|
32
|
-
Android buttons have different class names (android.widget.Button, android.widget.ImageButton)
|
|
33
|
-
so we consider the element a button if the class name contains the word button.
|
|
34
|
-
|
|
35
|
-
After looking for textfields and buttons, then we search all elements. Find will return
|
|
36
|
-
the first element that matches.
|
|
37
|
-
=end
|
|
38
|
-
|
|
39
|
-
# Find the value contained in content description or text. Search elements
|
|
40
|
-
# in this order: EditText, Button, ImageButton
|
|
41
|
-
#
|
|
42
|
-
# @param val [String] the value to search for
|
|
43
|
-
# @return [Element]
|
|
44
|
-
def find val
|
|
45
|
-
# s.className('android.widget.EditText').descriptionContains(value);
|
|
46
|
-
args = [ [4, 'android.widget.EditText'], [7, val] ],
|
|
47
|
-
# s.className('android.widget.EditText').textContains(value);
|
|
48
|
-
[ [4, 'android.widget.EditText'], [3, val] ],
|
|
49
|
-
|
|
50
|
-
# s.className('android.widget.Button').descriptionContains(value);
|
|
51
|
-
[ [4, 'android.widget.Button'], [7, val] ],
|
|
52
|
-
# s.className('android.widget.Button').textContains(value);
|
|
53
|
-
[ [4, 'android.widget.Button'], [3, val] ],
|
|
54
|
-
|
|
55
|
-
# s.className('android.widget.ImageButton').descriptionContains(value);
|
|
56
|
-
[ [4, 'android.widget.ImageButton'], [7, val] ],
|
|
57
|
-
# s.className('android.widget.ImageButton').textContains(value);
|
|
58
|
-
[ [4, 'android.widget.ImageButton'], [3, val] ],
|
|
59
|
-
|
|
60
|
-
# s.descriptionContains(value);
|
|
61
|
-
[ [7, val] ],
|
|
62
|
-
# s.textContains(value);
|
|
63
|
-
[ [3, val] ]
|
|
64
|
-
mobile :find, args
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Return the first element matching text.
|
|
68
|
-
# @param text [String] the text to search for
|
|
69
|
-
# @return [Element] the first matching element
|
|
70
|
-
def text text
|
|
71
|
-
# Return the first element matching selector.
|
|
72
|
-
# s.textContains(value)
|
|
73
|
-
mobile :find, [ [ [3, text] ] ]
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Return all elements matching text.
|
|
77
|
-
# @param text [String] the text to search for
|
|
78
|
-
# @return [Array<Element>] all matching elements
|
|
79
|
-
def texts text
|
|
80
|
-
@driver.find_elements :xpath, "//*[contains(@text, '#{text}')]"
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Return the first element matching name.
|
|
84
|
-
# on Android name is content description
|
|
85
|
-
# on iOS name is the accessibility label or the text.
|
|
86
|
-
# @param name [String] the name to search for
|
|
87
|
-
# @return [Element] the first matching element
|
|
88
|
-
def name name
|
|
89
|
-
# work around https://github.com/appium/appium/issues/543
|
|
90
|
-
# @driver.find_element :name, name
|
|
91
|
-
mobile :find, [ [ [7, name] ] ]
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Return the first element exactly matching name.
|
|
95
|
-
# on Android name is content description
|
|
96
|
-
# on iOS name is the accessibility label or the text.
|
|
97
|
-
# @param name [String] the name to search for
|
|
98
|
-
# @return [Element] the first matching element
|
|
99
|
-
def name_exact name
|
|
100
|
-
# exact description
|
|
101
|
-
result = mobile :find, [ [ [5, name] ] ]
|
|
102
|
-
|
|
103
|
-
return result if result.kind_of? Selenium::WebDriver::Element
|
|
104
|
-
|
|
105
|
-
if result.length > 0
|
|
106
|
-
result.first
|
|
107
|
-
else
|
|
108
|
-
Appium::Common.raise_no_element_error
|
|
1
|
+
module Appium
|
|
2
|
+
module Android
|
|
3
|
+
|
|
4
|
+
# Find the first element containing value
|
|
5
|
+
# @param value [String] the value to search for
|
|
6
|
+
# @return [Element]
|
|
7
|
+
def find value
|
|
8
|
+
xpath_visible_contains '*', value
|
|
109
9
|
end
|
|
110
|
-
end
|
|
111
10
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def names name=''
|
|
118
|
-
if name.nil? || name.empty?
|
|
119
|
-
args = 'all', [ [7, ''], [100] ]
|
|
120
|
-
mobile :find, args
|
|
121
|
-
else
|
|
122
|
-
args = 'all',
|
|
123
|
-
[ [7, name] ]
|
|
124
|
-
mobile :find, args
|
|
11
|
+
# Find all elements containing value
|
|
12
|
+
# @param value [String] the value to search for
|
|
13
|
+
# @return [Array<Element>]
|
|
14
|
+
def finds value
|
|
15
|
+
xpaths_visible_contains '*', value
|
|
125
16
|
end
|
|
126
|
-
end
|
|
127
17
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
[ [3, text] ],
|
|
135
|
-
# descriptionContains(text)
|
|
136
|
-
[ [7, text] ]
|
|
18
|
+
# Find the first element exactly matching value
|
|
19
|
+
# @param value [String] the value to search for
|
|
20
|
+
# @return [Element]
|
|
21
|
+
def find_exact value
|
|
22
|
+
xpath_visible_exact '*', value
|
|
23
|
+
end
|
|
137
24
|
|
|
138
|
-
|
|
139
|
-
|
|
25
|
+
# Find all elements exactly matching value
|
|
26
|
+
# @param value [String] the value to search for
|
|
27
|
+
# @return [Array<Element>]
|
|
28
|
+
def finds_exact value
|
|
29
|
+
xpaths_visible_exact '*', value
|
|
30
|
+
end
|
|
140
31
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
32
|
+
# Scroll to the first element containing target text or description.
|
|
33
|
+
# @param text [String] the text to search for in the text value and content description
|
|
34
|
+
# @return [Element] the element scrolled to
|
|
35
|
+
def scroll_to text
|
|
36
|
+
args =
|
|
37
|
+
# textContains(text)
|
|
38
|
+
[[3, text]],
|
|
39
|
+
# descriptionContains(text)
|
|
40
|
+
[[7, text]]
|
|
41
|
+
|
|
42
|
+
complex_find mode: 'scroll', selectors: args
|
|
43
|
+
end
|
|
150
44
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
45
|
+
# Scroll to the first element with the exact target text or description.
|
|
46
|
+
# @param text [String] the text to search for in the text value and content description
|
|
47
|
+
# @return [Element] the element scrolled to
|
|
48
|
+
def scroll_to_exact text
|
|
49
|
+
args =
|
|
50
|
+
# text(text)
|
|
51
|
+
[[1, text]],
|
|
52
|
+
# description(text)
|
|
53
|
+
[[5, text]]
|
|
54
|
+
|
|
55
|
+
complex_find mode: 'scroll', selectors: args
|
|
56
|
+
end
|
|
57
|
+
end # module Android
|
|
58
|
+
end # module Appium
|