watir-dom-wait 0.1.0

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,18 @@
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
18
+ .ruby-version
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ before_install:
5
+ - "export DISPLAY=:99.0"
6
+ - "sh -e /etc/init.d/xvfb start"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in watir-dom-wait.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alex Rodionov
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,68 @@
1
+ # watir-dom-wait [![Build Status](https://travis-ci.org/p0deje/watir-dom-wait.png?branch=master)](https://travis-ci.org/p0deje/watir-dom-wait) [![Gem Version](https://badge.fury.io/rb/watir-dom-wait.png)](http://badge.fury.io/rb/watir-dom-wait)
2
+
3
+ Watir extension which provides DOM-based waiting.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'watir-dom-wait'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install watir-dom-wait
18
+
19
+ ## Usage
20
+
21
+ With element returned:
22
+
23
+ ```ruby
24
+ browser.div(class: 'test').when_dom_changed.a(class: 'link').click
25
+ ```
26
+
27
+ With passing block:
28
+
29
+ ```ruby
30
+ browser.div(class: 'test').when_dom_changed do |div|
31
+ div.a(class: 'link').click
32
+ end
33
+ ```
34
+
35
+ With timeout of 10 seconds:
36
+
37
+ ```ruby
38
+ browser.div(class: 'test').when_dom_changed(timeout: 10).a(class: 'link').click
39
+ ```
40
+
41
+ With interval of checking for subtree modifications of 2 seconds:
42
+
43
+ ```ruby
44
+ browser.div(class: 'test').when_dom_changed(interval: 2).a(class: 'link').click
45
+ ```
46
+
47
+ With 5 seconds delay of how long to waiting for DOM to start modifying:
48
+
49
+ ```ruby
50
+ browser.div(class: 'test').when_dom_changed(delay: 5).a(class: 'link').click
51
+ ```
52
+
53
+ ## How it works
54
+
55
+ By attaching `DOMSubtreeModified` event to element. It's supported in all major browsers (except Presto-powered Opera).
56
+
57
+ ## Contributors
58
+
59
+ * [Alex Rodionov](https://github.com/p0deje)
60
+ * [Sasha Koss](https://github.com/kossnocorp)
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |spec|
5
+ spec.rspec_opts = %w(--color)
6
+ spec.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+
9
+ task default: :spec
@@ -0,0 +1,61 @@
1
+ module Watir
2
+ class Element
3
+
4
+ #
5
+ # Waits until DOM is changed within the element and returns/yields self.
6
+ #
7
+ # @example With self returned
8
+ # browser.div(id: 'test').when_dom_changed.a(id: 'link').click
9
+ #
10
+ # @example With passing block
11
+ # browser.div(id: 'test').when_dom_changed do |div|
12
+ # div.a(id: 'link').click
13
+ # end
14
+ #
15
+ # @example With timeout of 10 seconds
16
+ # browser.div(id: 'test').when_dom_changed(timeout: 10).a(id: 'link').click
17
+ #
18
+ # @example With interval of checking for subtree modifications of 2 seconds
19
+ # browser.div(id: 'test').when_dom_changed(interval: 2).a(id: 'link').click
20
+ #
21
+ # @example With 5 seconds delay of how long to waiting for DOM to start modifying
22
+ # browser.div(id: 'test').when_dom_changed(delay: 5).a(id: 'link').click
23
+ #
24
+ # @param [Hash] opts
25
+ # @option opts [Fixnum] timeout seconds to wait before timing out
26
+ # @option opts [Float] interval How long to wait between DOM nodes adding/removing in seconds. Defaults to 0.5
27
+ # @option opts [Float] delay How long to wait for DOM modifications to start in seconds. Defaults to 1
28
+ #
29
+
30
+ def when_dom_changed(opts = {})
31
+ message = "waiting for DOM subtree to finish modifying in #{selector_string}"
32
+ opts[:timeout] ||= 30
33
+ opts[:interval] ||= 0.5
34
+ opts[:delay] ||= 1
35
+
36
+ if block_given?
37
+ js = Dom::Wait::JAVASCRIPT.dup
38
+ browser.execute_script js, self, opts[:interval], opts[:delay]
39
+ Watir::Wait.until(opts[:timeout], message) { browser.execute_script(Dom::Wait::DOM_READY) == 0 }
40
+ yield self
41
+ else
42
+ WhenDOMChangedDecorator.new(self, opts, message)
43
+ end
44
+ end
45
+
46
+ #
47
+ # Waits until DOM is changed within the element.
48
+ #
49
+ # @param [Hash] opts
50
+ # @option opts [Fixnum] timeout seconds to wait before timing out
51
+ # @option opts [Float] interval How long to wait between DOM nodes adding/removing in seconds. Defaults to 0.5
52
+ # @option opts [Float] delay How long to wait for DOM modifications to start in seconds. Defaults to 1
53
+ #
54
+
55
+ def wait_until_dom_changed(opts = {})
56
+ when_dom_changed(opts)
57
+ nil
58
+ end
59
+
60
+ end # Element
61
+ end # Watir
@@ -0,0 +1,148 @@
1
+ /**
2
+ * There is a number of required functions provided by Underscore.js,
3
+ * but since we don't want to depend on it, we just copy-paste required
4
+ * things.
5
+ *
6
+ * See http://underscorejs.org/docs/underscore.html for explanation of functions.
7
+ */
8
+
9
+ var Underscore = {
10
+ slice: Array.prototype.slice,
11
+
12
+ nativeBind: Function.prototype.bind,
13
+
14
+ once: function(func) {
15
+ var ran = false, memo;
16
+ return function() {
17
+ if (ran) return memo;
18
+ ran = true;
19
+ memo = func.apply(this, arguments);
20
+ func = null;
21
+ return memo;
22
+ };
23
+ },
24
+
25
+ delay: function(func, wait) {
26
+ var args = this.slice.call(arguments, 2);
27
+ return setTimeout(function(){ return func.apply(null, args); }, wait);
28
+ },
29
+
30
+ debounce: function(func, wait, immediate) {
31
+ var timeout, result;
32
+ return function() {
33
+ var context = this, args = arguments;
34
+ var later = function() {
35
+ timeout = null;
36
+ if (!immediate) result = func.apply(context, args);
37
+ };
38
+ var callNow = immediate && !timeout;
39
+ clearTimeout(timeout);
40
+ timeout = setTimeout(later, wait);
41
+ if (callNow) result = func.apply(context, args);
42
+ return result;
43
+ };
44
+ },
45
+
46
+ bind: function(func, context) {
47
+ if (func.bind === this.nativeBind && this.nativeBind) return this.nativeBind.apply(func, this.slice.call(arguments, 1));
48
+ var args = this.slice.call(arguments, 2);
49
+ return function() {
50
+ return func.apply(context, args.concat(this.slice.call(arguments)));
51
+ };
52
+ }
53
+ };
54
+
55
+ function Watir(options) {
56
+ this.set(options);
57
+
58
+ this.startedModifying = false;
59
+ this.domReady = 1;
60
+
61
+ this.bindDOMEvents();
62
+ this.exitOnTimeout();
63
+ };
64
+
65
+ Watir.prototype.set = function (options) {
66
+ if (options == null) options = {};
67
+
68
+ this.el = options.el;
69
+ this.event = options.event || 'DOMSubtreeModified';
70
+ this.interval = options.interval;
71
+ this.delay = options.delay;
72
+
73
+ this.forceReady = this.wrappedForceReady();
74
+ this.startModifying = this.wrappedStartModifying();
75
+ }
76
+
77
+ Watir.prototype.exitOnTimeout = function () {
78
+ var that = this;
79
+
80
+ Underscore.delay(function() {
81
+ if (!that.startedModifying) {
82
+ that._forceReady();
83
+ }
84
+ }, this.delay);
85
+ };
86
+
87
+ Watir.prototype.bindDOMEvents = function() {
88
+ this.addEventListener(this.forceReady);
89
+ this.addEventListener(this.startModifying);
90
+ }
91
+
92
+ Watir.prototype.unbindDOMEvents = function() {
93
+ this.removeEventListener(this.forceReady);
94
+ this.removeEventListener(this.startModifying);
95
+ }
96
+
97
+ Watir.prototype.wrappedForceReady = function () {
98
+ return Underscore.bind(Underscore.debounce(this._forceReady, this.interval), this);
99
+ };
100
+
101
+ Watir.prototype.wrappedStartModifying = function () {
102
+ return Underscore.bind(Underscore.once(this._startModifying, this.interval), this);
103
+ }
104
+
105
+ Watir.prototype._forceReady = function() {
106
+ var that = this;
107
+
108
+ Underscore.once(function() {
109
+ that.unbindDOMEvents();
110
+ that.domReady -= 1;
111
+ })();
112
+ }
113
+
114
+ Watir.prototype._startModifying = function() {
115
+ this.startedModifying = true;
116
+ }
117
+
118
+ Watir.prototype.addEventListener = (function() {
119
+ if (window.addEventListener) {
120
+ return function (fn) {
121
+ this.el.addEventListener(this.event, fn, false);
122
+ };
123
+
124
+ } else {
125
+ return function (fn) {
126
+ this.el.attachEvent('on' + this.event, fn)
127
+ };
128
+ }
129
+ })();
130
+
131
+ Watir.prototype.removeEventListener = (function() {
132
+ if (window.removeEventListener) {
133
+ return function (fn) {
134
+ this.el.removeEventListener(this.event, fn, false);
135
+ };
136
+
137
+ } else {
138
+ return function (fn) {
139
+ this.el.detachEvent('on' + this.event, fn)
140
+ };
141
+ }
142
+ })();
143
+
144
+ window.watir = new Watir({
145
+ el: arguments[0],
146
+ interval: arguments[1] * 1000,
147
+ delay: arguments[2] * 1000,
148
+ });
@@ -0,0 +1,46 @@
1
+ require "watir-webdriver"
2
+ require "watir/dom/wait/version"
3
+ require "watir/dom/elements/element"
4
+
5
+ module Watir
6
+ module Dom
7
+ module Wait
8
+
9
+ JAVASCRIPT = File.read("lib/watir/dom/extensions/js/waitForDom.js")
10
+ DOM_READY = "return watir.domReady;"
11
+
12
+ end # Wait
13
+ end # Dom
14
+
15
+
16
+ #
17
+ # Wraps an Element so that any subsequent method calls are
18
+ # put on hold until the DOM subtree is modified within the element.
19
+ #
20
+
21
+ class WhenDOMChangedDecorator
22
+
23
+ def initialize(element, opts, message = nil)
24
+ @element = element
25
+ @opts = opts
26
+ @message = message
27
+ @js = Dom::Wait::JAVASCRIPT.dup
28
+ end
29
+
30
+ def method_missing(m, *args, &block)
31
+ unless @element.respond_to?(m)
32
+ raise NoMethodError, "undefined method `#{m}' for #{@element.inspect}:#{@element.class}"
33
+ end
34
+
35
+ @element.browser.execute_script @js, @element, @opts[:interval], @opts[:delay]
36
+ Watir::Wait.until(@opts[:timeout], @message) { @element.browser.execute_script(Dom::Wait::DOM_READY) == 0 }
37
+
38
+ @element.__send__(m, *args, &block)
39
+ end
40
+
41
+ def respond_to?(*args)
42
+ @element.respond_to?(*args)
43
+ end
44
+
45
+ end # WhenDOMChangedDecorator
46
+ end # Watir
@@ -0,0 +1,7 @@
1
+ module Watir
2
+ module Dom
3
+ module Wait
4
+ VERSION = "0.1.0"
5
+ end # Wait
6
+ end # Dom
7
+ end # Watir
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <title>wait for dom test</title>
5
+ <script type="text/javascript" charset="utf-8">
6
+ function modifySubtree(number, timeout) {
7
+ var timer = setInterval(function() {
8
+ var div = document.getElementById("container");
9
+ var span = document.createElement("span");
10
+ span.innerHTML = "Hello!";
11
+ div.appendChild(span);
12
+ div.appendChild(document.createElement("br"));
13
+ }, timeout);
14
+
15
+ setTimeout(function() {
16
+ clearInterval(timer);
17
+ }, number * timeout);
18
+ }
19
+ </script>
20
+ </head>
21
+
22
+ <body>
23
+ <div id="container"></div>
24
+ <br />
25
+ <button onclick="modifySubtree(5, 1000);" id="long">Start modifying subtree with 5 node operations and 1000 ms delay between them</button>
26
+ <br />
27
+ <button onclick="modifySubtree(20, 100);" id="quick">Start modifying subtree with 20 node operations and 100 ms delay between them</button>
28
+ </body>
29
+ </html>
@@ -0,0 +1,16 @@
1
+ require "watir/dom/wait"
2
+
3
+ RSpec.configure do |spec|
4
+ spec.before(:all) do
5
+ @browser = Watir::Browser.new
6
+ @browser.goto "data:text/html,#{File.read('spec/html/wait_for_dom.html')}"
7
+ end
8
+
9
+ spec.after(:all) do
10
+ @browser.quit
11
+ end
12
+
13
+ spec.after(:each) do
14
+ @browser.refresh
15
+ end
16
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Watir::Element do
4
+ describe "#when_dom_changed" do
5
+ context "when DOM is changed" do
6
+ context "when block is not given" do
7
+ it "waits using event handler" do
8
+ @browser.button(:id, "quick").click
9
+ @browser.div.when_dom_changed.should have(20).spans
10
+ end
11
+
12
+ it "may be run more than one time" do
13
+ 3.times do |i|
14
+ @browser.button(:id, "quick").click
15
+ @browser.div.when_dom_changed.should have(20 * (i + 1)).spans
16
+ end
17
+ end
18
+
19
+ it "waits using custom interval" do
20
+ @browser.button(:id, "long").click
21
+ @browser.div.when_dom_changed(:interval => 1.1).should have(5).spans
22
+ end
23
+
24
+ it "raises timeout error" do
25
+ @browser.button(:id, "quick").click
26
+ lambda { @browser.div.when_dom_changed(:timeout => 2).spans }.should raise_error(Watir::Wait::TimeoutError)
27
+ end
28
+ end
29
+
30
+ context "when block given" do
31
+ it "waits using event handler" do
32
+ @browser.button(:id, "quick").click
33
+ @browser.div.when_dom_changed do |div|
34
+ div.should have(20).spans
35
+ end
36
+ end
37
+
38
+ it "waits using custom interval" do
39
+ @browser.button(:id, "long").click
40
+ @browser.div.when_dom_changed(:interval => 1.1) do |div|
41
+ div.should have(5).spans
42
+ end
43
+ end
44
+
45
+ it "raises timeout error" do
46
+ @browser.button(:id, "quick").click
47
+ lambda do
48
+ @browser.div.when_dom_changed(:timeout => 2) { |div| div.spans }
49
+ end.should raise_error(Watir::Wait::TimeoutError)
50
+ end
51
+ end
52
+ end
53
+
54
+ context "when DOM is not changed" do
55
+ it "doesn't raise any exception" do
56
+ @browser.div.when_dom_changed.should have(0).spans
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#wait_until_dom_changed" do
62
+ it "calls #when_dom_changed" do
63
+ div = @browser.div
64
+ opts = { timeout: 1, interval: 2, delay: 3 }
65
+ div.should_receive(:when_dom_changed).with(opts)
66
+ div.wait_until_dom_changed(opts)
67
+ end
68
+
69
+ it "returns nil" do
70
+ @browser.div.wait_until_dom_changed.should == nil
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'watir/dom/wait/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "watir-dom-wait"
8
+ spec.version = Watir::Dom::Wait::VERSION
9
+ spec.authors = ["Alex Rodionov"]
10
+ spec.email = %w(p0deje@gmail.com)
11
+ spec.description = "Watir extension providing with DOM-based waiting"
12
+ spec.summary = "Watir extension providing with DOM-based waiting"
13
+ spec.homepage = "https://github.com/p0deje/watir-dom-wait"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "watir-webdriver"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watir-dom-wait
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Rodionov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: watir-webdriver
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Watir extension providing with DOM-based waiting
79
+ email:
80
+ - p0deje@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .travis.yml
87
+ - Gemfile
88
+ - LICENSE.txt
89
+ - README.md
90
+ - Rakefile
91
+ - lib/watir/dom/elements/element.rb
92
+ - lib/watir/dom/extensions/js/waitForDom.js
93
+ - lib/watir/dom/wait.rb
94
+ - lib/watir/dom/wait/version.rb
95
+ - spec/html/wait_for_dom.html
96
+ - spec/spec_helper.rb
97
+ - spec/watir-dom-wait_spec.rb
98
+ - watir-dom-wait.gemspec
99
+ homepage: https://github.com/p0deje/watir-dom-wait
100
+ licenses:
101
+ - MIT
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ segments:
113
+ - 0
114
+ hash: 2355813797107009921
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ segments:
122
+ - 0
123
+ hash: 2355813797107009921
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.23
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Watir extension providing with DOM-based waiting
130
+ test_files:
131
+ - spec/html/wait_for_dom.html
132
+ - spec/spec_helper.rb
133
+ - spec/watir-dom-wait_spec.rb