appium_lib 6.0.0 → 7.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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +28 -0
  4. data/.travis.yml +10 -0
  5. data/Rakefile +9 -1
  6. data/android_tests/Gemfile +1 -1
  7. data/android_tests/Rakefile +20 -13
  8. data/android_tests/lib/android/specs/android/element/alert.rb +1 -1
  9. data/android_tests/lib/android/specs/android/element/button.rb +2 -2
  10. data/android_tests/lib/android/specs/android/element/generic.rb +1 -2
  11. data/android_tests/lib/android/specs/android/element/text.rb +2 -3
  12. data/android_tests/lib/android/specs/android/element/textfield.rb +2 -2
  13. data/android_tests/lib/android/specs/android/helper.rb +5 -3
  14. data/android_tests/lib/android/specs/android/patch.rb +2 -2
  15. data/android_tests/lib/android/specs/common/device.rb +16 -9
  16. data/android_tests/lib/android/specs/common/device_touchaction.rb +5 -2
  17. data/android_tests/lib/android/specs/common/element/window.rb +1 -1
  18. data/android_tests/lib/android/specs/common/helper.rb +14 -15
  19. data/android_tests/lib/android/specs/common/patch.rb +11 -9
  20. data/android_tests/lib/android/specs/common/version.rb +3 -3
  21. data/android_tests/lib/android/specs/common/web_context.rb +2 -3
  22. data/android_tests/lib/android/specs/driver.rb +38 -29
  23. data/android_tests/lib/android/specs/install.rb +3 -3
  24. data/android_tests/lib/format.rb +6 -8
  25. data/android_tests/lib/run.rb +25 -17
  26. data/android_tests/readme.md +4 -2
  27. data/appium_lib.gemspec +13 -11
  28. data/contributing.md +1 -1
  29. data/docs/android_docs.md +358 -274
  30. data/docs/ios_docs.md +333 -270
  31. data/docs/migration.md +10 -0
  32. data/docs_gen/make_docs.rb +3 -1
  33. data/ios_tests/Gemfile +1 -1
  34. data/ios_tests/Rakefile +17 -10
  35. data/ios_tests/appium.txt +1 -1
  36. data/ios_tests/lib/common.rb +8 -4
  37. data/ios_tests/lib/format.rb +5 -7
  38. data/ios_tests/lib/ios/specs/common/element/window.rb +1 -1
  39. data/ios_tests/lib/ios/specs/common/helper.rb +40 -39
  40. data/ios_tests/lib/ios/specs/common/patch.rb +15 -11
  41. data/ios_tests/lib/ios/specs/common/version.rb +3 -3
  42. data/ios_tests/lib/ios/specs/common/web_context.rb +1 -2
  43. data/ios_tests/lib/ios/specs/device/device.rb +7 -7
  44. data/ios_tests/lib/ios/specs/device/multi_touch.rb +6 -8
  45. data/ios_tests/lib/ios/specs/device/touch_actions.rb +12 -12
  46. data/ios_tests/lib/ios/specs/driver.rb +23 -22
  47. data/ios_tests/lib/ios/specs/ios/element/alert.rb +6 -2
  48. data/ios_tests/lib/ios/specs/ios/element/button.rb +2 -2
  49. data/ios_tests/lib/ios/specs/ios/element/generic.rb +1 -1
  50. data/ios_tests/lib/ios/specs/ios/element/text.rb +4 -1
  51. data/ios_tests/lib/ios/specs/ios/element/textfield.rb +6 -6
  52. data/ios_tests/lib/ios/specs/ios/helper.rb +5 -5
  53. data/ios_tests/lib/ios/specs/ios/patch.rb +2 -2
  54. data/ios_tests/lib/run.rb +1 -1
  55. data/ios_tests/readme.md +3 -3
  56. data/ios_tests/upload/sauce_storage.rb +8 -8
  57. data/ios_tests/upload/upload.rb +1 -1
  58. data/lib/appium_lib/android/client_xpath.rb +7 -7
  59. data/lib/appium_lib/android/element/alert.rb +2 -2
  60. data/lib/appium_lib/android/element/button.rb +16 -16
  61. data/lib/appium_lib/android/element/generic.rb +12 -13
  62. data/lib/appium_lib/android/element/text.rb +5 -5
  63. data/lib/appium_lib/android/element/textfield.rb +5 -5
  64. data/lib/appium_lib/android/helper.rb +82 -52
  65. data/lib/appium_lib/android/mobile_methods.rb +2 -2
  66. data/lib/appium_lib/android/patch.rb +3 -3
  67. data/lib/appium_lib/common/element/window.rb +1 -1
  68. data/lib/appium_lib/common/helper.rb +30 -35
  69. data/lib/appium_lib/common/patch.rb +22 -20
  70. data/lib/appium_lib/common/version.rb +3 -3
  71. data/lib/appium_lib/common/wait.rb +9 -10
  72. data/lib/appium_lib/device/device.rb +39 -33
  73. data/lib/appium_lib/device/multi_touch.rb +5 -7
  74. data/lib/appium_lib/device/touch_actions.rb +14 -15
  75. data/lib/appium_lib/driver.rb +97 -76
  76. data/lib/appium_lib/ios/element/alert.rb +1 -1
  77. data/lib/appium_lib/ios/element/button.rb +5 -5
  78. data/lib/appium_lib/ios/element/generic.rb +5 -6
  79. data/lib/appium_lib/ios/element/text.rb +5 -5
  80. data/lib/appium_lib/ios/element/textfield.rb +15 -15
  81. data/lib/appium_lib/ios/helper.rb +103 -90
  82. data/lib/appium_lib/ios/mobile_methods.rb +2 -2
  83. data/lib/appium_lib/ios/patch.rb +4 -4
  84. data/lib/appium_lib/logger.rb +7 -5
  85. data/lib/appium_lib/rails/duplicable.rb +3 -1
  86. data/readme.md +7 -1
  87. data/release_notes.md +152 -0
  88. metadata +28 -54
@@ -1,44 +1,43 @@
1
1
  module Appium
2
2
  module Android
3
-
4
3
  # Find the first element containing value
5
4
  # @param value [String] the value to search for
6
5
  # @return [Element]
7
- def find value
6
+ def find(value)
8
7
  complex_find_contains '*', value
9
8
  end
10
9
 
11
10
  # Find all elements containing value
12
11
  # @param value [String] the value to search for
13
12
  # @return [Array<Element>]
14
- def finds value
13
+ def finds(value)
15
14
  complex_finds_contains '*', value
16
15
  end
17
16
 
18
17
  # Find the first element exactly matching value
19
18
  # @param value [String] the value to search for
20
19
  # @return [Element]
21
- def find_exact value
20
+ def find_exact(value)
22
21
  complex_find_exact '*', value
23
22
  end
24
23
 
25
24
  # Find all elements exactly matching value
26
25
  # @param value [String] the value to search for
27
26
  # @return [Array<Element>]
28
- def finds_exact value
27
+ def finds_exact(value)
29
28
  complex_finds_exact '*', value
30
29
  end
31
30
 
32
31
  # @private
33
- def scroll_uiselector content
34
- "new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(#{content}.instance(0));"
35
- end
32
+ def scroll_uiselector(content)
33
+ "new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(#{content}.instance(0));"
34
+ end
36
35
 
37
36
  # Scroll to the first element containing target text or description.
38
37
  # @param text [String] the text to search for in the text value and content description
39
38
  # @return [Element] the element scrolled to
40
- def scroll_to text
41
- text = %Q("#{text}")
39
+ def scroll_to(text)
40
+ text = %("#{text}")
42
41
 
43
42
  args = scroll_uiselector("new UiSelector().textContains(#{text})") +
44
43
  scroll_uiselector("new UiSelector().descriptionContains(#{text})")
@@ -49,8 +48,8 @@ module Appium
49
48
  # Scroll to the first element with the exact target text or description.
50
49
  # @param text [String] the text to search for in the text value and content description
51
50
  # @return [Element] the element scrolled to
52
- def scroll_to_exact text
53
- text = %Q("#{text}")
51
+ def scroll_to_exact(text)
52
+ text = %("#{text}")
54
53
 
55
54
  args = scroll_uiselector("new UiSelector().text(#{text})") +
56
55
  scroll_uiselector("new UiSelector().description(#{text})")
@@ -58,4 +57,4 @@ module Appium
58
57
  find_element :uiautomator, args
59
58
  end
60
59
  end # module Android
61
- end # module Appium
60
+ end # module Appium
@@ -7,7 +7,7 @@ module Appium
7
7
  # @param value [String, Integer] the value to find.
