rwebspec 4.2.1 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,8 @@
1
1
  CHANGELOG
2
2
  =========
3
+ 4.3
4
+ [TODO] RWebSpec.framework = "Auto", Watir for IE, Selenium for others.
5
+
3
6
  4.2.1
4
7
  [Fixes] assert_not_exists for Selenium
5
8
 
data/Rakefile CHANGED
@@ -78,7 +78,7 @@ end
78
78
  spec = Gem::Specification.new do |s|
79
79
  s.platform= Gem::Platform::RUBY
80
80
  s.name = "rwebspec"
81
- s.version = "4.2.1"
81
+ s.version = "4.3.1"
82
82
  s.summary = "Web application functional specification in Ruby"
83
83
  s.description = "Executable functional specification for web applications in RSpec syntax with Watir or Selenium"
84
84
 
@@ -1,396 +1,492 @@
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_for instead."
44
- try_for(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
- #= Convenient functions
96
- #
97
-
98
- # Using Ruby block syntax to create interesting domain specific language,
99
- # may be appeal to someone.
100
-
101
- # Example:
102
- # on @page do |i|
103
- # i.enter_text('btn1')
104
- # i.click_button('btn1')
105
- # end
106
- def on(page, & block)
107
- yield page
108
- end
109
-
110
- # fail the test if user can perform the operation
111
- #
112
- # Example:
113
- # shall_not_allow { 1/0 }
114
- def shall_not_allow(& block)
115
- operation_performed_ok = false
116
- begin
117
- yield
118
- operation_performed_ok = true
119
- rescue
120
- end
121
- raise "Operation shall not be allowed" if operation_performed_ok
122
- end
123
-
124
- alias do_not_allow shall_not_allow
125
-
126
- # Does not provide real function, other than make enhancing test syntax
127
- #
128
- # Example:
129
- # allow { click_button('Register') }
130
- def allow(& block)
131
- yield
132
- end
133
-
134
- alias shall_allow allow
135
- alias allowing allow
136
-
137
- # try operation, ignore if errors occur
138
- #
139
- # Example:
140
- # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
141
- def failsafe(& block)
142
- begin
143
- yield
144
- rescue =>e
145
- end
146
- end
147
-
148
- alias fail_safe failsafe
149
-
150
- # default date format returned is 29/12/2007.
151
- # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
152
- # Otherwise, "2007-12-29", which is most approiate date format
153
- #
154
- # %a - The abbreviated weekday name (``Sun'')
155
- # %A - The full weekday name (``Sunday'')
156
- # %b - The abbreviated month name (``Jan'')
157
- # %B - The full month name (``January'')
158
- # %c - The preferred local date and time representation
159
- # %d - Day of the month (01..31)
160
- # %H - Hour of the day, 24-hour clock (00..23)
161
- # %I - Hour of the day, 12-hour clock (01..12)
162
- # %j - Day of the year (001..366)
163
- # %m - Month of the year (01..12)
164
- # %M - Minute of the hour (00..59)
165
- # %p - Meridian indicator (``AM'' or ``PM'')
166
- # %S - Second of the minute (00..60)
167
- # %U - Week number of the current year,
168
- # starting with the first Sunday as the first
169
- # day of the first week (00..53)
170
- # %W - Week number of the current year,
171
- # starting with the first Monday as the first
172
- # day of the first week (00..53)
173
- # %w - Day of the week (Sunday is 0, 0..6)
174
- # %x - Preferred representation for the date alone, no time
175
- # %X - Preferred representation for the time alone, no date
176
- # %y - Year without a century (00..99)
177
- # %Y - Year with century
178
- # %Z - Time zone name
179
- # %% - Literal ``%'' character
180
-
181
- def today(format = nil)
182
- format_date(Time.now, date_format(format))
183
- end
184
- alias getToday_AU today
185
- alias getToday_US today
186
- alias getToday today
187
-
188
-
189
- def days_before(days, format = nil)
190
- return nil if !(days.instance_of?(Fixnum))
191
- format_date(Time.now - days * 24 * 3600, date_format(format))
192
- end
193
-
194
- def yesterday(format = nil)
195
- days_before(1, date_format(format))
196
- end
197
-
198
- def days_from_now(days, format = nil)
199
- return nil if !(days.instance_of?(Fixnum))
200
- format_date(Time.now + days * 24 * 3600, date_format(format))
201
- end
202
- alias days_after days_from_now
203
-
204
- def tomorrow(format = nil)
205
- days_from_now(1, date_format(format))
206
- end
207
-
208
-
209
- # return a random number >= min, but <= max
210
- def random_number(min, max)
211
- rand(max-min+1)+min
212
- end
213
-
214
- def random_boolean
215
- return random_number(0, 1) == 1
216
- end
217
-
218
- def random_char(lowercase = true)
219
- if lowercase
220
- sprintf("%c", random_number(97, 122))
221
- else
222
- sprintf("%c", random_number(65, 90))
223
- end
224
- end
225
-
226
- def random_digit()
227
- sprintf("%c", random_number(48, 57))
228
- end
229
-
230
- def random_str(length, lowercase = true)
231
- randomStr = ""
232
- length.times {
233
- randomStr += random_char(lowercase)
234
- }
235
- randomStr
236
- end
237
-
238
- # Return a random string in a rangeof pre-defined strings
239
- def random_string_in(arr)
240
- return nil if arr.empty?
241
- index = random_number(0, arr.length-1)
242
- arr[index]
243
- end
244
- alias random_string_in_collection random_string_in
245
-
246
-
247
- 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)
248
-
249
- # Pick a random value out of a given range.
250
- def value_in_range(range)
251
- case range.first
252
- when Integer then number_in_range(range)
253
- when Time then time_in_range(range)
254
- when Date then date_in_range(range)
255
- else range.to_a.rand
256
- end
257
- end
258
-
259
- # Generate a given number of words. If a range is passed, it will generate
260
- # a random number of words within that range.
261
- def words(total)
262
- if total.class == Range
263
- (1..interpret_value(total)).map { WORDS[random_number(total.min, total.max)] }.join(' ')
264
- else
265
- (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
266
- end
267
- end
268
-
269
- # Generate a given number of sentences. If a range is passed, it will generate
270
- # a random number of sentences within that range.
271
- def sentences(total)
272
- (1..interpret_value(total)).map do
273
- words(5..20).capitalize
274
- end.join('. ')
275
- end
276
-
277
- # Generate a given number of paragraphs. If a range is passed, it will generate
278
- # a random number of paragraphs within that range.
279
- def paragraphs(total)
280
- (1..interpret_value(total)).map do
281
- sentences(3..8).capitalize
282
- end.join("\n\n")
283
- end
284
-
285
- # If an array or range is passed, a random value will be selected to match.
286
- # All other values are simply returned.
287
- def interpret_value(value)
288
- case value
289
- when Array then value.rand
290
- when Range then value_in_range(value)
291
- else value
292
- end
293
- end
294
-
295
- private
296
-
297
- def time_in_range(range)
298
- Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
299
- end
300
-
301
- def date_in_range(range)
302
- Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
303
- end
304
-
305
- def number_in_range(range)
306
- if range.exclude_end?
307
- rand(range.last - range.first) + range.first
308
- else
309
- rand((range.last+1) - range.first) + range.first
310
- end
311
- end
312
-
313
- def format_date(date, date_format = '%d/%m/%Y')
314
- date.strftime(date_format)
315
- end
316
-
317
- def date_format(format_argument)
318
- if format_argument.nil? then
319
- get_locale_date_format(default_locale)
320
- elsif format_argument.class == Symbol then
321
- get_locale_date_format(format_argument)
322
- elsif format_argument.class == String then
323
- format_argument
324
- else
325
- # invalid input, use default
326
- get_locale_date_format(default_date_format)
327
- end
328
-
329
- end
330
-
331
- def get_locale_date_format(locale)
332
- case locale
333
- when :us
334
- "%m/%d/%Y"
335
- when :au, :uk
336
- "%d/%m/%Y"
337
- else
338
- "%Y-%m-%d"
339
- end
340
- end
341
-
342
- def default_locale
343
- return :au
344
- end
345
-
346
-
347
- def average_of(array)
348
- array.inject(0.0) { |sum, e| sum + e } / array.length
349
- end
350
-
351
- # NOTE might cause issues
352
- # why it is removed total
353
- def sum_of(array)
354
- array.inject(0.0) { |sum, e| sum + e }
355
- end
356
-
357
- ## Data Driven Tests
358
- #
359
- # Processing each row in a CSV file, must have heading rows
360
- #
361
- # Usage:
362
- #
363
- # process_each_row_in_csv_file(@csv_file) { |row|
364
- # goto_page("/")
365
- # enter_text("username", row[1])
366
- # enter_text("password", row[2])
367
- # click_button("Sign in")
368
- # page_text.should contain(row[3])
369
- # failsafe{ click_link("Sign off") }
370
- # }
371
- #
372
- def process_each_row_in_csv_file(csv_file, &block)
373
- require 'faster_csv'
374
- connect_to_testwise("CSV_START", csv_file) if $testwise_support
375
- has_error = false
376
- idx = 0
377
- FasterCSV.foreach(csv_file, :headers => :first_row, :encoding => 'u') do |row|
378
- connect_to_testwise("CSV_ON_ROW", idx.to_s) if $testwise_support
379
- begin
380
- yield row
381
- connect_to_testwise("CSV_ROW_PASS", idx.to_s) if $testwise_support
382
- rescue => e
383
- connect_to_testwise("CSV_ROW_FAIL", idx.to_s) if $testwise_support
384
- has_error = true
385
- ensure
386
- idx += 1
387
- end
388
- end
389
-
390
- connect_to_testwise("CSV_END", "") if $testwise_support
391
- raise "Test failed on data" if has_error
392
- end
393
-
394
-
395
- end
396
- 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 Core
10
+
11
+ # open a browser, and set base_url via hash, but does not acually
12
+ #
13
+ # example:
14
+ # open_browser :base_url => http://localhost:8080, :browser => :ie
15
+ #
16
+ # There are 3 ways to set base url
17
+ # 1. pass as first argument
18
+ # 2. If running using TestWise, used as confiured
19
+ # 3. Use default value set
20
+ #
21
+ #
22
+ # New Options:
23
+ # :browser => :ie | :firefox | :chrome
24
+ def open_browser(opts = {})
25
+ puts "[INFO] RWebSpec.Framework currently set to => #{RWebSpec.framework }"
26
+ =begin
27
+ if RWebSpec.framework =~ /watir/i
28
+ RWebSpec.load_watir
29
+ self.class.send(:include, RWebSpec::Driver)
30
+ load(File.dirname(__FILE__) + "/web_page.rb")
31
+ return open_browser_by_watir(opts)
32
+ end
33
+
34
+ if RWebSpec.framework =~ /selenium/i
35
+ RWebSpec.load_selenium
36
+ self.class.send(:include, RWebSpec::Driver)
37
+ load(File.dirname(__FILE__) + "/web_page.rb")
38
+ return open_browser_by_selenium(opts)
39
+ end
40
+ =end
41
+ puts "[INFO] No underlying framework is set, try to determine browser: #{opts.inspect}"
42
+ if opts.class == Hash
43
+ if opts[:browser]
44
+
45
+ if opts[:browser].to_s =~ /ie/i || opts[:browser].to_s =~ /internet\sexplorer/i
46
+ puts "[INFO] based on browser, set to Watir"
47
+ RWebSpec.framework = "Watir"
48
+ self.class.send(:include, RWebSpec::Driver)
49
+ load(File.dirname(__FILE__) + "/web_page.rb")
50
+ return open_browser_by_watir(opts)
51
+ end
52
+
53
+ puts "[INFO] based on browser, set to Selenium"
54
+ # not IE, using selenium
55
+ RWebSpec.framework = "Selenium"
56
+ self.class.send(:include, RWebSpec::Driver)
57
+ load(File.dirname(__FILE__) + "/web_page.rb")
58
+ return open_browser_by_selenium(opts)
59
+
60
+ end
61
+ end
62
+
63
+ puts "[INFO] browser type not specified, decide framework based on platform"
64
+ if RUBY_PLATFORM =~ /mingw/
65
+ # if it is Windows, set to Watir
66
+ RWebSpec.framework = "Watir"
67
+ self.class.send(:include, RWebSpec::Driver)
68
+ puts "[INFO] Extends of RWebSpec::Driver"
69
+ load(File.dirname(__FILE__) + "/web_page.rb")
70
+ return open_browser_by_watir(opts)
71
+ else
72
+ RWebSpec.framework = "Selenium"
73
+ self.class.send(:include, RWebSpec::Driver)
74
+ load(File.dirname(__FILE__) + "/web_page.rb")
75
+ # using extend somehow does not work for RSpec
76
+ # extend RWebSpec::Driver
77
+
78
+ return open_browser_by_selenium(opts)
79
+ end
80
+
81
+ end
82
+
83
+ def use_current_browser(how = :title, what = /.*/)
84
+ puts "[INFO] user current browser => #{RWebSpec.framework}"
85
+ if RWebSpec.framework =~ /watir/i
86
+ self.class.send(:include, RWebSpec::Driver)
87
+ use_current_watir_browser(how, what)
88
+ elsif RWebSpec.framework =~ /selenium/i
89
+ self.class.send(:include, RWebSpec::Driver)
90
+ use_current_selenium_browser(show, what)
91
+ else
92
+ # not specified, guess
93
+ if RUBY_PLATFORM =~ /mingw/i
94
+ RWebSpec.framework = "Watir"
95
+ self.class.send(:include, RWebSpec::Driver)
96
+ load(File.dirname(__FILE__) + "/web_page.rb")
97
+ use_current_watir_browser(how, what)
98
+ else
99
+ RWebSpec.framework = "Selenium"
100
+ self.class.send(:include, RWebSpec::Driver)
101
+ load(File.dirname(__FILE__) + "/web_page.rb")
102
+ use_current_selenium_browser(show, what)
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+
109
+ # Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
110
+ # Error will be ignored until timeout
111
+ # Example
112
+ # try_for { click_link('waiting')}
113
+ # try_for(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
114
+ # try_for { click_button('Search' }
115
+ def try_for(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
116
+ start_time = Time.now
117
+
118
+ last_error = nil
119
+ until (duration = Time.now - start_time) > timeout
120
+ begin
121
+ yield
122
+ last_error = nil
123
+ return true
124
+ rescue => e
125
+ last_error = e
126
+ end
127
+ sleep polling_interval
128
+ end
129
+
130
+ raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
131
+ raise "Timeout after #{duration.to_i} seconds."
132
+ end
133
+
134
+ alias try_upto try_for
135
+ alias try_up_to try_for
136
+ alias try_until try_for
137
+
138
+ def try(timeout = $testwise_polling_timeout, polling_interval = $testwise_polling_interval || 1, &block)
139
+ puts "Warning: method 'try' is deprecated (won't support in RWebSpec 3), use try_for instead."
140
+ try_for(timeout, polling_interval) {
141
+ yield
142
+ }
143
+ end
144
+
145
+
146
+ # Try the operation up to specified times, and sleep given interval (in seconds)
147
+ # Error will be ignored until timeout
148
+ # Example
149
+ # repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
150
+ # repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
151
+ def repeat_try(num_tries = $testwise_polling_timeout || 30, interval = $testwise_polling_interval || 1, & block)
152
+ num_tries ||= 1
153
+ (num_tries - 1).times do |num|
154
+ begin
155
+ yield
156
+ return
157
+ rescue => e
158
+ # puts "debug: #{num} failed: #{e}"
159
+ sleep interval
160
+ end
161
+ end
162
+
163
+ # last try, throw error if still fails
164
+ begin
165
+ yield
166
+ rescue => e
167
+ raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
168
+ end
169
+ yield
170
+ end
171
+
172
+
173
+ ##
174
+ # Convert :first to 1, :second to 2, and so on...
175
+ def symbol_to_sequence(symb)
176
+ value = {:zero => 0,
177
+ :first => 1,
178
+ :second => 2,
179
+ :third => 3,
180
+ :fourth => 4,
181
+ :fifth => 5,
182
+ :sixth => 6,
183
+ :seventh => 7,
184
+ :eighth => 8,
185
+ :ninth => 9,
186
+ :tenth => 10}[symb]
187
+ return value || symb.to_i
188
+ end
189
+
190
+
191
+ #= Convenient functions
192
+ #
193
+
194
+ # Using Ruby block syntax to create interesting domain specific language,
195
+ # may be appeal to someone.
196
+
197
+ # Example:
198
+ # on @page do |i|
199
+ # i.enter_text('btn1')
200
+ # i.click_button('btn1')
201
+ # end
202
+ def on(page, & block)
203
+ yield page
204
+ end
205
+
206
+ # fail the test if user can perform the operation
207
+ #
208
+ # Example:
209
+ # shall_not_allow { 1/0 }
210
+ def shall_not_allow(& block)
211
+ operation_performed_ok = false
212
+ begin
213
+ yield
214
+ operation_performed_ok = true
215
+ rescue
216
+ end
217
+ raise "Operation shall not be allowed" if operation_performed_ok
218
+ end
219
+
220
+ alias do_not_allow shall_not_allow
221
+
222
+ # Does not provide real function, other than make enhancing test syntax
223
+ #
224
+ # Example:
225
+ # allow { click_button('Register') }
226
+ def allow(& block)
227
+ yield
228
+ end
229
+
230
+ alias shall_allow allow
231
+ alias allowing allow
232
+
233
+ # try operation, ignore if errors occur
234
+ #
235
+ # Example:
236
+ # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
237
+ def failsafe(& block)
238
+ begin
239
+ yield
240
+ rescue =>e
241
+ end
242
+ end
243
+
244
+ alias fail_safe failsafe
245
+
246
+ # default date format returned is 29/12/2007.
247
+ # if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
248
+ # Otherwise, "2007-12-29", which is most approiate date format
249
+ #
250
+ # %a - The abbreviated weekday name (``Sun'')
251
+ # %A - The full weekday name (``Sunday'')
252
+ # %b - The abbreviated month name (``Jan'')
253
+ # %B - The full month name (``January'')
254
+ # %c - The preferred local date and time representation
255
+ # %d - Day of the month (01..31)
256
+ # %H - Hour of the day, 24-hour clock (00..23)
257
+ # %I - Hour of the day, 12-hour clock (01..12)
258
+ # %j - Day of the year (001..366)
259
+ # %m - Month of the year (01..12)
260
+ # %M - Minute of the hour (00..59)
261
+ # %p - Meridian indicator (``AM'' or ``PM'')
262
+ # %S - Second of the minute (00..60)
263
+ # %U - Week number of the current year,
264
+ # starting with the first Sunday as the first
265
+ # day of the first week (00..53)
266
+ # %W - Week number of the current year,
267
+ # starting with the first Monday as the first
268
+ # day of the first week (00..53)
269
+ # %w - Day of the week (Sunday is 0, 0..6)
270
+ # %x - Preferred representation for the date alone, no time
271
+ # %X - Preferred representation for the time alone, no date
272
+ # %y - Year without a century (00..99)
273
+ # %Y - Year with century
274
+ # %Z - Time zone name
275
+ # %% - Literal ``%'' character
276
+
277
+ def today(format = nil)
278
+ format_date(Time.now, date_format(format))
279
+ end
280
+ alias getToday_AU today
281
+ alias getToday_US today
282
+ alias getToday today
283
+
284
+
285
+ def days_before(days, format = nil)
286
+ return nil if !(days.instance_of?(Fixnum))
287
+ format_date(Time.now - days * 24 * 3600, date_format(format))
288
+ end
289
+
290
+ def yesterday(format = nil)
291
+ days_before(1, date_format(format))
292
+ end
293
+
294
+ def days_from_now(days, format = nil)
295
+ return nil if !(days.instance_of?(Fixnum))
296
+ format_date(Time.now + days * 24 * 3600, date_format(format))
297
+ end
298
+ alias days_after days_from_now
299
+
300
+ def tomorrow(format = nil)
301
+ days_from_now(1, date_format(format))
302
+ end
303
+
304
+
305
+ # return a random number >= min, but <= max
306
+ def random_number(min, max)
307
+ rand(max-min+1)+min
308
+ end
309
+
310
+ def random_boolean
311
+ return random_number(0, 1) == 1
312
+ end
313
+
314
+ def random_char(lowercase = true)
315
+ if lowercase
316
+ sprintf("%c", random_number(97, 122))
317
+ else
318
+ sprintf("%c", random_number(65, 90))
319
+ end
320
+ end
321
+
322
+ def random_digit()
323
+ sprintf("%c", random_number(48, 57))
324
+ end
325
+
326
+ def random_str(length, lowercase = true)
327
+ randomStr = ""
328
+ length.times {
329
+ randomStr += random_char(lowercase)
330
+ }
331
+ randomStr
332
+ end
333
+
334
+ # Return a random string in a rangeof pre-defined strings
335
+ def random_string_in(arr)
336
+ return nil if arr.empty?
337
+ index = random_number(0, arr.length-1)
338
+ arr[index]
339
+ end
340
+ alias random_string_in_collection random_string_in
341
+
342
+
343
+ 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)
344
+
345
+ # Pick a random value out of a given range.
346
+ def value_in_range(range)
347
+ case range.first
348
+ when Integer then number_in_range(range)
349
+ when Time then time_in_range(range)
350
+ when Date then date_in_range(range)
351
+ else range.to_a.rand
352
+ end
353
+ end
354
+
355
+ # Generate a given number of words. If a range is passed, it will generate
356
+ # a random number of words within that range.
357
+ def words(total)
358
+ if total.class == Range
359
+ (1..interpret_value(total)).map { WORDS[random_number(total.min, total.max)] }.join(' ')
360
+ else
361
+ (1..interpret_value(total)).map { WORDS[random_number(0, total)] }.join(' ')
362
+ end
363
+ end
364
+
365
+ # Generate a given number of sentences. If a range is passed, it will generate
366
+ # a random number of sentences within that range.
367
+ def sentences(total)
368
+ (1..interpret_value(total)).map do
369
+ words(5..20).capitalize
370
+ end.join('. ')
371
+ end
372
+
373
+ # Generate a given number of paragraphs. If a range is passed, it will generate
374
+ # a random number of paragraphs within that range.
375
+ def paragraphs(total)
376
+ (1..interpret_value(total)).map do
377
+ sentences(3..8).capitalize
378
+ end.join("\n\n")
379
+ end
380
+
381
+ # If an array or range is passed, a random value will be selected to match.
382
+ # All other values are simply returned.
383
+ def interpret_value(value)
384
+ case value
385
+ when Array then value.rand
386
+ when Range then value_in_range(value)
387
+ else value
388
+ end
389
+ end
390
+
391
+ private
392
+
393
+ def time_in_range(range)
394
+ Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, rangee.exclude_end?))
395
+ end
396
+
397
+ def date_in_range(range)
398
+ Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?))
399
+ end
400
+
401
+ def number_in_range(range)
402
+ if range.exclude_end?
403
+ rand(range.last - range.first) + range.first
404
+ else
405
+ rand((range.last+1) - range.first) + range.first
406
+ end
407
+ end
408
+
409
+ def format_date(date, date_format = '%d/%m/%Y')
410
+ date.strftime(date_format)
411
+ end
412
+
413
+ def date_format(format_argument)
414
+ if format_argument.nil? then
415
+ get_locale_date_format(default_locale)
416
+ elsif format_argument.class == Symbol then
417
+ get_locale_date_format(format_argument)
418
+ elsif format_argument.class == String then
419
+ format_argument
420
+ else
421
+ # invalid input, use default
422
+ get_locale_date_format(default_date_format)
423
+ end
424
+
425
+ end
426
+
427
+ def get_locale_date_format(locale)
428
+ case locale
429
+ when :us
430
+ "%m/%d/%Y"
431
+ when :au, :uk
432
+ "%d/%m/%Y"
433
+ else
434
+ "%Y-%m-%d"
435
+ end
436
+ end
437
+
438
+ def default_locale
439
+ return :au
440
+ end
441
+
442
+
443
+ def average_of(array)
444
+ array.inject(0.0) { |sum, e| sum + e } / array.length
445
+ end
446
+
447
+ # NOTE might cause issues
448
+ # why it is removed total
449
+ def sum_of(array)
450
+ array.inject(0.0) { |sum, e| sum + e }
451
+ end
452
+
453
+ ## Data Driven Tests
454
+ #
455
+ # Processing each row in a CSV file, must have heading rows
456
+ #
457
+ # Usage:
458
+ #
459
+ # process_each_row_in_csv_file(@csv_file) { |row|
460
+ # goto_page("/")
461
+ # enter_text("username", row[1])
462
+ # enter_text("password", row[2])
463
+ # click_button("Sign in")
464
+ # page_text.should contain(row[3])
465
+ # failsafe{ click_link("Sign off") }
466
+ # }
467
+ #
468
+ def process_each_row_in_csv_file(csv_file, &block)
469
+ require 'faster_csv'
470
+ connect_to_testwise("CSV_START", csv_file) if $testwise_support
471
+ has_error = false
472
+ idx = 0
473
+ FasterCSV.foreach(csv_file, :headers => :first_row, :encoding => 'u') do |row|
474
+ connect_to_testwise("CSV_ON_ROW", idx.to_s) if $testwise_support
475
+ begin
476
+ yield row
477
+ connect_to_testwise("CSV_ROW_PASS", idx.to_s) if $testwise_support
478
+ rescue => e
479
+ connect_to_testwise("CSV_ROW_FAIL", idx.to_s) if $testwise_support
480
+ has_error = true
481
+ ensure
482
+ idx += 1
483
+ end
484
+ end
485
+
486
+ connect_to_testwise("CSV_END", "") if $testwise_support
487
+ raise "Test failed on data" if has_error
488
+ end
489
+
490
+
491
+ end
492
+ end
@@ -2,7 +2,7 @@
2
2
  module RWebSpec
