watir-rspec 0.0.1

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/.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: