calabash 1.2.1 → 1.9.9.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -1,3 +1,5 @@
1
1
  module Calabash
2
- VERSION = "1.2.1"
2
+
3
+ # @!visibility private
4
+ VERSION = '1.9.9.pre1'
3
5
  end
@@ -0,0 +1,474 @@
1
+ module Calabash
2
+
3
+ # A public API for waiting for things to happen.
4
+ module Wait
5
+ # @!visibility private
6
+ class TimeoutError < RuntimeError
7
+ end
8
+
9
+ # The default options used in the "wait" methods
10
+ @@default_options =
11
+ {
12
+ # default upper limit on how long to wait
13
+ timeout: Environment::WAIT_TIMEOUT,
14
+
15
+ # default message (String or Proc) if timeout occurs
16
+ message: lambda do |options|
17
+ "Timed out after waiting for #{options[:timeout]} seconds..."
18
+ end,
19
+
20
+ # default polling frequency for waiting
21
+ retry_frequency: 0.1,
22
+
23
+ # default exception type to raise when the timeout is exceeded
24
+ exception_class: Calabash::Wait::TimeoutError,
25
+
26
+ # whether to embed a screenshot on failure
27
+ screenshot_on_error: true
28
+ }
29
+
30
+ def self.default_options
31
+ @@default_options
32
+ end
33
+
34
+ def self.default_options=(value)
35
+ @@default_options = value
36
+ end
37
+
38
+ # Evaluates the block given. If the execution time of the block exceeds
39
+ # `timeout` it will raise a TimeoutError.
40
+ #
41
+ # If you have an explicit or implicit loop in your block, or
42
+ # you want to limit the possible execution time of your block, use
43
+ # `with_timeout`.
44
+ #
45
+ # @example
46
+ # # If the 'PictureRow' view does not exist, keep scrolling down.
47
+ # with_timeout(15, 'Could not find picture row') do
48
+ # scroll_down until view_exists?("PictureRow")
49
+ # end
50
+ #
51
+ # # Scroll down **at least once** and continue scrolling down until the
52
+ # # 'PictureRow' exists.
53
+ # wait_for(15, 'Could not find picture row') do
54
+ # scroll_down
55
+ # view_exists?("PictureRow")
56
+ # end
57
+ #
58
+ # @param [Number] timeout The time before failing
59
+ # @param [String, Proc] timeout_message The error message if timed out
60
+ # @param [Class] exception_class The exception type raised if timed out
61
+ # @return The returned value of `block`
62
+ # @raise [ArgumentError] If an invalid timeout is given (<= 0)
63
+ # @raise [ArgumentError] If no timeout_message is given
64
+ # @raise [ArgumentError] If no block is given
65
+ def with_timeout(timeout, timeout_message, exception_class = TimeoutError, &block)
66
+ if timeout_message.nil? ||
67
+ (timeout_message.is_a?(String) && timeout_message.empty?)
68
+ raise ArgumentError, 'You must provide a timeout message'
69
+ end
70
+
71
+ unless block_given?
72
+ raise ArgumentError, 'You must provide a block'
73
+ end
74
+
75
+ # Timeout.timeout will never timeout if the given `timeout` is zero.
76
+ # We will raise an exception if the timeout is zero.
77
+ # Timeout.timeout already raises an exception if `timeout` is negative.
78
+ if timeout == 0
79
+ raise ArgumentError, 'Timeout cannot be 0'
80
+ end
81
+
82
+ message = if timeout_message.is_a?(Proc)
83
+ timeout_message.call({timeout: timeout})
84
+ else
85
+ timeout_message
86
+ end
87
+
88
+ failed = false
89
+
90
+ begin
91
+ Timeout.timeout(timeout, PrivateWaitTimeoutError) do
92
+ return block.call
93
+ end
94
+ rescue PrivateWaitTimeoutError => _
95
+ # If we raise Timeout here the stack trace will be cluttered and we
96
+ # wish to show the user a clear message, avoiding
97
+ # "`rescue in with_timeout':" in the stack trace.
98
+ failed = true
99
+ end
100
+
101
+ if failed
102
+ fail(exception_class, message)
103
+ end
104
+ end
105
+
106
+ # Evaluates the given block until the block evaluates to truthy. If the
107
+ # block raises an error, it is **not** rescued.
108
+ #
109
+ # If the block does not evaluate to truthy within the given timeout
110
+ # an TimeoutError will be raised.
111
+ #
112
+ # The default timeout will be `Wait.default_options[:timeout]`.
113
+ #
114
+ # @see Calabash::Wait#with_timeout
115
+ # @see Calabash::Environment::WAIT_TIMEOUT
116
+ # @see Calabash::Wait.default_options
117
+ #
118
+ # @param [String, Proc] timeout_message The error message if timed out.
119
+ # @param [Hash] options Used to control the behavior of the wait.
120
+ # @option options [Number] :timeout (30) How long to wait before timing out.
121
+ # @option options [Number] :retry_frequency (0.3) How often to check for
122
+ # the condition block to be truthy.
123
+ # @option options [Boolean] :screenshot_on_error (true) Take a screenshot
124
+ # if the block fails to be truthy or an error is raised in the block.
125
+ # @return The returned value of `block` if it is truthy
126
+ def wait_for(timeout_message, options={}, &block)
127
+ wait_options = Wait.default_options.merge(options)
128
+ timeout = wait_options[:timeout]
129
+
130
+ with_timeout(timeout, timeout_message, wait_options[:exception_class]) do
131
+ loop do
132
+ value = block.call
133
+
134
+ return value if value
135
+
136
+ sleep(wait_options[:retry_frequency])
137
+ end
138
+ end
139
+ end
140
+
141
+ # Waits for `query` to match one or more views.
142
+ #
143
+ # @param [String] query Query to match view
144
+ # @see Calabash::Wait#with_timeout for options
145
+ # @return [Object] The first view matching `query`.
146
+ def wait_for_view(query, options={})
147
+ if query.nil?
148
+ raise ArgumentError, 'Query cannot be nil'
149
+ end
150
+
151
+ defaults = Wait.default_options.dup
152
+
153
+ defaults[:message] = lambda do |wait_options|
154
+ "Waited #{wait_options[:timeout]} seconds for #{parse_query_list(query)} to match a view"
155
+ end
156
+
157
+ defaults[:exception_class] = ViewNotFoundError
158
+
159
+ timeout_options = defaults.merge(options)
160
+
161
+ wait_for(timeout_options[:message],
162
+ {timeout: timeout_options[:timeout],
163
+ exception_class: timeout_options[:exception_class],
164
+ retry_frequency: timeout_options[:retry_frequency]}) do
165
+ view_exists?(query)
166
+ end.first
167
+ end
168
+
169
+ # Waits for all `queries` to simultaneously match at least one view.
170
+ #
171
+ # @param [Array<String>, String] queries List of queries or a query.
172
+ # @see Calabash::Wait#with_timeout for options
173
+ # @return [void] The return value for this method is undefined.
174
+ def wait_for_views(*queries, **options)
175
+ if queries.nil? || queries.any?(&:nil?)
176
+ raise ArgumentError, 'Query cannot be nil'
177
+ end
178
+
179
+ defaults = Wait.default_options.dup
180
+ defaults[:message] = lambda do |wait_options|
181
+ "Waited #{wait_options[:timeout]} seconds for #{parse_query_list(queries)} to each match a view"
182
+ end
183
+
184
+ defaults[:exception_class] = ViewNotFoundError
185
+
186
+ timeout_options = defaults.merge(options)
187
+
188
+ wait_for(timeout_options[:message],
189
+ {timeout: timeout_options[:timeout],
190
+ exception_class: timeout_options[:exception_class],
191
+ retry_frequency: timeout_options[:retry_frequency]}) do
192
+ views_exist?(*queries)
193
+ end
194
+
195
+ # Do not return the value of views_exist?(queries) as it clutters
196
+ # a console environment
197
+ true
198
+ end
199
+
200
+ # Waits for `query` not to match any views
201
+ #
202
+ # @param [String] query Query to match view
203
+ # @see Calabash::Wait#with_timeout for options
204
+ def wait_for_no_view(query, options={})
205
+ if query.nil?
206
+ raise ArgumentError, 'Query cannot be nil'
207
+ end
208
+
209
+ defaults = Wait.default_options.dup
210
+ defaults[:message] = lambda do |wait_options|
211
+ "Waited #{wait_options[:timeout]} seconds for #{parse_query_list(query)} to not match any view"
212
+ end
213
+
214
+ defaults[:exception_class] = ViewFoundError
215
+
216
+ timeout_options = defaults.merge(options)
217
+
218
+ wait_for(timeout_options[:message],
219
+ {timeout: timeout_options[:timeout],
220
+ exception_class: timeout_options[:exception_class],
221
+ retry_frequency: timeout_options[:retry_frequency]}) do
222
+ !view_exists?(query)
223
+ end
224
+ end
225
+
226
+ # Waits for all `queries` to simultaneously match no views
227
+ #
228
+ # @param [Array<String>, String] queries List of queries or a query.
229
+ # @see Calabash::Wait#with_timeout for options
230
+ def wait_for_no_views(*queries, **options)
231
+ if queries.nil? || queries.any?(&:nil?)
232
+ raise ArgumentError, 'Query cannot be nil'
233
+ end
234
+
235
+ defaults = Wait.default_options.dup
236
+ defaults[:message] = lambda do |wait_options|
237
+ "Waited #{wait_options[:timeout]} seconds for #{parse_query_list(queries)} to each not match any view"
238
+ end
239
+
240
+ defaults[:exception_class] = ViewFoundError
241
+
242
+ timeout_options = defaults.merge(options)
243
+
244
+ wait_for(timeout_options[:message],
245
+ {timeout: timeout_options[:timeout],
246
+ exception_class: timeout_options[:exception_class],
247
+ retry_frequency: timeout_options[:retry_frequency]}) do
248
+ !views_exist?(*queries)
249
+ end
250
+ end
251
+
252
+ # Does the given `query` match at least one view?
253
+ #
254
+ # @param [String] query Query to match view
255
+ # @return [Object] Returns truthy if the `query` matches at least one view
256
+ # @raise [ArgumentError] If given an invalid `query`
257
+ def view_exists?(query)
258
+ if query.nil?
259
+ raise ArgumentError, 'Query cannot be nil'
260
+ end
261
+
262
+ result = query(query)
263
+
264
+ if result.empty?
265
+ false
266
+ else
267
+ result
268
+ end
269
+ end
270
+
271
+ # Does the given `queries` all match at least one view?
272
+ #
273
+ # @param [Array<String>, String] queries List of queries or a query
274
+ # @return Returns truthy if the `queries` all match at least one view
275
+ # @raise [ArgumentError] If given an invalid list of queries
276
+ def views_exist?(*queries)
277
+ if queries.nil? || queries.any?(&:nil?)
278
+ raise ArgumentError, 'Query cannot be nil'
279
+ end
280
+
281
+ results = queries.map{|query| view_exists?(query)}
282
+
283
+ if results.all?
284
+ results
285
+ else
286
+ false
287
+ end
288
+ end
289
+
290
+ # Expect `query` to match at least one view. Raise an exception if it does
291
+ # not.
292
+ #
293
+ # @param [String] query Query to match view
294
+ # @raise [ArgumentError] If given an invalid `query`
295
+ # @raise [ViewNotFoundError] If `query` does not match at least one view
296
+ def expect_view(query)
297
+ if query.nil?
298
+ raise ArgumentError, 'Query cannot be nil'
299
+ end
300
+
301
+ unless view_exists?(query)
302
+ raise ViewNotFoundError,
303
+ "No view matched #{parse_query_list(query)}"
304
+ end
305
+ end
306
+
307
+ alias_method :view_should_exist, :expect_view
308
+
309
+ # Expect `queries` to each match at least one view. Raise an exception if
310
+ # they do not.
311
+ #
312
+ # @param [String] queries List of queries or a query
313
+ # @raise [ArgumentError] If given an invalid list of queries
314
+ # @raise [ViewNotFoundError] If `queries` do not all match at least one
315
+ # view.
316
+ def expect_views(*queries)
317
+ if queries.nil? || queries.any?(&:nil?)
318
+ raise ArgumentError, 'Query cannot be nil'
319
+ end
320
+
321
+ unless views_exist?(*queries)
322
+ raise ViewNotFoundError,
323
+ "Not all queries #{parse_query_list(queries)} matched a view"
324
+ end
325
+ end
326
+
327
+ alias_method :views_should_exist, :expect_views
328
+
329
+ # Expect `query` to match no views. Raise an exception if it does.
330
+ #
331
+ # @raise [ArgumentError] If given an invalid `query`
332
+ # @raise [ViewFoundError] If `query` matches any views.
333
+ def do_not_expect_view(query)
334
+ if query.nil?
335
+ raise ArgumentError, 'Query cannot be nil'
336
+ end
337
+
338
+ if view_exists?(query)
339
+ raise ViewFoundError, "A view matched #{parse_query_list(query)}"
340
+ end
341
+ end
342
+
343
+ alias_method :view_should_not_exist, :do_not_expect_view
344
+
345
+ # Expect `queries` to each match no views. Raise an exception if they do.
346
+ #
347
+ # @param [Array<String>, String] queries List of queries or a query
348
+ # @raise [ArgumentError] If given an invalid list of queries
349
+ # @raise [ViewFoundError] If one of `queries` matched any views
350
+ def do_not_expect_views(*queries)
351
+ if queries.nil? || queries.any?(&:nil?)
352
+ raise ArgumentError, 'Query cannot be nil'
353
+ end
354
+
355
+ if queries.map{|query| view_exists?(query)}.any?
356
+ raise ViewFoundError,
357
+ "Some views matched #{parse_query_list(queries)}"
358
+ end
359
+ end
360
+
361
+ alias_method :views_should_not_exist, :do_not_expect_views
362
+
363
+ # Waits for a view containing `text`.
364
+ #
365
+ # @param text [String] Text to look for
366
+ # @return [Object] The view matched by the text query
367
+ # @see Calabash::Wait#wait_for_view
368
+ def wait_for_text(text, options={})
369
+ wait_for_view("* {text CONTAINS[c] '#{text}'}", options)
370
+ end
371
+
372
+ # Waits for no views containing `text`.
373
+ #
374
+ # @param text [String] Text to look for
375
+ # @see Calabash::Wait#wait_for_no_view
376
+ def wait_for_text_to_disappear(text, options={})
377
+ wait_for_no_view("* {text CONTAINS[c] '#{text}'}", options)
378
+ end
379
+
380
+ # Raises an exception. Embeds a screenshot if
381
+ # Calabash::Wait#default_options[:screenshot_on_error] is true. The fail
382
+ # method should be used when the test should fail and stop executing. Do
383
+ # not use fail if you intent on rescuing the error raised without
384
+ # re-raising.
385
+ #
386
+ # @example
387
+ # unless view_exists?("* marked:'login'")
388
+ # fail('Did not see "login" button')
389
+ # end
390
+ #
391
+ # @example
392
+ # entries = query("ListEntry").length
393
+ #
394
+ # if entries < 5
395
+ # fail(MyError, "Should see at least 5 entries, saw #{entries}")
396
+ # end
397
+ #
398
+ # @raise [RuntimeError, StandardError] By default, raises a RuntimeError with
399
+ # `message`. You can pass in your own Exception class to override the
400
+ # the default behavior.
401
+ def fail(*several_variants)
402
+ arg0 = several_variants[0]
403
+ arg1 = several_variants[1]
404
+
405
+ if arg1.nil?
406
+ exception_type = RuntimeError
407
+ message = arg0
408
+ else
409
+ exception_type = arg0
410
+ message = arg1
411
+ end
412
+
413
+ screenshot_embed if Wait.default_options[:screenshot_on_error]
414
+
415
+ raise exception_type, message
416
+ end
417
+
418
+ # Raises an exception and always embeds a screenshot
419
+ #
420
+ # @raise [RuntimeError, StandardError] By default, raises a RuntimeError with
421
+ # `message`. You can pass in your own Exception class to override the
422
+ # the default behavior.
423
+ # @see Wait#fail
424
+ def screenshot_and_raise(*several_variants)
425
+ arg0 = several_variants[0]
426
+ arg1 = several_variants[1]
427
+
428
+ if arg1.nil?
429
+ exception_type = RuntimeError
430
+ message = arg0
431
+ else
432
+ exception_type = arg0
433
+ message = arg1
434
+ end
435
+
436
+ screenshot_embed
437
+
438
+ raise exception_type, message
439
+ end
440
+
441
+ # @!visibility private
442
+ def parse_query_list(queries)
443
+ queries = [queries] unless queries.is_a?(Array)
444
+ queries_dup = queries.map{|query| "\"#{query}\""}
445
+
446
+ if queries_dup.length == 0
447
+ ''
448
+ elsif queries_dup.length == 1
449
+ queries_dup.first
450
+ elsif queries_dup.length == 2
451
+ "[#{queries_dup.first} and #{queries_dup.last}]"
452
+ else
453
+ "[#{queries_dup[0, queries_dup.length-1].join(',')}, and #{queries_dup.last}]"
454
+ end
455
+ end
456
+
457
+ # Query matched an unexpected set of views
458
+ class UnexpectedMatchError < RuntimeError
459
+ end
460
+
461
+ # View was found
462
+ class ViewFoundError < UnexpectedMatchError
463
+ end
464
+
465
+ # View was not found
466
+ class ViewNotFoundError < UnexpectedMatchError
467
+ end
468
+
469
+ # @!visibility private
470
+ class PrivateWaitTimeoutError < RuntimeError
471
+ end
472
+
473
+ end
474
+ end