3
3
  module LoadTestHelper
4
4
 
5
- include RWebSpec::Utils
5
+ include RWebSpec::Core
6
6
  include RWebSpec::Assert
7
7
 
8
8
  MAX_VU = 1000
@@ -17,8 +17,8 @@ end
17
17
 
18
18
  module RWebSpec
19
19
  module RSpecHelper
20
- include RWebSpec::Driver
21
- include RWebSpec::Utils
20
+
21
+ include RWebSpec::Core
22
22
  include RWebSpec::Assert
23
23
 
24
24
  # --
@@ -1,7 +1,7 @@
1
1
  module RWebSpec
2
2
  module TestScript
3
- include RWebSpec::Driver
4
- include RWebSpec::Utils
3
+ # include RWebSpec::Driver
4
+ include RWebSpec::Core
5
5
  include RWebSpec::Assert
6
6
 
7
7
  end
@@ -22,8 +22,12 @@ module RWebSpec
22
22
  class AbstractWebPage
23
23
 
24
24
  include RWebSpec::Assert
25
- include RWebSpec::Driver
26
- include RWebSpec::Utils
25
+ begin
26
+ include RWebSpec::Driver
27
+ rescue => e
28
+ puts "[WARN] Failed to load Driver, it will be reloaded. #{e.backtrace}"
29
+ end
30
+ include RWebSpec::Core
27
31
 
28
32
  # browser: passed to do assertion within the page
29
33
  # page_text: text used to identify the page, title will be the first candidate
@@ -14,7 +14,7 @@ module RWebSpec
14
14
  class WebTestCase < Test::Unit::TestCase
15
15
  include RWebSpec::Driver
16
16
  include RWebSpec::Assert
17
- include RWebSpec::Utils
17
+ include RWebSpec::Core
18
18
 
19
19
  attr_reader :web_tester
20
20
 
@@ -29,7 +29,7 @@ module RWebSpec
29
29
  # 1. pass as first argument
30
30
  # 2. If running using TestWise, used as confiured
31
31
  # 3. Use default value set
32
- def open_browser(options = {})
32
+ def open_browser_by_watir(options = {})
33
33
 
34
34
  begin
35
35
  support_unicode
@@ -83,7 +83,6 @@ module RWebSpec
83
83
  return @web_browser
84
84
  end
85
85
 
86
- alias open_browser_with open_browser
87
86
 
88
87
  # return the underlying RWebSpec::Browser object
89
88
  def browser
@@ -214,9 +213,9 @@ module RWebSpec
214
213
 
215
214
  # Reuse current an opened browser window instead of opening a new one
216
215
  # example:
217
- # use_current_browser(:title, /.*/) # use what ever browser window
218
- # use_current_browser(:title, "TestWise") # use browser window with title "TestWise"
219
- def use_current_browser(how = :title, what = /.*/)
216
+ # use_current_watir_browser(:title, /.*/) # use what ever browser window
217
+ # use_current_watir_browser(:title, "TestWise") # use browser window with title "TestWise"
218
+ def use_current_watir_browser(how = :title, what = /.*/)
220
219
  @web_browser = WebBrowser.attach_browser(how, what)
221
220
  end
222
221
 
@@ -785,7 +784,6 @@ module RWebSpec
785
784
  FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
786
785
  end
787
786
 
788
- if RWebSpec.framework == "Watir"
789
787
  begin
790
788
  if is_firefox? then
791
789
  Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
@@ -800,11 +798,7 @@ module RWebSpec
800
798
  rescue => e
801
799
  puts "error on taking screenshot: #{e}"
802
800
  end
803
- else
804
- # save screenshot with selenium
805
- @web_browser.driver.save_screenshot(screenshot_image_filepath)
806
- notify_screenshot_location(screenshot_image_filepath)
807
- end
801
+
808
802
 
809
803
  end
810
804
 
@@ -2,6 +2,9 @@
2
2
  #* Copyright (c) 2006, Zhimin Zhan.
3
3
  #* Distributed open-source, see full license in MIT-LICENSE
4
4
  #***********************************************************
5
+
6
+ =begin
7
+
5
8
  begin
6
9
  require 'watir'
7
10
  # require 'watir/contrib/enabled_popup'
@@ -20,6 +23,8 @@ if RUBY_PLATFORM =~ /mingw/
20
23
  raise "You have must at least Watir installed" unless $watir_loaded
21
24
  end
22
25
 
26
+ =end
27
+
23
28
  module RWebSpec
24
29
 
25
30
  ##
@@ -29,7 +29,7 @@ module RWebSpec
29
29
  #
30
30
  # New Options:
31
31
  # :browser => :ie | :firefox | :chrome
32
- def open_browser(options = {})
32
+ def open_browser_by_selenium(options = {})
33
33
  # puts "[DEBUG] [SeleniumDriver] Callling open_browser #{options.inspect}"
34
34
 
35
35
  begin
@@ -99,7 +99,6 @@ module RWebSpec
99
99
  return @web_browser
100
100
  end
101
101
 
102
- alias open_browser_with open_browser
103
102
 
104
103
  # return the underlying RWebSpec::WebDriver::Browser object
105
104
  def browser
@@ -228,9 +227,9 @@ module RWebSpec
228
227
 
229
228
  # Reuse current an opened browser window instead of opening a new one
230
229
  # example:
231
- # use_current_browser(:title, /.*/) # use what ever browser window
232
- # use_current_browser(:title, "TestWise") # use browser window with title "TestWise"
233
- def use_current_browser(how = :title, what = /.*/)
230
+ # use_current_selenium_browser(:title, /.*/) # use what ever browser window
231
+ # use_current_selenium_browser(:title, "TestWise") # use browser window with title "TestWise"
232
+ def use_current_selenium_browser(how = :title, what = /.*/)
234
233
  @web_browser = $browser || WebBrowser.attach_browser(how, what)
