rwebspec 2.0.4 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/Rakefile +1 -1
- data/lib/rwebspec/driver.rb +1 -201
- data/lib/rwebspec/test_utils.rb +171 -0
- data/lib/rwebspec.rb +1 -1
- metadata +3 -3
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -71,7 +71,7 @@ end
|
|
71
71
|
spec = Gem::Specification.new do |s|
|
72
72
|
s.platform= Gem::Platform::RUBY
|
73
73
|
s.name = "rwebspec"
|
74
|
-
s.version = "2.0
|
74
|
+
s.version = "2.1.0"
|
75
75
|
s.summary = "Web application functional specification in Ruby"
|
76
76
|
s.description = "Executable functional specification for web applications in RSpec syntax and Watir"
|
77
77
|
|
data/lib/rwebspec/driver.rb
CHANGED
@@ -612,60 +612,6 @@ module RWebSpec
|
|
612
612
|
|
613
613
|
alias support_unicode support_utf8
|
614
614
|
|
615
|
-
#= Convenient functions
|
616
|
-
#
|
617
|
-
|
618
|
-
# Using Ruby block syntax to create interesting domain specific language,
|
619
|
-
# may be appeal to someone.
|
620
|
-
|
621
|
-
# Example:
|
622
|
-
# on @page do |i|
|
623
|
-
# i.enter_text('btn1')
|
624
|
-
# i.click_button('btn1')
|
625
|
-
# end
|
626
|
-
def on(page, & block)
|
627
|
-
yield page
|
628
|
-
end
|
629
|
-
|
630
|
-
# fail the test if user can perform the operation
|
631
|
-
#
|
632
|
-
# Example:
|
633
|
-
# shall_not_allow { 1/0 }
|
634
|
-
def shall_not_allow(& block)
|
635
|
-
operation_performed_ok = false
|
636
|
-
begin
|
637
|
-
yield
|
638
|
-
operation_performed_ok = true
|
639
|
-
rescue
|
640
|
-
end
|
641
|
-
raise "Operation shall not be allowed" if operation_performed_ok
|
642
|
-
end
|
643
|
-
|
644
|
-
alias do_not_allow shall_not_allow
|
645
|
-
|
646
|
-
# Does not provide real function, other than make enhancing test syntax
|
647
|
-
#
|
648
|
-
# Example:
|
649
|
-
# allow { click_button('Register') }
|
650
|
-
def allow(& block)
|
651
|
-
yield
|
652
|
-
end
|
653
|
-
|
654
|
-
alias shall_allow allow
|
655
|
-
alias allowing allow
|
656
|
-
|
657
|
-
# try operation, ignore if errors occur
|
658
|
-
#
|
659
|
-
# Example:
|
660
|
-
# failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
|
661
|
-
def failsafe(& block)
|
662
|
-
begin
|
663
|
-
yield
|
664
|
-
rescue =>e
|
665
|
-
end
|
666
|
-
end
|
667
|
-
|
668
|
-
alias fail_safe failsafe
|
669
615
|
|
670
616
|
|
671
617
|
# Execute the provided block until either (1) it returns true, or
|
@@ -729,119 +675,6 @@ module RWebSpec
|
|
729
675
|
end
|
730
676
|
end
|
731
677
|
|
732
|
-
=begin
|
733
|
-
|
734
|
-
# TODO: Firewatir does not suport retrieving style or outerHtml
|
735
|
-
# http://jira.openqa.org/browse/WTR-260
|
736
|
-
# http://code.google.com/p/firewatir/issues/detail?id=76
|
737
|
-
#
|
738
|
-
# Max timeout value is 10 minutes
|
739
|
-
#
|
740
|
-
def ajax_call_complete_after_element_hidden(elem_id, check_start = 0.5, timeout = 5, interval = 0.5, &block)
|
741
|
-
yield
|
742
|
-
sleep check_start # the time allowed to perform the coomplete
|
743
|
-
timeout = 10 * 60 if timeout > 10 * 600 or timeout <= 0
|
744
|
-
begin
|
745
|
-
Timeout::timeout(timeout) {
|
746
|
-
begin
|
747
|
-
elem = element_by_id(elem_id)
|
748
|
-
while elem do
|
749
|
-
puts "outer=>#{elem.outerHtml}|"
|
750
|
-
puts "style =>#{elem.attribute_value('style')}|"
|
751
|
-
sleep interval
|
752
|
-
elem = element_by_id(elem_id)
|
753
|
-
end
|
754
|
-
rescue => e
|
755
|
-
puts e
|
756
|
-
end
|
757
|
-
}
|
758
|
-
rescue Timeout::Error
|
759
|
-
# Too slow!!
|
760
|
-
raise "Too slow, wait max #{timeout} seconds, the element #{elem_id} still there"
|
761
|
-
end
|
762
|
-
end
|
763
|
-
|
764
|
-
=end
|
765
|
-
|
766
|
-
# Try the operation up to specified times, and sleep given interval (in seconds)
|
767
|
-
# Error will be ignored until timeout
|
768
|
-
# Example
|
769
|
-
# repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
|
770
|
-
# repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
|
771
|
-
def repeat_try(num_tries = @@default_timeout || 30, interval = @@default_polling_interval || 1, & block)
|
772
|
-
num_tries ||= 1
|
773
|
-
(num_tries - 1).times do |num|
|
774
|
-
begin
|
775
|
-
yield
|
776
|
-
return
|
777
|
-
rescue => e
|
778
|
-
# puts "debug: #{num} failed: #{e}"
|
779
|
-
sleep interval
|
780
|
-
end
|
781
|
-
end
|
782
|
-
|
783
|
-
# last try, throw error if still fails
|
784
|
-
begin
|
785
|
-
yield
|
786
|
-
rescue => e
|
787
|
-
raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
|
788
|
-
end
|
789
|
-
yield
|
790
|
-
end
|
791
|
-
|
792
|
-
# TODO: syntax
|
793
|
-
|
794
|
-
# Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
|
795
|
-
# Error will be ignored until timeout
|
796
|
-
# Example
|
797
|
-
# try_until { click_link('waiting')}
|
798
|
-
# try_until(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
|
799
|
-
# try_until { click_button('Search' }
|
800
|
-
def try_until(timeout = @@default_timeout, polling_interval = @@default_polling_interval || 1, &block)
|
801
|
-
start_time = Time.now
|
802
|
-
|
803
|
-
last_error = nil
|
804
|
-
until (duration = Time.now - start_time) > timeout
|
805
|
-
begin
|
806
|
-
yield
|
807
|
-
last_error = nil
|
808
|
-
return true
|
809
|
-
rescue => e
|
810
|
-
last_error = e
|
811
|
-
end
|
812
|
-
sleep polling_interval
|
813
|
-
end
|
814
|
-
|
815
|
-
raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
|
816
|
-
raise "Timeout after #{duration.to_i} seconds."
|
817
|
-
end
|
818
|
-
|
819
|
-
alias try_upto try_until
|
820
|
-
|
821
|
-
def try(timeout = @@default_timeout, polling_interval = @@default_polling_interval || 1, &block)
|
822
|
-
puts "Warning: method 'try' is deprecated (won't support in RWebSpec 3), use try_until instead."
|
823
|
-
try_until(timeout, polling_interval) {
|
824
|
-
yield
|
825
|
-
}
|
826
|
-
end
|
827
|
-
|
828
|
-
##
|
829
|
-
# Convert :first to 1, :second to 2, and so on...
|
830
|
-
def symbol_to_sequence(symb)
|
831
|
-
value = {:zero => 0,
|
832
|
-
:first => 1,
|
833
|
-
:second => 2,
|
834
|
-
:third => 3,
|
835
|
-
:fourth => 4,
|
836
|
-
:fifth => 5,
|
837
|
-
:sixth => 6,
|
838
|
-
:seventh => 7,
|
839
|
-
:eighth => 8,
|
840
|
-
:ninth => 9,
|
841
|
-
:tenth => 10}[symb]
|
842
|
-
return value || symb.to_i
|
843
|
-
end
|
844
|
-
|
845
678
|
# Clear popup windows such as 'Security Alert' or 'Security Information' popup window,
|
846
679
|
#
|
847
680
|
# Screenshot see http://kb2.adobe.com/cps/165/tn_16588.html
|
@@ -981,40 +814,7 @@ module RWebSpec
|
|
981
814
|
end
|
982
815
|
end
|
983
816
|
|
984
|
-
|
985
|
-
# use win32screenshot library to save curernt active window, which shall be IE
|
986
|
-
#
|
987
|
-
# opts[:to_dir] => the direcotry to save image under
|
988
|
-
def take_screenshot(opts = {})
|
989
|
-
# puts "calling new take screenshot: #{$screenshot_supported}"
|
990
|
-
unless $screenshot_supported
|
991
|
-
puts " [WARN] Screenhost not supported, check whether win32screenshot gem is installed"
|
992
|
-
return
|
993
|
-
end
|
994
|
-
|
995
|
-
begin
|
996
|
-
screenshot_image_filename = "screenshot_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
|
997
|
-
the_dump_dir = opts[:to_dir] || default_dump_dir
|
998
|
-
FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
|
999
|
-
screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
|
1000
|
-
screenshot_image_filepath.gsub!("/", "\\") if is_windows?
|
1001
|
-
|
1002
|
-
FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
|
1003
|
-
|
1004
|
-
if is_firefox? then
|
1005
|
-
Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
|
1006
|
-
elsif ie
|
1007
|
-
Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
|
1008
|
-
else
|
1009
|
-
Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
|
1010
|
-
end
|
1011
|
-
notify_screenshot_location(screenshot_image_filepath)
|
1012
|
-
rescue => e
|
1013
|
-
puts "error on taking screenshot: #{e}"
|
1014
|
-
end
|
1015
|
-
|
1016
|
-
end
|
1017
|
-
# end of methods
|
817
|
+
# end of methods
|
1018
818
|
|
1019
819
|
end
|
1020
820
|
|
data/lib/rwebspec/test_utils.rb
CHANGED
@@ -8,6 +8,177 @@
|
|
8
8
|
module RWebSpec
|
9
9
|
module Utils
|
10
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_until { click_link('waiting')}
|
17
|
+
# try_until(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
|
18
|
+
# try_until { click_button('Search' }
|
19
|
+
def try_until(timeout = @@default_timeout, polling_interval = @@default_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_until
|
39
|
+
|
40
|
+
def try(timeout = @@default_timeout, polling_interval = @@default_polling_interval || 1, &block)
|
41
|
+
puts "Warning: method 'try' is deprecated (won't support in RWebSpec 3), use try_until instead."
|
42
|
+
try_until(timeout, polling_interval) {
|
43
|
+
yield
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# Try the operation up to specified times, and sleep given interval (in seconds)
|
49
|
+
# Error will be ignored until timeout
|
50
|
+
# Example
|
51
|
+
# repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
|
52
|
+
# repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
|
53
|
+
def repeat_try(num_tries = @@default_timeout || 30, interval = @@default_polling_interval || 1, & block)
|
54
|
+
num_tries ||= 1
|
55
|
+
(num_tries - 1).times do |num|
|
56
|
+
begin
|
57
|
+
yield
|
58
|
+
return
|
59
|
+
rescue => e
|
60
|
+
# puts "debug: #{num} failed: #{e}"
|
61
|
+
sleep interval
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# last try, throw error if still fails
|
66
|
+
begin
|
67
|
+
yield
|
68
|
+
rescue => e
|
69
|
+
raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
|
70
|
+
end
|
71
|
+
yield
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
##
|
76
|
+
# Convert :first to 1, :second to 2, and so on...
|
77
|
+
def symbol_to_sequence(symb)
|
78
|
+
value = {:zero => 0,
|
79
|
+
:first => 1,
|
80
|
+
:second => 2,
|
81
|
+
:third => 3,
|
82
|
+
:fourth => 4,
|
83
|
+
:fifth => 5,
|
84
|
+
:sixth => 6,
|
85
|
+
:seventh => 7,
|
86
|
+
:eighth => 8,
|
87
|
+
:ninth => 9,
|
88
|
+
:tenth => 10}[symb]
|
89
|
+
return value || symb.to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
# use win32screenshot library to save curernt active window, which shall be IE
|
95
|
+
#
|
96
|
+
# opts[:to_dir] => the direcotry to save image under
|
97
|
+
def take_screenshot(opts = {})
|
98
|
+
# puts "calling new take screenshot: #{$screenshot_supported}"
|
99
|
+
unless $screenshot_supported
|
100
|
+
puts " [WARN] Screenhost not supported, check whether win32screenshot gem is installed"
|
101
|
+
return
|
102
|
+
end
|
103
|
+
|
104
|
+
begin
|
105
|
+
screenshot_image_filename = "screenshot_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
|
106
|
+
the_dump_dir = opts[:to_dir] || default_dump_dir
|
107
|
+
FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
|
108
|
+
screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
|
109
|
+
screenshot_image_filepath.gsub!("/", "\\") if is_windows?
|
110
|
+
|
111
|
+
FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
|
112
|
+
|
113
|
+
if is_firefox? then
|
114
|
+
Win32::Screenshot::Take.of(:window, :title => /mozilla\sfirefox/i).write(screenshot_image_filepath)
|
115
|
+
elsif ie
|
116
|
+
Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
|
117
|
+
else
|
118
|
+
Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
|
119
|
+
end
|
120
|
+
notify_screenshot_location(screenshot_image_filepath)
|
121
|
+
rescue => e
|
122
|
+
puts "error on taking screenshot: #{e}"
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
#= Convenient functions
|
128
|
+
#
|
129
|
+
|
130
|
+
# Using Ruby block syntax to create interesting domain specific language,
|
131
|
+
# may be appeal to someone.
|
132
|
+
|
133
|
+
# Example:
|
134
|
+
# on @page do |i|
|
135
|
+
# i.enter_text('btn1')
|
136
|
+
# i.click_button('btn1')
|
137
|
+
# end
|
138
|
+
def on(page, & block)
|
139
|
+
yield page
|
140
|
+
end
|
141
|
+
|
142
|
+
# fail the test if user can perform the operation
|
143
|
+
#
|
144
|
+
# Example:
|
145
|
+
# shall_not_allow { 1/0 }
|
146
|
+
def shall_not_allow(& block)
|
147
|
+
operation_performed_ok = false
|
148
|
+
begin
|
149
|
+
yield
|
150
|
+
operation_performed_ok = true
|
151
|
+
rescue
|
152
|
+
end
|
153
|
+
raise "Operation shall not be allowed" if operation_performed_ok
|
154
|
+
end
|
155
|
+
|
156
|
+
alias do_not_allow shall_not_allow
|
157
|
+
|
158
|
+
# Does not provide real function, other than make enhancing test syntax
|
159
|
+
#
|
160
|
+
# Example:
|
161
|
+
# allow { click_button('Register') }
|
162
|
+
def allow(& block)
|
163
|
+
yield
|
164
|
+
end
|
165
|
+
|
166
|
+
alias shall_allow allow
|
167
|
+
alias allowing allow
|
168
|
+
|
169
|
+
# try operation, ignore if errors occur
|
170
|
+
#
|
171
|
+
# Example:
|
172
|
+
# failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
|
173
|
+
def failsafe(& block)
|
174
|
+
begin
|
175
|
+
yield
|
176
|
+
rescue =>e
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
alias fail_safe failsafe
|
181
|
+
|
11
182
|
# default date format returned is 29/12/2007.
|
12
183
|
# if supplied parameter is not '%m/%d/%Y' -> 12/29/2007
|
13
184
|
# Otherwise, "2007-12-29", which is most approiate date format
|
data/lib/rwebspec.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 2
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 2.0.4
|
9
|
+
version: 2.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Zhimin Zhan
|
@@ -14,7 +14,7 @@ autorequire: rwebspec
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2012-01-19 00:00:00 +10:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|