rwebspec-mechanize 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,393 @@
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 Mechanize
10
+
11
+ module Utils
12
+
13
+ # TODO: syntax
14
+
15
+ # Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
16
+ # Error will be ignored until timeout
17
+ # Example
18
+ # try_until { click_link('waiting')}
19
+ # try_until(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
20
+ # try_until { click_button('Search' }
21
+ def try_until(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
22
+ start_time = Time.now
23
+
24
+ last_error = nil
25
+ until (duration = Time.now - start_time) > timeout
26
+ begin
27
+ yield
28
+ last_error = nil
29
+ return true
30
+ rescue => e
31
+ last_error = e
32
+ end
33
+ sleep polling_interval
34
+ end
35
+
36
+ raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
37
+ raise "Timeout after #{duration.to_i} seconds."
38
+ end
39
+
40
+ alias try_upto try_until
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 => e
124
+ puts "error on taking screenshot: #{e}"
125
+ end
126
+
127
+ end
128
+
129
+ #= Convenient functions
130
+ #
131
+
132
+ # Using Ruby block syntax to create interesting domain specific language,
133
+ # may be appeal to someone.
134
+
135
+ # Example:
136
+ # on @page do |i|
137
+ # i.enter_text('btn1')
138
+ # i.click_button('btn1')
139
+ # end
140
+ def on(page, & block)
141
+ yield page
142
+ end
143
+
144
+ # fail the test if user can perform the operation
145
+ #
146
+ # Example:
147
+ # shall_not_allow { 1/0 }
148
+ def shall_not_allow(& block)
149
+ operation_performed_ok = false
150
+ begin
151
+ yield
152
+ operation_performed_ok = true
153
+ rescue
154
+ end
155
+ raise "Operation shall not be allowed" if operation_performed_ok
156
+ end
157
+
158
+ alias do_not_allow shall_not_allow
159
+
160
+ # Does not provide real function, other than make enhancing test syntax
161
+ #
162
+ # Example:
163
+ # allow { click_button('Register') }
164
+ def allow(& block)
165
+ yield
166
+ end
167
+
168
+ alias shall_allow allow
169
+ alias allowing allow
170
+
171
+ # try operation, ignore if errors occur
172
+ #
173
+ # Example:
174
+ # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
175
+ def failsafe(& block)
176
+ begin
177
+ yield
178
+ rescue =>e
179
+ end
180
+ end
181
+
182
+ alias fail_safe failsafe
183
+
184
+ # default date format returned is 29/12/2007.
185
+ # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
186
+ # Otherwise, "2007-12-29", which is most approiate date format
187
+ #
188
+ # %a - The abbreviated weekday name (``Sun'')
189
+ # %A - The full weekday name (``Sunday'')
190
+ # %b - The abbreviated month name (``Jan'')
191
+ # %B - The full month name (``January'')
192
+ # %c - The preferred local date and time representation
193
+ # %d - Day of the month (01..31)
194
+ # %H - Hour of the day, 24-hour clock (00..23)
195
+ # %I - Hour of the day, 12-hour clock (01..12)
196
+ # %j - Day of the year (001..366)
197
+ # %m - Month of the year (01..12)
198
+ # %M - Minute of the hour (00..59)
199
+ # %p - Meridian indicator (``AM'' or ``PM'')
200
+ # %S - Second of the minute (00..60)
201
+ # %U - Week number of the current year,
202
+ # starting with the first Sunday as the first
203
+ # day of the first week (00..53)
204
+ # %W - Week number of the current year,
205
+ # starting with the first Monday as the first
206
+ # day of the first week (00..53)
207
+ # %w - Day of the week (Sunday is 0, 0..6)
208
+ # %x - Preferred representation for the date alone, no time
209
+ # %X - Preferred representation for the time alone, no date
210
+ # %y - Year without a century (00..99)
211
+ # %Y - Year with century
212
+ # %Z - Time zone name
213
+ # %% - Literal ``%'' character
214
+
215
+ def today(format = nil)
216
+ format_date(Time.now, date_format(format))
217
+ end
218
+ alias getToday_AU today
219
+ alias getToday_US today
220
+ alias getToday today
221
+
222
+
223
+ def days_before(days, format = nil)
224
+ return nil if !(days.instance_of?(Fixnum))
225
+ format_date(Time.now - days * 24 * 3600, date_format(format))
226
+ end
227
+
228
+ def yesterday(format = nil)
229
+ days_before(1, date_format(format))
230
+ end
231
+
232
+ def days_from_now(days, format = nil)
233
+ return nil if !(days.instance_of?(Fixnum))
234
+ format_date(Time.now + days * 24 * 3600, date_format(format))
235
+ end
236
+ alias days_after days_from_now
237
+
238
+ def tomorrow(format = nil)
239
+ days_from_now(1, date_format(format))
240
+ end
241
+
242
+
243
+ # return a random number >= min, but <= max
244
+ def random_number(min, max)
245
+ rand(max-min+1)+min
246
+ end
247
+
248
+ def random_boolean
249
+ return random_number(0, 1) == 1
250
+ end
251
+
252
+ def random_char(lowercase = true)
253
+ if lowercase
254
+ sprintf("%c", random_number(97, 122))
255
+ else
256
+ sprintf("%c", random_number(65, 90))
257
+ end
258
+ end
259
+
260
+ def random_digit()
261
+ sprintf("%c", random_number(48, 57))
262
+ end
263
+
264
+ def random_str(length, lowercase = true)
265
+ randomStr = ""
266
+ length.times {
267
+ randomStr += random_char(lowercase)
268
+ }
269
+ randomStr
270
+ end
271
+
272
+ # Return a random string in a rangeof pre-defined strings
273
+ def random_string_in(arr)
274
+ return nil if arr.empty?
275
+ index = random_number(0, arr.length-1)
276
+ arr[index]
277
+ end
278
+ alias random_string_in_collection random_string_in
279
+
280
+
281
+ 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)
282
+
283
+ # Pick a random value out of a given range.
284
+ def value_in_range(range)
285
+ case range.first
286
+ when Integer then number_in_range(range)
287
+ when Time then time_in_range(range)
288
+ when Date then date_in_range(range)
289
+ else range.to_a.rand
290
+ end
291
+ end
292
+
293
+ # Generate a given number of words. If a range is passed, it will generate
294
+ # a random number of words within that range.
295
+ def words(total)
296
+ if total.class == Range
297
+ (1..interpret_value(total)).map { WORDS[random_number(total.min, total.max)] }.join(' ')
298
+ else
299
+ (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
300
+ end
301
+ end
302
+
303
+ # Generate a given number of sentences. If a range is passed, it will generate
304
+ # a random number of sentences within that range.
305
+ def sentences(total)
306
+ (1..interpret_value(total)).map do
307
+ words(5..20).capitalize
308
+ end.join('. ')
309
+ end
310
+
311
+ # Generate a given number of paragraphs. If a range is passed, it will generate
312
+ # a random number of paragraphs within that range.
313
+ def paragraphs(total)
314
+ (1..interpret_value(total)).map do
315
+ sentences(3..8).capitalize
316
+ end.join("\n\n")
317
+ end
318
+
319
+ # If an array or range is passed, a random value will be selected to match.
320
+ # All other values are simply returned.
321
+ def interpret_value(value)
322
+ case value
323
+ when Array then value.rand
324
+ when Range then value_in_range(value)
325
+ else value
326
+ end
327
+ end
328
+
329
+ private
330
+
331
+ def time_in_range(range)
332
+ Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
333
+ end
334
+
335
+ def date_in_range(range)
336
+ Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
337
+ end
338
+
339
+ def number_in_range(range)
340
+ if range.exclude_end?
341
+ rand(range.last - range.first) + range.first
342
+ else
343
+ rand((range.last+1) - range.first) + range.first
344
+ end
345
+ end
346
+
347
+ def format_date(date, date_format = '%d/%m/%Y')
348
+ date.strftime(date_format)
349
+ end
350
+
351
+ def date_format(format_argument)
352
+ if format_argument.nil? then
353
+ get_locale_date_format(default_locale)
354
+ elsif format_argument.class == Symbol then
355
+ get_locale_date_format(format_argument)
356
+ elsif format_argument.class == String then
357
+ format_argument
358
+ else
359
+ # invalid input, use default
360
+ get_locale_date_format(default_date_format)
361
+ end
362
+
363
+ end
364
+
365
+ def get_locale_date_format(locale)
366
+ case locale
367
+ when :us
368
+ "%m/%d/%Y"
369
+ when :au, :uk
370
+ "%d/%m/%Y"
371
+ else
372
+ "%Y-%m-%d"
373
+ end
374
+ end
375
+
376
+ def default_locale
377
+ return :au
378
+ end
379
+
380
+
381
+ def average_of(array)
382
+ array.inject(0.0) { |sum, e| sum + e } / array.length
383
+ end
384
+
385
+ # NOTE might cause issues
386
+ # why it is removed total
387
+ def sum_of(array)
388
+ array.inject(0.0) { |sum, e| sum + e }
389
+ end
390
+
391
+ end
392
+ end
393
+ end