235
234
  end
236
235
 
@@ -784,26 +783,9 @@ module RWebSpec
784
783
  FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
785
784
  end
786
785
 
787
- if RWebSpec.framework == "Watir"
788
- begin
789
- if is_firefox? then
790
- Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
791
- elsif ie
792
- Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
793
- else
794
- Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
795
- end
796
- notify_screenshot_location(screenshot_image_filepath)
797
- rescue ::DL::DLTypeError => de
798
- puts "No screenshot libray found: #{de}"
799
- rescue => e
800
- puts "error on taking screenshot: #{e}"
801
- end
802
- else
803
786
  # save screenshot with selenium
804
787
  @web_browser.driver.save_screenshot(screenshot_image_filepath)
805
788
  notify_screenshot_location(screenshot_image_filepath)
806
- end
807
789
 
808
790
  end
809
791
 
@@ -3,11 +3,11 @@
3
3
  #* Distributed open-source, see full license in MIT-LICENSE
4
4
  #***********************************************************
5
5
 
6
- begin
7
- require "selenium-webdriver"
8
- rescue LoadError => e
9
- raise "You have must at least WebDriver installed"
10
- end
6
+ # begin
7
+ # require "selenium-webdriver"
8
+ # rescue LoadError => e
9
+ # raise "You have must at least WebDriver installed"
10
+ # end
11
11
 
12
12
  require File.join(File.dirname(__FILE__), "element_locator.rb")
13
13
 
data/lib/rwebspec.rb CHANGED
@@ -16,7 +16,7 @@ end
16
16
  require 'rspec'
17
17
 
18
18
  unless defined? RWEBSPEC_VERSION
19
- RWEBSPEC_VERSION = RWEBUNIT_VERSION = "4.2.1"
19
+ RWEBSPEC_VERSION = RWEBUNIT_VERSION = "4.3.1"
20
20
  end
21
21
 
22
22
  $testwise_polling_interval = 1 # seconds
@@ -24,7 +24,7 @@ $testwise_polling_interval = 1 # seconds
24
24
  $testwise_polling_timeout = 30 # seconds
25
25
 
26
26
 
27
- if RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /mingw/
27
+ if RUBY_PLATFORM =~ /mingw/
28
28
  $screenshot_supported = false
29
29
  begin
30
30
  require 'win32/screenshot'
@@ -33,6 +33,13 @@ if RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /mingw/
33
33
  end
34
34
  end
35
35
 
36
+ begin
37
+ require 'selenium-webdriver'
38
+ rescue LoadError => e
39
+ $selenium_loaded = false
40
+ end
41
+
42
+
36
43
  module RWebSpec
37
44
  class << self
38
45
  def version
@@ -41,7 +48,8 @@ module RWebSpec
41
48
 
42
49
  def framework
43
50
  @_framework ||= begin
44
- ENV["RWEBSPEC_FRAMEWORK"] ||= (RUBY_PLATFORM =~ /mingw/ ? "Watir" : "Selenium-WebDriver")
51
+ ENV["RWEBSPEC_FRAMEWORK"]
52
+ # ||= (RUBY_PLATFORM =~ /mingw/ ? "Watir" : "Selenium-WebDriver")
45
53
  end
46
54
  @_framework
47
55
  end
@@ -57,6 +65,8 @@ module RWebSpec
57
65
 
58
66
  def load_watir
59
67
  # puts "Loading Watir"
68
+ require 'watir'
69
+ require 'watir-classic/ie'
60
70
  load(File.dirname(__FILE__) + "/rwebspec-watir/web_browser.rb")
61
71
  load(File.dirname(__FILE__) + "/rwebspec-watir/driver.rb")
62
72
  require File.dirname(__FILE__) + "/extensions/watir_extensions"
@@ -64,6 +74,7 @@ module RWebSpec
64
74
  end
65
75
 
66
76
  def load_selenium
77
+ require 'selenium-webdriver'
67
78
  # puts "Loading Selenium"
68
79
  load(File.dirname(__FILE__) + "/rwebspec-webdriver/web_browser.rb")
69
80
  load(File.dirname(__FILE__) + "/rwebspec-webdriver/driver.rb")
@@ -74,7 +85,18 @@ module RWebSpec
74
85
  if @_framework.nil?
75
86
  framework
76
87
  end
77
- RWebSpec.framework == "Watir" ? load_watir : load_selenium
88
+
89
+ if RWebSpec.framework =~ /watir/i
90
+ load_watir
91
+ return
92
+ end
93
+
94
+ if RWebSpec.framework =~ /selenium/i
95
+ load_selenium
96
+ return
97
+ end
98
+
99
+ puts "[WARN] not framework loaded yet"
78
100
  end
79
101
 
80
102
  end
@@ -83,16 +105,17 @@ end
83
105
  # Watir 3 API Changes, no Watir/Container
84
106
  require File.dirname(__FILE__) + "/plugins/testwise_plugin.rb"
85
107
 
86
- RWebSpec.load_framework
108
+ #RWebSpec.load_framework
87
109
 
88
110
  # Extra full path to load libraries
89
111
  require File.dirname(__FILE__) + "/rwebspec-common/using_pages"
90
- require File.dirname(__FILE__) + "/rwebspec-common/test_utils"
112
+ require File.dirname(__FILE__) + "/rwebspec-common/core"
91
113
  require File.dirname(__FILE__) + "/rwebspec-common/web_page"
92
114
  require File.dirname(__FILE__) + "/rwebspec-common/assert"
93
- require File.dirname(__FILE__) + "/rwebspec-common/test_script"
94
115
  require File.dirname(__FILE__) + "/rwebspec-common/context"
95
- require File.dirname(__FILE__) + "/rwebspec-common/rspec_helper"
116
+ require File.dirname(__FILE__) + "/rwebspec-common/test_script.rb"
117
+ require File.dirname(__FILE__) + "/rwebspec-common/rspec_helper.rb"
118
+
96
119
  require File.dirname(__FILE__) + "/rwebspec-common/load_test_helper"
97
120
  require File.dirname(__FILE__) + "/rwebspec-common/matchers/contains_text"
98
121
  require File.dirname(__FILE__) + "/extensions/rspec_extensions"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rwebspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire: rwebspec
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-29 00:00:00.000000000 Z
12
+ date: 2013-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -126,13 +126,13 @@ files:
126
126
  - lib/rwebspec-common/assert.rb
127
127
  - lib/rwebspec-common/clickJSDialog.rb
128
128
  - lib/rwebspec-common/context.rb
129
+ - lib/rwebspec-common/core.rb
129
130
  - lib/rwebspec-common/database_checker.rb
130
131
  - lib/rwebspec-common/load_test_helper.rb
131
132
  - lib/rwebspec-common/matchers/contains_text.rb
132
133
  - lib/rwebspec-common/popup.rb
133
134
  - lib/rwebspec-common/rspec_helper.rb
134
135
  - lib/rwebspec-common/test_script.rb
135
- - lib/rwebspec-common/test_utils.rb
136
136
  - lib/rwebspec-common/using_pages.rb
137
137
  - lib/rwebspec-common/web_page.rb
138
138
  - lib/rwebspec-common/web_testcase.rb