rformspec 0.4-x86-mingw32 → 0.5.1-x86-mingw32
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 +57 -49
- data/MIT-LICENSE +21 -21
- data/README +24 -24
- data/Rakefile +63 -63
- data/docs/index.html +183 -183
- data/lib/ext/rspec_rformunit.rb +46 -46
- data/lib/rformspec.rb +41 -41
- data/lib/rformspec/control.rb +160 -153
- data/lib/rformspec/driver.rb +120 -72
- data/lib/rformspec/form_testcase.rb +40 -40
- data/lib/rformspec/keyboard.rb +24 -24
- data/lib/rformspec/mouse.rb +55 -55
- data/lib/rformspec/open_file_dialog.rb +19 -19
- data/lib/rformspec/process.rb +27 -27
- data/lib/rformspec/saveas_file_dialog.rb +18 -18
- data/lib/rformspec/testwise_plugin.rb +92 -0
- data/lib/rformspec/window.rb +130 -114
- data/sample/form_calculator/calc_helper.rb +68 -68
- data/sample/form_calculator/calc_spec.rb +33 -33
- data/sample/form_calculator/calculator.tpr +27 -27
- data/sample/form_calculator/calculator.tws +13 -13
- data/sample/mouse.rb +19 -19
- data/sample/notepad.rb +19 -19
- data/sample/notepad1.rb +14 -14
- data/sample/test_calc.rb +33 -33
- metadata +9 -7
data/lib/rformspec/process.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
require File.dirname(__FILE__) + "/driver"
|
2
|
-
require 'singleton'
|
3
|
-
|
4
|
-
module RFormSpec
|
5
|
-
|
6
|
-
class Process
|
7
|
-
include Singleton
|
8
|
-
include Driver
|
9
|
-
|
10
|
-
def self.run(prog, work_path = nil)
|
11
|
-
instance._run(prog, work_path)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.execute(prog, work_path = nil)
|
15
|
-
instance._run(prog, work_path)
|
16
|
-
end
|
17
|
-
|
18
|
-
# --
|
19
|
-
# instance methods
|
20
|
-
def _run(program, work_path = nil)
|
21
|
-
driver.Run(program, work_path)
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
1
|
+
require File.dirname(__FILE__) + "/driver"
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module RFormSpec
|
5
|
+
|
6
|
+
class Process
|
7
|
+
include Singleton
|
8
|
+
include Driver
|
9
|
+
|
10
|
+
def self.run(prog, work_path = nil)
|
11
|
+
instance._run(prog, work_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.execute(prog, work_path = nil)
|
15
|
+
instance._run(prog, work_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
# --
|
19
|
+
# instance methods
|
20
|
+
def _run(program, work_path = nil)
|
21
|
+
driver.Run(program, work_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
module RFormSpec
|
2
|
-
class SaveasFileDialog < RFormSpec::Window
|
3
|
-
|
4
|
-
def initialize(title = "Save As")
|
5
|
-
focus_window(title)
|
6
|
-
end
|
7
|
-
|
8
|
-
def enter_filepath(file_path)
|
9
|
-
set_control_text("Edit1", file_path)
|
10
|
-
end
|
11
|
-
|
12
|
-
def click_save
|
13
|
-
click_button("Button2")
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
1
|
+
module RFormSpec
|
2
|
+
class SaveasFileDialog < RFormSpec::Window
|
3
|
+
|
4
|
+
def initialize(title = "Save As")
|
5
|
+
focus_window(title)
|
6
|
+
end
|
7
|
+
|
8
|
+
def enter_filepath(file_path)
|
9
|
+
set_control_text("Edit1", file_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def click_save
|
13
|
+
click_button("Button2")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
MAX_MESSAGE_LENGTH = 8192 # < 10K
|
4
|
+
$testwise_support = true
|
5
|
+
|
6
|
+
module RFormSpec
|
7
|
+
module TestWisePlugin
|
8
|
+
|
9
|
+
def debug(message)
|
10
|
+
if $RUN_IN_TESTWISE && message
|
11
|
+
the_sent_msg = message.to_s
|
12
|
+
if the_sent_msg.size > MAX_MESSAGE_LENGTH
|
13
|
+
the_sent_msg = the_sent_msg[0..MAX_MESSAGE_LENGTH] + "..."
|
14
|
+
end
|
15
|
+
connect_to_testwise(" DEBUG", the_sent_msg + "\r\n")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Support of iTest to ajust the intervals between keystroke/mouse operations
|
21
|
+
def operation_delay
|
22
|
+
begin
|
23
|
+
if $TESTWISE_OPERATION_DELAY && $TESTWISE_OPERATION_DELAY > 0 &&
|
24
|
+
$TESTWISE_OPERATION_DELAY && $TESTWISE_OPERATION_DELAY < 30000 then # max 30 seconds
|
25
|
+
sleep($TESTWISE_OPERATION_DELAY / 1000)
|
26
|
+
end
|
27
|
+
|
28
|
+
while $TESTWISE_PAUSE
|
29
|
+
debug("Paused, waiting ...")
|
30
|
+
sleep 1
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
puts "Error on delaying: #{e}"
|
34
|
+
# ignore
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def notify_screenshot_location(image_file_path)
|
39
|
+
connect_to_testwise(" SHOT", image_file_path)
|
40
|
+
end
|
41
|
+
|
42
|
+
# find out the line (and file) the execution is on, and notify iTest via Socket
|
43
|
+
def dump_caller_stack
|
44
|
+
return unless $TESTWISE_TRACE_EXECUTION
|
45
|
+
begin
|
46
|
+
trace_lines = []
|
47
|
+
trace_file = nil
|
48
|
+
found_first_spec_reference = false
|
49
|
+
caller.each_with_index do |position, idx|
|
50
|
+
next unless position =~ /\A(.*?):(\d+)/
|
51
|
+
trace_file = $1
|
52
|
+
if trace_file =~ /(_spec|_test|_rwebspec)\.rb\s*$/
|
53
|
+
found_first_spec_reference = true
|
54
|
+
trace_lines << position
|
55
|
+
break
|
56
|
+
end
|
57
|
+
trace_lines << position
|
58
|
+
break if trace_file =~ /example\/example_methods\.rb$/ or trace_file =~ /example\/example_group_methods\.rb$/
|
59
|
+
break if trace_lines.size > 10
|
60
|
+
# TODO: send multiple trace to be parse with pages.rb
|
61
|
+
# 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
|
62
|
+
end
|
63
|
+
|
64
|
+
# (trace_file.include?("_spec.rb") || trace_file.include?("_rwebspec.rb") || trace_file.include?("_test.rb") || trace_file.include?("_cmd.rb"))
|
65
|
+
if !trace_lines.empty?
|
66
|
+
connect_to_testwise(" TRACE", trace_lines.reverse.join("|"))
|
67
|
+
end
|
68
|
+
|
69
|
+
rescue => e
|
70
|
+
puts "failed to capture log: #{e}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def connect_to_testwise (message_type, body)
|
76
|
+
begin
|
77
|
+
the_message = message_type + "|" + body
|
78
|
+
if @last_message == the_message then # ignore the message same as preivous one
|
79
|
+
return
|
80
|
+
end
|
81
|
+
itest_port = $TESTWISE_TRACE_PORT || 7025
|
82
|
+
itest_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
83
|
+
itest_socket.connect(Socket.pack_sockaddr_in(itest_port, '127.0.0.1'))
|
84
|
+
itest_socket.puts(the_message)
|
85
|
+
@last_message = the_message
|
86
|
+
itest_socket.close
|
87
|
+
rescue => e
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
data/lib/rformspec/window.rb
CHANGED
@@ -1,114 +1,130 @@
|
|
1
|
-
require File.dirname(__FILE__) + "/driver"
|
2
|
-
require File.dirname(__FILE__) + "/control"
|
3
|
-
|
4
|
-
module RFormSpec
|
5
|
-
|
6
|
-
class Window < BaseControl
|
7
|
-
attr_accessor :title, :text
|
8
|
-
|
9
|
-
##
|
10
|
-
# title : page title, depends autoit options, might use as substring match or exact match
|
11
|
-
# text: some text in window for further identifing the window
|
12
|
-
# options:
|
13
|
-
# present => true | false, already there
|
14
|
-
# wait_timeout: wiat for maxium seconds if not active, throw error
|
15
|
-
# (active: means the window becomes the active window)
|
16
|
-
# otherwise, inside window class, using focus_window methods
|
17
|
-
def initialize(title, text = '', options = {:present => false, :wait_timeout => 0})
|
18
|
-
# for some windows, the title might change depends when it is invoked
|
19
|
-
if title.class == Array
|
20
|
-
title.each { |a_title|
|
21
|
-
@title = a_title
|
22
|
-
@text = text if text
|
23
|
-
timeout = options[:wait_timeout]
|
24
|
-
result = driver.WinWaitActive(@title, @text, timeout)
|
25
|
-
return if result != 0
|
26
|
-
}
|
27
|
-
raise "timeout while waiting for window: #{self.to_s}"
|
28
|
-
end
|
29
|
-
|
30
|
-
@title = title
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
result = driver.
|
38
|
-
raise "
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
def
|
47
|
-
driver.
|
48
|
-
end
|
49
|
-
|
50
|
-
def
|
51
|
-
driver.
|
52
|
-
end
|
53
|
-
|
54
|
-
def
|
55
|
-
driver.
|
56
|
-
end
|
57
|
-
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
combo
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
def
|
87
|
-
BaseControl.new(self, ctrl_id).
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
def
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
1
|
+
require File.dirname(__FILE__) + "/driver"
|
2
|
+
require File.dirname(__FILE__) + "/control"
|
3
|
+
|
4
|
+
module RFormSpec
|
5
|
+
|
6
|
+
class Window < BaseControl
|
7
|
+
attr_accessor :title, :text, :class_list
|
8
|
+
|
9
|
+
##
|
10
|
+
# title : page title, depends autoit options, might use as substring match or exact match
|
11
|
+
# text: some text in window for further identifing the window
|
12
|
+
# options:
|
13
|
+
# present => true | false, already there
|
14
|
+
# wait_timeout: wiat for maxium seconds if not active, throw error
|
15
|
+
# (active: means the window becomes the active window)
|
16
|
+
# otherwise, inside window class, using focus_window methods
|
17
|
+
def initialize(title, text = '', options = {:present => false, :wait_timeout => 0})
|
18
|
+
# for some windows, the title might change depends when it is invoked
|
19
|
+
if title.class == Array
|
20
|
+
title.each { |a_title|
|
21
|
+
@title = a_title
|
22
|
+
@text = text if text
|
23
|
+
timeout = options[:wait_timeout]
|
24
|
+
result = driver.WinWaitActive(@title, @text, timeout)
|
25
|
+
return if result != 0
|
26
|
+
}
|
27
|
+
raise "timeout while waiting for window: #{self.to_s}"
|
28
|
+
end
|
29
|
+
|
30
|
+
@title = title
|
31
|
+
# puts "[DEBUG ] setting title => #{@title}"
|
32
|
+
@text = text if text
|
33
|
+
# useful when ID changes
|
34
|
+
|
35
|
+
timeout = options[:wait_timeout]
|
36
|
+
if options[:present]
|
37
|
+
result = driver.WinActivate(@title, @text)
|
38
|
+
raise "window not found: #{self.to_s}" if result == 0
|
39
|
+
elsif timeout && timeout.to_i > 1 then
|
40
|
+
result = driver.WinWaitActive(@title, @text, timeout)
|
41
|
+
raise "timeout while waiting for window: #{self.to_s}" if result == 0
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def focus
|
47
|
+
driver.WinActivate(@title, @text)
|
48
|
+
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
driver.WinClose(@title, @text)
|
52
|
+
end
|
53
|
+
|
54
|
+
def exists?
|
55
|
+
driver.WinExists(@title, @text)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_text
|
59
|
+
driver.WinGetText(@title, @text)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_class_list
|
63
|
+
driver.WinGetClassList(@title, @text)
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_control_text(control_id, new_text)
|
67
|
+
BaseControl.new(self, control_id).set_text(new_text)
|
68
|
+
end
|
69
|
+
|
70
|
+
def click_button(btn_id)
|
71
|
+
Button.new(self, btn_id).click
|
72
|
+
end
|
73
|
+
|
74
|
+
def show_dropdown(combo_id)
|
75
|
+
combo = ComboBox.new(self, combo_id)
|
76
|
+
combo.show_dropdown
|
77
|
+
combo
|
78
|
+
end
|
79
|
+
|
80
|
+
def hide_dropdown(combo_id)
|
81
|
+
combo = ComboBox.new(self, combo_id)
|
82
|
+
combo.hide_dropdown
|
83
|
+
combo
|
84
|
+
end
|
85
|
+
|
86
|
+
def focus_control(ctrl_id)
|
87
|
+
BaseControl.new(self, ctrl_id).focus
|
88
|
+
end
|
89
|
+
|
90
|
+
def send_control_text(ctrl_id, text)
|
91
|
+
BaseControl.new(self, ctrl_id).send_text(text)
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_control_text(ctrl_id)
|
95
|
+
BaseControl.new(self, ctrl_id).get_text
|
96
|
+
end
|
97
|
+
|
98
|
+
#Not fully verified yet
|
99
|
+
def statusbar_text
|
100
|
+
driver.StatusbarGetText(@title)
|
101
|
+
end
|
102
|
+
|
103
|
+
def pixel_color(x,y)
|
104
|
+
driver.PixelGetColor(x,y)
|
105
|
+
end
|
106
|
+
alias pixel_colour pixel_color
|
107
|
+
alias get_pixel_colour pixel_color
|
108
|
+
alias get_pixel_color pixel_color
|
109
|
+
|
110
|
+
def to_s
|
111
|
+
"Window{title => '#{@title}', text=>'#{@text}'}"
|
112
|
+
end
|
113
|
+
|
114
|
+
# a list
|
115
|
+
def button(button_id)
|
116
|
+
RFormSpec::Button.new(self, button_id)
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# return the class match by name
|
121
|
+
def get_class(name)
|
122
|
+
@class_list = get_class_list
|
123
|
+
@class_list.select {|x| x.include?(name)}.collect{|y| y.strip}
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -1,68 +1,68 @@
|
|
1
|
-
require 'rformspec'
|
2
|
-
|
3
|
-
module CalcSpecHelper
|
4
|
-
include RFormSpec::Driver
|
5
|
-
|
6
|
-
def run_calc
|
7
|
-
RFormSpec::Process.run("calc.exe")
|
8
|
-
@calc_win = RFormSpec::Window.new('Calculator', "", :wait_timeout => 2)
|
9
|
-
end
|
10
|
-
alias start_calc run_calc
|
11
|
-
|
12
|
-
def exit_calc
|
13
|
-
@calc_win.close
|
14
|
-
end
|
15
|
-
|
16
|
-
def click_3
|
17
|
-
@calc_win.click_button('127') #3
|
18
|
-
sleep(0.5)
|
19
|
-
end
|
20
|
-
|
21
|
-
def click_7
|
22
|
-
@calc_win.click_button('131') #7
|
23
|
-
sleep(0.5)
|
24
|
-
end
|
25
|
-
|
26
|
-
def click_add
|
27
|
-
@calc_win.click_button('92') # +
|
28
|
-
sleep(0.5)
|
29
|
-
end
|
30
|
-
alias click_plus click_add
|
31
|
-
|
32
|
-
def click_multiply
|
33
|
-
@calc_win.click_button('91') #*
|
34
|
-
sleep(0.5)
|
35
|
-
end
|
36
|
-
|
37
|
-
def click_equals
|
38
|
-
@calc_win.click_button('112') #=
|
39
|
-
sleep(0.5)
|
40
|
-
end
|
41
|
-
|
42
|
-
def result
|
43
|
-
@calc_win.get_control_text('403')
|
44
|
-
end
|
45
|
-
alias get_result result
|
46
|
-
|
47
|
-
def perform(actions)
|
48
|
-
methods_to_call = actions.collect { |act|
|
49
|
-
case act
|
50
|
-
when '+':
|
51
|
-
'plus'
|
52
|
-
when '-':
|
53
|
-
'minus'
|
54
|
-
when '*':
|
55
|
-
'multiply'
|
56
|
-
when '=':
|
57
|
-
'equals'
|
58
|
-
else
|
59
|
-
act
|
60
|
-
end
|
61
|
-
}
|
62
|
-
|
63
|
-
methods_to_call.each { |met|
|
64
|
-
self.send("click_#{met}")
|
65
|
-
}
|
66
|
-
get_result
|
67
|
-
end
|
68
|
-
end
|
1
|
+
require 'rformspec'
|
2
|
+
|
3
|
+
module CalcSpecHelper
|
4
|
+
include RFormSpec::Driver
|
5
|
+
|
6
|
+
def run_calc
|
7
|
+
RFormSpec::Process.run("calc.exe")
|
8
|
+
@calc_win = RFormSpec::Window.new('Calculator', "", :wait_timeout => 2)
|
9
|
+
end
|
10
|
+
alias start_calc run_calc
|
11
|
+
|
12
|
+
def exit_calc
|
13
|
+
@calc_win.close
|
14
|
+
end
|
15
|
+
|
16
|
+
def click_3
|
17
|
+
@calc_win.click_button('127') #3
|
18
|
+
sleep(0.5)
|
19
|
+
end
|
20
|
+
|
21
|
+
def click_7
|
22
|
+
@calc_win.click_button('131') #7
|
23
|
+
sleep(0.5)
|
24
|
+
end
|
25
|
+
|
26
|
+
def click_add
|
27
|
+
@calc_win.click_button('92') # +
|
28
|
+
sleep(0.5)
|
29
|
+
end
|
30
|
+
alias click_plus click_add
|
31
|
+
|
32
|
+
def click_multiply
|
33
|
+
@calc_win.click_button('91') #*
|
34
|
+
sleep(0.5)
|
35
|
+
end
|
36
|
+
|
37
|
+
def click_equals
|
38
|
+
@calc_win.click_button('112') #=
|
39
|
+
sleep(0.5)
|
40
|
+
end
|
41
|
+
|
42
|
+
def result
|
43
|
+
@calc_win.get_control_text('403')
|
44
|
+
end
|
45
|
+
alias get_result result
|
46
|
+
|
47
|
+
def perform(actions)
|
48
|
+
methods_to_call = actions.collect { |act|
|
49
|
+
case act
|
50
|
+
when '+':
|
51
|
+
'plus'
|
52
|
+
when '-':
|
53
|
+
'minus'
|
54
|
+
when '*':
|
55
|
+
'multiply'
|
56
|
+
when '=':
|
57
|
+
'equals'
|
58
|
+
else
|
59
|
+
act
|
60
|
+
end
|
61
|
+
}
|
62
|
+
|
63
|
+
methods_to_call.each { |met|
|
64
|
+
self.send("click_#{met}")
|
65
|
+
}
|
66
|
+
get_result
|
67
|
+
end
|
68
|
+
end
|