rwebspec 3.1.4 → 4.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.
@@ -1,432 +1,432 @@
1
- #***********************************************************
2
- #* Copyright (c) 2006, Zhimin Zhan.
3
- #* Distributed open-source, see full license in MIT-LICENSE
4
- #***********************************************************
5
-
6
- # useful hekoer methods for testing
7
- #
8
- module RWebSpec
9
- module Utils
10
-
11
- # TODO: syntax
12
-
13
- # Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
14
- # Error will be ignored until timeout
15
- # Example
16
- # try_for { click_link('waiting')}
17
- # try_for(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
18
- # try_for { click_button('Search' }
19
- def try_for(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
20
- start_time = Time.now
21
-
22
- last_error = nil
23
- until (duration = Time.now - start_time) > timeout
24
- begin
25
- yield
26
- last_error = nil
27
- return true
28
- rescue => e
29
- last_error = e
30
- end
31
- sleep polling_interval
32
- end
33
-
34
- raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
35
- raise "Timeout after #{duration.to_i} seconds."
36
- end
37
-
38
- alias try_upto try_for
39
- alias try_up_to try_for
40
- alias try_until try_for
41
-
42
- def try(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
43
- puts "Warning: method 'try' is deprecated (won't support in RWebSpec 3), use try_until instead."
44
- try_until(timeout, polling_interval) {
45
- yield
46
- }
47
- end
48
-
49
-
50
- # Try the operation up to specified times, and sleep given interval (in seconds)
51
- # Error will be ignored until timeout
52
- # Example
53
- # repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
54
- # repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
55
- def repeat_try(num_tries = $testwise_polling_timeout || 30, interval = $testwise_polling_interval || 1, & block)
56
- num_tries ||= 1
57
- (num_tries - 1).times do |num|
58
- begin
59
- yield
60
- return
61
- rescue => e
62
- # puts "debug: #{num} failed: #{e}"
63
- sleep interval
64
- end
65
- end
66
-
67
- # last try, throw error if still fails
68
- begin
69
- yield
70
- rescue => e
71
- raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
72
- end
73
- yield
74
- end
75
-
76
-
77
- ##
78
- # Convert :first to 1, :second to 2, and so on...
79
- def symbol_to_sequence(symb)
80
- value = {:zero => 0,
81
- :first => 1,
82
- :second => 2,
83
- :third => 3,
84
- :fourth => 4,
85
- :fifth => 5,
86
- :sixth => 6,
87
- :seventh => 7,
88
- :eighth => 8,
89
- :ninth => 9,
90
- :tenth => 10}[symb]
91
- return value || symb.to_i
92
- end
93
-
94
-
95
-
96
- # use win32screenshot library to save curernt active window, which shall be IE
97
- #
98
- # opts[:to_dir] => the direcotry to save image under
99
- def take_screenshot(opts = {})
100
- # puts "calling new take screenshot: #{$screenshot_supported}"
101
- unless $screenshot_supported
102
- puts " [WARN] Screenhost not supported, check whether win32screenshot gem is installed"
103
- return
104
- end
105
-
106
- begin
107
- screenshot_image_filename = "screenshot_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
108
- the_dump_dir = opts[:to_dir] || default_dump_dir
109
- FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
110
- screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
111
- screenshot_image_filepath.gsub!("/", "\\") if is_windows?
112
-
113
- FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
114
-
115
- if is_firefox? then
116
- Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
117
- elsif ie
118
- Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
119
- else
120
- Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
121
- end
122
- notify_screenshot_location(screenshot_image_filepath)
123
- rescue ::DL::DLTypeError => de
124
- puts "No screenshot libray found: #{de}"
125
- rescue => e
126
- puts "error on taking screenshot: #{e}"
127
- end
128
-
129
- end
130
-
131
- #= Convenient functions
132
- #
133
-
134
- # Using Ruby block syntax to create interesting domain specific language,
135
- # may be appeal to someone.
136
-
137
- # Example:
138
- # on @page do |i|
139
- # i.enter_text('btn1')
140
- # i.click_button('btn1')
141
- # end
142
- def on(page, & block)
143
- yield page
144
- end
145
-
146
- # fail the test if user can perform the operation
147
- #
148
- # Example:
149
- # shall_not_allow { 1/0 }
150
- def shall_not_allow(& block)
151
- operation_performed_ok = false
152
- begin
153
- yield
154
- operation_performed_ok = true
155
- rescue
156
- end
157
- raise "Operation shall not be allowed" if operation_performed_ok
158
- end
159
-
160
- alias do_not_allow shall_not_allow
161
-
162
- # Does not provide real function, other than make enhancing test syntax
163
- #
164
- # Example:
165
- # allow { click_button('Register') }
166
- def allow(& block)
167
- yield
168
- end
169
-
170
- alias shall_allow allow
171
- alias allowing allow
172
-
173
- # try operation, ignore if errors occur
174
- #
175
- # Example:
176
- # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
177
- def failsafe(& block)
178
- begin
179
- yield
180
- rescue =>e
181
- end
182
- end
183
-
184
- alias fail_safe failsafe
185
-
186
- # default date format returned is 29/12/2007.
187
- # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
188
- # Otherwise, "2007-12-29", which is most approiate date format
189
- #
190
- # %a - The abbreviated weekday name (``Sun'')
191
- # %A - The full weekday name (``Sunday'')
192
- # %b - The abbreviated month name (``Jan'')
193
- # %B - The full month name (``January'')
194
- # %c - The preferred local date and time representation
195
- # %d - Day of the month (01..31)
196
- # %H - Hour of the day, 24-hour clock (00..23)
197
- # %I - Hour of the day, 12-hour clock (01..12)
198
- # %j - Day of the year (001..366)
199
- # %m - Month of the year (01..12)
200
- # %M - Minute of the hour (00..59)
201
- # %p - Meridian indicator (``AM'' or ``PM'')
202
- # %S - Second of the minute (00..60)
203
- # %U - Week number of the current year,
204
- # starting with the first Sunday as the first
205
- # day of the first week (00..53)
206
- # %W - Week number of the current year,
207
- # starting with the first Monday as the first
208
- # day of the first week (00..53)
209
- # %w - Day of the week (Sunday is 0, 0..6)
210
- # %x - Preferred representation for the date alone, no time
211
- # %X - Preferred representation for the time alone, no date
212
- # %y - Year without a century (00..99)
213
- # %Y - Year with century
214
- # %Z - Time zone name
215
- # %% - Literal ``%'' character
216
-
217
- def today(format = nil)
218
- format_date(Time.now, date_format(format))
219
- end
220
- alias getToday_AU today
221
- alias getToday_US today
222
- alias getToday today
223
-
224
-
225
- def days_before(days, format = nil)
226
- return nil if !(days.instance_of?(Fixnum))
227
- format_date(Time.now - days * 24 * 3600, date_format(format))
228
- end
229
-
230
- def yesterday(format = nil)
231
- days_before(1, date_format(format))
232
- end
233
-
234
- def days_from_now(days, format = nil)
235
- return nil if !(days.instance_of?(Fixnum))
236
- format_date(Time.now + days * 24 * 3600, date_format(format))
237
- end
238
- alias days_after days_from_now
239
-
240
- def tomorrow(format = nil)
241
- days_from_now(1, date_format(format))
242
- end
243
-
244
-
245
- # return a random number >= min, but <= max
246
- def random_number(min, max)
247
- rand(max-min+1)+min
248
- end
249
-
250
- def random_boolean
251
- return random_number(0, 1) == 1
252
- end
253
-
254
- def random_char(lowercase = true)
255
- if lowercase
256
- sprintf("%c", random_number(97, 122))
257
- else
258
- sprintf("%c", random_number(65, 90))
259
- end
260
- end
261
-
262
- def random_digit()
263
- sprintf("%c", random_number(48, 57))
264
- end
265
-
266
- def random_str(length, lowercase = true)
267
- randomStr = ""
268
- length.times {
269
- randomStr += random_char(lowercase)
270
- }
271
- randomStr
272
- end
273
-
274
- # Return a random string in a rangeof pre-defined strings
275
- def random_string_in(arr)
276
- return nil if arr.empty?
277
- index = random_number(0, arr.length-1)
278
- arr[index]
279
- end
280
- alias random_string_in_collection random_string_in
281
-
282
-
283
- WORDS = %w(alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo aspernatur aut odit aut fugit sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt neque dolorem ipsum quia dolor sit amet consectetur adipisci velit sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem ut enim ad minima veniam quis nostrum exercitationem ullam corporis nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam nisi ut aliquid ex ea commodi consequatur quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi id est laborum et dolorum fuga et harum quidem rerum facilis est et expedita distinctio nam libero tempore cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est qui minus id quod maxime placeat facere possimus omnis voluptas assumenda est omnis dolor repellendus temporibus autem quibusdam et aut consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur at vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae itaque earum rerum hic tenetur a sapiente delectus ut aut reiciendis voluptatibus maiores doloribus asperiores repellat)
284
-
285
- # Pick a random value out of a given range.
286
- def value_in_range(range)
287
- case range.first
288
- when Integer then number_in_range(range)
289
- when Time then time_in_range(range)
290
- when Date then date_in_range(range)
291
- else range.to_a.rand
292
- end
293
- end
294
-
295
- # Generate a given number of words. If a range is passed, it will generate
296
- # a random number of words within that range.
297
- def words(total)
298
- if total.class == Range
299
- (1..interpret_value(total)).map { WORDS[random_number(total.min, total.max)] }.join(' ')
300
- else
301
- (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
302
- end
303
- end
304
-
305
- # Generate a given number of sentences. If a range is passed, it will generate
306
- # a random number of sentences within that range.
307
- def sentences(total)
308
- (1..interpret_value(total)).map do
309
- words(5..20).capitalize
310
- end.join('. ')
311
- end
312
-
313
- # Generate a given number of paragraphs. If a range is passed, it will generate
314
- # a random number of paragraphs within that range.
315
- def paragraphs(total)
316
- (1..interpret_value(total)).map do
317
- sentences(3..8).capitalize
318
- end.join("\n\n")
319
- end
320
-
321
- # If an array or range is passed, a random value will be selected to match.
322
- # All other values are simply returned.
323
- def interpret_value(value)
324
- case value
325
- when Array then value.rand
326
- when Range then value_in_range(value)
327
- else value
328
- end
329
- end
330
-
331
- private
332
-
333
- def time_in_range(range)
334
- Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
335
- end
336
-
337
- def date_in_range(range)
338
- Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
339
- end
340
-
341
- def number_in_range(range)
342
- if range.exclude_end?
343
- rand(range.last - range.first) + range.first
344
- else
345
- rand((range.last+1) - range.first) + range.first
346
- end
347
- end
348
-
349
- def format_date(date, date_format = '%d/%m/%Y')
350
- date.strftime(date_format)
351
- end
352
-
353
- def date_format(format_argument)
354
- if format_argument.nil? then
355
- get_locale_date_format(default_locale)
356
- elsif format_argument.class == Symbol then
357
- get_locale_date_format(format_argument)
358
- elsif format_argument.class == String then
359
- format_argument
360
- else
361
- # invalid input, use default
362
- get_locale_date_format(default_date_format)
363
- end
364
-
365
- end
366
-
367
- def get_locale_date_format(locale)
368
- case locale
369
- when :us
370
- "%m/%d/%Y"
371
- when :au, :uk
372
- "%d/%m/%Y"
373
- else
374
- "%Y-%m-%d"
375
- end
376
- end
377
-
378
- def default_locale
379
- return :au
380
- end
381
-
382
-
383
- def average_of(array)
384
- array.inject(0.0) { |sum, e| sum + e } / array.length
385
- end
386
-
387
- # NOTE might cause issues
388
- # why it is removed total
389
- def sum_of(array)
390
- array.inject(0.0) { |sum, e| sum + e }
391
- end
392
-
393
- ## Data Driven Tests
394
- #
395
- # Processing each row in a CSV file, must have heading rows
396
- #
397
- # Usage:
398
- #
399
- # process_each_row_in_csv_file(@csv_file) { |row|
400
- # goto_page("/")
401
- # enter_text("username", row[1])
402
- # enter_text("password", row[2])
403
- # click_button("Sign in")
404
- # page_text.should contain(row[3])
405
- # failsafe{ click_link("Sign off") }
406
- # }
407
- #
408
- def process_each_row_in_csv_file(csv_file, &block)
409
- require 'faster_csv'
410
- connect_to_testwise("CSV_START", csv_file) if $testwise_support
411
- has_error = false
412
- idx = 0
413
- FasterCSV.foreach(csv_file, :headers => :first_row, :encoding => 'u') do |row|
414
- connect_to_testwise("CSV_ON_ROW", idx.to_s) if $testwise_support
415
- begin
416
- yield row
417
- connect_to_testwise("CSV_ROW_PASS", idx.to_s) if $testwise_support
418
- rescue => e
419
- connect_to_testwise("CSV_ROW_FAIL", idx.to_s) if $testwise_support
420
- has_error = true
421
- ensure
422
- idx += 1
423
- end
424
- end
425
-
426
- connect_to_testwise("CSV_END", "") if $testwise_support
427
- raise "Test failed on data" if has_error
428
- end
429
-
430
-
431
- end
432
- end
1
+ #***********************************************************
2
+ #* Copyright (c) 2006, Zhimin Zhan.
3
+ #* Distributed open-source, see full license in MIT-LICENSE
4
+ #***********************************************************
5
+
6
+ # useful hekoer methods for testing
7
+ #
8
+ module RWebSpec
9
+ module Utils
10
+
11
+ # TODO: syntax
12
+
13
+ # Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
14
+ # Error will be ignored until timeout
15
+ # Example
16
+ # try_for { click_link('waiting')}
17
+ # try_for(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
18
+ # try_for { click_button('Search' }
19
+ def try_for(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
20
+ start_time = Time.now
21
+
22
+ last_error = nil
23
+ until (duration = Time.now - start_time) > timeout
24
+ begin
25
+ yield
26
+ last_error = nil
27
+ return true
28
+ rescue => e
29
+ last_error = e
30
+ end
31
+ sleep polling_interval
32
+ end
33
+
34
+ raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
35
+ raise "Timeout after #{duration.to_i} seconds."
36
+ end
37
+
38
+ alias try_upto try_for
39
+ alias try_up_to try_for
40
+ alias try_until try_for
41
+
42
+ def try(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
43
+ puts "Warning: method 'try' is deprecated (won't support in RWebSpec 3), use try_until instead."
44
+ try_until(timeout, polling_interval) {
45
+ yield
46
+ }
47
+ end
48
+
49
+
50
+ # Try the operation up to specified times, and sleep given interval (in seconds)
51
+ # Error will be ignored until timeout
52
+ # Example
53
+ # repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
54
+ # repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
55
+ def repeat_try(num_tries = $testwise_polling_timeout || 30, interval = $testwise_polling_interval || 1, & block)
56
+ num_tries ||= 1
57
+ (num_tries - 1).times do |num|
58
+ begin
59
+ yield
60
+ return
61
+ rescue => e
62
+ # puts "debug: #{num} failed: #{e}"
63
+ sleep interval
64
+ end
65
+ end
66
+
67
+ # last try, throw error if still fails
68
+ begin
69
+ yield
70
+ rescue => e
71
+ raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
72
+ end
73
+ yield
74
+ end
75
+
76
+
77
+ ##
78
+ # Convert :first to 1, :second to 2, and so on...
79
+ def symbol_to_sequence(symb)
80
+ value = {:zero => 0,
81
+ :first => 1,
82
+ :second => 2,
83
+ :third => 3,
84
+ :fourth => 4,
85
+ :fifth => 5,
86
+ :sixth => 6,
87
+ :seventh => 7,
88
+ :eighth => 8,
89
+ :ninth => 9,
90
+ :tenth => 10}[symb]
91
+ return value || symb.to_i
92
+ end
93
+
94
+
95
+
96
+ # use win32screenshot library to save curernt active window, which shall be IE
97
+ #
98
+ # opts[:to_dir] => the direcotry to save image under
99
+ def take_screenshot(opts = {})
100
+ # puts "calling new take screenshot: #{$screenshot_supported}"
101
+ unless $screenshot_supported
102
+ puts " [WARN] Screenhost not supported, check whether win32screenshot gem is installed"
103
+ return
104
+ end
105
+
106
+ begin
107
+ screenshot_image_filename = "screenshot_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
108
+ the_dump_dir = opts[:to_dir] || default_dump_dir
109
+ FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
110
+ screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
111
+ screenshot_image_filepath.gsub!("/", "\\") if is_windows?
112
+
113
+ FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
114
+
115
+ if is_firefox? then
116
+ Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
117
+ elsif ie
118
+ Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
119
+ else
120
+ Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
121
+ end
122
+ notify_screenshot_location(screenshot_image_filepath)
123
+ rescue ::DL::DLTypeError => de
124
+ puts "No screenshot libray found: #{de}"
125
+ rescue => e
126
+ puts "error on taking screenshot: #{e}"
127
+ end
128
+
129
+ end
130
+
131
+ #= Convenient functions
132
+ #
133
+
134
+ # Using Ruby block syntax to create interesting domain specific language,
135
+ # may be appeal to someone.
136
+
137
+ # Example:
138
+ # on @page do |i|
139
+ # i.enter_text('btn1')
140
+ # i.click_button('btn1')
141
+ # end
142
+ def on(page, & block)
143
+ yield page
144
+ end
145
+
146
+ # fail the test if user can perform the operation
147
+ #
148
+ # Example:
149
+ # shall_not_allow { 1/0 }
150
+ def shall_not_allow(& block)
151
+ operation_performed_ok = false
152
+ begin
153
+ yield
154
+ operation_performed_ok = true
155
+ rescue
156
+ end
157
+ raise "Operation shall not be allowed" if operation_performed_ok
158
+ end
159
+
160
+ alias do_not_allow shall_not_allow
161
+
162
+ # Does not provide real function, other than make enhancing test syntax
163
+ #
164
+ # Example:
165
+ # allow { click_button('Register') }
166
+ def allow(& block)
167
+ yield
168
+ end
169
+
170
+ alias shall_allow allow
171
+ alias allowing allow
172
+
173
+ # try operation, ignore if errors occur
174
+ #
175
+ # Example:
176
+ # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
177
+ def failsafe(& block)
178
+ begin
179
+ yield
180
+ rescue =>e
181
+ end
182
+ end
183
+
184
+ alias fail_safe failsafe
185
+
186
+ # default date format returned is 29/12/2007.
187
+ # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
188
+ # Otherwise, "2007-12-29", which is most approiate date format
189
+ #
190
+ # %a - The abbreviated weekday name (``Sun'')
191
+ # %A - The full weekday name (``Sunday'')
192
+ # %b - The abbreviated month name (``Jan'')
193
+ # %B - The full month name (``January'')
194
+ # %c - The preferred local date and time representation
195
+ # %d - Day of the month (01..31)
196
+ # %H - Hour of the day, 24-hour clock (00..23)
197
+ # %I - Hour of the day, 12-hour clock (01..12)
198
+ # %j - Day of the year (001..366)
199
+ # %m - Month of the year (01..12)
200
+ # %M - Minute of the hour (00..59)
201
+ # %p - Meridian indicator (``AM'' or ``PM'')
202
+ # %S - Second of the minute (00..60)
203
+ # %U - Week number of the current year,
204
+ # starting with the first Sunday as the first
205
+ # day of the first week (00..53)
206
+ # %W - Week number of the current year,
207
+ # starting with the first Monday as the first
208
+ # day of the first week (00..53)
209
+ # %w - Day of the week (Sunday is 0, 0..6)
210
+ # %x - Preferred representation for the date alone, no time
211
+ # %X - Preferred representation for the time alone, no date
212
+ # %y - Year without a century (00..99)
213
+ # %Y - Year with century
214
+ # %Z - Time zone name
215
+ # %% - Literal ``%'' character
216
+
217
+ def today(format = nil)
218
+ format_date(Time.now, date_format(format))
219
+ end
220
+ alias getToday_AU today
221
+ alias getToday_US today
222
+ alias getToday today
223
+
224
+
225
+ def days_before(days, format = nil)
226
+ return nil if !(days.instance_of?(Fixnum))
227
+ format_date(Time.now - days * 24 * 3600, date_format(format))
228
+ end
229
+
230
+ def yesterday(format = nil)
231
+ days_before(1, date_format(format))
232
+ end
233
+
234
+ def days_from_now(days, format = nil)
235
+ return nil if !(days.instance_of?(Fixnum))
236
+ format_date(Time.now + days * 24 * 3600, date_format(format))
237
+ end
238
+ alias days_after days_from_now
239
+
240
+ def tomorrow(format = nil)
241
+ days_from_now(1, date_format(format))
242
+ end
243
+
244
+
245
+ # return a random number >= min, but <= max
246
+ def random_number(min, max)
247
+ rand(max-min+1)+min
248
+ end
249
+
250
+ def random_boolean
251
+ return random_number(0, 1) == 1
252
+ end
253
+
254
+ def random_char(lowercase = true)
255
+ if lowercase
256
+ sprintf("%c", random_number(97, 122))
257
+ else
258
+ sprintf("%c", random_number(65, 90))
259
+ end
260
+ end
261
+
262
+ def random_digit()
263
+ sprintf("%c", random_number(48, 57))
264
+ end
265
+
266
+ def random_str(length, lowercase = true)
267
+ randomStr = ""
268
+ length.times {
269
+ randomStr += random_char(lowercase)
270
+ }
271
+ randomStr
272
+ end
273
+
274
+ # Return a random string in a rangeof pre-defined strings
275
+ def random_string_in(arr)
276
+ return nil if arr.empty?
277
+ index = random_number(0, arr.length-1)
278
+ arr[index]
279
+ end
280
+ alias random_string_in_collection random_string_in
281
+
282
+
283
+ WORDS = %w(alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo aspernatur aut odit aut fugit sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt neque dolorem ipsum quia dolor sit amet consectetur adipisci velit sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem ut enim ad minima veniam quis nostrum exercitationem ullam corporis nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam nisi ut aliquid ex ea commodi consequatur quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi id est laborum et dolorum fuga et harum quidem rerum facilis est et expedita distinctio nam libero tempore cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est qui minus id quod maxime placeat facere possimus omnis voluptas assumenda est omnis dolor repellendus temporibus autem quibusdam et aut consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur at vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae itaque earum rerum hic tenetur a sapiente delectus ut aut reiciendis voluptatibus maiores doloribus asperiores repellat)
284
+
285
+ # Pick a random value out of a given range.
286
+ def value_in_range(range)
287
+ case range.first
288
+ when Integer then number_in_range(range)
289
+ when Time then time_in_range(range)
290
+ when Date then date_in_range(range)
291
+ else range.to_a.rand
292
+ end
293
+ end
294
+
295
+ # Generate a given number of words. If a range is passed, it will generate
296
+ # a random number of words within that range.
297
+ def words(total)
298
+ if total.class == Range
299
+ (1..interpret_value(total)).map { WORDS[random_number(total.min, total.max)] }.join(' ')
300
+ else
301
+ (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
302
+ end
303
+ end
304
+
305
+ # Generate a given number of sentences. If a range is passed, it will generate
306
+ # a random number of sentences within that range.
307
+ def sentences(total)
308
+ (1..interpret_value(total)).map do
309
+ words(5..20).capitalize
310
+ end.join('. ')
311
+ end
312
+
313
+ # Generate a given number of paragraphs. If a range is passed, it will generate
314
+ # a random number of paragraphs within that range.
315
+ def paragraphs(total)
316
+ (1..interpret_value(total)).map do
317
+ sentences(3..8).capitalize
318
+ end.join("\n\n")
319
+ end
320
+
321
+ # If an array or range is passed, a random value will be selected to match.
322
+ # All other values are simply returned.
323
+ def interpret_value(value)
324
+ case value
325
+ when Array then value.rand
326
+ when Range then value_in_range(value)
327
+ else value
328
+ end
329
+ end
330
+
331
+ private
332
+
333
+ def time_in_range(range)
334
+ Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
335
+ end
336
+
337
+ def date_in_range(range)
338
+ Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
339
+ end
340
+
341
+ def number_in_range(range)
342
+ if range.exclude_end?
343
+ rand(range.last - range.first) + range.first
344
+ else
345
+ rand((range.last+1) - range.first) + range.first
346
+ end
347
+ end
348
+
349
+ def format_date(date, date_format = '%d/%m/%Y')
350
+ date.strftime(date_format)
351
+ end
352
+
353
+ def date_format(format_argument)
354
+ if format_argument.nil? then
355
+ get_locale_date_format(default_locale)
356
+ elsif format_argument.class == Symbol then
357
+ get_locale_date_format(format_argument)
358
+ elsif format_argument.class == String then
359
+ format_argument
360
+ else
361
+ # invalid input, use default
362
+ get_locale_date_format(default_date_format)
363
+ end
364
+
365
+ end
366
+
367
+ def get_locale_date_format(locale)
368
+ case locale
369
+ when :us
370
+ "%m/%d/%Y"
371
+ when :au, :uk
372
+ "%d/%m/%Y"
373
+ else
374
+ "%Y-%m-%d"
375
+ end
376
+ end
377
+
378
+ def default_locale
379
+ return :au
380
+ end
381
+
382
+
383
+ def average_of(array)
384
+ array.inject(0.0) { |sum, e| sum + e } / array.length
385
+ end
386
+
387
+ # NOTE might cause issues
388
+ # why it is removed total
389
+ def sum_of(array)
390
+ array.inject(0.0) { |sum, e| sum + e }
391
+ end
392
+
393
+ ## Data Driven Tests
394
+ #
395
+ # Processing each row in a CSV file, must have heading rows
396
+ #
397
+ # Usage:
398
+ #
399
+ # process_each_row_in_csv_file(@csv_file) { |row|
400
+ # goto_page("/")
401
+ # enter_text("username", row[1])
402
+ # enter_text("password", row[2])
403
+ # click_button("Sign in")
404
+ # page_text.should contain(row[3])
405
+ # failsafe{ click_link("Sign off") }
406
+ # }
407
+ #
408
+ def process_each_row_in_csv_file(csv_file, &block)
409
+ require 'faster_csv'
410
+ connect_to_testwise("CSV_START", csv_file) if $testwise_support
411
+ has_error = false
412
+ idx = 0
413
+ FasterCSV.foreach(csv_file, :headers => :first_row, :encoding => 'u') do |row|
414
+ connect_to_testwise("CSV_ON_ROW", idx.to_s) if $testwise_support
415
+ begin
416
+ yield row
417
+ connect_to_testwise("CSV_ROW_PASS", idx.to_s) if $testwise_support
418
+ rescue => e
419
+ connect_to_testwise("CSV_ROW_FAIL", idx.to_s) if $testwise_support
420
+ has_error = true
421
+ ensure
422
+ idx += 1
423
+ end
424
+ end
425
+
426
+ connect_to_testwise("CSV_END", "") if $testwise_support
427
+ raise "Test failed on data" if has_error
428
+ end
429
+
430
+
431
+ end
432
+ end