watirsplash 0.1.9
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/History.rdoc +51 -0
- data/License.txt +24 -0
- data/README.rdoc +171 -0
- data/Rakefile +16 -0
- data/bin/watirsplash +10 -0
- data/lib/spec.opts +5 -0
- data/lib/watirsplash/autoit.rb +54 -0
- data/lib/watirsplash/html_formatter.rb +118 -0
- data/lib/watirsplash/runner.rb +97 -0
- data/lib/watirsplash/spec.rb +43 -0
- data/lib/watirsplash/spec_helper.rb +68 -0
- data/lib/watirsplash/util.rb +35 -0
- data/lib/watirsplash/version.rb +3 -0
- data/lib/watirsplash/waiter.rb +29 -0
- data/lib/watirsplash/watir.rb +151 -0
- data/lib/watirsplash.rb +11 -0
- data/spec/spec_helper_spec.rb +56 -0
- data/spec/spec_match_array_spec.rb +21 -0
- data/spec/util_spec.rb +38 -0
- data/spec/watir_ie_spec.rb +13 -0
- data/spec/watir_table_row_spec.rb +46 -0
- data/spec/watir_table_spec.rb +79 -0
- data/templates/common/config.rb +28 -0
- data/templates/common/environment.rb +17 -0
- data/templates/common/lib/common_application_helper.rb +14 -0
- data/templates/project/application_helper.rb +18 -0
- data/templates/project/config.rb +20 -0
- data/templates/project/environment.rb +13 -0
- data/templates/project/ide_runner.rb +3 -0
- data/templates/project/spec/dummy_spec.rb +44 -0
- metadata +205 -0
data/History.rdoc
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
=== Version 0.1.9 / 2010-05-01
|
2
|
+
|
3
|
+
* Changed name of the library to WatirSplash due to name conflict
|
4
|
+
- this means that all watirspec commands are now obsolete and you have to use watirsplash commands instead
|
5
|
+
- all WatiRspec constants (module names etc) are now named as WatirSplash
|
6
|
+
|
7
|
+
=== Version 0.1.8 / 2010-04-19
|
8
|
+
|
9
|
+
* tidied up some code, no changes in functionality
|
10
|
+
|
11
|
+
=== Version 0.1.7 / 2010-04-15
|
12
|
+
|
13
|
+
* minor fix
|
14
|
+
|
15
|
+
=== Version 0.1.6 / 2010-04-08
|
16
|
+
|
17
|
+
* browser was not closed when Watir::IE#run_error_checks throwed an exception
|
18
|
+
|
19
|
+
=== Version 0.1.5 / 2010-04-08
|
20
|
+
|
21
|
+
* fixed a problem where HtmlFormatter threw an ugly exception due to the problem when browser was not opened
|
22
|
+
|
23
|
+
=== Version 0.1.4 / 2010-04-06
|
24
|
+
|
25
|
+
* added dependency for win32screenshot
|
26
|
+
|
27
|
+
=== Version 0.1.3 / 2010-04-06
|
28
|
+
|
29
|
+
* fixed a bug where inner table was not shown with Watir::Table#to_a when it was not a direct child, but some other element was in between for example form, span, div etc.
|
30
|
+
|
31
|
+
=== Version 0.1.2 / 2010-04-05
|
32
|
+
|
33
|
+
* Added match_array matcher for RSpec for using with Array when regular expressions are needed. It is useful when verifying html tables with #to_a method.
|
34
|
+
expected_array = ["1", "2", /\d+/, "3"]
|
35
|
+
|
36
|
+
["1", "2", "66", "3"].should match_array(expected_array)
|
37
|
+
table(:id => "table_id").to_a.should match_array(expected_array)
|
38
|
+
|
39
|
+
=== Version 0.1.1 / 2010-04-04
|
40
|
+
|
41
|
+
* Watir::Table#to_a and Watir::TableRow#to_a work now well with tr, th, td elements, colspan and nested tables.
|
42
|
+
This means that you can test easily tables now:
|
43
|
+
expected_table = [["one", "two"], ["three", "four"]]
|
44
|
+
table(:id => "table_id").to_a.should =~ expected_table
|
45
|
+
|
46
|
+
* removed strict version requirements for dependencies
|
47
|
+
|
48
|
+
|
49
|
+
=== Version 0.1.0 / 2010-04-03
|
50
|
+
|
51
|
+
First release of WatiRspec, a small library for combining Watir and RSpec for browser-based functional testing in Ruby.
|
data/License.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 Jarmo Pertman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person
|
6
|
+
obtaining a copy of this software and associated documentation
|
7
|
+
files (the "Software"), to deal in the Software without
|
8
|
+
restriction, including without limitation the rights to use,
|
9
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the
|
11
|
+
Software is furnished to do so, subject to the following
|
12
|
+
conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
19
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
21
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
22
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
23
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
24
|
+
OTHER DEALINGS IN THE SOFTWARE
|
data/README.rdoc
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
= WatirSplash
|
2
|
+
|
3
|
+
* Web: http://github.com/jarmo/WatirSplash
|
4
|
+
* Author: Jarmo Pertman (mailto:jarmo.p[at]gmail.com)
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
WatirSplash is a small library for easier browser-based functional testing in Ruby.
|
9
|
+
It combines Watir (http://www.watir.com) for controlling the browser (currently mainly IE) and
|
10
|
+
RSpec (http://rspec.info) for testing framework. This powerful combination gives you
|
11
|
+
the ability to write easily well-maintained and easy-to-read specs (specifications in RSpec) so
|
12
|
+
you don't need to have any extra documentation for your applications.
|
13
|
+
|
14
|
+
WatirSplash makes it easier to use best features of both of these tools together so
|
15
|
+
you won't have to spend time on thinking how to do that yourself - you can start
|
16
|
+
testing right away!
|
17
|
+
|
18
|
+
== FEATURES:
|
19
|
+
|
20
|
+
* generate command for generating default project structure
|
21
|
+
* generate_common command for generating common ui-tests directory
|
22
|
+
* Browser will be opened and closed for each example group automatically
|
23
|
+
* You can use Watir method names directly without having to specify a browser object:
|
24
|
+
text_field(:name => "locator") # instead of @browser.text_field(:name => "locator")
|
25
|
+
* All needed libraries will be loaded and helper modules will be included automatically
|
26
|
+
* All JavaScript errors will be detected automatically
|
27
|
+
* Some additional methods to help using Watir (download_file, wait_until, wait_until! etc.)
|
28
|
+
|
29
|
+
* Custom html formatter for RSpec:
|
30
|
+
* Saves screenshot of the browser window
|
31
|
+
* Saves html of the page
|
32
|
+
* Saves all the files created/downloaded during the example and shows them on the report
|
33
|
+
* Automatically archives test results for later reviewing
|
34
|
+
|
35
|
+
== SYNOPSIS:
|
36
|
+
|
37
|
+
describe "Google" do
|
38
|
+
before :all do
|
39
|
+
goto "http://google.com"
|
40
|
+
url.should =~ /google/
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has search field" do
|
44
|
+
text_field = text_field(:name => "q")
|
45
|
+
text_field.should exist
|
46
|
+
text_field.should be_visible
|
47
|
+
end
|
48
|
+
|
49
|
+
it "performs search" do
|
50
|
+
text_field(:name => "q").set "Bing"
|
51
|
+
button(:name => "btnG").click
|
52
|
+
text.should include("Bing")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
C:\project\ui-test>watirsplash spec\google_spec.rb
|
57
|
+
Results will be saved into the directory C:/project/ui-test/results
|
58
|
+
Google
|
59
|
+
has search field
|
60
|
+
performs search
|
61
|
+
|
62
|
+
Finished in 6.782388 seconds
|
63
|
+
|
64
|
+
2 examples, 0 failures
|
65
|
+
|
66
|
+
== INSTALL:
|
67
|
+
|
68
|
+
* install Ruby 1.8.6:
|
69
|
+
http://rubyinstaller.org/
|
70
|
+
|
71
|
+
* install ImageMagick with rmagick-win32 for making the screenshots:
|
72
|
+
http://rubyforge.org/frs/?group_id=12&release_id=42049
|
73
|
+
|
74
|
+
* update RubyGems:
|
75
|
+
gem update --system
|
76
|
+
|
77
|
+
* install WatirSplash:
|
78
|
+
gem install watirsplash
|
79
|
+
|
80
|
+
== USAGE:
|
81
|
+
|
82
|
+
If you have a web-application project (it may have been written in any programming language) without any browser-based tests,
|
83
|
+
then it has probably a directory structure similar to this example:
|
84
|
+
C:\example_project
|
85
|
+
├───doc
|
86
|
+
├───lib
|
87
|
+
└───test
|
88
|
+
|
89
|
+
Now from the command line go to this directory and execute generate command:
|
90
|
+
C:\>cd example_project
|
91
|
+
|
92
|
+
C:\example_project>watirsplash generate
|
93
|
+
Creating WatirSplash project directory structure to C:/example_project/ui-test...
|
94
|
+
Done
|
95
|
+
|
96
|
+
After that the directory structure will be something like this:
|
97
|
+
C:\example_project
|
98
|
+
├───doc
|
99
|
+
├───lib
|
100
|
+
├───test
|
101
|
+
└───ui-test
|
102
|
+
└───spec
|
103
|
+
|
104
|
+
The contents of that ui-test directory will be:
|
105
|
+
ui-test\application_helper.rb
|
106
|
+
ui-test\config.rb
|
107
|
+
ui-test\environment.rb
|
108
|
+
ui-test\ide_runner.rb
|
109
|
+
|
110
|
+
ui-test\spec
|
111
|
+
ui-test\spec\dummy_spec.rb
|
112
|
+
|
113
|
+
Just check out all the files to see some example code and comments in it and execute dummy_spec.rb
|
114
|
+
to verify that everything works correctly:
|
115
|
+
watirsplash spec\dummy_spec.rb
|
116
|
+
|
117
|
+
You can have whatever directory structure for your tests just make sure that all test files have _spec.rb in
|
118
|
+
the end of their filename (if using default RSpec options).
|
119
|
+
|
120
|
+
== USAGE FOR MULTIPLE PROJECTS:
|
121
|
+
|
122
|
+
Usually you're going to write tests for multiple different projects. It would be shame if you'd
|
123
|
+
going to create all those common helper methods again for different projects or just copy-paste
|
124
|
+
the code from previous project's helpers. This is the place where ui-test-common comes into play.
|
125
|
+
|
126
|
+
ui-test-common would be a place where you can hold all your common functionality in helper
|
127
|
+
modules/methods/classes and then use those things in your tests so you won't have multiple
|
128
|
+
copies of similar or even same code in different places. So it helps you
|
129
|
+
to keep DRY (http://en.wikipedia.org/wiki/Don't_repeat_yourself).
|
130
|
+
|
131
|
+
After finding yourself in a situation where a new project comes into play, then execute
|
132
|
+
generate_common command once somewhere in a higher level of a directory tree than your project's ui-test directory
|
133
|
+
to generate ui-test-common directory:
|
134
|
+
C:\example_project>cd ..
|
135
|
+
|
136
|
+
C:\>watirsplash generate_common
|
137
|
+
Creating WatirSplash common project directory structure to C:/ui-test-common...
|
138
|
+
Done
|
139
|
+
|
140
|
+
It has a structure of:
|
141
|
+
C:\UI-TEST-COMMON
|
142
|
+
└───lib
|
143
|
+
|
144
|
+
ui-test-common\config.rb
|
145
|
+
ui-test-common\environment.rb
|
146
|
+
ui-test-common\lib
|
147
|
+
ui-test-common\lib\common_application_helper.rb
|
148
|
+
|
149
|
+
In environment.rb under project/ui-test you shall add common functionality to your project.
|
150
|
+
Add the following line before any other require statements to do that:
|
151
|
+
WatirSplash::Util.load_common
|
152
|
+
|
153
|
+
This gives you by default the access to every method in ui-test-common/lib/common_application_helper.rb
|
154
|
+
|
155
|
+
Now, in ui-test-common/config.rb change the URL to your hostname and in config.rb under project/ui-test:
|
156
|
+
URL = Config.full_url("/relative_path")
|
157
|
+
|
158
|
+
This gives you the ability to have host and port written only in one place.
|
159
|
+
|
160
|
+
Now move all the common functionality away from your project's files into ui-test-common files and start testing.
|
161
|
+
From now on, add all common functionality into ui-test-common/lib
|
162
|
+
|
163
|
+
== KNOWN PROBLEMS (& SOLUTIONS)
|
164
|
+
|
165
|
+
=== PROBLEM #1
|
166
|
+
|
167
|
+
If you see the following error message when running watirsplash:
|
168
|
+
R6034. An application has made an attempt to load the C runtime library incorrectly.
|
169
|
+
|
170
|
+
Solution:
|
171
|
+
Install Microsoft Visual C++ 2008 SP1 Redistributable Package
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
5
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
6
|
+
t.rcov = true
|
7
|
+
t.rcov_dir = 'coverage'
|
8
|
+
t.rcov_opts << '--sort coverage --text-summary --aggregate coverage.data'
|
9
|
+
end
|
10
|
+
|
11
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
12
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
13
|
+
t.spec_opts << "--options" << "lib/spec.opts" <<
|
14
|
+
"--require" << "lib/watirsplash/html_formatter" <<
|
15
|
+
"--format" << "WatirSplash::HtmlFormatter:results/index.html"
|
16
|
+
end
|
data/bin/watirsplash
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
watirsplash_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(watirsplash_dir) unless $LOAD_PATH.include?(watirsplash_dir)
|
4
|
+
require 'watirsplash/runner'
|
5
|
+
|
6
|
+
if ARGV.size == 1 && ::WatirSplash::Runner.respond_to?(ARGV[0])
|
7
|
+
exit ::WatirSplash::Runner.send(ARGV[0])
|
8
|
+
else
|
9
|
+
exit ::WatirSplash::Runner.run
|
10
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Helper class for AutoIt
|
2
|
+
class AutoItHelper
|
3
|
+
extend WatirSplash::Waiter
|
4
|
+
|
5
|
+
@@autoit = Watir.autoit
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# clicks save button on window with specified title,
|
9
|
+
# activates window automatically and makes sure that the click
|
10
|
+
# was successful
|
11
|
+
def click_save(window_title="File Download")
|
12
|
+
click_button(window_title, "&Save")
|
13
|
+
end
|
14
|
+
|
15
|
+
# sets edit field value to field_value on window with specified title,
|
16
|
+
# activates window automatically and makes sure that the field's
|
17
|
+
# value got changed
|
18
|
+
def set_edit(field_value, window_title="Save As")
|
19
|
+
set_field(window_title, "Edit1", field_value)
|
20
|
+
end
|
21
|
+
|
22
|
+
# sets specified field's value on window with specified title,
|
23
|
+
# activates window automatically and makes sure that the field's
|
24
|
+
# value got changed
|
25
|
+
def set_field(window_title, field_name, field_value)
|
26
|
+
wait_until! do
|
27
|
+
activate_window(window_title) &&
|
28
|
+
@@autoit.ControlFocus(window_title, "", field_name) == 1 &&
|
29
|
+
@@autoit.ControlSetText(window_title, "", field_name, field_value) == 1 &&
|
30
|
+
@@autoit.ControlGetText(window_title, "", field_name) == field_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# clicks specified button on window with specified title,
|
35
|
+
# activates window automatically and makes sure that the click
|
36
|
+
# was successful
|
37
|
+
def click_button(window_title, button_name)
|
38
|
+
wait_until! do
|
39
|
+
activate_window(window_title) &&
|
40
|
+
@@autoit.ControlFocus(window_title, "", button_name) == 1 &&
|
41
|
+
@@autoit.ControlClick(window_title, "", button_name) == 1 &&
|
42
|
+
wait_until(3) {@@autoit.WinExists(window_title) == 0}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# makes window active with specified title
|
47
|
+
# * returns true if activation was successful and false otherwise
|
48
|
+
def activate_window(window_title)
|
49
|
+
@@autoit.WinWait(window_title, "", 1) == 1 &&
|
50
|
+
@@autoit.WinActivate(window_title) != 0 &&
|
51
|
+
@@autoit.WinActive(window_title) != 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec/runner/formatter/html_formatter'
|
2
|
+
require 'win32screenshot'
|
3
|
+
require 'rmagick'
|
4
|
+
require 'pathname'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module WatirSplash
|
8
|
+
# Custom RSpec formatter for WatirSplash
|
9
|
+
# * saves screenshot of the browser upon test failure
|
10
|
+
# * saves html of the browser upon test failure
|
11
|
+
# * saves javascript error dialog upon test failure
|
12
|
+
# * saves all files generated/downloaded during the test and shows them in the report
|
13
|
+
class HtmlFormatter < ::Spec::Runner::Formatter::HtmlFormatter
|
14
|
+
|
15
|
+
# currently used browser object
|
16
|
+
# needed for saving of screenshots and html
|
17
|
+
attr_writer :browser
|
18
|
+
|
19
|
+
def initialize(options, output) # :nodoc:
|
20
|
+
raise "output has to be a file path!" unless output.is_a?(String)
|
21
|
+
@output_dir = File.expand_path(File.dirname(output))
|
22
|
+
puts "Results will be saved into the directory #{@output_dir}"
|
23
|
+
@files_dir = File.join(@output_dir, "files")
|
24
|
+
if File.exists?(@output_dir)
|
25
|
+
archive_dir = File.join(@output_dir, "../archive")
|
26
|
+
FileUtils.mkdir_p(archive_dir) unless File.exists?(archive_dir)
|
27
|
+
FileUtils.mv @output_dir, File.join(archive_dir, "#{File.basename(@output_dir)}_#{File.mtime(@output_dir).strftime("%y%m%d_%H%M%S")}")
|
28
|
+
end
|
29
|
+
FileUtils.mkdir_p(@files_dir)
|
30
|
+
@files_saved_during_example = []
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def example_started(example) # :nodoc:
|
35
|
+
@files_saved_during_example.clear
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def extra_failure_content(failure) # :nodoc:
|
40
|
+
save_javascript_error
|
41
|
+
save_html
|
42
|
+
save_screenshot
|
43
|
+
|
44
|
+
content = []
|
45
|
+
content << "<span>"
|
46
|
+
@files_saved_during_example.each {|f| content << link_for(f)}
|
47
|
+
content << "</span>"
|
48
|
+
super + content.join($/)
|
49
|
+
end
|
50
|
+
|
51
|
+
def link_for(file) # :nodoc:
|
52
|
+
return unless File.exists?(file[:path])
|
53
|
+
|
54
|
+
description = file[:desc] ? file[:desc] : File.extname(file[:path]).upcase[1..-1]
|
55
|
+
path = Pathname.new(file[:path])
|
56
|
+
"<a href='#{path.relative_path_from(Pathname.new(@output_dir))}'>#{description}</a> "
|
57
|
+
end
|
58
|
+
|
59
|
+
def save_html # :nodoc:
|
60
|
+
begin
|
61
|
+
html = @browser.html
|
62
|
+
file_name = file_path("browser.html")
|
63
|
+
File.open(file_name, 'w') {|f| f.puts html}
|
64
|
+
rescue => e
|
65
|
+
$stderr.puts "saving of html failed: #{e.message}"
|
66
|
+
$stderr.puts e.backtrace
|
67
|
+
end
|
68
|
+
file_name
|
69
|
+
end
|
70
|
+
|
71
|
+
def save_screenshot(description="Screenshot", hwnd=@browser.hwnd) # :nodoc:
|
72
|
+
begin
|
73
|
+
@browser.bring_to_front
|
74
|
+
width, height, blob = Win32::Screenshot.capture_hwnd(hwnd)
|
75
|
+
file_name = file_path("screenshot.png", description)
|
76
|
+
img = Magick::ImageList.new
|
77
|
+
img.from_blob(blob)
|
78
|
+
img.write(file_name)
|
79
|
+
rescue => e
|
80
|
+
$stderr.puts "saving of screenshot failed: #{e.message}"
|
81
|
+
$stderr.puts e.backtrace
|
82
|
+
end
|
83
|
+
file_name
|
84
|
+
end
|
85
|
+
|
86
|
+
def save_javascript_error # :nodoc:
|
87
|
+
file_name = nil
|
88
|
+
begin
|
89
|
+
if @browser.is_a?(Watir::IE) && @browser.status =~ /Error on page/
|
90
|
+
autoit = Watir::autoit
|
91
|
+
autoit.AutoItSetOption("MouseCoordMode", 0)
|
92
|
+
autoit.ControlClick("[TITLE:#{@browser.title}]", "", "[CLASS:msctls_statusbar32]", "left", 2)
|
93
|
+
popup_title = "[REGEXPTITLE:^(Windows )?Internet Explorer$]"
|
94
|
+
autoit.WinWait(popup_title, "", 10)
|
95
|
+
file_name = save_screenshot("JS_Error", autoit.WinGetHandle(popup_title).hex)
|
96
|
+
autoit.WinClose(popup_title)
|
97
|
+
end
|
98
|
+
rescue => e
|
99
|
+
$stderr.puts "saving of javascript error failed: #{e.message}"
|
100
|
+
$stderr.puts e.backtrace
|
101
|
+
end
|
102
|
+
file_name
|
103
|
+
end
|
104
|
+
|
105
|
+
# Generates unique file name and path for each example.
|
106
|
+
#
|
107
|
+
# All file names generated with this method will be shown
|
108
|
+
# on the report.
|
109
|
+
def file_path(file_name, description=nil)
|
110
|
+
extension = File.extname(file_name)
|
111
|
+
basename = File.basename(file_name, extension)
|
112
|
+
file_path = File.join(@files_dir, "#{basename}_#{Time.now.strftime("%H%M%S")}_#{example_group_number}_#{example_number}#{extension}")
|
113
|
+
@files_saved_during_example.unshift(:desc => description, :path => file_path)
|
114
|
+
file_path
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module WatirSplash
|
2
|
+
|
3
|
+
# WatirSplash runner class is responsible for:
|
4
|
+
# * generating directory structures for projects
|
5
|
+
# * starting RSpec with specified settings
|
6
|
+
class Runner
|
7
|
+
@@template_directory = File.join(File.dirname(__FILE__), "../../templates/")
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Run RSpec with custom settings
|
12
|
+
# * loads spec.opts from project's directory if exists
|
13
|
+
# * loads environment.rb from project's directory if exists
|
14
|
+
# * loads custom Formatter
|
15
|
+
def run
|
16
|
+
unless ARGV.empty?
|
17
|
+
require "watirsplash"
|
18
|
+
load_formatter
|
19
|
+
load_options
|
20
|
+
load_project_env
|
21
|
+
else
|
22
|
+
return help
|
23
|
+
end
|
24
|
+
|
25
|
+
::Spec::Runner::CommandLine.run
|
26
|
+
end
|
27
|
+
|
28
|
+
# Generates ui-test project structure for project
|
29
|
+
def generate
|
30
|
+
ui_test_dir = File.join(Dir.pwd, "ui-test")
|
31
|
+
puts "Creating WatirSplash project directory structure to #{ui_test_dir}..."
|
32
|
+
require "fileutils"
|
33
|
+
FileUtils.cp_r File.join(@@template_directory, "project/."), ui_test_dir
|
34
|
+
puts "Done"
|
35
|
+
return 0
|
36
|
+
rescue => e
|
37
|
+
puts "Failed:"
|
38
|
+
puts e.message
|
39
|
+
return -1
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generates ui-test-common directory structure
|
43
|
+
def generate_common
|
44
|
+
common_dir = File.join(Dir.pwd, "ui-test-common")
|
45
|
+
puts "Creating WatirSplash common project directory structure to #{common_dir}..."
|
46
|
+
require "fileutils"
|
47
|
+
FileUtils.cp_r File.join(@@template_directory, "common/."), common_dir
|
48
|
+
puts "Done"
|
49
|
+
return 0
|
50
|
+
rescue => e
|
51
|
+
puts "Failed:"
|
52
|
+
puts e.message
|
53
|
+
return -1
|
54
|
+
end
|
55
|
+
|
56
|
+
# Shows help
|
57
|
+
def help
|
58
|
+
puts %Q{WatirSplash:
|
59
|
+
Usage: watirsplash (COMMAND|FILE(:LINE)?|DIRECTORY|GLOB)+ [options]
|
60
|
+
Commands:
|
61
|
+
* generate - generate default directory structure for new project
|
62
|
+
* generate_common - generate common project directory structure
|
63
|
+
* help - show this help
|
64
|
+
* --help - show RSpec's help
|
65
|
+
|
66
|
+
All other commands/options will be passed to RSpec directly.}
|
67
|
+
|
68
|
+
return 1
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def load_formatter
|
74
|
+
ARGV << "--require" << "watirsplash/html_formatter.rb"
|
75
|
+
ARGV << "--format" << "WatirSplash::HtmlFormatter:#{File.join(Dir.pwd, "results/index.html")}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def load_options
|
79
|
+
ARGV << "--options"
|
80
|
+
project_spec_opts = File.join(Dir.pwd, "spec.opts")
|
81
|
+
if File.exists?(project_spec_opts)
|
82
|
+
ARGV << project_spec_opts
|
83
|
+
else
|
84
|
+
ARGV << "#{File.join(File.dirname(__FILE__), "../spec.opts")}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def load_project_env
|
89
|
+
project_env_file = File.join(Dir.pwd, "environment.rb")
|
90
|
+
if File.exists?(project_env_file)
|
91
|
+
ARGV << "--require" << project_env_file
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Spec::Runner.configure do |config| #:nodoc:
|
2
|
+
config.include(WatirSplash::SpecHelper)
|
3
|
+
|
4
|
+
config.before(:all) do
|
5
|
+
open_browser_at "about:blank"
|
6
|
+
end
|
7
|
+
|
8
|
+
config.after(:all) do
|
9
|
+
close
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Spec #:nodoc:all
|
14
|
+
class ExampleGroup
|
15
|
+
subject {self}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# match_array is useful for matching arrays where some elements are regular expressions.
|
20
|
+
# expected_array = ["1", "2", /\d+/, "3"]
|
21
|
+
#
|
22
|
+
# ["1", "2", "66", "3"].should match_array(expected_array)
|
23
|
+
# table(:id => "table_id").to_a.should match_array(expected_array)
|
24
|
+
Spec::Matchers.define :match_array do |array2|
|
25
|
+
match do |array1|
|
26
|
+
raise "match_array works only with Array objects!" unless array1.is_a?(Array) && array2.is_a?(Array)
|
27
|
+
match?(array1, array2)
|
28
|
+
end
|
29
|
+
|
30
|
+
def match?(array1, array2)
|
31
|
+
array2.each_with_index do |element, i|
|
32
|
+
if element.is_a?(Array)
|
33
|
+
return false unless match?(array1[i], element)
|
34
|
+
elsif element.is_a?(Regexp)
|
35
|
+
return false unless array1[i] =~ element
|
36
|
+
else
|
37
|
+
return false unless array1[i] == element
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module WatirSplash
|
2
|
+
# main helper module
|
3
|
+
#
|
4
|
+
# these methods can be used in specs directly
|
5
|
+
module SpecHelper
|
6
|
+
include Waiter
|
7
|
+
|
8
|
+
# opens the browser at specified url
|
9
|
+
def open_browser_at url
|
10
|
+
@browser = Watir::Browser.new
|
11
|
+
@browser.speed = :fast
|
12
|
+
add_checker Watir::PageCheckers::JAVASCRIPT_ERRORS_CHECKER
|
13
|
+
begin
|
14
|
+
formatter.browser = @browser
|
15
|
+
rescue
|
16
|
+
end
|
17
|
+
goto url
|
18
|
+
maximize
|
19
|
+
end
|
20
|
+
|
21
|
+
# downloads file with browser
|
22
|
+
#
|
23
|
+
# you need to use click_no_wait to use this method:
|
24
|
+
# button(:id => "something").click_no_wait # opens a browser save as dialog
|
25
|
+
# download_file("document.pdf")
|
26
|
+
#
|
27
|
+
# * raises an exception if saving the file is unsuccessful
|
28
|
+
# * returns absolute file_path of the saved file
|
29
|
+
def download_file file_name
|
30
|
+
AutoItHelper.click_save
|
31
|
+
file_path = native_file_path(file_path(file_name))
|
32
|
+
AutoItHelper.set_edit(file_path)
|
33
|
+
AutoItHelper.click_save("Save As")
|
34
|
+
wait_until! {File.exists?(file_path)}
|
35
|
+
file_path
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns WatirSplash::HtmlFormatter object, nil if not in use
|
39
|
+
def formatter
|
40
|
+
@formatter ||= Spec::Runner.options.formatters.find {|f| f.kind_of?(WatirSplash::HtmlFormatter) rescue false}
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns unique file path for use in examples.
|
44
|
+
#
|
45
|
+
# all file names generated with this method will
|
46
|
+
# be shown on the report upon test failure.
|
47
|
+
def file_path(file_name, description=nil)
|
48
|
+
formatter.file_path(file_name, description)
|
49
|
+
rescue
|
50
|
+
extension = File.extname(file_name)
|
51
|
+
basename = File.basename(file_name, extension)
|
52
|
+
file_path = File.join(Dir.pwd, "#{basename}_#{Time.now.strftime("%H%M%S")}#{extension}")
|
53
|
+
file_path
|
54
|
+
end
|
55
|
+
|
56
|
+
# returns native file path
|
57
|
+
# e.g. on Windows:
|
58
|
+
# native_file_path("c:/blah/blah2/file.txt") => c:\\blah\\blah2\\file.txt
|
59
|
+
def native_file_path(file_path)
|
60
|
+
File::ALT_SEPARATOR ? file_path.gsub(File::SEPARATOR, File::ALT_SEPARATOR) : file_path
|
61
|
+
end
|
62
|
+
|
63
|
+
def method_missing name, *arg #:nodoc:
|
64
|
+
@browser.respond_to?(name) ? @browser.send(name, *arg) : super
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|