8
8
  # If int then the TextView at that index is returned.
9
9
  # @return [TextView]
10
- def text value
10
+ def text(value)
11
11
  return ele_index TextView, value if value.is_a? Numeric
12
12
  complex_find_contains TextView, value
13
13
  end
@@ -16,7 +16,7 @@ module Appium
16
16
  # If value is omitted, all texts are returned.
17
17
  # @param value [String] the value to search for
18
18
  # @return [Array<TextView>]
19
- def texts value=false
19
+ def texts(value = false)
20
20
  return tags TextView unless value
21
21
  complex_finds_contains TextView, value
22
22
  end
@@ -36,15 +36,15 @@ module Appium
36
36
  # Find the first TextView that exactly matches value.
37
37
  # @param value [String] the value to match exactly
38
38
  # @return [TextView]
39
- def text_exact value
39
+ def text_exact(value)
40
40
  complex_find_exact TextView, value
41
41
  end
42
42
 
43
43
  # Find all TextViews that exactly match value.
44
44
  # @param value [String] the value to match exactly
45
45
  # @return [Array<TextView>]
46
- def texts_exact value
46
+ def texts_exact(value)
47
47
  complex_finds_exact TextView, value
48
48
  end
49
49
  end # module Android
50
- end # module Appium
50
+ end # module Appium
@@ -6,7 +6,7 @@ module Appium
6
6
  # @param value [String, Integer] the text to match exactly.
7
7
  # If int then the EditText at that index is returned.
8
8
  # @return [EditText]
9
- def textfield value
9
+ def textfield(value)
10
10
  return ele_index EditText, value if value.is_a? Numeric
11
11
  complex_find_contains EditText, value
12
12
  end
@@ -15,7 +15,7 @@ module Appium
15
15
  # If value is omitted, all EditTexts are returned.
16
16
  # @param value [String] the value to search for
17
17
  # @return [Array<EditText>]
18
- def textfields value=false
18
+ def textfields(value = false)
19
19
  return tags EditText unless value
20
20
  complex_finds_contains EditText, value
21
21
  end
@@ -35,15 +35,15 @@ module Appium
35
35
  # Find the first EditText that exactly matches value.
36
36
  # @param value [String] the value to match exactly
37
37
  # @return [EditText]
38
- def textfield_exact value
38
+ def textfield_exact(value)
39
39
  complex_find_exact EditText, value
40
40
  end
41
41
 
42
42
  # Find all EditTexts that exactly match value.
43
43
  # @param value [String] the value to match exactly
44
44
  # @return [Array<EditText>]
45
- def textfields_exact value
45
+ def textfields_exact(value)
46
46
  complex_finds_exact EditText, value
47
47
  end
48
48
  end # module Android
49
- end # module Appium
49
+ end # module Appium
@@ -3,14 +3,10 @@ module Appium
3
3
  # @private
4
4
  # http://nokogiri.org/Nokogiri/XML/SAX.html
5
5
  class AndroidElements < Nokogiri::XML::SAX::Document
6
- attr_reader :result, :keys, :instance
7
-
8
- def filter
9
- @filter
10
- end
6
+ attr_reader :result, :keys, :instance, :filter
11
7
 
12
8
  # convert to string to support symbols
13
- def filter= value
9
+ def filter=(value)
14
10
  # nil and false disable the filter
15
11
  return @filter = false unless value
16
12
  @filter = value.to_s.downcase
@@ -19,17 +15,17 @@ module Appium
19
15
  def initialize
20
16
  reset
21
17
  @filter = false
22
- @instance = Hash.new -1
18
+ @instance = Hash.new(-1)
23
19
  end
24
20
 
25
21
  def reset
26
22
  @result = ''
27
- @keys = %w[text resource-id content-desc]
28
- @instance = Hash.new -1
23
+ @keys = %w(text resource-id content-desc)
24
+ @instance = Hash.new(-1)
29
25
  end
30
26
 
31
27
  # http://nokogiri.org/Nokogiri/XML/SAX/Document.html
32
- def start_element name, attrs = []
28
+ def start_element(name, attrs = [])
33
29
  return if filter && !name.downcase.include?(filter)
34
30
 
35
31
  # instance numbers start at 0.
@@ -38,15 +34,18 @@ module Appium
38
34
  attributes = {}
39
35
 
40
36
  attrs.each do |key, value|
41
- if keys.include?(key) && !value.empty?
42
- attributes[key] = value
43
- end
37
+ attributes[key] = value if keys.include?(key) && !value.empty?
44
38
  end
45
39
 
46
40
  # scoped to: text resource-id content-desc
47
41
  attributes_values = attributes.values
48
- id_matches = $driver.lazy_load_strings.select do |key, value|
49
- attributes_values.include? value
42
+ strings = $driver.lazy_load_strings
43
+ id_matches = []
44
+
45
+ unless strings.empty?
46
+ id_matches = strings.select do |_key, value|
47
+ attributes_values.include? value
48
+ end
50
49
  end
51
50
 
52
51
  string_ids = nil
@@ -56,7 +55,7 @@ module Appium
56
55
  string_ids = ''
57
56
 
58
57
  # add first
59
- string_ids += "#{id_matches.shift[0]}\n"
58
+ string_ids += "#{id_matches.shift[0]}\n"
60
59
 
61
60
  # use padding for remaining values
62
61
  # [0] = key, [1] = value
@@ -76,8 +75,8 @@ module Appium
76
75
  string += " text: #{text}\n" unless text.nil?
77
76
  string += " desc: #{desc}\n" unless desc.nil?
78
77
  end
79
- string += " id: #{id}\n" unless id.nil?
80
- string += " strings.xml: #{string_ids}" unless string_ids.nil?
78
+ string += " id: #{id}\n" unless id.nil?
79
+ string += " strings.xml: #{string_ids}" unless string_ids.nil?
81
80
 
82
81
  @result += "\n#{name} (#{number})\n#{string}" unless attributes.empty?
83
82
  end
@@ -86,7 +85,7 @@ module Appium
86
85
  # Fix uiautomator's xml dump.
87
86
  # https://github.com/appium/appium/issues/2822
88
87
  # https://code.google.com/p/android/issues/detail?id=74143
89
- def _fix_android_native_source source
88
+ def _fix_android_native_source(source)
90
89
  # <android.app.ActionBar$Tab
91
90
  # <android.app.ActionBar $ Tab
92
91
 
@@ -105,8 +104,8 @@ module Appium
105
104
 
106
105
  # <android.app.ActionBar$Tab => <android.app.ActionBar.Tab
107
106
  # </android.app.ActionBar$Tab> => </android.app.ActionBar.Tab>
108
- source = source.gsub(/<#{before}\s*\$\s*#{after}/, "<#{fixed}").
109
- gsub(/<\/#{before}\s*\$\s*#{after}>/, "</#{fixed}>")
107
+ source = source.gsub(/<#{before}\s*\$\s*#{after}/,
108
+ "<#{fixed}").gsub(/<\/#{before}\s*\$\s*#{after}>/, "</#{fixed}>")
110
109
  end
111
110
 
112
111
  source
@@ -124,7 +123,7 @@ module Appium
124
123
  # @param class_name [String] the class name to filter on.
125
124
  # if false (default) then all classes will be inspected
126
125
  # @return [String]
127
- def get_android_inspect class_name=false
126
+ def get_android_inspect(class_name = false)
128
127
  source = get_source
129
128
 
130
129
  doctype_string = '<!doctyp'
@@ -150,7 +149,7 @@ module Appium
150
149
  # @option class [Symbol] the class name to filter on. case insensitive include match.
151
150
  # if nil (default) then all classes will be inspected
152
151
  # @return [void]
153
- def page opts={}
152
+ def page(opts = {})
154
153
  class_name = opts.is_a?(Hash) ? opts.fetch(:class, nil) : opts
155
154
  puts get_android_inspect class_name
156
155
  nil
@@ -160,7 +159,8 @@ module Appium
160
159
  # Works on local host only (not remote).
161
160
 
162
161
  # example line:
163
- # "mFocusedApp=AppWindowToken{b1420058 token=Token{b128add0 ActivityRecord{b1264d10 u0 com.example.android.apis/.ApiDemos t23}}}"
162
+ # "mFocusedApp=AppWindowToken{b1420058 token=Token{b128add0
163
+ # ActivityRecord{b1264d10 u0 com.example.android.apis/.ApiDemos t23}}}"
164
164
  def current_app
165
165
  line = `adb shell dumpsys window windows`.each_line.grep(/mFocusedApp/).first.strip
166
166
 
@@ -169,7 +169,7 @@ module Appium
169
169
 
170
170
  # @private
171
171
  # noinspection RubyArgCount
172
- def _parse_current_app_line line
172
+ def _parse_current_app_line(line)
173
173
  match = line.match(/ ([^\/ ]+\/[^ }]+)[ }]/)
174
174
  return nil unless match && match[1]
175
175
 
@@ -185,7 +185,7 @@ module Appium
185
185
  # Find the first matching element by id
186
186
  # @param id [String] the id to search for
187
187
  # @return [Element]
188
- def id id
188
+ def id(id)
189
189
  # Android auto resolves strings.xml ids
190
190
  find_element :id, id
191
191
  end
@@ -193,7 +193,7 @@ module Appium
193
193
  # Find all matching elements by id
194
194
  # @param id [String] the id to search for
195
195
  # @return [Element]
196
- def ids id
196
+ def ids(id)
197
197
  # Android auto resolves strings.xml ids
198
198
  find_elements :id, id
199
199
  end
@@ -202,13 +202,13 @@ module Appium
202
202
  # @param class_name [String] the class name to find
203
203
  # @param index [Integer] the index
204
204
  # @return [Element] the found element of type class_name
205
- def ele_index class_name, index
205
+ def ele_index(class_name, index)
206
206
  results = tags(class_name)
207
207
  if index == 'last()'
208
208
  index = results.length
209
209
  index -= 1 if index >= 0
210
210
  else
211
- raise 'Index must be >= 1' unless index >= 1
211
+ fail 'Index must be >= 1' unless index >= 1
212
212
  index -= 1 if index >= 1
213
213
  end
214
214
 
@@ -220,14 +220,14 @@ module Appium
220
220
  # Find the first element that matches class_name
221
221
  # @param class_name [String] the tag to match
222
222
  # @return [Element]
223
- def first_ele class_name
223
+ def first_ele(class_name)
224
224
  tag(class_name)
225
225
  end
226
226
 
227
227
  # Find the last element that matches class_name
228
228
  # @param class_name [String] the tag to match
229
229
  # @return [Element]
230
- def last_ele class_name
230
+ def last_ele(class_name)
231
231
  ele_index class_name, 'last()'
232
232
  end
233
233
 
@@ -235,7 +235,7 @@ module Appium
235
235
  #
236
236
  # @param class_name [String] the class_name to search for
237
237
  # @return [Element]
238
- def tag class_name
238
+ def tag(class_name)
239
239
  find_element :class, class_name
240
240
  end
241
241
 
@@ -243,11 +243,41 @@ module Appium
243
243
  #
244
244
  # @param class_name [String] the class_name to search for
245
245
  # @return [Element]
246
- def tags class_name
246
+ def tags(class_name)
247
247
  find_elements :class, class_name
248
248
  end
249
249
 
250
250
  # @private
251
+ # Detects if the string represents a resourceId
252
+ # resourceId is only supported on API >= 18 devices
253
+ #
254
+ # @param string [String] the string check for a resourceId
255
+ # value will be auto unquoted
256
+ # @param on_match [String] the string to return on resourceId match
257
+ #
258
+ # @return [String] empty string on failure, on_match on successful match
259
+ def _resource_id(string, on_match)
260
+ return '' unless string
261
+
262
+ # unquote the string
263
+ # "com.example.Test:id/enter" -> com.example.Test:id/enter
264
+ unquote = string.match(/"(.+)"/)
265
+ string = unquote[1] if unquote
266
+
267
+ # java_package : type / name
268
+ #
269
+ # com.example.Test:id/enter
270
+ #
271
+ # ^[a-zA-Z_] - Java package must start with letter or underscore
272
+ # [a-zA-Z0-9\._]* - Java package may contain letters, numbers, periods and underscores
273
+ # : - : ends the package and starts the type
274
+ # [^\/]+ - type is made up of at least one non-/ characters
275
+ # \\/ - / ends the type and starts the name
276
+ # [\S]+$ - the name contains at least one non-space character and then the line is ended
277
+ resource_id = /^[a-zA-Z_][a-zA-Z0-9\._]*:[^\/]+\/[\S]+$/
278
+ string.match(resource_id) ? on_match : ''
279
+ end
280
+
251
281
  # Returns a string that matches the first element that contains value
252
282
  #
253
283
  # example: complex_find_contains 'UIATextField', 'sign in'
@@ -255,19 +285,19 @@ module Appium
255
285
  # @param class_name [String] the class name for the element
256
286
  # @param value [String] the value to search for
257
287
  # @return [String]
258
- def string_visible_contains class_name, value
259
- value = %Q("#{value}")
288
+ def string_visible_contains(class_name, value)
289
+ value = %("#{value}")
260
290
 
261
291
  if class_name == '*'
262
- return "new UiSelector().resourceId(#{value});" +
263
- "new UiSelector().descriptionContains(#{value});" +
292
+ return _resource_id(value, "new UiSelector().resourceId(#{value});") +
293
+ "new UiSelector().descriptionContains(#{value});" \
264
294
  "new UiSelector().textContains(#{value});"
265
295
  end
266
296
 
267
- class_name = %Q("#{class_name}")
297
+ class_name = %("#{class_name}")
268
298
 
269
- "new UiSelector().className(#{class_name}).resourceId(#{value});" +
270
- "new UiSelector().className(#{class_name}).descriptionContains(#{value});" +
299
+ _resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
300
+ "new UiSelector().className(#{class_name}).descriptionContains(#{value});" \
271
301
  "new UiSelector().className(#{class_name}).textContains(#{value});"
272
302
  end
273
303
 
@@ -275,7 +305,7 @@ module Appium
275
305
  # @param element [String] the class name for the element
276
306
  # @param value [String] the value to search for
277
307
  # @return [Element]
278
- def complex_find_contains element, value
308
+ def complex_find_contains(element, value)
279
309
  find_element :uiautomator, string_visible_contains(element, value)
280
310
  end
281
311
 
@@ -283,7 +313,7 @@ module Appium
283
313
  # @param element [String] the class name for the element
284
314
  # @param value [String] the value to search for
285
315
  # @return [Array<Element>]
286
- def complex_finds_contains element, value
316
+ def complex_finds_contains(element, value)
287
317
  find_elements :uiautomator, string_visible_contains(element, value)
288
318
  end
289
319
 
@@ -292,19 +322,19 @@ module Appium
292
322
  # @param class_name [String] the class name for the element
293
323
  # @param value [String] the value to search for
294
324
  # @return [String]
295
- def string_visible_exact class_name, value
296
- value = %Q("#{value}")
325
+ def string_visible_exact(class_name, value)
326
+ value = %("#{value}")
297
327
 
298
328
  if class_name == '*'
299
- return "new UiSelector().resourceId(#{value});" +
300
- "new UiSelector().description(#{value});" +
329
+ return _resource_id(value, "new UiSelector().resourceId(#{value});") +
330
+ "new UiSelector().description(#{value});" \
301
331
  "new UiSelector().text(#{value});"
302
332
  end
303
333
 
304
- class_name = %Q("#{class_name}")
334
+ class_name = %("#{class_name}")
305
335
 
306
- "new UiSelector().className(#{class_name}).resourceId(#{value});" +
307
- "new UiSelector().className(#{class_name}).description(#{value});" +
336
+ _resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
337
+ "new UiSelector().className(#{class_name}).description(#{value});" \
308
338
  "new UiSelector().className(#{class_name}).text(#{value});"
309
339
  end
310
340
 
@@ -312,7 +342,7 @@ module Appium
312
342
  # @param class_name [String] the class name for the element
313
343
  # @param value [String] the value to search for
314
344
  # @return [Element]
315
- def complex_find_exact class_name, value
345
+ def complex_find_exact(class_name, value)
316
346
  find_element :uiautomator, string_visible_exact(class_name, value)
317
347
  end
318
348
 
@@ -320,7 +350,7 @@ module Appium
320
350
  # @param class_name [String] the class name for the element
321
351
  # @param value [String] the value to search for
322
352
  # @return [Element]
323
- def complex_finds_exact class_name, value
353
+ def complex_finds_exact(class_name, value)
324
354
  find_elements :uiautomator, string_visible_exact(class_name, value)
325
355
  end
326
356
 
@@ -334,4 +364,4 @@ module Appium
334
364
  src
335
365
  end
336
366
  end # module Android
337
- end # module Appium
367
+ end # module Appium