scudco-spec_ui 0.2.5
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.txt +10 -0
- data/Manifest.txt +29 -0
- data/README.txt +12 -0
- data/Rakefile +133 -0
- data/TODO +8 -0
- data/examples/selenium/README.txt +32 -0
- data/examples/selenium/Rakefile +45 -0
- data/examples/selenium/spec/selenium/find_rspecs_homepage_spec.rb +37 -0
- data/examples/selenium/spec/spec_helper.rb +24 -0
- data/examples/watir/README.txt +12 -0
- data/examples/watir/Rakefile +45 -0
- data/examples/watir/spec/spec_helper.rb +34 -0
- data/examples/watir/spec/watir/find_rspecs_homepage_spec.rb +35 -0
- data/lib/spec/ui/formatter.rb +168 -0
- data/lib/spec/ui/images/rmagick_not_installed.png +0 -0
- data/lib/spec/ui/images/win32screenshot_not_installed.png +0 -0
- data/lib/spec/ui/images/wrong_win32screenshot.png +0 -0
- data/lib/spec/ui/screenshot_saver.rb +63 -0
- data/lib/spec/ui/selenium/driver_ext.rb +21 -0
- data/lib/spec/ui/selenium.rb +1 -0
- data/lib/spec/ui/version.rb +11 -0
- data/lib/spec/ui/watir/matchers.rb +97 -0
- data/lib/spec/ui/watir.rb +5 -0
- data/lib/spec/ui.rb +2 -0
- data/spec/spec/ui/watir/matchers_spec.rb +40 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +2 -0
- metadata +103 -0
data/History.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
== 0.2.4 (In SVN)
|
2
|
+
* Made the formatter compatible with the RSpec 1.0.8 Formatter constructor
|
3
|
+
* Examples are using Spec::Distributed's Rinda runners
|
4
|
+
* Moved project from RSpec's subversion
|
5
|
+
|
6
|
+
== 0.2.3
|
7
|
+
* Made setup much easier
|
8
|
+
|
9
|
+
== 0.2.2
|
10
|
+
* Applied [#7685] Spec::Ui feedback and patch (Patch from Alvin Schur)
|
data/Manifest.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
TODO
|
2
|
+
History.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
examples/selenium/README.txt
|
7
|
+
examples/selenium/Rakefile
|
8
|
+
examples/selenium/spec/selenium/find_rspecs_homepage_spec.rb
|
9
|
+
examples/selenium/spec/spec_helper.rb
|
10
|
+
examples/watir/README.txt
|
11
|
+
examples/watir/Rakefile
|
12
|
+
examples/watir/spec/spec_helper.rb
|
13
|
+
examples/watir/spec/watir/find_rspecs_homepage_spec.rb
|
14
|
+
lib/spec/ui.rb
|
15
|
+
lib/spec/ui/formatter.rb
|
16
|
+
lib/spec/ui/images/rmagick_not_installed.png
|
17
|
+
lib/spec/ui/images/win32screenshot_not_installed.png
|
18
|
+
lib/spec/ui/images/wrong_win32screenshot.png
|
19
|
+
lib/spec/ui/screenshot_saver.rb
|
20
|
+
lib/spec/ui/selenium.rb
|
21
|
+
lib/spec/ui/selenium/driver_ext.rb
|
22
|
+
lib/spec/ui/version.rb
|
23
|
+
lib/spec/ui/watir.rb
|
24
|
+
lib/spec/ui/watir/browser.rb
|
25
|
+
lib/spec/ui/watir/matchers.rb
|
26
|
+
lib/spec/ui/watir/watir_behaviour.rb
|
27
|
+
spec/spec.opts
|
28
|
+
spec/spec/ui/watir/matchers_spec.rb
|
29
|
+
spec/spec_helper.rb
|
data/README.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Spec::Ui
|
2
|
+
========
|
3
|
+
|
4
|
+
Spec::Ui is an add-on to RSpec that lets you use a UI-testing framework
|
5
|
+
such as Selenium or Watir/Safariwatir from RSpec. Spec::Ui also makes it
|
6
|
+
easy to create HTML reports with screenshots as described in this blogpost:
|
7
|
+
|
8
|
+
http://blog.aslakhellesoy.com/articles/2006/12/02/getting-screenshots-from-watir
|
9
|
+
|
10
|
+
As much as possible of the supporting code has been factored out to separate files
|
11
|
+
under Spec::Ui, and the distribution contains examples with a spec_helper and a Rakefile
|
12
|
+
that you can copy into your own project and tweak if needed.
|
data/Rakefile
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
require 'spec/rake/spectask'
|
12
|
+
|
13
|
+
include FileUtils
|
14
|
+
require File.join(File.dirname(__FILE__), 'lib', 'spec', 'ui', 'version')
|
15
|
+
|
16
|
+
AUTHOR = 'Aslak Hellesoy'
|
17
|
+
EMAIL = 'aslak.hellesoy@gmail.com'
|
18
|
+
DESCRIPTION = "Run RSpec with UI testing tools"
|
19
|
+
GEM_NAME = 'spec_ui' # what ppl will type to install your gem
|
20
|
+
|
21
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
22
|
+
@config = nil
|
23
|
+
def rubyforge_username
|
24
|
+
unless @config
|
25
|
+
begin
|
26
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
27
|
+
rescue
|
28
|
+
puts <<-EOS
|
29
|
+
ERROR: No rubyforge config file found: #{@config_file}"
|
30
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
31
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
32
|
+
EOS
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@rubyforge_username ||= @config["username"]
|
37
|
+
end
|
38
|
+
|
39
|
+
RUBYFORGE_PROJECT = 'rspec-ext' # The unix name for your project
|
40
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
41
|
+
|
42
|
+
|
43
|
+
#REV = YAML.load(`svn info`)['Revision'] rescue nil
|
44
|
+
REV=nil
|
45
|
+
VERS = Spec::Ui::VERSION::STRING + (REV ? ".#{REV}" : "")
|
46
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
|
47
|
+
RDOC_OPTS = ['--quiet', '--title', 'Spec::Ui documentation',
|
48
|
+
"--opname", "index.html",
|
49
|
+
"--line-numbers",
|
50
|
+
"--main", "README",
|
51
|
+
"--inline-source"]
|
52
|
+
|
53
|
+
class Hoe
|
54
|
+
def extra_deps
|
55
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Generate all the Rake tasks
|
60
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
61
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
62
|
+
p.author = AUTHOR
|
63
|
+
p.description = DESCRIPTION
|
64
|
+
p.email = EMAIL
|
65
|
+
p.summary = DESCRIPTION
|
66
|
+
p.url = HOMEPATH
|
67
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
68
|
+
p.test_globs = ["test/**/test_*.rb"]
|
69
|
+
p.clean_globs |= CLEAN #An array of file patterns to delete on clean.
|
70
|
+
|
71
|
+
# == Optional
|
72
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
73
|
+
p.extra_deps = [['rspec', '>= 1.0.8']] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
74
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
75
|
+
end
|
76
|
+
|
77
|
+
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\n\n")
|
78
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
79
|
+
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
80
|
+
|
81
|
+
desc 'Generate website files'
|
82
|
+
task :website_generate do
|
83
|
+
Dir['website/**/*.txt'].each do |txt|
|
84
|
+
sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'Upload website files to rubyforge'
|
89
|
+
task :website_upload do
|
90
|
+
host = "#{rubyforge_username}@rubyforge.org"
|
91
|
+
remote_dir = "/var/www/gforge-projects/#{PATH}/"
|
92
|
+
local_dir = 'website'
|
93
|
+
sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
|
94
|
+
end
|
95
|
+
|
96
|
+
desc 'Generate and upload website files'
|
97
|
+
task :website => [:website_generate, :website_upload, :publish_docs]
|
98
|
+
|
99
|
+
desc 'Release the website and new gem version'
|
100
|
+
task :deploy => [:check_version, :website, :release] do
|
101
|
+
puts "Remember to create SVN tag:"
|
102
|
+
puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
|
103
|
+
"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
|
104
|
+
puts "Suggested comment:"
|
105
|
+
puts "Tagging release #{CHANGES}"
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
|
109
|
+
task :local_deploy => [:website_generate, :install_gem]
|
110
|
+
|
111
|
+
task :check_version do
|
112
|
+
unless ENV['VERSION']
|
113
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
114
|
+
exit
|
115
|
+
end
|
116
|
+
unless ENV['VERSION'] == VERS
|
117
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
118
|
+
exit
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "Run specs"
|
123
|
+
Spec::Rake::SpecTask.new do |t|
|
124
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
125
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
126
|
+
end
|
127
|
+
|
128
|
+
# Hoe insists on setting task :default => :test
|
129
|
+
# !@#$ no easy way to empty the default list of prerequisites
|
130
|
+
Rake::Task['default'].send :instance_variable_set, "@prerequisites", FileList[]
|
131
|
+
desc "Default task is to run specs"
|
132
|
+
task :default => :spec
|
133
|
+
|
data/TODO
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
= Using Selenium with spec/ui =
|
2
|
+
|
3
|
+
The files in this directory are examples illustrating how to use Selenium
|
4
|
+
with spec/ui. Prerequisites:
|
5
|
+
|
6
|
+
* Install Java 1.4 or later
|
7
|
+
* Download SeleniumRC 0.9.0 or later (http://www.openqa.org/selenium-rc/)
|
8
|
+
* Copy selenium-server.jar into the spec directory.
|
9
|
+
* Copy selenium.rb into the spec directory.
|
10
|
+
|
11
|
+
After this is installed, open two shells in this directory.
|
12
|
+
|
13
|
+
In the first one, run:
|
14
|
+
|
15
|
+
java -jar spec/selenium-server.jar
|
16
|
+
|
17
|
+
In the second one, run:
|
18
|
+
|
19
|
+
rake spec:selenium
|
20
|
+
|
21
|
+
= Note for OS X users =
|
22
|
+
|
23
|
+
== Firefox 2.0.0.1 ==
|
24
|
+
If you experience that the selenium server is just hanging, read this:
|
25
|
+
http://forums.openqa.org/message.jspa?messageID=16541
|
26
|
+
|
27
|
+
You may have better luck with one of the snapshot jars found under
|
28
|
+
http://maven.openqa.org/org/openqa/selenium/server/selenium-server
|
29
|
+
|
30
|
+
== Safari ==
|
31
|
+
You may have to set up Safari's proxy settings manually:
|
32
|
+
http://forums.openqa.org/thread.jspa?messageID=20570做
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec', '>=1.0.8'
|
3
|
+
gem 'spec_distributed', '>=0.0.3'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
desc "Run Selenium Specs"
|
7
|
+
Spec::Rake::SpecTask.new('spec:selenium') do |t|
|
8
|
+
t.spec_files = FileList['spec/selenium/**/*.rb']
|
9
|
+
t.spec_opts = [
|
10
|
+
'--color', '--diff',
|
11
|
+
'--require', 'rubygems,spec/ui',
|
12
|
+
'--format', 'Spec::Ui::ScreenshotFormatter:doc/report/index.html',
|
13
|
+
'--format', 'progress'
|
14
|
+
]
|
15
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
16
|
+
end
|
17
|
+
|
18
|
+
# IMPORTANT: If you use the master/slave mode you really ought to
|
19
|
+
# run everything on different machines.
|
20
|
+
|
21
|
+
desc "Run Selenium Specs as Spec::Distributed slave"
|
22
|
+
Spec::Rake::SpecTask.new('spec:selenium:slave') do |t|
|
23
|
+
t.spec_files = FileList['spec/selenium/**/*.rb']
|
24
|
+
t.spec_opts = [
|
25
|
+
'--color', '--diff',
|
26
|
+
'--require', 'rubygems,spec/ui,spec/distributed',
|
27
|
+
'--format', 'Spec::Ui::SlaveScreenshotFormatter:doc/report/index.html',
|
28
|
+
'--format', 'progress',
|
29
|
+
'--runner', 'Spec::Distributed::RindaSlaveRunner'
|
30
|
+
]
|
31
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Run Selenium Specs as Spec::Distributed master"
|
35
|
+
Spec::Rake::SpecTask.new('spec:selenium:master') do |t|
|
36
|
+
t.spec_files = FileList['spec/selenium/**/*.rb']
|
37
|
+
t.spec_opts = [
|
38
|
+
'--color', '--diff',
|
39
|
+
'--require', 'rubygems,spec/ui,spec/distributed',
|
40
|
+
'--format', 'Spec::Ui::MasterScreenshotFormatter:doc/report/index.html',
|
41
|
+
'--format', 'progress',
|
42
|
+
'--runner', 'Spec::Distributed::RindaMasterRunner'
|
43
|
+
]
|
44
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
45
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Google's search page I" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
# The @browser is initialised in spec_helper.rb
|
7
|
+
@browser.open('http://www.google.no')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should find rspec's home page when I search for rspec" do
|
11
|
+
@browser.type "name=q", "rspec"
|
12
|
+
@browser.click_and_wait "name=btnG"
|
13
|
+
@browser.is_text_present("rspec.rubyforge.org").should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "Google's search page II" do
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
# The @browser is initialised in spec_helper.rb
|
22
|
+
@browser.open('http://www.google.no')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should find rspec's home page when I search for 'better than fudge' (will probably fail)" do
|
26
|
+
@browser.type "name=q", "better than fudge"
|
27
|
+
@browser.click_and_wait "name=btnG"
|
28
|
+
@browser.is_text_present("rspec.rubyforge.org").should be_true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not find Ali G when I search for rspec" do
|
32
|
+
@browser.type "name=q", "rspec"
|
33
|
+
@browser.click_and_wait "name=btnG"
|
34
|
+
@browser.is_text_present("Ali G").should be_false
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# You don't need to tweak the $LOAD_PATH if you have Spec::Ui installed as gems
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../../lib')
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec'
|
6
|
+
require 'spec/ui'
|
7
|
+
require File.dirname(__FILE__) + '/selenium'
|
8
|
+
require 'spec/ui/selenium'
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
config.before(:all) do
|
12
|
+
@browser = Selenium::SeleniumDriver.new("localhost", 4444, "*firefox", "http://www.google.no", 10000)
|
13
|
+
@browser.start
|
14
|
+
end
|
15
|
+
|
16
|
+
config.after(:each) do
|
17
|
+
Spec::Ui::ScreenshotFormatter.instance.take_screenshot_of(@browser)
|
18
|
+
end
|
19
|
+
|
20
|
+
config.after(:all) do
|
21
|
+
@browser.kill! rescue nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
= Using Watir with spec/ui =
|
2
|
+
|
3
|
+
The files in this directory are examples illustrating how to use Watir
|
4
|
+
with spec/ui. Prerequisites:
|
5
|
+
|
6
|
+
* See the general prerequisites in the toplevel README
|
7
|
+
* gem install watir -y # If you're on Windows
|
8
|
+
* gem install safariwatir -y # If you're on OS X
|
9
|
+
|
10
|
+
After this is installed, run the watir specs:
|
11
|
+
|
12
|
+
rake spec:watir
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec', '>=1.0.8'
|
3
|
+
gem 'spec_distributed', '>=0.0.3'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
desc "Run Watir Specs"
|
7
|
+
Spec::Rake::SpecTask.new('spec:watir') do |t|
|
8
|
+
t.spec_files = FileList['spec/watir/**/*.rb']
|
9
|
+
t.spec_opts = [
|
10
|
+
'--color', '--diff',
|
11
|
+
'--require', 'rubygems,spec/ui',
|
12
|
+
'--format', 'Spec::Ui::ScreenshotFormatter:doc/report/index.html',
|
13
|
+
'--format', 'progress'
|
14
|
+
]
|
15
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
16
|
+
end
|
17
|
+
|
18
|
+
# IMPORTANT: If you use the master/slave mode you really ought to
|
19
|
+
# run everything on different machines.
|
20
|
+
|
21
|
+
desc "Run Watir Specs as Spec::Distributed slave"
|
22
|
+
Spec::Rake::SpecTask.new('spec:watir:slave') do |t|
|
23
|
+
t.spec_files = FileList['spec/watir/**/*.rb']
|
24
|
+
t.spec_opts = [
|
25
|
+
'--color', '--diff',
|
26
|
+
'--require', 'rubygems,spec/ui,spec/distributed',
|
27
|
+
'--format', 'Spec::Ui::SlaveScreenshotFormatter:doc/report/index.html',
|
28
|
+
'--format', 'progress',
|
29
|
+
'--runner', 'Spec::Distributed::RindaSlaveRunner'
|
30
|
+
]
|
31
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Run Watir Specs as Spec::Distributed master"
|
35
|
+
Spec::Rake::SpecTask.new('spec:watir:master') do |t|
|
36
|
+
t.spec_files = FileList['spec/watir/**/*.rb']
|
37
|
+
t.spec_opts = [
|
38
|
+
'--color', '--diff',
|
39
|
+
'--require', 'rubygems,spec/ui,spec/distributed',
|
40
|
+
'--format', 'Spec::Ui::MasterScreenshotFormatter:doc/report/index.html',
|
41
|
+
'--format', 'progress',
|
42
|
+
'--runner', 'Spec::Distributed::RindaMasterRunner'
|
43
|
+
]
|
44
|
+
t.libs = ["../../lib"] # This line is not necessary if you have Spec::Ui installed as a gem
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# You don't need to tweak the $LOAD_PATH if you have Spec::Ui installed as gems
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../../lib')
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec'
|
6
|
+
require 'spec/ui'
|
7
|
+
require 'spec/ui/watir'
|
8
|
+
|
9
|
+
if RUBY_PLATFORM =~ /darwin/
|
10
|
+
require 'safariwatir'
|
11
|
+
Watir::Browser = Watir::Safari
|
12
|
+
elsif RUBY_PLATFORM =~ /linux/
|
13
|
+
require 'firewatir'
|
14
|
+
Watir = FireWatir
|
15
|
+
Watir::Browser = FireWatir::Firefox
|
16
|
+
else
|
17
|
+
require 'watir'
|
18
|
+
Watir::Browser = Watir::IE
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Runner.configure do |config|
|
22
|
+
config.before(:all) do
|
23
|
+
@browser = Watir::Browser.new
|
24
|
+
end
|
25
|
+
|
26
|
+
config.after(:each) do
|
27
|
+
Spec::Ui::ScreenshotFormatter.instance.take_screenshot_of(@browser)
|
28
|
+
end
|
29
|
+
|
30
|
+
config.after(:all) do
|
31
|
+
@browser.close
|
32
|
+
sleep 5.5 # WTF apple throws an OS 609 Error unless we sleep for some arbitrary(okay maybe not) time
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Google's search page I" do
|
4
|
+
before(:each) do
|
5
|
+
# The @browser is initialised in spec_helper.rb
|
6
|
+
@browser.goto('http://www.google.com')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should find rspec's home page when I search for rspec" do
|
10
|
+
@browser.text_field(:name, "q").set("rspec")
|
11
|
+
@browser.button(:name, "btnG").click
|
12
|
+
@browser.should have_link(:url, "http://rspec.rubyforge.org/")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "Google's search page II" do
|
17
|
+
before(:each) do
|
18
|
+
# The @browser is initialised in spec_helper.rb
|
19
|
+
@browser.goto('http://www.google.com')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should find rspec's home page when I search for 'better than fudge' (this is supposed to fail)" do
|
23
|
+
@browser.text_field(:name, "q").set("better than fudge")
|
24
|
+
@browser.button(:name, "btnG").click
|
25
|
+
@browser.should have_link(:url, "http://rspec.rubyforge.org/")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not find Ali G when I search for respec" do
|
29
|
+
@browser.text_field(:name, "q").set("respec")
|
30
|
+
@browser.button(:name, "btnG").click
|
31
|
+
@browser.should_not have_text("Ali G")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should do something we haven't done yet"
|
35
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec/runner/formatter/html_formatter'
|
2
|
+
require 'spec/ui/screenshot_saver'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
module Spec
|
6
|
+
module Ui
|
7
|
+
class ScreenshotFormatter < Spec::Runner::Formatter::HtmlFormatter
|
8
|
+
class << self
|
9
|
+
attr_accessor :instance
|
10
|
+
end
|
11
|
+
|
12
|
+
include ScreenshotSaver
|
13
|
+
|
14
|
+
def initialize(options, where)
|
15
|
+
if where.is_a?(String)
|
16
|
+
@root = File.dirname(where)
|
17
|
+
ensure_dir(where)
|
18
|
+
super
|
19
|
+
else
|
20
|
+
raise "#{self.class} must write to a file, so that we know where to store screenshots"
|
21
|
+
end
|
22
|
+
raise "Only one instance of #{self.class} is allowed" unless self.class.instance.nil?
|
23
|
+
ScreenshotFormatter.instance = self
|
24
|
+
end
|
25
|
+
|
26
|
+
# Takes screenshot and snapshot of the +browser+'s html.
|
27
|
+
# This method calls #screenshot! so that method should not be called
|
28
|
+
# when this method is used.
|
29
|
+
# This method *must* be called in an after(:each) block.
|
30
|
+
def take_screenshot_of(browser)
|
31
|
+
save_html(browser)
|
32
|
+
screenshot
|
33
|
+
end
|
34
|
+
|
35
|
+
# Takes a screenshot of the current window and saves it to disk.
|
36
|
+
# Use this method when you don't have a browser object.
|
37
|
+
def screenshot
|
38
|
+
ensure_dir!(absolute_png_path)
|
39
|
+
save_screenshot(absolute_png_path)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Writes the HTML from +browser+ to disk
|
43
|
+
def save_html(browser)
|
44
|
+
ensure_dir!(absolute_html_path)
|
45
|
+
File.open(absolute_html_path, "w") {|io| io.write(browser.html)}
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_dir(file)
|
49
|
+
dir = File.dirname(file)
|
50
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
51
|
+
end
|
52
|
+
|
53
|
+
def ensure_dir!(file)
|
54
|
+
dir = File.dirname(file)
|
55
|
+
FileUtils.mkdir_p(dir)
|
56
|
+
end
|
57
|
+
|
58
|
+
def absolute_png_path
|
59
|
+
File.join(@root, relative_png_path)
|
60
|
+
end
|
61
|
+
|
62
|
+
def relative_png_path
|
63
|
+
"images/#{example_number}.png"
|
64
|
+
end
|
65
|
+
|
66
|
+
def absolute_html_path
|
67
|
+
File.join(@root, relative_html_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
def relative_html_path
|
71
|
+
"html/#{example_number}.html"
|
72
|
+
end
|
73
|
+
|
74
|
+
def global_scripts
|
75
|
+
super + <<-EOF
|
76
|
+
function showImage(e) {
|
77
|
+
w = window.open();
|
78
|
+
w.location = e.childNodes[0].src
|
79
|
+
}
|
80
|
+
|
81
|
+
// Lifted from Ruby RDoc
|
82
|
+
function toggleSource( id ) {
|
83
|
+
var elem
|
84
|
+
var link
|
85
|
+
|
86
|
+
if( document.getElementById )
|
87
|
+
{
|
88
|
+
elem = document.getElementById( id )
|
89
|
+
link = document.getElementById( "l_" + id )
|
90
|
+
}
|
91
|
+
else if ( document.all )
|
92
|
+
{
|
93
|
+
elem = eval( "document.all." + id )
|
94
|
+
link = eval( "document.all.l_" + id )
|
95
|
+
}
|
96
|
+
else
|
97
|
+
return false;
|
98
|
+
|
99
|
+
if( elem.style.display == "block" )
|
100
|
+
{
|
101
|
+
elem.style.display = "none"
|
102
|
+
link.innerHTML = "show snapshot"
|
103
|
+
}
|
104
|
+
else
|
105
|
+
{
|
106
|
+
elem.style.display = "block"
|
107
|
+
link.innerHTML = "hide snapshot"
|
108
|
+
}
|
109
|
+
}
|
110
|
+
EOF
|
111
|
+
end
|
112
|
+
|
113
|
+
def global_styles
|
114
|
+
super + <<-EOF
|
115
|
+
div.rspec-report textarea {
|
116
|
+
width: 100%;
|
117
|
+
}
|
118
|
+
|
119
|
+
div.rspec-report div.dyn-source {
|
120
|
+
background:#FFFFEE none repeat scroll 0%;
|
121
|
+
border:1px dotted black;
|
122
|
+
color:#000000;
|
123
|
+
display:none;
|
124
|
+
margin:0.5em 2em;
|
125
|
+
padding:0.5em;
|
126
|
+
}
|
127
|
+
EOF
|
128
|
+
end
|
129
|
+
|
130
|
+
def extra_failure_content(failure)
|
131
|
+
result = super(failure)
|
132
|
+
if File.exist?(absolute_png_path)
|
133
|
+
result += img_div
|
134
|
+
end
|
135
|
+
if File.exist?(absolute_html_path)
|
136
|
+
source_id = "#{example_number}_source"
|
137
|
+
result += " <div>[<a id=\"l_#{source_id}\" href=\"javascript:toggleSource('#{source_id}')\">show snapshot</a>]</div>\n"
|
138
|
+
result += " <div id=\"#{source_id}\" class=\"dyn-source\"><iframe src=\"#{relative_html_path}\" width=\"100%\" height=\"300px\"></iframe></div>\n"
|
139
|
+
end
|
140
|
+
result
|
141
|
+
end
|
142
|
+
|
143
|
+
def img_div
|
144
|
+
" <div><a href=\"#{relative_png_path}\"><img width=\"25%\" height=\"25%\" src=\"#{relative_png_path}\" /></a></div>\n"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# This formatter produces the same HTML as ScreenshotFormatter, except that
|
149
|
+
# it doesn't save screenshot PNGs and browser snapshot HTML source to disk.
|
150
|
+
# It is meant to be used from a Spec::Distributed master
|
151
|
+
class MasterScreenshotFormatter < ScreenshotFormatter
|
152
|
+
def screenshot
|
153
|
+
end
|
154
|
+
|
155
|
+
def save_html(browser)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# This formatter writes PNG and browser snapshot HTML to disk, just like its superclass,
|
160
|
+
# but it doesn't write the HTML report itself.
|
161
|
+
# It is meant to be used from Spec::Distributed slaves
|
162
|
+
class SlaveScreenshotFormatter < ScreenshotFormatter
|
163
|
+
def initialize(where)
|
164
|
+
super(where, StringIO.new)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Ui
|
5
|
+
module ScreenshotSaver
|
6
|
+
if RUBY_PLATFORM =~ /darwin/
|
7
|
+
def save_screenshot(png_path)
|
8
|
+
# How do we capture the current window??
|
9
|
+
`screencapture #{png_path}`
|
10
|
+
end
|
11
|
+
elsif RUBY_PLATFORM =~ /linux/
|
12
|
+
def save_screenshot(png_path)
|
13
|
+
# How do we capture the current window??
|
14
|
+
`scrot #{png_path}`
|
15
|
+
end
|
16
|
+
else # Win32
|
17
|
+
begin
|
18
|
+
# TODO: Move all this code to win32screenshot
|
19
|
+
require 'rubygems'
|
20
|
+
require 'RMagick'
|
21
|
+
gem 'win32screenshot', '>=0.0.2'
|
22
|
+
require 'win32screenshot'
|
23
|
+
def save_screenshot(png_path)
|
24
|
+
width, height, bmp = ::Win32::Screenshot.foreground
|
25
|
+
begin
|
26
|
+
img = Magick::Image.from_blob(bmp)[0]
|
27
|
+
img.write(png_path)
|
28
|
+
nil
|
29
|
+
rescue Magick::ImageMagickError => e
|
30
|
+
if e.message =~ /Insufficient image data in file/
|
31
|
+
e.message << <<-EOM
|
32
|
+
This is a bug in win32screenshot - it fails to take screenshots of "small" windows. Try this workaround:
|
33
|
+
|
34
|
+
1) Close all instances of the app you're trying to take a screenshot of (e.g. Internet Explorer)
|
35
|
+
2) Open the app
|
36
|
+
3) Resize the window so it occupies the entire screen (without maximizing it!)
|
37
|
+
4) Exit the app. Windows will now remember its size the next time it starts.
|
38
|
+
|
39
|
+
This *may* make this error go away
|
40
|
+
EOM
|
41
|
+
end
|
42
|
+
raise e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue Gem::LoadError => e
|
46
|
+
def save_screenshot(png_path)
|
47
|
+
FileUtils.cp(File.dirname(__FILE__) + '/images/wrong_win32screenshot.png', png_path)
|
48
|
+
end
|
49
|
+
rescue LoadError => e
|
50
|
+
if(e.message =~ /win32screenshot/)
|
51
|
+
def save_screenshot(png_path)
|
52
|
+
FileUtils.cp(File.dirname(__FILE__) + '/images/win32screenshot_not_installed.png', png_path)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
def save_screenshot(png_path)
|
56
|
+
FileUtils.cp(File.dirname(__FILE__) + '/images/rmagick_not_installed.png', png_path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Selenium
|
2
|
+
class SeleniumDriver
|
3
|
+
def click_and_wait(locator, timeout="5000")
|
4
|
+
click(locator)
|
5
|
+
wait_for_page_to_load(timeout)
|
6
|
+
end
|
7
|
+
|
8
|
+
def open_and_wait(url, timeout="5000")
|
9
|
+
open(url)
|
10
|
+
wait_for_page_to_load(timeout)
|
11
|
+
end
|
12
|
+
|
13
|
+
def html
|
14
|
+
get_html_source
|
15
|
+
end
|
16
|
+
|
17
|
+
def kill!
|
18
|
+
stop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec/ui/selenium/driver_ext'
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Matchers for Watir::IE/Watir::Safari instances
|
2
|
+
module Spec::Matchers::Watir
|
3
|
+
class ContentMatcher # :nodoc
|
4
|
+
def initialize(kind, text_or_regexp)
|
5
|
+
@kind, @text_or_regexp = kind, text_or_regexp
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(container)
|
9
|
+
@container = container
|
10
|
+
@content = container.__send__(@kind)
|
11
|
+
if @text_or_regexp.is_a?(Regexp)
|
12
|
+
!!@content =~ @text_or_regexp
|
13
|
+
else
|
14
|
+
!!@content.index(@text_or_regexp.to_s)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message
|
19
|
+
"Expected #{@container.class} to have #{@kind} matching #{@text_or_regexp}, but it was not found in:\n#{@content}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def negative_failure_message
|
23
|
+
"Expected #{@container.class} to not have #{@kind} matching #{@text_or_regexp}, but it was found in:\n#{@content}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# RSpec matcher that passes if @container#text matches +text_or_regexp+ (String or Regexp)
|
28
|
+
def have_text(text_or_regexp)
|
29
|
+
ContentMatcher.new(:text, text_or_regexp)
|
30
|
+
end
|
31
|
+
|
32
|
+
# RSpec matcher that passes if @container#html matches +text_or_regexp+ (String or Regexp)
|
33
|
+
def have_html(text_or_regexp)
|
34
|
+
ContentMatcher.new(:html, text_or_regexp)
|
35
|
+
end
|
36
|
+
|
37
|
+
class ElementMatcher # :nodoc
|
38
|
+
def initialize(kind, *args)
|
39
|
+
@kind, @args = kind, args
|
40
|
+
end
|
41
|
+
|
42
|
+
def matches?(container)
|
43
|
+
@container = container
|
44
|
+
begin
|
45
|
+
element = @container.__send__(@kind, *@args)
|
46
|
+
if element.respond_to?(:assert_exists)
|
47
|
+
# IE
|
48
|
+
element.assert_exists
|
49
|
+
true
|
50
|
+
else
|
51
|
+
# Safari
|
52
|
+
element.exists?
|
53
|
+
end
|
54
|
+
rescue ::Watir::Exception::UnknownObjectException => e
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def failure_message
|
60
|
+
"Expected #{@container.class} to have #{@kind}(#{arg_string}), but it was not found"
|
61
|
+
end
|
62
|
+
|
63
|
+
def negative_failure_message
|
64
|
+
"Expected #{@container.class} to not have #{@kind}(#{arg_string}), but it was found"
|
65
|
+
end
|
66
|
+
|
67
|
+
def arg_string
|
68
|
+
@args.map{|a| a.inspect}.join(", ")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# All the xxx(what, how) methods in Watir
|
73
|
+
[
|
74
|
+
:button,
|
75
|
+
:cell,
|
76
|
+
:checkbox,
|
77
|
+
:div,
|
78
|
+
:file_field,
|
79
|
+
:form,
|
80
|
+
:hidden,
|
81
|
+
:image,
|
82
|
+
:label,
|
83
|
+
:link,
|
84
|
+
:p,
|
85
|
+
:radio,
|
86
|
+
:row,
|
87
|
+
:select_list,
|
88
|
+
:span,
|
89
|
+
:table,
|
90
|
+
:text_field
|
91
|
+
].each do |kind|
|
92
|
+
# RSpec matcher that passes if container##{kind}(*args) returns an existing #{kind} element.
|
93
|
+
define_method("have_#{kind}".to_sym) do |*args|
|
94
|
+
ElementMatcher.new(kind, *args)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/spec/ui.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require 'spec/ui/watir/matchers'
|
3
|
+
|
4
|
+
class BrowserStub
|
5
|
+
def label(*args)
|
6
|
+
LabelStub.new(*args)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class LabelStub
|
11
|
+
def initialize(how, what)
|
12
|
+
@how, @what = how, what
|
13
|
+
end
|
14
|
+
|
15
|
+
def exists?
|
16
|
+
@what
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "Browser" do
|
21
|
+
include Spec::Matchers::Watir
|
22
|
+
|
23
|
+
before do
|
24
|
+
@b = BrowserStub.new
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should support should have_label" do
|
28
|
+
lambda do
|
29
|
+
@b.should have_label(:foo, false)
|
30
|
+
end.should raise_error(Spec::Expectations::ExpectationNotMetError,
|
31
|
+
'Expected BrowserStub to have label(:foo, false), but it was not found')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should support should_not have_label" do
|
35
|
+
lambda do
|
36
|
+
@b.should_not have_label(:foo, true)
|
37
|
+
end.should raise_error(Spec::Expectations::ExpectationNotMetError,
|
38
|
+
'Expected BrowserStub to not have label(:foo, true), but it was found')
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scudco-spec_ui
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aslak Hellesoy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-11 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.8
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: hoe
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.8.2
|
32
|
+
version:
|
33
|
+
description: Run RSpec with UI testing tools
|
34
|
+
email: aslak.hellesoy@gmail.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files:
|
40
|
+
- History.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- README.txt
|
43
|
+
- examples/selenium/README.txt
|
44
|
+
- examples/watir/README.txt
|
45
|
+
files:
|
46
|
+
- TODO
|
47
|
+
- History.txt
|
48
|
+
- Manifest.txt
|
49
|
+
- README.txt
|
50
|
+
- Rakefile
|
51
|
+
- examples/selenium/README.txt
|
52
|
+
- examples/selenium/Rakefile
|
53
|
+
- examples/selenium/spec/selenium/find_rspecs_homepage_spec.rb
|
54
|
+
- examples/selenium/spec/spec_helper.rb
|
55
|
+
- examples/watir/README.txt
|
56
|
+
- examples/watir/Rakefile
|
57
|
+
- examples/watir/spec/spec_helper.rb
|
58
|
+
- examples/watir/spec/watir/find_rspecs_homepage_spec.rb
|
59
|
+
- lib/spec/ui.rb
|
60
|
+
- lib/spec/ui/formatter.rb
|
61
|
+
- lib/spec/ui/images/rmagick_not_installed.png
|
62
|
+
- lib/spec/ui/images/win32screenshot_not_installed.png
|
63
|
+
- lib/spec/ui/images/wrong_win32screenshot.png
|
64
|
+
- lib/spec/ui/screenshot_saver.rb
|
65
|
+
- lib/spec/ui/selenium.rb
|
66
|
+
- lib/spec/ui/selenium/driver_ext.rb
|
67
|
+
- lib/spec/ui/version.rb
|
68
|
+
- lib/spec/ui/watir.rb
|
69
|
+
- lib/spec/ui/watir/browser.rb
|
70
|
+
- lib/spec/ui/watir/matchers.rb
|
71
|
+
- lib/spec/ui/watir/watir_behaviour.rb
|
72
|
+
- spec/spec.opts
|
73
|
+
- spec/spec/ui/watir/matchers_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
has_rdoc: true
|
76
|
+
homepage: http://rspec-ext.rubyforge.org
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- --main
|
80
|
+
- README.txt
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
version:
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project: rspec-ext
|
98
|
+
rubygems_version: 1.2.0
|
99
|
+
signing_key:
|
100
|
+
specification_version: 2
|
101
|
+
summary: Run RSpec with UI testing tools
|
102
|
+
test_files: []
|
103
|
+
|