appium_lib 4.1.0 → 5.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/android_tests/api.apk +0 -0
- data/android_tests/lib/android/specs/android/element/text.rb +2 -2
- data/android_tests/lib/android/specs/android/helper.rb +2 -2
- data/android_tests/lib/android/specs/common/device.rb +10 -28
- data/android_tests/lib/android/specs/common/device_touchaction.rb +29 -0
- data/android_tests/lib/android/specs/common/helper.rb +4 -4
- data/android_tests/lib/android/specs/common/patch.rb +2 -2
- data/android_tests/lib/android/specs/driver.rb +11 -1
- data/android_tests/lib/android/specs/install.rb +7 -6
- data/appium_lib.gemspec +2 -10
- data/contributing.md +23 -0
- data/docs/android_docs.md +274 -217
- data/docs/docs.md +28 -0
- data/docs/ios_docs.md +372 -212
- data/ios_tests/UICatalog.app/Info.plist +0 -0
- data/ios_tests/appium.txt +2 -1
- data/ios_tests/lib/ios/specs/common/helper.rb +12 -21
- data/ios_tests/lib/ios/specs/common/web_context.rb +7 -2
- data/ios_tests/lib/ios/specs/device/device.rb +16 -10
- data/ios_tests/lib/ios/specs/driver.rb +13 -2
- data/ios_tests/lib/ios/specs/ios/element/button.rb +5 -4
- data/ios_tests/lib/ios/specs/ios/element/generic.rb +2 -2
- data/ios_tests/lib/ios/specs/ios/element/text.rb +11 -7
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +9 -9
- data/lib/appium_lib.rb +1 -17
- data/lib/appium_lib/android/helper.rb +55 -5
- data/lib/appium_lib/common/helper.rb +26 -30
- data/lib/appium_lib/common/patch.rb +12 -0
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/device/device.rb +83 -12
- data/lib/appium_lib/driver.rb +26 -14
- data/lib/appium_lib/ios/element/button.rb +4 -4
- data/lib/appium_lib/ios/element/generic.rb +4 -4
- data/lib/appium_lib/ios/element/text.rb +4 -4
- data/lib/appium_lib/ios/element/textfield.rb +41 -22
- data/lib/appium_lib/ios/helper.rb +216 -47
- data/lib/appium_lib/ios/patch.rb +0 -19
- data/readme.md +1 -0
- data/release_notes.md +64 -0
- metadata +7 -5
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'selenium/webdriver/common/error'
|
2
|
+
|
1
3
|
# Generic helper methods not specific
|
2
4
|
# to a particular tag name
|
3
5
|
module Appium
|
@@ -53,28 +55,14 @@ module Appium
|
|
53
55
|
find_elements :xpath, xpath_str
|
54
56
|
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
def source
|
59
|
-
source = @driver.page_source
|
58
|
+
def _print_source source
|
59
|
+
opts = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
60
60
|
if source.start_with? '<html'
|
61
|
-
doc = Nokogiri::HTML(source)
|
62
|
-
config.options = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
63
|
-
end
|
64
|
-
puts doc.to_xhtml indent: 2
|
61
|
+
doc = Nokogiri::HTML(source) { |cfg| cfg.options = opts }
|
65
62
|
else
|
66
|
-
doc = Nokogiri::XML(source)
|
67
|
-
config.options = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
68
|
-
end
|
69
|
-
puts doc.to_xml indent: 2
|
63
|
+
doc = Nokogiri::XML(source) { |cfg| cfg.options = opts }
|
70
64
|
end
|
71
|
-
|
72
|
-
|
73
|
-
# Returns XML string for the current page
|
74
|
-
# Same as driver.page_source
|
75
|
-
# @return [String]
|
76
|
-
def get_source
|
77
|
-
@driver.page_source
|
65
|
+
puts doc.to_xml indent: 2
|
78
66
|
end
|
79
67
|
|
80
68
|
# @private
|
@@ -93,7 +81,7 @@ module Appium
|
|
93
81
|
# http://nokogiri.org/Nokogiri/XML/SAX/Document.html
|
94
82
|
def start_element name, attrs = []
|
95
83
|
# Count only visible elements. Android is always visible
|
96
|
-
element_visible = $driver.device_is_android? ? true : attrs
|
84
|
+
element_visible = $driver.device_is_android? ? true : Hash[attrs]['visible'] == 'true'
|
97
85
|
@result[name] += 1 if element_visible
|
98
86
|
end
|
99
87
|
|
@@ -140,7 +128,9 @@ module Appium
|
|
140
128
|
|
141
129
|
# @private
|
142
130
|
def lazy_load_strings
|
143
|
-
|
131
|
+
# app strings only works on local apps.
|
132
|
+
# on disk apps (ex: com.android.settings) will error
|
133
|
+
@strings_xml ||= ignore { app_strings } || {}
|
144
134
|
end
|
145
135
|
|
146
136
|
# Search strings.xml's values for target.
|
@@ -185,16 +175,18 @@ module Appium
|
|
185
175
|
end
|
186
176
|
|
187
177
|
def reset
|
188
|
-
@element_stack
|
178
|
+
@element_stack = []
|
189
179
|
@elements_in_order = []
|
190
|
-
@skip_element
|
180
|
+
@skip_element = false
|
191
181
|
end
|
192
182
|
|
193
183
|
def result
|
194
184
|
@elements_in_order.reduce('') do |r, e|
|
195
|
-
name
|
185
|
+
name = e.delete :name
|
196
186
|
attr_string = e.reduce('') do |string, attr|
|
197
|
-
|
187
|
+
attr_1 = attr[1]
|
188
|
+
attr_1 = attr_1 ? attr_1.strip : attr_1
|
189
|
+
string += " #{attr[0]}: #{attr_1}\n"
|
198
190
|
end
|
199
191
|
|
200
192
|
unless attr_string.nil? || attr_string.empty?
|
@@ -207,8 +199,8 @@ module Appium
|
|
207
199
|
def start_element name, attrs = []
|
208
200
|
@skip_element = filter && !filter.include?(name.downcase)
|
209
201
|
unless @skip_element
|
210
|
-
element = {name: name}
|
211
|
-
attrs.each {|a| element[a[0]] = a[1]}
|
202
|
+
element = { name: name }
|
203
|
+
attrs.each { |a| element[a[0]] = a[1] }
|
212
204
|
@element_stack.push element
|
213
205
|
@elements_in_order.push element
|
214
206
|
end
|
@@ -216,16 +208,20 @@ module Appium
|
|
216
208
|
|
217
209
|
def end_element name
|
218
210
|
return if filter && !filter.include?(name.downcase)
|
219
|
-
element_index = @element_stack.rindex {|e| e[:name] == name}
|
211
|
+
element_index = @element_stack.rindex { |e| e[:name] == name }
|
220
212
|
@element_stack.delete_at element_index
|
221
213
|
end
|
222
214
|
|
223
215
|
def characters(chars)
|
224
216
|
unless @skip_element
|
225
|
-
element
|
217
|
+
element = @element_stack.last
|
226
218
|
element[:text] = chars
|
227
219
|
end
|
228
220
|
end
|
229
221
|
end
|
222
|
+
|
223
|
+
def _no_such_element
|
224
|
+
raise Selenium::WebDriver::Error::NoSuchElementError, 'An element could not be located on the page using the given search parameters.'
|
225
|
+
end
|
230
226
|
end # module Common
|
231
|
-
end # module Appium
|
227
|
+
end # module Appium
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
|
1
3
|
module Appium
|
2
4
|
module Common
|
3
5
|
# Implement useful features for element.
|
@@ -89,6 +91,7 @@ def patch_webdriver_bridge
|
|
89
91
|
path_str = path.sub(path_match[0], '') unless path_match.nil?
|
90
92
|
|
91
93
|
puts "#{verb} #{path_str}"
|
94
|
+
|
92
95
|
# must check to see if command_hash is a hash. sometimes it's not.
|
93
96
|
if command_hash.is_a?(Hash) && !command_hash.empty?
|
94
97
|
print_command = command_hash.clone
|
@@ -104,6 +107,10 @@ def patch_webdriver_bridge
|
|
104
107
|
else
|
105
108
|
ap print_command
|
106
109
|
end
|
110
|
+
else # non-standard command hash
|
111
|
+
# It's important to output this for debugging problems.
|
112
|
+
# for example invalid JSON will not be a Hash
|
113
|
+
ap command_hash if command_hash
|
107
114
|
end
|
108
115
|
delay = $driver.global_webdriver_http_sleep
|
109
116
|
sleep delay if !delay.nil? && delay > 0
|
@@ -131,4 +138,9 @@ class Selenium::WebDriver::Remote::Response
|
|
131
138
|
|
132
139
|
msg
|
133
140
|
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Selenium::WebDriver::Remote::Http::Common
|
144
|
+
remove_const :DEFAULT_HEADERS if defined? DEFAULT_HEADERS
|
145
|
+
DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib/#{::Appium::VERSION}" }
|
134
146
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Appium
|
2
2
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
3
|
-
VERSION = '
|
4
|
-
DATE = '2014-
|
3
|
+
VERSION = '5.0.0' unless defined? ::Appium::VERSION
|
4
|
+
DATE = '2014-12-23' unless defined? ::Appium::DATE
|
5
5
|
end
|
@@ -8,14 +8,15 @@ module Appium
|
|
8
8
|
post: {
|
9
9
|
open_notifications: 'session/:session_id/appium/device/open_notifications',
|
10
10
|
shake: 'session/:session_id/appium/device/shake',
|
11
|
-
|
11
|
+
launch_app: 'session/:session_id/appium/app/launch',
|
12
12
|
close_app: 'session/:session_id/appium/app/close',
|
13
13
|
reset: 'session/:session_id/appium/app/reset',
|
14
14
|
toggle_airplane_mode: 'session/:session_id/appium/device/toggle_airplane_mode',
|
15
15
|
},
|
16
16
|
get: {
|
17
|
-
current_activity:
|
18
|
-
current_context:
|
17
|
+
current_activity: 'session/:session_id/appium/device/current_activity',
|
18
|
+
current_context: 'session/:session_id/context',
|
19
|
+
get_network_connection: 'session/:session_id/network_connection',
|
19
20
|
}
|
20
21
|
}
|
21
22
|
|
@@ -32,7 +33,7 @@ module Appium
|
|
32
33
|
|
33
34
|
# @!method current_activity
|
34
35
|
|
35
|
-
# @!method
|
36
|
+
# @!method launch_app
|
36
37
|
# Start the simulator and applicaton configured with desired capabilities
|
37
38
|
|
38
39
|
# @!method reset
|
@@ -92,6 +93,13 @@ module Appium
|
|
92
93
|
# Android only; Ends the test coverage and writes the results to the given path on device.
|
93
94
|
# @param path (String) Path on the device to write too.
|
94
95
|
# @param intent (String) Intent to broadcast when ending coverage.
|
96
|
+
|
97
|
+
# @!method get_settings
|
98
|
+
# Get appium Settings for current test session
|
99
|
+
|
100
|
+
# @!method update_settings
|
101
|
+
# Update appium Settings for current test session
|
102
|
+
# @param settings (hash) Settings to update, keys are settings, values to value to set each setting to
|
95
103
|
class << self
|
96
104
|
def extended(mod)
|
97
105
|
extend_webdriver_with_forwardable
|
@@ -120,15 +128,15 @@ module Appium
|
|
120
128
|
end
|
121
129
|
end
|
122
130
|
|
123
|
-
add_endpoint_method(:
|
124
|
-
def
|
125
|
-
execute :
|
131
|
+
add_endpoint_method(:install_app, 'session/:session_id/appium/device/install_app') do
|
132
|
+
def install_app(path)
|
133
|
+
execute :install_app, {}, :appPath => path
|
126
134
|
end
|
127
135
|
end
|
128
136
|
|
129
|
-
add_endpoint_method(:
|
130
|
-
def
|
131
|
-
execute :
|
137
|
+
add_endpoint_method(:remove_app, 'session/:session_id/appium/device/remove_app') do
|
138
|
+
def remove_app(id)
|
139
|
+
execute :remove_app, {}, :appId => id
|
132
140
|
end
|
133
141
|
end
|
134
142
|
|
@@ -144,6 +152,36 @@ module Appium
|
|
144
152
|
end
|
145
153
|
end
|
146
154
|
|
155
|
+
# @!method start_activity
|
156
|
+
# Start a new activity within the current app or launch a new app and start the target activity.
|
157
|
+
#
|
158
|
+
# Android only.
|
159
|
+
# @param [String] The package owning the activity [required]
|
160
|
+
# @param [String] The target activity [required]
|
161
|
+
# @param [String] The package to start before the target package [optional]
|
162
|
+
# @param [String] The activity to start before the target activity [optional]
|
163
|
+
#
|
164
|
+
# ```ruby
|
165
|
+
# start_activity app_package: 'io.appium.android.apis', app_activity: '.accessibility.AccessibilityNodeProviderActivity'
|
166
|
+
# ```
|
167
|
+
add_endpoint_method(:start_activity, 'session/:session_id/appium/device/start_activity') do
|
168
|
+
def start_activity(opts)
|
169
|
+
raise 'opts must be a hash' unless opts.is_a? Hash
|
170
|
+
app_package = opts[:app_package]
|
171
|
+
raise 'app_package is required' unless app_package
|
172
|
+
app_activity = opts[:app_activity]
|
173
|
+
raise 'app_activity is required' unless opts[:app_activity]
|
174
|
+
app_wait_package = opts.fetch(:app_wait_package, '')
|
175
|
+
app_wait_activity = opts.fetch(:app_wait_activity, '')
|
176
|
+
|
177
|
+
unknown_opts = opts.keys - [:app_package, :app_activity, :app_wait_package, :app_wait_activity]
|
178
|
+
raise "Unknown options #{unknown_opts}" unless unknown_opts.empty?
|
179
|
+
|
180
|
+
execute :start_activity, {}, { appPackage: app_package, appActivity: app_activity,
|
181
|
+
appWaitPackage: app_wait_package, appWaitActivity: app_wait_activity }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
147
185
|
add_endpoint_method(:set_context, 'session/:session_id/context') do
|
148
186
|
def set_context(context=null)
|
149
187
|
execute :set_context, {}, :name => context
|
@@ -181,7 +219,7 @@ module Appium
|
|
181
219
|
# TODO TEST ME
|
182
220
|
add_endpoint_method(:set_immediate_value, 'session/:session_id/appium/element/:id/value') do
|
183
221
|
def set_immediate_value(element, value)
|
184
|
-
execute :set_immediate_value, { :id => element.ref }, value
|
222
|
+
execute :set_immediate_value, { :id => element.ref }, value: value
|
185
223
|
end
|
186
224
|
end
|
187
225
|
|
@@ -214,6 +252,39 @@ module Appium
|
|
214
252
|
end
|
215
253
|
end
|
216
254
|
|
255
|
+
add_endpoint_method(:get_settings, 'session/:session_id/appium/settings', :get) do
|
256
|
+
def get_settings
|
257
|
+
execute :get_settings, {}
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
add_endpoint_method(:update_settings, 'session/:session_id/appium/settings') do
|
262
|
+
def update_settings(settings)
|
263
|
+
execute :update_settings, {}, settings: settings
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# @!method get_network_connection
|
268
|
+
# Get the device network connection current status
|
269
|
+
# See set_network_connection method for return value
|
270
|
+
|
271
|
+
# @!method set_network_connection
|
272
|
+
# Set the device network connection mode
|
273
|
+
# @param path (String) Bit mask that represent the network mode
|
274
|
+
# Value (Alias) | Data | Wifi | Airplane Mode
|
275
|
+
# -------------------------------------------------
|
276
|
+
# 1 (Airplane Mode) | 0 | 0 | 1
|
277
|
+
# 6 (All network on) | 1 | 1 | 0
|
278
|
+
# 4 (Data only) | 1 | 0 | 0
|
279
|
+
# 2 (Wifi only) | 0 | 1 | 0
|
280
|
+
# 0 (None) | 0 | 0 | 0
|
281
|
+
#
|
282
|
+
add_endpoint_method(:set_network_connection, 'session/:session_id/network_connection') do
|
283
|
+
def set_network_connection(mode)
|
284
|
+
execute :set_network_connection, {}, type: mode
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
217
288
|
add_touch_actions
|
218
289
|
extend_search_contexts
|
219
290
|
end
|
@@ -280,7 +351,7 @@ module Appium
|
|
280
351
|
def add_touch_actions
|
281
352
|
add_endpoint_method(:touch_actions, 'session/:session_id/touch/perform') do
|
282
353
|
def touch_actions(actions)
|
283
|
-
actions = [actions].flatten
|
354
|
+
actions = { actions: [actions].flatten }
|
284
355
|
execute :touch_actions, {}, actions
|
285
356
|
end
|
286
357
|
end
|
data/lib/appium_lib/driver.rb
CHANGED
@@ -223,19 +223,32 @@ module Appium
|
|
223
223
|
|
224
224
|
# attr readers are promoted to global scope. To avoid clobbering, they're
|
225
225
|
# made available via the driver_attributes method
|
226
|
+
#
|
227
|
+
# attr_accessor is repeated for each one so YARD documents them properly.
|
228
|
+
|
226
229
|
|
227
230
|
# The amount to sleep in seconds before every webdriver http call.
|
228
|
-
attr_accessor :global_webdriver_http_sleep
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
231
|
+
attr_accessor :global_webdriver_http_sleep
|
232
|
+
# Selenium webdriver capabilities
|
233
|
+
attr_accessor :caps
|
234
|
+
# Custom URL for the selenium server
|
235
|
+
attr_accessor :custom_url
|
236
|
+
# Export session id to textfile in /tmp for 3rd party tools
|
237
|
+
attr_accessor :export_session
|
238
|
+
# Default wait time for elements to appear
|
239
|
+
attr_accessor :default_wait
|
240
|
+
# Array of previous wait time values
|
241
|
+
attr_accessor :last_waits
|
242
|
+
# Username for use on Sauce Labs
|
243
|
+
attr_accessor :sauce_username
|
244
|
+
# Access Key for use on Sauce Labs
|
245
|
+
attr_accessor :sauce_access_key
|
246
|
+
# Appium's server port
|
247
|
+
attr_accessor :appium_port
|
248
|
+
# Device type to request from the appium server
|
249
|
+
attr_accessor :appium_device
|
250
|
+
# Boolean debug mode for the Appium Ruby bindings
|
251
|
+
attr_accessor :appium_debug
|
239
252
|
|
240
253
|
# Creates a new driver
|
241
254
|
#
|
@@ -475,8 +488,7 @@ module Appium
|
|
475
488
|
raise 'ERROR: Unable to connect to Appium. Is the server running?'
|
476
489
|
end
|
477
490
|
|
478
|
-
|
479
|
-
@driver.manage.timeouts.implicit_wait = @default_wait unless defined? Pry
|
491
|
+
@driver.manage.timeouts.implicit_wait = @default_wait
|
480
492
|
|
481
493
|
@driver
|
482
494
|
end
|
@@ -592,4 +604,4 @@ end # module Appium
|
|
592
604
|
# Paging in Pry is annoying :q required to exit.
|
593
605
|
# With pager disabled, the output is similar to IRB
|
594
606
|
# Only set if Pry is defined.
|
595
|
-
Pry.config.pager = false if defined?(Pry)
|
607
|
+
Pry.config.pager = false if defined?(Pry)
|
@@ -10,7 +10,7 @@ module Appium
|
|
10
10
|
def button value
|
11
11
|
# return button at index.
|
12
12
|
return ele_index UIAButton, value if value.is_a? Numeric
|
13
|
-
|
13
|
+
ele_by_json_visible_contains UIAButton, value
|
14
14
|
end
|
15
15
|
|
16
16
|
# Find all UIAButtons containing value.
|
@@ -19,7 +19,7 @@ module Appium
|
|
19
19
|
# @return [Array<UIAButton>]
|
20
20
|
def buttons value=false
|
21
21
|
return tags UIAButton unless value
|
22
|
-
|
22
|
+
eles_by_json_visible_contains UIAButton, value
|
23
23
|
end
|
24
24
|
|
25
25
|
# Find the first UIAButton.
|
@@ -38,14 +38,14 @@ module Appium
|
|
38
38
|
# @param value [String] the value to match exactly
|
39
39
|
# @return [UIAButton]
|
40
40
|
def button_exact value
|
41
|
-
|
41
|
+
ele_by_json_visible_exact UIAButton, value
|
42
42
|
end
|
43
43
|
|
44
44
|
# Find all UIAButtons that exactly match value.
|
45
45
|
# @param value [String] the value to match exactly
|
46
46
|
# @return [Array<UIAButton>]
|
47
47
|
def buttons_exact value
|
48
|
-
|
48
|
+
eles_by_json_visible_exact UIAButton, value
|
49
49
|
end
|
50
50
|
end # module Ios
|
51
51
|
end # module Appium
|
@@ -5,28 +5,28 @@ module Appium
|
|
5
5
|
# @param value [String] the value to search for
|
6
6
|
# @return [Element]
|
7
7
|
def find value
|
8
|
-
|
8
|
+
ele_by_json_visible_contains '*', value
|
9
9
|
end
|
10
10
|
|
11
11
|
# Find all elements containing value
|
12
12
|
# @param value [String] the value to search for
|
13
13
|
# @return [Array<Element>]
|
14
14
|
def finds value
|
15
|
-
|
15
|
+
eles_by_json_visible_contains '*', value
|
16
16
|
end
|
17
17
|
|
18
18
|
# Find the first element exactly matching value
|
19
19
|
# @param value [String] the value to search for
|
20
20
|
# @return [Element]
|
21
21
|
def find_exact value
|
22
|
-
|
22
|
+
ele_by_json_visible_exact '*', value
|
23
23
|
end
|
24
24
|
|
25
25
|
# Find all elements exactly matching value
|
26
26
|
# @param value [String] the value to search for
|
27
27
|
# @return [Array<Element>]
|
28
28
|
def finds_exact value
|
29
|
-
|
29
|
+
eles_by_json_visible_exact '*', value
|
30
30
|
end
|
31
31
|
end # module Ios
|
32
32
|
end # module Appium
|
@@ -9,7 +9,7 @@ module Appium
|
|
9
9
|
# @return [UIAStaticText]
|
10
10
|
def text value
|
11
11
|
return ele_index UIAStaticText, value if value.is_a? Numeric
|
12
|
-
|
12
|
+
ele_by_json_visible_contains UIAStaticText, value
|
13
13
|
end
|
14
14
|
|
15
15
|
# Find all UIAStaticText containing value.
|
@@ -18,7 +18,7 @@ module Appium
|
|
18
18
|
# @return [Array<UIAStaticText>]
|
19
19
|
def texts value=false
|
20
20
|
return tags UIAStaticText unless value
|
21
|
-
|
21
|
+
eles_by_json_visible_contains UIAStaticText, value
|
22
22
|
end
|
23
23
|
|
24
24
|
# Find the first UIAStaticText.
|
@@ -37,14 +37,14 @@ module Appium
|
|
37
37
|
# @param value [String] the value to match exactly
|
38
38
|
# @return [UIAStaticText]
|
39
39
|
def text_exact value
|
40
|
-
|
40
|
+
ele_by_json_visible_exact UIAStaticText, value
|
41
41
|
end
|
42
42
|
|
43
43
|
# Find all UIAStaticTexts that exactly match value.
|
44
44
|
# @param value [String] the value to match exactly
|
45
45
|
# @return [Array<UIAStaticText>]
|
46
46
|
def texts_exact value
|
47
|
-
|
47
|
+
eles_by_json_visible_exact UIAStaticText, value
|
48
48
|
end
|
49
49
|
end # module Ios
|
50
50
|
end # module Appium
|