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
|
@@ -1,95 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Click the first button:
|
|
10
|
-
# alert_click 0
|
|
11
|
-
#
|
|
12
|
-
# @param value [Integer, String] either an integer index of the button or the button's name
|
|
13
|
-
# @return [void]
|
|
14
|
-
def alert_click value
|
|
15
|
-
value = "'#{value}'" if value.is_a?(String)
|
|
16
|
-
@driver.execute_script "UIATarget.localTarget().frontMostApp().alert().buttons()[#{value}].tap();"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Get the alert message text.
|
|
20
|
-
# @return [String]
|
|
21
|
-
def alert_text
|
|
22
|
-
# this will call get text twice so call bridge directly
|
|
23
|
-
# ".switch_to.alert" calls it once, then ".text" another time.
|
|
24
|
-
# @driver.switch_to.alert.text
|
|
25
|
-
driver.send(:bridge).getAlertText
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Accept the alert.
|
|
29
|
-
# @return [void]
|
|
30
|
-
def alert_accept
|
|
31
|
-
# @driver.switch_to.alert.accept
|
|
32
|
-
# ".switch_to.alert" calls getAlertText so use bridge directly
|
|
33
|
-
driver.send(:bridge).acceptAlert
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Get the text of the alert's accept button.
|
|
37
|
-
# The last button is considered "accept." on iOS 6
|
|
38
|
-
# The first button is considered "accept." on iOS 7
|
|
39
|
-
# @return [String]
|
|
40
|
-
def alert_accept_text
|
|
41
|
-
old_wait = default_wait
|
|
42
|
-
set_wait 0
|
|
43
|
-
target_text = ''
|
|
44
|
-
|
|
45
|
-
a = ignore { @driver.find_element(:tag_name, :alert) }
|
|
46
|
-
|
|
47
|
-
begin
|
|
48
|
-
if a.nil? # either no alert or on iOS 7
|
|
49
|
-
b = xpaths 'actionsheet/button'
|
|
50
|
-
target_text = b.first.text if b && b.size >= 1
|
|
51
|
-
else # iOS 6 alert found
|
|
52
|
-
b = a.find_elements(:tag_name, :button)
|
|
53
|
-
target_text = b.last.text if b && b.size >= 1
|
|
54
|
-
end
|
|
55
|
-
rescue
|
|
56
|
-
ensure
|
|
57
|
-
set_wait old_wait
|
|
58
|
-
return target_text
|
|
1
|
+
module Appium
|
|
2
|
+
module Ios
|
|
3
|
+
# Accept the alert.
|
|
4
|
+
# @return [void]
|
|
5
|
+
def alert_accept
|
|
6
|
+
# @driver.switch_to.alert.accept
|
|
7
|
+
# ".switch_to.alert" calls getAlertText so use bridge directly
|
|
8
|
+
driver.send(:bridge).acceptAlert
|
|
59
9
|
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Dismiss the alert.
|
|
63
|
-
# @return [void]
|
|
64
|
-
def alert_dismiss
|
|
65
|
-
# @driver.switch_to.alert.dismiss
|
|
66
|
-
# ".switch_to.alert" calls getAlertText so use bridge directly
|
|
67
|
-
driver.send(:bridge).dismissAlert
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Get the text of the alert's dismiss button.
|
|
71
|
-
# The first button is considered "dismiss." on iOS 6
|
|
72
|
-
# The last button is considered "dismiss." on iOS 7
|
|
73
|
-
# @return [String]
|
|
74
|
-
def alert_dismiss_text
|
|
75
|
-
old_wait = default_wait
|
|
76
|
-
set_wait 0
|
|
77
|
-
target_text = ''
|
|
78
|
-
|
|
79
|
-
a = ignore { @driver.find_element(:tag_name, :alert) }
|
|
80
10
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
target_text = b.first.text if b && b.size >= 1
|
|
88
|
-
end
|
|
89
|
-
rescue
|
|
90
|
-
ensure
|
|
91
|
-
set_wait old_wait
|
|
92
|
-
return target_text
|
|
11
|
+
# Dismiss the alert.
|
|
12
|
+
# @return [void]
|
|
13
|
+
def alert_dismiss
|
|
14
|
+
# @driver.switch_to.alert.dismiss
|
|
15
|
+
# ".switch_to.alert" calls getAlertText so use bridge directly
|
|
16
|
+
driver.send(:bridge).dismissAlert
|
|
93
17
|
end
|
|
94
|
-
end
|
|
95
|
-
end # module Appium
|
|
18
|
+
end # module Ios
|
|
19
|
+
end # module Appium
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# UIAButton methods
|
|
2
|
+
module Appium
|
|
3
|
+
module Ios
|
|
4
|
+
UIAButton = 'UIAButton'
|
|
5
|
+
|
|
6
|
+
# Find the first UIAButton that contains value or by index.
|
|
7
|
+
# @param value [String, Integer] the value to exactly match.
|
|
8
|
+
# If int then the UIAButton at that index is returned.
|
|
9
|
+
# @return [UIAButton]
|
|
10
|
+
def button value
|
|
11
|
+
# return button at index.
|
|
12
|
+
return ele_index UIAButton, value if value.is_a? Numeric
|
|
13
|
+
xpath_visible_contains UIAButton, value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Find all UIAButtons containing value
|
|
17
|
+
# @param value [String] the value to search for
|
|
18
|
+
# @return [Array<UIAButton>]
|
|
19
|
+
def buttons value
|
|
20
|
+
xpaths_visible_contains UIAButton, value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Find the first UIAButton.
|
|
24
|
+
# @return [UIAButton]
|
|
25
|
+
def first_button
|
|
26
|
+
first_ele UIAButton
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Find the last UIAButton.
|
|
30
|
+
# @return [UIAButton]
|
|
31
|
+
def last_button
|
|
32
|
+
last_ele UIAButton
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Find the first UIAButton that exactly matches value.
|
|
36
|
+
# @param value [String] the value to match exactly
|
|
37
|
+
# @return [UIAButton]
|
|
38
|
+
def button_exact value
|
|
39
|
+
xpath_visible_exact UIAButton, value
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Find all UIAButtons that exactly match value.
|
|
43
|
+
# @param value [String] the value to match exactly
|
|
44
|
+
# @return [Array<UIAButton>]
|
|
45
|
+
def buttons_exact value
|
|
46
|
+
xpaths_visible_exact UIAButton, value
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Find all UIAButtons.
|
|
50
|
+
# @return [Array<UIAButton>]
|
|
51
|
+
def e_buttons
|
|
52
|
+
tags UIAButton
|
|
53
|
+
end
|
|
54
|
+
end # module Ios
|
|
55
|
+
end # module Appium
|
|
@@ -1,165 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name defaults to label when undefined. value is never a default so that must be
|
|
10
|
-
included in a new search.
|
|
11
|
-
|
|
12
|
-
Find - search everything.
|
|
13
|
-
|
|
14
|
-
The search order is:
|
|
15
|
-
1. name
|
|
16
|
-
2. label (implied by name)
|
|
17
|
-
3. value
|
|
18
|
-
|
|
19
|
-
Android name = iOS name & label
|
|
20
|
-
Android text = iOS value
|
|
21
|
-
=end
|
|
22
|
-
|
|
23
|
-
# @private
|
|
24
|
-
# returnElems requires a wrapped $(element).
|
|
25
|
-
# set to empty array when length is zero to prevent hang.
|
|
26
|
-
#
|
|
27
|
-
# UIAElementNil when not matched
|
|
28
|
-
#
|
|
29
|
-
# 1. secureTextFields
|
|
30
|
-
# 2. textFields
|
|
31
|
-
# 3. buttons
|
|
32
|
-
# 4. elements
|
|
33
|
-
#
|
|
34
|
-
# search takes the window to search.
|
|
35
|
-
# start searching webview first.
|
|
36
|
-
# window 0 is the main window.
|
|
37
|
-
# window 1 is the 1st webview (if it exists)
|
|
38
|
-
# must break instead of return because it's not a function.
|
|
39
|
-
#
|
|
40
|
-
# single element length is undefined when found and 0 when not found.
|
|
41
|
-
# @param predicate [String] the predicate
|
|
42
|
-
# @return [String] the completed JavaScript program
|
|
43
|
-
def first_ele_js predicate
|
|
44
|
-
(<<-JS).strip # remove trailing newline
|
|
45
|
-
au.mainApp().getFirstWithPredicateWeighted("#{predicate}");
|
|
46
|
-
JS
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# @private
|
|
50
|
-
# @param predicate [String] the predicate
|
|
51
|
-
# @return [String] the completed JavaScript program
|
|
52
|
-
def all_ele_js predicate
|
|
53
|
-
(<<-JS).strip # remove trailing newline
|
|
54
|
-
au.mainApp().getAllWithPredicate("#{predicate}");
|
|
55
|
-
JS
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Return the first element matching text.
|
|
59
|
-
# @param text [String] the text to search for
|
|
60
|
-
# @return [Element] the first matching element
|
|
61
|
-
def find text
|
|
62
|
-
text = escape_single_quote text
|
|
63
|
-
ele = nil
|
|
64
|
-
# prefer value search. this may error with:
|
|
65
|
-
# Can't use in/contains operator with collection 1
|
|
66
|
-
js = first_ele_js "value contains[c] '#{text}'"
|
|
67
|
-
ele = ignore { execute_script js }
|
|
68
|
-
|
|
69
|
-
# now search name and label if the value search didn't match.
|
|
70
|
-
unless ele
|
|
71
|
-
js = first_ele_js "name contains[c] '#{text}' || label contains[c] '#{text}'"
|
|
72
|
-
ele = ignore { execute_script js }
|
|
1
|
+
module Appium
|
|
2
|
+
module Ios
|
|
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
|
|
73
9
|
end
|
|
74
10
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
# Return all elements matching text.
|
|
82
|
-
# @param text [String] the text to search for
|
|
83
|
-
# @return [Array<Element>] all matching elements
|
|
84
|
-
def finds text
|
|
85
|
-
text = escape_single_quote text
|
|
86
|
-
eles = []
|
|
87
|
-
# value contains may error
|
|
88
|
-
js = all_ele_js "value contains[c] '#{text}'"
|
|
89
|
-
eles = ignore { execute_script js }
|
|
90
|
-
|
|
91
|
-
js = all_ele_js "name contains[c] '#{text}' || label contains[c] '#{text}'"
|
|
92
|
-
eles += ignore { execute_script js }
|
|
93
|
-
eles
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Return the first element matching text.
|
|
97
|
-
# @param text [String] the text to search for
|
|
98
|
-
# @return [Element] the first matching element
|
|
99
|
-
def text text
|
|
100
|
-
text = escape_single_quote text
|
|
101
|
-
js = first_ele_js "value contains[c] '#{text}'"
|
|
102
|
-
execute_script js
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Return all elements matching text.
|
|
106
|
-
# @param text [String] the text to search for
|
|
107
|
-
# @return [Array<Element>] all matching elements
|
|
108
|
-
def texts text
|
|
109
|
-
text = escape_single_quote text
|
|
110
|
-
# XPath //* is not implemented on iOS
|
|
111
|
-
# https://github.com/appium/appium/issues/430
|
|
112
|
-
js = all_ele_js "value contains[c] '#{text}'"
|
|
113
|
-
execute_script js
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Return the first element matching name.
|
|
117
|
-
# on Android name is content description
|
|
118
|
-
# on iOS name is the accessibility label or the text.
|
|
119
|
-
#
|
|
120
|
-
# ```ruby
|
|
121
|
-
# # find element with name or label containing example and access the name attribute.
|
|
122
|
-
# name('example').name
|
|
123
|
-
#
|
|
124
|
-
# # find element with name or label containing example and access the label attribute.
|
|
125
|
-
# name('example').label
|
|
126
|
-
# ```
|
|
127
|
-
#
|
|
128
|
-
# @param name [String] the name to search for
|
|
129
|
-
# @return [Element] the first matching element
|
|
130
|
-
def name name
|
|
131
|
-
name = escape_single_quote name
|
|
132
|
-
mobile :findElementNameContains, name: name
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def name_exact name
|
|
136
|
-
name = escape_single_quote name
|
|
137
|
-
js = all_ele_js "name == '#{name}'"
|
|
138
|
-
result = execute_script js
|
|
139
|
-
|
|
140
|
-
return result if result.kind_of? Selenium::WebDriver::Element
|
|
141
|
-
|
|
142
|
-
if result.length > 0
|
|
143
|
-
result.first
|
|
144
|
-
else
|
|
145
|
-
Appium::Common.raise_no_element_error
|
|
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
|
|
146
16
|
end
|
|
147
|
-
end
|
|
148
17
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
name = escape_single_quote name
|
|
156
|
-
# :name is not consistent across iOS and Android so use custom JavaScript
|
|
157
|
-
# https://github.com/appium/appium/issues/379
|
|
158
|
-
js = all_ele_js "name contains[c] '#{name}' || label contains[c] '#{name}'"
|
|
159
|
-
execute_script js
|
|
160
|
-
end
|
|
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
|
|
161
24
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
31
|
+
end # module Ios
|
|
32
|
+
end # module Appium
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# UIAStaticText methods
|
|
2
|
+
module Appium
|
|
3
|
+
module Ios
|
|
4
|
+
UIAStaticText = 'UIAStaticText'
|
|
5
|
+
|
|
6
|
+
# Find the first UIAStaticText that contains value or by index.
|
|
7
|
+
# @param value [String, Integer] the value to find.
|
|
8
|
+
# If int then the UIAStaticText at that index is returned.
|
|
9
|
+
# @return [UIAStaticText]
|
|
10
|
+
def s_text value
|
|
11
|
+
return ele_index UIAStaticText, value if value.is_a? Numeric
|
|
12
|
+
xpath_visible_contains UIAStaticText, value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Find all UIAStaticText containing value.
|
|
16
|
+
# @param value [String] the value to search for
|
|
17
|
+
# @return [Array<UIAStaticText>]
|
|
18
|
+
def s_texts value
|
|
19
|
+
xpaths_visible_contains UIAStaticText, value
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Find the first UIAStaticText.
|
|
23
|
+
# @return [UIAStaticText]
|
|
24
|
+
def first_s_text
|
|
25
|
+
first_ele UIAStaticText
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Find the last UIAStaticText.
|
|
29
|
+
# @return [UIAStaticText]
|
|
30
|
+
def last_s_text
|
|
31
|
+
last_ele UIAStaticText
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Find the first UIAStaticText that exactly matches value.
|
|
35
|
+
# @param value [String] the value to match exactly
|
|
36
|
+
# @return [UIAStaticText]
|
|
37
|
+
def s_text_exact value
|
|
38
|
+
xpath_visible_exact UIAStaticText, value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Find all UIAStaticTexts that exactly match value.
|
|
42
|
+
# @param value [String] the value to match exactly
|
|
43
|
+
# @return [Array<UIAStaticText>]
|
|
44
|
+
def s_texts_exact value
|
|
45
|
+
xpaths_visible_exact UIAStaticText, value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Find all UIAStaticTexts.
|
|
49
|
+
# @return [Array<UIAStaticText>]
|
|
50
|
+
def e_s_texts
|
|
51
|
+
tags UIAStaticText
|
|
52
|
+
end
|
|
53
|
+
end # module Ios
|
|
54
|
+
end # module Appium
|
|
@@ -1,77 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# Find textfield and then secure elements in one server call
|
|
6
|
-
# to match Android.
|
|
1
|
+
module Appium
|
|
2
|
+
module Ios
|
|
3
|
+
UIATextField = 'UIATextField'
|
|
4
|
+
UIASecureTextField = 'UIASecureTextField'
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
ele = execute_script(js)
|
|
10
|
-
ele = ele.first if ele.kind_of? Array
|
|
11
|
-
raise_no_element_error unless ele.kind_of? Selenium::WebDriver::Element
|
|
12
|
-
ele
|
|
13
|
-
end
|
|
6
|
+
private
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
# @private
|
|
9
|
+
def _textfield_visible_string opts={}
|
|
10
|
+
index = opts.fetch :index, false
|
|
11
|
+
if index
|
|
12
|
+
%Q(//#{UIATextField}[@visible="true"][#{index}] | //#{UIASecureTextField}[@visible="true"][#{index}])
|
|
13
|
+
else
|
|
14
|
+
%Q(//#{UIATextField}[@visible="true"] | //#{UIASecureTextField}[@visible="true"])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @private
|
|
19
|
+
def _textfield_exact_string value
|
|
20
|
+
textfield = string_visible_exact UIATextField, value
|
|
21
|
+
secure = string_visible_exact UIASecureTextField, value
|
|
22
|
+
"#{textfield} | #{secure}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @private
|
|
26
|
+
def _textfield_contains_string value
|
|
27
|
+
textfield = string_visible_contains UIATextField, value
|
|
28
|
+
secure = string_visible_contains UIASecureTextField, value
|
|
29
|
+
"#{textfield} | #{secure}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
public
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
# Find the first TextField that contains value or by index.
|
|
35
|
+
# @param value [String, Integer] the text to match exactly.
|
|
36
|
+
# If int then the TextField at that index is returned.
|
|
37
|
+
# @return [TextField]
|
|
38
|
+
def textfield value
|
|
39
|
+
# Don't use ele_index because that only works on one element type.
|
|
40
|
+
# iOS needs to combine textfield and secure to match Android.
|
|
41
|
+
if value.is_a? Numeric
|
|
42
|
+
index = value
|
|
43
|
+
raise "#{index} is not a valid xpath index. Must be >= 1" if index <= 0
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def first_textfield
|
|
31
|
-
xpath 'textfield'
|
|
32
|
-
end
|
|
45
|
+
return xpath _textfield_visible_string index: index
|
|
46
|
+
end
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
xpath _textfield_contains_string value
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Find all TextFields containing value.
|
|
52
|
+
# @param value [String] the value to search for
|
|
53
|
+
# @return [Array<TextField>]
|
|
54
|
+
def textfields value
|
|
55
|
+
xpaths _textfield_contains_string value
|
|
56
|
+
end
|
|
39
57
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# Don't use ele_index because that only works on one element type.
|
|
45
|
-
# iOS needs to combine textfield and secure to match Android.
|
|
46
|
-
if text.is_a? Numeric
|
|
47
|
-
raise "#{text} is not a valid xpath index. Must be >= 1" if text <= 0
|
|
48
|
-
return xpath("textfield[#{text}]")
|
|
58
|
+
# Find the first TextField.
|
|
59
|
+
# @return [TextField]
|
|
60
|
+
def first_textfield
|
|
61
|
+
xpath _textfield_visible_string
|
|
49
62
|
end
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
# Find the last TextField.
|
|
65
|
+
# @return [TextField]
|
|
66
|
+
def last_textfield
|
|
67
|
+
xpath _textfield_visible_string index: 'last()'
|
|
68
|
+
end
|
|
53
69
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
# Find the first TextField that exactly matches value.
|
|
71
|
+
# @param value [String] the value to match exactly
|
|
72
|
+
# @return [TextField]
|
|
73
|
+
def textfield_exact value
|
|
74
|
+
xpath _textfield_exact_string value
|
|
75
|
+
end
|
|
60
76
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
# Find all TextFields that exactly match value.
|
|
78
|
+
# @param value [String] the value to match exactly
|
|
79
|
+
# @return [Array<TextField>]
|
|
80
|
+
def textfields_exact value
|
|
81
|
+
xpaths _textfield_exact_string value
|
|
82
|
+
end
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
target = e_textfields.detect { |e| e.name == target_name }
|
|
73
|
-
raise "Textfield named #{target_name} not found" unless target
|
|
74
|
-
target
|
|
84
|
+
# Find all TextFields.
|
|
85
|
+
# @return [Array<TextField>]
|
|
86
|
+
def e_textfields
|
|
87
|
+
xpaths _textfield_visible_string
|
|
75
88
|
end
|
|
76
|
-
end
|
|
77
|
-
end # module Appium
|
|
89
|
+
end # module Ios
|
|
90
|
+
end # module Appium
|