watir-rspec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jarmo Pertman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Watir::RSpec
2
+
3
+ Use Watir with RSpec with ease.
4
+
5
+ ## Installation
6
+
7
+ Add these lines to your application's Gemfile:
8
+
9
+ group :test do
10
+ gem 'watir-rspec'
11
+ end
12
+
13
+ And add these lines to your spec\_helper.rb file:
14
+
15
+ RSpec.configure do |config|
16
+ # Add Watir::RSpec::HtmlFormatter to get links to the screenshots, html and
17
+ # all other files created during the failing examples.
18
+ config.add_formatter('documentation')
19
+ config.add_formatter(Watir::RSpec::HtmlFormatter)
20
+
21
+ # Open up the browser for each example.
22
+ config.before :all do
23
+ @browser = Watir::Browser.new
24
+ end
25
+
26
+ # Close that browser after each example.
27
+ config.after :all do
28
+ @browser.close if @browser
29
+ end
30
+
31
+ # Include RSpec::Helper into each of your example group for making it possible to
32
+ # write in your examples instead of:
33
+ # @browser.goto "localhost"
34
+ # @browser.text_field(:name => "first_name").set "Bob"
35
+ #
36
+ # like this:
37
+ # goto "localhost"
38
+ # text_field(:name => "first_name").set "Bob"
39
+ #
40
+ # This needs that you've used @browser as an instance variable name in
41
+ # before :all block.
42
+ config.include Watir::RSpec::Helper
43
+ end
44
+
45
+
46
+ When using Rails and writing specs to requests directory, add an additional filter for RSpec:
47
+
48
+ config.before :all, :type => :request do
49
+ @browser = Watir::Browser.new :chrome
50
+ end
51
+
52
+ config.after :all, :type => :request do
53
+ @browser.close if @browser
54
+ end
55
+
56
+ config.include Watir::RSpec::Helper, :type => :request
57
+
58
+ ## Usage
59
+
60
+ Just use the browser in your examples. If you haven't included
61
+ Watir::RSpec::Helper, then you need to use the @browser instance variable when
62
+ calling Watir::Browser methods, otherwise you may omit it.
63
+
64
+ When creating/downloading/uploading files in your examples and using
65
+ Watir::RSpec::HtmlFormatter then you can generate links automatically to these files when example
66
+ fails. To do that you need to use Watir::RSpec.file\_path method for generating
67
+ unique file name:
68
+
69
+ uploaded_file_path = Watir::RSpec.file_path("uploaded.txt")
70
+ File.open(uploaded_file_path, "w") {|file| file.write "Generated File Input"}
71
+
72
+ If you're using Rails, then you also need to install [watir-rails](https://github.com/watir/watir-rails) gem.
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,16 @@
1
+ RSpec.configuration.before(:suite) do
2
+ # Allow RSpec specs to use transactional fixtures when using Watir.
3
+ #
4
+ # Tip from http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/
5
+ class ::ActiveRecord::Base
6
+ mattr_accessor :shared_connection
7
+ @@shared_connection = nil
8
+
9
+ def self.connection
10
+ @@shared_connection || retrieve_connection
11
+ end
12
+ end
13
+
14
+ # Forces all threads to share the same connection.
15
+ ::ActiveRecord::Base.shared_connection = ::ActiveRecord::Base.connection
16
+ end
@@ -0,0 +1,25 @@
1
+ module Watir
2
+ class RSpec
3
+ module Helper
4
+ extend Forwardable
5
+
6
+ def method_missing name, *args #:nodoc:
7
+ if @browser.respond_to?(name)
8
+ Helper.module_eval %Q[
9
+ def #{name}(*args)
10
+ @browser.send(:#{name}, *args) {yield}
11
+ end
12
+ ]
13
+ self.send(name, *args) {yield}
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ # make sure that using method 'p' will be invoked on browser
20
+ # and not Kernel
21
+ # use Kernel.p if you need to dump some variable
22
+ def_delegators :@browser, :p
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,91 @@
1
+ require 'rspec/core/formatters/html_formatter'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+
5
+ module Watir
6
+ class RSpec
7
+ # Custom RSpec formatter
8
+ # * saves screenshot of the browser upon test failure
9
+ # * saves html of the browser upon test failure
10
+ # * saves all files generated/downloaded during the test and shows them in the report
11
+ class HtmlFormatter < ::RSpec::Core::Formatters::HtmlFormatter
12
+ def initialize(output) # :nodoc:
13
+ @output_path = File.expand_path(ENV["WATIR_RESULTS_PATH"] || (output.respond_to?(:path) ? output.path : "tmp/spec-results/index.html"))
14
+ FileUtils.rm_rf File.dirname(@output_path), :verbose => true if File.exists?(@output_path)
15
+
16
+ @output_relative_path = Pathname.new(@output_path).relative_path_from(Pathname.new(Dir.pwd))
17
+ puts "Results will be saved to #{@output_relative_path}"
18
+
19
+ @files_dir = File.dirname(@output_path)
20
+ FileUtils.mkdir_p(@files_dir)
21
+ @files_saved_during_example = []
22
+
23
+ super(File.open(@output_path, "w"))
24
+ end
25
+
26
+ def example_group_started(example_group) # :nodoc:
27
+ @files_saved_during_example.clear
28
+ super
29
+ end
30
+
31
+ def example_started(example) # :nodoc:
32
+ @files_saved_during_example.clear
33
+ super
34
+ end
35
+
36
+ def extra_failure_content(exception) # :nodoc:
37
+ browser = example_group.before_all_ivars[:@browser]
38
+ return super unless browser && browser.exists?
39
+
40
+ save_screenshot browser
41
+ save_html browser
42
+
43
+ content = []
44
+ content << "<span>"
45
+ @files_saved_during_example.each {|f| content << link_for(f)}
46
+ content << "</span>"
47
+ super + content.join($/)
48
+ end
49
+
50
+ # Generates unique file name and path for each example.
51
+ #
52
+ # All file names generated with this method will be shown
53
+ # on the report.
54
+ def file_path(file_name, description=nil)
55
+ extension = File.extname(file_name)
56
+ basename = File.basename(file_name, extension)
57
+ file_path = File.join(@files_dir, "#{basename}_#{::Time.now.strftime("%H%M%S")}_#{example_group_number}_#{example_number}#{extension}")
58
+ @files_saved_during_example.unshift(:desc => description, :path => file_path)
59
+ file_path
60
+ end
61
+
62
+ private
63
+
64
+ def link_for(file) # :nodoc:
65
+ return unless File.exists?(file[:path])
66
+
67
+ description = file[:desc] ? file[:desc] : File.extname(file[:path]).upcase[1..-1]
68
+ path = Pathname.new(file[:path])
69
+ "<a href='#{path.relative_path_from(Pathname.new(@output_path).dirname)}'>#{description}</a>&nbsp;"
70
+ end
71
+
72
+ def save_html(browser) # :nodoc:
73
+ file_name = file_path("browser.html")
74
+ begin
75
+ html = browser.html
76
+ File.open(file_name, 'w') {|f| f.puts html}
77
+ rescue => e
78
+ $stderr.puts "saving of html failed: #{e.message}"
79
+ end
80
+ file_name
81
+ end
82
+
83
+ def save_screenshot(browser, description="Screenshot") # :nodoc:
84
+ file_name = file_path("screenshot.png", description)
85
+ browser.screenshot.save(file_name)
86
+ file_name
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,5 @@
1
+ module Watir
2
+ class RSpec
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,158 @@
1
+ require 'rspec'
2
+ require File.expand_path("rspec/helper", File.dirname(__FILE__))
3
+ require File.expand_path("rspec/html_formatter", File.dirname(__FILE__))
4
+
5
+ if defined? ActiveRecord
6
+ require File.expand_path("rspec/active_record_shared_connection", File.dirname(__FILE__))
7
+ end
8
+
9
+ module Watir
10
+ # add #within(timeout) and #during(timeout) methods for every matcher for allowing to wait until some condition is met.
11
+ # div.click
12
+ # another_div.should be_present.within(5)
13
+ #
14
+ # expect {
15
+ # div.click
16
+ # }.to change {another_div.text}.from("before").to("after").within(5)
17
+ #
18
+ # expect {
19
+ # div.click
20
+ # }.to make {another_div.present?}.within(5)
21
+ #
22
+ # expect {
23
+ # div.click
24
+ # }.to change {another_div.text}.soon
25
+ #
26
+ class RSpec
27
+ class << self
28
+ def bootstrap const
29
+ const.class_eval do
30
+
31
+ inst_methods = instance_methods.map &:to_sym
32
+
33
+ if !(inst_methods.include?(:__matches?) || inst_methods.include?(:__does_not_match?)) &&
34
+ (inst_methods.include?(:matches?) || inst_methods.include?(:does_not_match?))
35
+
36
+ def within(timeout)
37
+ @within_timeout = timeout
38
+ self
39
+ end
40
+
41
+ def during(timeout)
42
+ @during_timeout = timeout
43
+ self
44
+ end
45
+
46
+ def soon
47
+ within(30)
48
+ end
49
+
50
+ def seconds
51
+ # for syntactic sugar
52
+ self
53
+ end
54
+
55
+ alias_method :second, :seconds
56
+
57
+ def minutes
58
+ @within_timeout *= 60 if @within_timeout
59
+ @during_timeout *= 60 if @during_timeout
60
+ self
61
+ end
62
+
63
+ alias_method :minute, :minutes
64
+ end
65
+
66
+ if inst_methods.include? :matches?
67
+ alias_method :__matches?, :matches?
68
+
69
+ def matches?(actual)
70
+ match_with_wait {__matches?(actual)}
71
+ end
72
+ end
73
+
74
+ if inst_methods.include? :does_not_match?
75
+ alias_method :__does_not_match?, :does_not_match?
76
+
77
+ def does_not_match?(actual)
78
+ match_with_wait {__does_not_match?(actual)}
79
+ end
80
+ elsif inst_methods.include? :matches?
81
+ def does_not_match?(actual)
82
+ match_with_wait {!__matches?(actual)}
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def match_with_wait
89
+ if @within_timeout
90
+ timeout = @within_timeout; @within_timeout = nil
91
+ Watir::Wait.until(timeout) {yield} rescue false
92
+ elsif @during_timeout
93
+ timeout = @during_timeout; @during_timeout = nil
94
+ Watir::Wait.while(timeout) {yield} rescue true
95
+ else
96
+ yield
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ def file_path(file_name, description=nil)
103
+ formatter.file_path(file_name, description=nil)
104
+ end
105
+
106
+ private
107
+
108
+ def formatter
109
+ @formatter ||= begin
110
+ formatter = ::RSpec.configuration.formatters.find {|f| f.kind_of? Watir::RSpec::HtmlFormatter}
111
+ unless formatter
112
+ raise <<-EOF
113
+ Watir::RSpec::HtmlFormatter is not set as a RSpec formatter.
114
+
115
+ You need to add it into your spec_helper.rb file like this:
116
+ RSpec.configure do |config|
117
+ config.add_formatter('documentation')
118
+ config.add_formatter(Watir::RSpec::HtmlFormatter)
119
+ end
120
+ EOF
121
+ end
122
+ formatter
123
+ end
124
+ end
125
+
126
+
127
+ end
128
+
129
+ end
130
+ end
131
+
132
+ # patch for #within(timeout) method
133
+ module ::RSpec::Matchers
134
+ class BuiltIn::Change
135
+ def matches?(event_proc)
136
+ raise_block_syntax_error if block_given?
137
+
138
+ # to make #change work with #in(timeout) method
139
+ unless defined? @actual_before
140
+ @actual_before = evaluate_value_proc
141
+ event_proc.call
142
+ end
143
+ @actual_after = evaluate_value_proc
144
+
145
+ (!change_expected? || changed?) && matches_before? && matches_after? && matches_expected_delta? && matches_min? && matches_max?
146
+ end
147
+ end
148
+
149
+ alias_method :make, :change
150
+ end
151
+
152
+ matchers = RSpec::Matchers::BuiltIn.constants.map(&:to_sym)
153
+ matchers.delete :BaseMatcher
154
+ matchers.each do |const|
155
+ Watir::RSpec.bootstrap RSpec::Matchers::BuiltIn.const_get const
156
+ end
157
+
158
+ Watir::RSpec.bootstrap RSpec::Matchers::DSL::Matcher
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/watir/rspec/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jarmo Pertman"]
6
+ gem.email = ["jarmo.p@gmail.com"]
7
+ gem.description = %q{Use Watir with RSpec with ease.}
8
+ gem.summary = %q{Use Watir with RSpec with ease.}
9
+ gem.homepage = "http://github.com/watir/watir-rspec"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "watir-rspec"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Watir::RSpec::VERSION
17
+
18
+ gem.add_dependency "rspec", "~>2.0"
19
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watir-rspec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jarmo Pertman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ description: Use Watir with RSpec with ease.
31
+ email:
32
+ - jarmo.p@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - lib/watir/rspec.rb
43
+ - lib/watir/rspec/active_record_shared_connection.rb
44
+ - lib/watir/rspec/helper.rb
45
+ - lib/watir/rspec/html_formatter.rb
46
+ - lib/watir/rspec/version.rb
47
+ - watir-rspec.gemspec
48
+ homepage: http://github.com/watir/watir-rspec
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.24
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Use Watir with RSpec with ease.
72
+ test_files: []
73
+ has_rdoc: