rwebspec 1.4.0.1 → 1.4.0.2
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.
- data/CHANGELOG +306 -300
- data/MIT-LICENSE +21 -21
- data/README +32 -32
- data/Rakefile +104 -94
- data/lib/rspec_extensions.rb +50 -50
- data/lib/rwebspec/assert.rb +361 -361
- data/lib/rwebspec/clickJSDialog.rb +15 -15
- data/lib/rwebspec/context.rb +24 -24
- data/lib/rwebspec/driver.rb +7 -0
- data/lib/rwebspec/itest_plugin.rb +20 -9
- data/lib/rwebspec/matchers/contains_text.rb +37 -37
- data/lib/rwebspec/popup.rb +147 -147
- data/lib/rwebspec/rspec_helper.rb +96 -96
- data/lib/rwebspec/test_script.rb +8 -8
- data/lib/rwebspec/test_utils.rb +171 -171
- data/lib/rwebspec/using_pages.rb +49 -49
- data/lib/rwebspec/web_browser.rb +566 -528
- data/lib/rwebspec/web_page.rb +104 -94
- data/lib/rwebspec/web_testcase.rb +38 -36
- data/lib/rwebspec.rb +31 -31
- data/lib/rwebunit.rb +3 -3
- data/lib/watir_extensions.rb +69 -69
- metadata +16 -6
@@ -1,15 +1,15 @@
|
|
1
|
-
#
|
2
|
-
# clickJSDialog.rb
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# This file contains the JS clicker when it runs as a separate process
|
6
|
-
require 'watir/winClicker'
|
7
|
-
|
8
|
-
button = "OK"
|
9
|
-
button = ARGV[0] unless ARGV[0] == nil
|
10
|
-
sleepTime = 0
|
11
|
-
sleepTime = ARGV[1] unless ARGV[1] == nil
|
12
|
-
|
13
|
-
clicker= WinClicker.new
|
14
|
-
result = clicker.clickJavaScriptDialog( button )
|
15
|
-
clicker = nil
|
1
|
+
#
|
2
|
+
# clickJSDialog.rb
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# This file contains the JS clicker when it runs as a separate process
|
6
|
+
require 'watir/winClicker'
|
7
|
+
|
8
|
+
button = "OK"
|
9
|
+
button = ARGV[0] unless ARGV[0] == nil
|
10
|
+
sleepTime = 0
|
11
|
+
sleepTime = ARGV[1] unless ARGV[1] == nil
|
12
|
+
|
13
|
+
clicker= WinClicker.new
|
14
|
+
result = clicker.clickJavaScriptDialog( button )
|
15
|
+
clicker = nil
|
data/lib/rwebspec/context.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
#***********************************************************
|
2
|
-
#* Copyright (c) 2006 - 2009 Zhimin Zhan.
|
3
|
-
#* Distributed open-source, see full license in MIT-LICENSE
|
4
|
-
#***********************************************************
|
5
|
-
|
6
|
-
module RWebSpec
|
7
|
-
|
8
|
-
##
|
9
|
-
# Store test optionns
|
10
|
-
#
|
11
|
-
class Context
|
12
|
-
attr_accessor :base_url
|
13
|
-
|
14
|
-
def initialize(base_url)
|
15
|
-
set_base_url(base_url)
|
16
|
-
end
|
17
|
-
|
18
|
-
def set_base_url(baseUrl)
|
19
|
-
@base_url = baseUrl
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
1
|
+
#***********************************************************
|
2
|
+
#* Copyright (c) 2006 - 2009 Zhimin Zhan.
|
3
|
+
#* Distributed open-source, see full license in MIT-LICENSE
|
4
|
+
#***********************************************************
|
5
|
+
|
6
|
+
module RWebSpec
|
7
|
+
|
8
|
+
##
|
9
|
+
# Store test optionns
|
10
|
+
#
|
11
|
+
class Context
|
12
|
+
attr_accessor :base_url
|
13
|
+
|
14
|
+
def initialize(base_url)
|
15
|
+
set_base_url(base_url)
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_base_url(baseUrl)
|
19
|
+
@base_url = baseUrl
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/rwebspec/driver.rb
CHANGED
@@ -28,6 +28,13 @@ module RWebSpec
|
|
28
28
|
# 2. If running using iTest2, used as confiured
|
29
29
|
# 3. Use default value set
|
30
30
|
def open_browser(base_url = nil, options = {})
|
31
|
+
|
32
|
+
begin
|
33
|
+
support_unicode
|
34
|
+
rescue => e
|
35
|
+
puts "Unicode may not work in IE, #{e}"
|
36
|
+
end
|
37
|
+
|
31
38
|
base_url ||= $ITEST2_PROJECT_BASE_URL
|
32
39
|
base_url ||= $BASE_URL
|
33
40
|
raise "base_url must be set" if base_url.nil?
|
@@ -46,23 +46,34 @@ module RWebSpec
|
|
46
46
|
# find out the line (and file) the execution is on, and notify iTest via Socket
|
47
47
|
def dump_caller_stack
|
48
48
|
return unless $ITEST2_TRACE_EXECUTION
|
49
|
-
begin
|
49
|
+
begin
|
50
|
+
trace_lines = []
|
51
|
+
trace_file = nil
|
52
|
+
found_first_spec_reference = false
|
50
53
|
caller.each_with_index do |position, idx|
|
51
54
|
next unless position =~ /\A(.*?):(\d+)/
|
52
|
-
|
55
|
+
trace_file = $1
|
56
|
+
if trace_file =~ /(_spec|_test|_rwebspec)\.rb\s*$/
|
57
|
+
found_first_spec_reference = true
|
58
|
+
trace_lines << position
|
59
|
+
break
|
60
|
+
end
|
61
|
+
trace_lines << position
|
62
|
+
break if trace_file =~ /example\/example_methods\.rb$/ or trace_file =~ /example\/example_group_methods\.rb$/
|
63
|
+
break if trace_lines.size > 10
|
53
64
|
# TODO: send multiple trace to be parse with pages.rb
|
54
|
-
#
|
55
|
-
|
56
|
-
if file.include?("_spec.rb") || file.include?("_test.rb") || file.include?("_cmd.rb")
|
57
|
-
connect_to_itest(" TRACE", position)
|
58
|
-
end
|
65
|
+
# break if trace_file =~ /example\/example_methods\.rb$/ or trace_file =~ /example\/example_group_methods\.rb$/ or trace_file =~ /driver\.rb$/ or trace_file =~ /timeout\.rb$/ # don't include rspec or ruby trace
|
66
|
+
end
|
59
67
|
|
60
|
-
|
68
|
+
# (trace_file.include?("_spec.rb") || trace_file.include?("_rwebspec.rb") || trace_file.include?("_test.rb") || trace_file.include?("_cmd.rb"))
|
69
|
+
if !trace_lines.empty?
|
70
|
+
connect_to_itest(" TRACE", trace_lines.reverse.join("|"))
|
61
71
|
end
|
72
|
+
|
62
73
|
rescue => e
|
63
74
|
puts "failed to capture log: #{e}"
|
64
75
|
end
|
65
76
|
end
|
66
77
|
|
67
78
|
end
|
68
|
-
end
|
79
|
+
end
|
@@ -1,37 +1,37 @@
|
|
1
|
-
class ContainsText
|
2
|
-
|
3
|
-
# this is what the matcher is called on.
|
4
|
-
# In this case:
|
5
|
-
# foo.should contains(:bars)
|
6
|
-
# foo would be passed to the +initialize+
|
7
|
-
def initialize(expected)
|
8
|
-
@expected = expected
|
9
|
-
end
|
10
|
-
|
11
|
-
def matches?(actual)
|
12
|
-
@actual = actual
|
13
|
-
return actual && actual.include?(@expected)
|
14
|
-
end
|
15
|
-
|
16
|
-
def actual_text
|
17
|
-
@actual.to_s.length > 1000000 ? @actual[0, 1000] : @actual
|
18
|
-
end
|
19
|
-
|
20
|
-
# error message for should
|
21
|
-
def failure_message
|
22
|
-
"expected #{actual_text} not to contains #{@expected}, but it did't"
|
23
|
-
end
|
24
|
-
|
25
|
-
# error message for should_not
|
26
|
-
def negative_failure_message
|
27
|
-
"expected #{actual_text} not to contains #{@expected}, but it did"
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
# This method is the one you use with should/should_not
|
34
|
-
def contains_text?(expected)
|
35
|
-
ContainsText.new(expected)
|
36
|
-
end
|
37
|
-
alias contains? contains_text?
|
1
|
+
class ContainsText
|
2
|
+
|
3
|
+
# this is what the matcher is called on.
|
4
|
+
# In this case:
|
5
|
+
# foo.should contains(:bars)
|
6
|
+
# foo would be passed to the +initialize+
|
7
|
+
def initialize(expected)
|
8
|
+
@expected = expected
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(actual)
|
12
|
+
@actual = actual
|
13
|
+
return actual && actual.include?(@expected)
|
14
|
+
end
|
15
|
+
|
16
|
+
def actual_text
|
17
|
+
@actual.to_s.length > 1000000 ? @actual[0, 1000] : @actual
|
18
|
+
end
|
19
|
+
|
20
|
+
# error message for should
|
21
|
+
def failure_message
|
22
|
+
"expected #{actual_text} not to contains #{@expected}, but it did't"
|
23
|
+
end
|
24
|
+
|
25
|
+
# error message for should_not
|
26
|
+
def negative_failure_message
|
27
|
+
"expected #{actual_text} not to contains #{@expected}, but it did"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# This method is the one you use with should/should_not
|
34
|
+
def contains_text?(expected)
|
35
|
+
ContainsText.new(expected)
|
36
|
+
end
|
37
|
+
alias contains? contains_text?
|
data/lib/rwebspec/popup.rb
CHANGED
@@ -1,147 +1,147 @@
|
|
1
|
-
module RWebSpec
|
2
|
-
module Popup
|
3
|
-
|
4
|
-
#= Popup
|
5
|
-
#
|
6
|
-
|
7
|
-
# Start background thread to click popup windows
|
8
|
-
# Warning:
|
9
|
-
# Make browser window active
|
10
|
-
# Don't mouse your mouse to focus other window during test execution
|
11
|
-
def check_for_popups
|
12
|
-
autoit = WIN32OLE.new('AutoItX3.Control')
|
13
|
-
#
|
14
|
-
# Do forever - assumes popups could occur anywhere/anytime in your
|
15
|
-
# application.
|
16
|
-
loop do
|
17
|
-
# Look for window with given title. Give up after 1 second.
|
18
|
-
ret = autoit.WinWait('Windows Internet Explorer', '', 1)
|
19
|
-
#
|
20
|
-
# If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
|
21
|
-
if (ret==1) then
|
22
|
-
autoit.Send('{enter}')
|
23
|
-
end
|
24
|
-
#
|
25
|
-
# Take a rest to avoid chewing up cycles and give another thread a go.
|
26
|
-
# Then resume the loop.
|
27
|
-
sleep(3)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# Check for "Security Information" and "Security Alert" alert popup, click 'Yes'
|
33
|
-
#
|
34
|
-
# Usage: For individual test suite
|
35
|
-
#
|
36
|
-
# before(:all) do
|
37
|
-
# $popup = Thread.new { check_for_alerts }
|
38
|
-
# open_in_browser
|
39
|
-
# ...
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# after(:all) do
|
43
|
-
# close_browser
|
44
|
-
# Thread.kill($popup)
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# or for all tests,
|
48
|
-
# $popup = Thread.new { check_for_alerts }
|
49
|
-
# at_exit{ Thread.kill($popup) }
|
50
|
-
def check_for_security_alerts
|
51
|
-
autoit = WIN32OLE.new('AutoItX3.Control')
|
52
|
-
loop do
|
53
|
-
["Security Alert", "Security Information"].each do |win_title|
|
54
|
-
ret = autoit.WinWait(win_title, '', 1)
|
55
|
-
if (ret==1) then
|
56
|
-
autoit.Send('{Y}')
|
57
|
-
end
|
58
|
-
end
|
59
|
-
sleep(3)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def verify_alert(title = "Microsoft Internet Explorer", button = "OK")
|
64
|
-
if is_windows? && !is_firefox?
|
65
|
-
WIN32OLE.new('AutoItX3.Control').ControlClick(title, '', button)
|
66
|
-
else
|
67
|
-
raise "This function only supports IE"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def click_button_in_security_information_popup(button = "&Yes")
|
72
|
-
verify_alert("Security Information", "", button)
|
73
|
-
end
|
74
|
-
alias click_security_information_popup click_button_in_security_information_popup
|
75
|
-
|
76
|
-
def click_button_in_security_alert_popup(button = "&Yes")
|
77
|
-
verify_alert("Security Alert", "", button)
|
78
|
-
end
|
79
|
-
alias click_security_alert_popup click_button_in_security_alert_popup
|
80
|
-
|
81
|
-
def click_button_in_javascript_popup(button = "OK")
|
82
|
-
verify_alert()
|
83
|
-
end
|
84
|
-
alias click_javascript_popup click_button_in_javascript_popup
|
85
|
-
|
86
|
-
##
|
87
|
-
# This only works for IEs
|
88
|
-
# Cons:
|
89
|
-
# - Slow
|
90
|
-
# - only works in IE
|
91
|
-
# - does not work for security alert ?
|
92
|
-
def ie_popup_clicker(button_name = "OK", max_wait = 15)
|
93
|
-
require 'watir/contrib/enabled_popup'
|
94
|
-
require 'win32ole'
|
95
|
-
hwnd = ie.enabled_popup(15)
|
96
|
-
if (hwnd) #yeah! a popup
|
97
|
-
popup = WinClicker.new
|
98
|
-
popup.makeWindowActive(hwnd) #Activate the window.
|
99
|
-
popup.clickWindowsButton_hwnd(hwnd, button_name) #Click the button
|
100
|
-
#popup.clickWindowsButton(/Internet/,button_name,30)
|
101
|
-
popup = nil
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def click_popup_window(button, wait_time= 9, user_input=nil )
|
106
|
-
@web_browser.start_clicker(button, wait_time, user_input)
|
107
|
-
sleep 0.5
|
108
|
-
end
|
109
|
-
# run a separate process waiting for the popup window to click
|
110
|
-
#
|
111
|
-
#
|
112
|
-
def prepare_to_click_button_in_popup(button = "OK", wait_time = 3)
|
113
|
-
# !@web_browser.is_firefox?
|
114
|
-
# TODO: firefox is OK
|
115
|
-
if RUBY_PLATFORM =~ /mswin/ then
|
116
|
-
start_checking_js_dialog(button, wait_time)
|
117
|
-
else
|
118
|
-
raise "this only support on Windows and on IE"
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# Start a background process to click the button on a javascript popup window
|
123
|
-
def start_checking_js_dialog(button = "OK", wait_time = 3)
|
124
|
-
w = WinClicker.new
|
125
|
-
longName = File.expand_path(File.dirname(__FILE__)).gsub("/", "\\" )
|
126
|
-
shortName = w.getShortFileName(longName)
|
127
|
-
c = "start ruby #{shortName}\\clickJSDialog.rb #{button} #{wait_time} "
|
128
|
-
w.winsystem(c)
|
129
|
-
w = nil
|
130
|
-
end
|
131
|
-
|
132
|
-
# Click the button in javascript popup dialog
|
133
|
-
# Usage:
|
134
|
-
# click_button_in_popup_after { click_link('Cancel')}
|
135
|
-
# click_button_in_popup_after("OK") { click_link('Cancel')}
|
136
|
-
#
|
137
|
-
def click_button_in_popup_after(options = {:button => "OK", :wait_time => 3}, &block)
|
138
|
-
if is_windows? then
|
139
|
-
start_checking_js_dialog(options[:button], options[:wait_time])
|
140
|
-
yield
|
141
|
-
else
|
142
|
-
raise "this only support on Windows and on IE"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|
1
|
+
module RWebSpec
|
2
|
+
module Popup
|
3
|
+
|
4
|
+
#= Popup
|
5
|
+
#
|
6
|
+
|
7
|
+
# Start background thread to click popup windows
|
8
|
+
# Warning:
|
9
|
+
# Make browser window active
|
10
|
+
# Don't mouse your mouse to focus other window during test execution
|
11
|
+
def check_for_popups
|
12
|
+
autoit = WIN32OLE.new('AutoItX3.Control')
|
13
|
+
#
|
14
|
+
# Do forever - assumes popups could occur anywhere/anytime in your
|
15
|
+
# application.
|
16
|
+
loop do
|
17
|
+
# Look for window with given title. Give up after 1 second.
|
18
|
+
ret = autoit.WinWait('Windows Internet Explorer', '', 1)
|
19
|
+
#
|
20
|
+
# If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
|
21
|
+
if (ret==1) then
|
22
|
+
autoit.Send('{enter}')
|
23
|
+
end
|
24
|
+
#
|
25
|
+
# Take a rest to avoid chewing up cycles and give another thread a go.
|
26
|
+
# Then resume the loop.
|
27
|
+
sleep(3)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Check for "Security Information" and "Security Alert" alert popup, click 'Yes'
|
33
|
+
#
|
34
|
+
# Usage: For individual test suite
|
35
|
+
#
|
36
|
+
# before(:all) do
|
37
|
+
# $popup = Thread.new { check_for_alerts }
|
38
|
+
# open_in_browser
|
39
|
+
# ...
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# after(:all) do
|
43
|
+
# close_browser
|
44
|
+
# Thread.kill($popup)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# or for all tests,
|
48
|
+
# $popup = Thread.new { check_for_alerts }
|
49
|
+
# at_exit{ Thread.kill($popup) }
|
50
|
+
def check_for_security_alerts
|
51
|
+
autoit = WIN32OLE.new('AutoItX3.Control')
|
52
|
+
loop do
|
53
|
+
["Security Alert", "Security Information"].each do |win_title|
|
54
|
+
ret = autoit.WinWait(win_title, '', 1)
|
55
|
+
if (ret==1) then
|
56
|
+
autoit.Send('{Y}')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
sleep(3)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify_alert(title = "Microsoft Internet Explorer", button = "OK")
|
64
|
+
if is_windows? && !is_firefox?
|
65
|
+
WIN32OLE.new('AutoItX3.Control').ControlClick(title, '', button)
|
66
|
+
else
|
67
|
+
raise "This function only supports IE"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def click_button_in_security_information_popup(button = "&Yes")
|
72
|
+
verify_alert("Security Information", "", button)
|
73
|
+
end
|
74
|
+
alias click_security_information_popup click_button_in_security_information_popup
|
75
|
+
|
76
|
+
def click_button_in_security_alert_popup(button = "&Yes")
|
77
|
+
verify_alert("Security Alert", "", button)
|
78
|
+
end
|
79
|
+
alias click_security_alert_popup click_button_in_security_alert_popup
|
80
|
+
|
81
|
+
def click_button_in_javascript_popup(button = "OK")
|
82
|
+
verify_alert()
|
83
|
+
end
|
84
|
+
alias click_javascript_popup click_button_in_javascript_popup
|
85
|
+
|
86
|
+
##
|
87
|
+
# This only works for IEs
|
88
|
+
# Cons:
|
89
|
+
# - Slow
|
90
|
+
# - only works in IE
|
91
|
+
# - does not work for security alert ?
|
92
|
+
def ie_popup_clicker(button_name = "OK", max_wait = 15)
|
93
|
+
require 'watir/contrib/enabled_popup'
|
94
|
+
require 'win32ole'
|
95
|
+
hwnd = ie.enabled_popup(15)
|
96
|
+
if (hwnd) #yeah! a popup
|
97
|
+
popup = WinClicker.new
|
98
|
+
popup.makeWindowActive(hwnd) #Activate the window.
|
99
|
+
popup.clickWindowsButton_hwnd(hwnd, button_name) #Click the button
|
100
|
+
#popup.clickWindowsButton(/Internet/,button_name,30)
|
101
|
+
popup = nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def click_popup_window(button, wait_time= 9, user_input=nil )
|
106
|
+
@web_browser.start_clicker(button, wait_time, user_input)
|
107
|
+
sleep 0.5
|
108
|
+
end
|
109
|
+
# run a separate process waiting for the popup window to click
|
110
|
+
#
|
111
|
+
#
|
112
|
+
def prepare_to_click_button_in_popup(button = "OK", wait_time = 3)
|
113
|
+
# !@web_browser.is_firefox?
|
114
|
+
# TODO: firefox is OK
|
115
|
+
if RUBY_PLATFORM =~ /mswin/ then
|
116
|
+
start_checking_js_dialog(button, wait_time)
|
117
|
+
else
|
118
|
+
raise "this only support on Windows and on IE"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Start a background process to click the button on a javascript popup window
|
123
|
+
def start_checking_js_dialog(button = "OK", wait_time = 3)
|
124
|
+
w = WinClicker.new
|
125
|
+
longName = File.expand_path(File.dirname(__FILE__)).gsub("/", "\\" )
|
126
|
+
shortName = w.getShortFileName(longName)
|
127
|
+
c = "start ruby #{shortName}\\clickJSDialog.rb #{button} #{wait_time} "
|
128
|
+
w.winsystem(c)
|
129
|
+
w = nil
|
130
|
+
end
|
131
|
+
|
132
|
+
# Click the button in javascript popup dialog
|
133
|
+
# Usage:
|
134
|
+
# click_button_in_popup_after { click_link('Cancel')}
|
135
|
+
# click_button_in_popup_after("OK") { click_link('Cancel')}
|
136
|
+
#
|
137
|
+
def click_button_in_popup_after(options = {:button => "OK", :wait_time => 3}, &block)
|
138
|
+
if is_windows? then
|
139
|
+
start_checking_js_dialog(options[:button], options[:wait_time])
|
140
|
+
yield
|
141
|
+
else
|
142
|
+
raise "this only support on Windows and on IE"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|