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 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,8 @@
1
+ == Formatter
2
+ * Get screenshots working without command line utilities?
3
+
4
+ == WATIR
5
+ * Fix matchers
6
+
7
+ == Selenium
8
+ * ???
@@ -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&#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
@@ -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,11 @@
1
+ module Spec
2
+ module Ui
3
+ module VERSION #:nodoc:
4
+ MAJOR = 0
5
+ MINOR = 2
6
+ TINY = 6
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ end
10
+ end
11
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ require 'spec/ui/watir/matchers'
2
+
3
+ Spec::Runner.configure do |config|
4
+ include Spec::Matchers::Watir
5
+ end
data/lib/spec/ui.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'spec/ui/formatter'
2
+ require 'spec/ui/version'
@@ -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
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --diff
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
2
+ require 'spec/ui'
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
+