watir-dom-wait 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -4
- data/LICENSE.txt +1 -1
- data/README.md +12 -37
- data/lib/watir-dom-wait.rb +2 -1
- data/lib/watir/dom/elements/element.rb +15 -47
- data/lib/watir/dom/extensions/js/waitForDom.js +20 -79
- data/spec/spec_helper.rb +10 -3
- data/spec/support/html/wait_for_dom.html +1 -1
- data/spec/support/travis.sh +14 -0
- data/spec/watir-dom-wait/element_spec.rb +16 -70
- data/watir-dom-wait.gemspec +5 -5
- metadata +24 -11
- data/lib/watir/dom/decorator.rb +0 -28
- data/lib/watir/dom/wait.rb +0 -91
- data/lib/watir/dom/wait/version.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93e9ba59672d1b85a9b7068e6423683c6dc32046
|
4
|
+
data.tar.gz: dfb2a55dec1e3cec71669f0d4ed201109c6833d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 739f87a17b60dfcb303041633cb35fd91a25761942990dfe4d107cbd2147d25d382d39460d0519fa3f7276604603761aa2c0a9824983dfd1a61a857670bdf891
|
7
|
+
data.tar.gz: 47edb3d7bee52504afd61a4501d37bd9410f2ff61ca2933899029e6d88ccf78e90fe28325996f0ff676bdc5c2f51537b6daaf8ce0c17baf27254aebb451a4149
|
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# watir-dom-wait [](https://travis-ci.org/p0deje/watir-dom-wait) [](http://badge.fury.io/rb/watir-dom-wait)
|
2
2
|
|
3
|
-
Watir extension which provides DOM
|
3
|
+
[Watir](https://github.com/watir/watir) extension which provides with method to check for DOM changes.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -30,58 +30,33 @@ Require to monkey patch `Watir::Element` instance:
|
|
30
30
|
require 'watir-dom-wait'
|
31
31
|
```
|
32
32
|
|
33
|
-
|
33
|
+
There is only one method added:
|
34
34
|
|
35
35
|
```ruby
|
36
|
-
browser.div(class: 'test').
|
36
|
+
browser.div(class: 'test').dom_changed?
|
37
37
|
```
|
38
38
|
|
39
|
-
|
39
|
+
which returns `true` if DOM is changed inside element or `false`
|
40
|
+
if DOM is currently changing.
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
```
|
44
|
-
|
45
|
-
With passing block:
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
browser.div(class: 'test').when_dom_changed do |div|
|
49
|
-
div.a(class: 'link').click
|
50
|
-
end
|
51
|
-
```
|
52
|
-
|
53
|
-
With timeout of 10 seconds:
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
browser.div(class: 'test').when_dom_changed(timeout: 10).a(class: 'link').click
|
57
|
-
```
|
58
|
-
|
59
|
-
With interval of checking for subtree modifications of 2 seconds:
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
browser.div(class: 'test').when_dom_changed(interval: 2).a(class: 'link').click
|
63
|
-
```
|
64
|
-
|
65
|
-
With 5 seconds delay of how long to waiting for DOM to start modifying:
|
42
|
+
Default delay of waiting until DOM starts changing is `1.1` seconds, but
|
43
|
+
can be changed:
|
66
44
|
|
67
45
|
```ruby
|
68
|
-
browser.div(class: 'test').
|
46
|
+
browser.div(class: 'test').dom_changed?(delay: 2.5)
|
69
47
|
```
|
70
48
|
|
71
|
-
|
49
|
+
You probably don't want to use the method directly. Instead, you can combine
|
50
|
+
usage of the method with built-in Watir waiting mechanism:
|
72
51
|
|
73
52
|
```ruby
|
74
|
-
|
75
|
-
Watir::Dom::Wait.delay = 1
|
76
|
-
Watir::Dom::Wait.interval = 0.15
|
53
|
+
browser.div(class: 'test').wait_until(&:dom_changed?)
|
77
54
|
```
|
78
55
|
|
79
56
|
## How it works
|
80
57
|
|
81
58
|
Using [MutationObserver](https://developer.mozilla.org/en/docs/Web/API/MutationObserver).
|
82
59
|
|
83
|
-
Note, that it also rescues `Selenium::WebDriver::Error::StaleElementReferenceError`, `Selenium::WebDriver::Error::JavascriptError` and `Watir::Exception::UnknownObjectException` (only when its message contains `Element not found in the cache - perhaps the page has changed since it was looked up`) when waits for DOM.
|
84
|
-
|
85
60
|
## Contributors
|
86
61
|
|
87
62
|
* [Alex Rodionov](https://github.com/p0deje)
|
data/lib/watir-dom-wait.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require 'watir
|
1
|
+
require 'watir'
|
2
|
+
require 'watir/dom/elements/element'
|
@@ -1,60 +1,28 @@
|
|
1
1
|
module Watir
|
2
2
|
class Element
|
3
|
+
DOM_WAIT_JS = File.read("#{File.dirname(__FILE__)}/../extensions/js/waitForDom.js").freeze
|
3
4
|
|
4
5
|
#
|
5
|
-
#
|
6
|
+
# Returns true if DOM is changed within the element.
|
6
7
|
#
|
7
|
-
# @example
|
8
|
-
# browser.div(id: 'test').
|
8
|
+
# @example Wait until DOM is changed inside element with default delay
|
9
|
+
# browser.div(id: 'test').wait_until(&:dom_changed?).click
|
9
10
|
#
|
10
|
-
# @example
|
11
|
-
# browser.div(id: 'test').
|
12
|
-
#
|
11
|
+
# @example Wait until DOM is changed inside element with default delay
|
12
|
+
# browser.div(id: 'test').wait_until do |element|
|
13
|
+
# element.dom_changed?(delay: 5)
|
13
14
|
# end
|
14
15
|
#
|
15
|
-
# @
|
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 [Float] interval How long to wait between DOM nodes adding/removing in seconds. Defaults to 0.5
|
26
|
-
# @option opts [Float] delay How long to wait for DOM modifications to start
|
27
|
-
# @option opts [Fixnum] timeout seconds to wait before timing out
|
16
|
+
# @param delay [Integer, Float] how long to wait for DOM modifications to start
|
28
17
|
#
|
29
18
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Dom::Wait.wait_for_dom(self, opts, message)
|
38
|
-
yield self
|
39
|
-
else
|
40
|
-
WhenDOMChangedDecorator.new(self, opts, message)
|
41
|
-
end
|
19
|
+
def dom_changed?(delay: 1.1)
|
20
|
+
driver.manage.timeouts.script_timeout = delay + 1
|
21
|
+
driver.execute_async_script(DOM_WAIT_JS, wd, delay)
|
22
|
+
ensure
|
23
|
+
# TODO: make sure we rollback to user-defined timeout
|
24
|
+
# blocked by https://code.google.com/p/selenium/issues/detail?id=6608
|
25
|
+
driver.manage.timeouts.script_timeout = 1
|
42
26
|
end
|
43
|
-
|
44
|
-
#
|
45
|
-
# Waits until DOM is changed within the element.
|
46
|
-
#
|
47
|
-
# @param [Hash] opts
|
48
|
-
# @option opts [Float] interval How long to wait between DOM nodes adding/removing in seconds. Defaults to 0.5
|
49
|
-
# @option opts [Float] delay How long to wait for DOM modifications to start
|
50
|
-
# @option opts [Fixnum] timeout seconds to wait before timing out
|
51
|
-
#
|
52
|
-
|
53
|
-
def wait_until_dom_changed(opts = {})
|
54
|
-
when_dom_changed(opts) do
|
55
|
-
# just trigger waiting
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
27
|
end # Element
|
60
28
|
end # Watir
|
@@ -1,92 +1,33 @@
|
|
1
|
-
// arguments from WebDriver
|
2
|
-
var element = arguments[0];
|
3
|
-
var interval = arguments[1] * 1000;
|
4
|
-
var delay = arguments[2] * 1000;
|
5
|
-
var timeout = arguments[3] * 1000;
|
6
|
-
var exit = arguments[4];
|
7
|
-
|
8
|
-
// flag that DOM has started modifying
|
9
|
-
var startedModifying = false;
|
10
|
-
|
11
|
-
// exits codes
|
12
|
-
var exits = {
|
13
|
-
modified: 0, // DOM modifications have started and successfully finished
|
14
|
-
timeout: 1, // DOM modifications have started but exceeded timeout
|
15
|
-
noop: 2, // DOM modifications have not started
|
16
|
-
}
|
17
|
-
|
18
|
-
/**
|
19
|
-
* Copy-paste of Underscore.js debounce function.
|
20
|
-
* @see http://underscorejs.org/docs/underscore.html#section-67
|
21
|
-
*/
|
22
|
-
var _debounce = function(func, wait, immediate) {
|
23
|
-
var timeout, args, context, timestamp, result;
|
24
|
-
return function() {
|
25
|
-
context = this;
|
26
|
-
args = arguments;
|
27
|
-
timestamp = new Date();
|
28
|
-
var later = function() {
|
29
|
-
var last = (new Date()) - timestamp;
|
30
|
-
if (last < wait) {
|
31
|
-
timeout = setTimeout(later, wait - last);
|
32
|
-
} else {
|
33
|
-
timeout = null;
|
34
|
-
if (!immediate) result = func.apply(context, args);
|
35
|
-
}
|
36
|
-
};
|
37
|
-
var callNow = immediate && !timeout;
|
38
|
-
if (!timeout) {
|
39
|
-
timeout = setTimeout(later, wait);
|
40
|
-
}
|
41
|
-
if (callNow) result = func.apply(context, args);
|
42
|
-
return result;
|
43
|
-
};
|
44
|
-
};
|
45
|
-
|
46
1
|
/**
|
47
|
-
* Disconnects observer and
|
48
|
-
*
|
49
|
-
* to show that DOM has finished modifying.
|
2
|
+
* Disconnects observer and invokes WebDriver's callback function
|
3
|
+
* to show that DOM has started modifying.
|
50
4
|
*/
|
51
|
-
var
|
52
|
-
clearTimeout(
|
5
|
+
var exitOnStartedModifying = function() {
|
6
|
+
clearTimeout(exitOnNotStartedModifying);
|
53
7
|
observer.disconnect();
|
54
|
-
|
55
|
-
}
|
8
|
+
callback(false);
|
9
|
+
}
|
56
10
|
|
57
11
|
/**
|
58
|
-
* Disconnects observer and
|
59
|
-
*
|
60
|
-
* to show that DOM has started modifying
|
61
|
-
* but exceeded timeout.
|
12
|
+
* Disconnects observer and invokes WebDriver's callback function
|
13
|
+
* to show that DOM has not started modifying.
|
62
14
|
*/
|
63
|
-
var
|
15
|
+
var exitOnNotStartedModifying = function() {
|
64
16
|
return setTimeout(function() {
|
65
17
|
observer.disconnect();
|
66
|
-
|
67
|
-
},
|
18
|
+
callback(true);
|
19
|
+
}, 1000);
|
68
20
|
}
|
69
21
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
*/
|
75
|
-
var exitNoop = function() {
|
76
|
-
setTimeout(function() {
|
77
|
-
if (!startedModifying) {
|
78
|
-
clearTimeout(exitTimeout);
|
79
|
-
observer.disconnect();
|
80
|
-
exit(exits.noop);
|
81
|
-
}
|
82
|
-
}, delay);
|
83
|
-
}
|
22
|
+
// arguments from WebDriver
|
23
|
+
var element = arguments[0];
|
24
|
+
var delay = arguments[1] * 1000;
|
25
|
+
var callback = arguments[2];
|
84
26
|
|
85
|
-
|
86
|
-
|
87
|
-
exitOnModified();
|
88
|
-
});
|
27
|
+
// start observer
|
28
|
+
var observer = new MutationObserver(exitOnStartedModifying);
|
89
29
|
var config = { attributes: true, childList: true, characterData: true, subtree: true };
|
90
30
|
observer.observe(element, config);
|
91
|
-
|
92
|
-
|
31
|
+
|
32
|
+
// make sure we exit if DOM has not started modifying
|
33
|
+
var exitOnNotStartedModifying = exitOnNotStartedModifying();
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
-
require "
|
1
|
+
require "pry"
|
2
|
+
require "watir-dom-wait"
|
2
3
|
|
3
4
|
RSpec.configure do |spec|
|
4
5
|
spec.filter_run_excluding bug: /\d+/
|
5
6
|
|
6
7
|
spec.before(:all) do
|
7
|
-
|
8
|
+
opts = {}
|
9
|
+
if ENV['TRAVIS']
|
10
|
+
Selenium::WebDriver::Chrome.path = "#{File.dirname(__FILE__)}/../bin/google-chrome"
|
11
|
+
opts[:args] = ['no-sandbox']
|
12
|
+
end
|
13
|
+
@browser = Watir::Browser.new(:chrome, opts)
|
8
14
|
@browser.goto "data:text/html,#{File.read('spec/support/html/wait_for_dom.html')}"
|
9
15
|
end
|
10
16
|
|
@@ -12,7 +18,8 @@ RSpec.configure do |spec|
|
|
12
18
|
@browser.quit
|
13
19
|
end
|
14
20
|
|
15
|
-
spec.after(:each) do
|
21
|
+
spec.after(:each) do |example|
|
22
|
+
binding.pry if example.exception && ENV['DEBUG']
|
16
23
|
@browser.refresh
|
17
24
|
end
|
18
25
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/bin/bash -ex
|
2
|
+
|
3
|
+
mkdir bin/
|
4
|
+
|
5
|
+
# https://omahaproxy.appspot.com
|
6
|
+
# https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/
|
7
|
+
CHROME_REVISION=386257
|
8
|
+
curl -L -O "http://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/${CHROME_REVISION}/chrome-linux.zip"
|
9
|
+
unzip chrome-linux.zip
|
10
|
+
ln -s "$(pwd)/chrome-linux/chrome" "$(pwd)/bin/google-chrome"
|
11
|
+
|
12
|
+
curl -L -O "http://chromedriver.storage.googleapis.com/2.21/chromedriver_linux64.zip"
|
13
|
+
unzip chromedriver_linux64.zip
|
14
|
+
ln -s "$(pwd)/chromedriver" "$(pwd)/bin/chromedriver"
|
@@ -5,112 +5,58 @@ describe Watir::Element do
|
|
5
5
|
context "when DOM is changed" do
|
6
6
|
context "when block is not given" do
|
7
7
|
it "waits using mutation observer" do
|
8
|
-
@browser.button(:
|
9
|
-
expect(@browser.div.
|
8
|
+
@browser.button(id: "quick").click
|
9
|
+
expect(@browser.div.wait_until(&:dom_changed?).spans.count).to eq(20)
|
10
10
|
end
|
11
11
|
|
12
12
|
it "waits using custom interval" do
|
13
|
-
@browser.button(:
|
14
|
-
expect(@browser.div.
|
13
|
+
@browser.button(id: "long").click
|
14
|
+
expect(@browser.div.wait_until(&:dom_changed?).spans.count).to eq(5)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "raises timeout error" do
|
18
|
-
@browser.button(:
|
19
|
-
expect { @browser.div.
|
18
|
+
@browser.button(id: "quick").click
|
19
|
+
expect { @browser.div.wait_until(timeout: 1, &:dom_changed?) }.to raise_error(Watir::Wait::TimeoutError)
|
20
20
|
end
|
21
21
|
|
22
22
|
context "when run more than one time" do
|
23
23
|
it "waits for DOM consecutively" do
|
24
24
|
3.times do |i|
|
25
25
|
sleep 1
|
26
|
-
@browser.button(:
|
27
|
-
expect(@browser.div.
|
26
|
+
@browser.button(id: "quick").click
|
27
|
+
expect(@browser.div.wait_until(&:dom_changed?).spans.count).to eq(20 * (i + 1))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
33
|
-
context "when block given" do
|
34
|
-
it "waits using mutation observer" do
|
35
|
-
@browser.button(:id => "quick").click
|
36
|
-
@browser.div.when_dom_changed do |div|
|
37
|
-
expect(div).to have(20).spans
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it "waits using custom interval" do
|
42
|
-
@browser.button(:id => "long").click
|
43
|
-
@browser.div.when_dom_changed(:interval => 1.1) do |div|
|
44
|
-
expect(div).to have(5).spans
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
it "raises timeout error" do
|
49
|
-
@browser.button(:id => "quick").click
|
50
|
-
expect {
|
51
|
-
@browser.div.when_dom_changed(:timeout => 2) { |div| div.spans }
|
52
|
-
}.to raise_error(Watir::Wait::TimeoutError)
|
53
|
-
end
|
54
|
-
|
55
|
-
it "returns block evaluation" do
|
56
|
-
@browser.button(:id => "quick").click
|
57
|
-
size = @browser.div.when_dom_changed do |div|
|
58
|
-
div.spans.size
|
59
|
-
end
|
60
|
-
expect(size).to eq(20)
|
61
|
-
end
|
62
|
-
end
|
63
32
|
end
|
64
33
|
|
65
34
|
context "when DOM is not changed" do
|
66
35
|
it "doesn't raise any exception" do
|
67
|
-
expect(@browser.div.
|
36
|
+
expect(@browser.div.wait_until(&:dom_changed?).spans.count).to eq(0)
|
68
37
|
end
|
69
38
|
end
|
70
39
|
|
71
40
|
context "when effects are used" do
|
72
41
|
it "properly handles fading" do
|
73
|
-
@browser.button(:
|
74
|
-
text = @browser.div(:
|
42
|
+
@browser.button(id: 'fade').click
|
43
|
+
text = @browser.div(id: 'container3').wait_until(&:dom_changed?).span.text
|
75
44
|
expect(text).to eq('Faded')
|
76
45
|
end
|
77
46
|
end
|
78
47
|
|
79
48
|
context "when element goes stale" do
|
80
|
-
before(:all) do
|
81
|
-
Watir.always_locate = false
|
82
|
-
end
|
83
|
-
|
84
|
-
after(:all) do
|
85
|
-
Watir.always_locate = true
|
86
|
-
end
|
87
|
-
|
88
49
|
it "relocates element" do
|
89
|
-
|
90
|
-
div.
|
91
|
-
@browser.refresh
|
92
|
-
expect { div.when_dom_changed.text }.not_to raise_error
|
50
|
+
@browser.button(id: 'stale').click
|
51
|
+
expect { @browser.div(id: 'container2').wait_until(&:dom_changed?) }.not_to raise_error
|
93
52
|
end
|
94
53
|
end
|
95
54
|
|
96
55
|
context "when element cannot be located" do
|
97
|
-
it "
|
98
|
-
div = @browser.div(:
|
99
|
-
expect { div.
|
56
|
+
it "raises error" do
|
57
|
+
div = @browser.div(id: 'doesnotexist')
|
58
|
+
expect { div.wait_until(&:dom_changed?) }.to raise_error(Watir::Exception::UnknownObjectException)
|
100
59
|
end
|
101
60
|
end
|
102
61
|
end
|
103
|
-
|
104
|
-
describe "#wait_until_dom_changed" do
|
105
|
-
it "calls #when_dom_changed" do
|
106
|
-
div = @browser.div
|
107
|
-
opts = { timeout: 1, interval: 2, delay: 3 }
|
108
|
-
expect(div).to receive(:when_dom_changed).with(opts)
|
109
|
-
div.wait_until_dom_changed(opts)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "returns nil" do
|
113
|
-
expect(@browser.div.wait_until_dom_changed).to eq(nil)
|
114
|
-
end
|
115
|
-
end
|
116
62
|
end
|
data/watir-dom-wait.gemspec
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'watir/dom/wait/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "watir-dom-wait"
|
8
|
-
spec.version =
|
7
|
+
spec.version = "0.3.0"
|
9
8
|
spec.authors = ["Alex Rodionov"]
|
10
9
|
spec.email = %w(p0deje@gmail.com)
|
11
|
-
spec.description = "Watir extension
|
12
|
-
spec.summary = "Watir extension
|
10
|
+
spec.description = "Watir extension which provides with method to check for DOM changes."
|
11
|
+
spec.summary = "Watir extension which provides with method to check for DOM changes."
|
13
12
|
spec.homepage = "https://github.com/p0deje/watir-dom-wait"
|
14
13
|
spec.license = "MIT"
|
15
14
|
|
@@ -18,9 +17,10 @@ Gem::Specification.new do |spec|
|
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
|
-
spec.add_dependency "watir
|
20
|
+
spec.add_dependency "watir", ">= 6.0"
|
22
21
|
|
23
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
23
|
spec.add_development_dependency "rake"
|
25
24
|
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "pry"
|
26
26
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watir-dom-wait
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Rodionov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: watir
|
14
|
+
name: watir
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '6.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '6.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,21 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Watir extension which provides with method to check for DOM changes.
|
70
84
|
email:
|
71
85
|
- p0deje@gmail.com
|
72
86
|
executables: []
|
@@ -80,13 +94,11 @@ files:
|
|
80
94
|
- README.md
|
81
95
|
- Rakefile
|
82
96
|
- lib/watir-dom-wait.rb
|
83
|
-
- lib/watir/dom/decorator.rb
|
84
97
|
- lib/watir/dom/elements/element.rb
|
85
98
|
- lib/watir/dom/extensions/js/waitForDom.js
|
86
|
-
- lib/watir/dom/wait.rb
|
87
|
-
- lib/watir/dom/wait/version.rb
|
88
99
|
- spec/spec_helper.rb
|
89
100
|
- spec/support/html/wait_for_dom.html
|
101
|
+
- spec/support/travis.sh
|
90
102
|
- spec/watir-dom-wait/element_spec.rb
|
91
103
|
- watir-dom-wait.gemspec
|
92
104
|
homepage: https://github.com/p0deje/watir-dom-wait
|
@@ -109,11 +121,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
121
|
version: '0'
|
110
122
|
requirements: []
|
111
123
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.
|
124
|
+
rubygems_version: 2.4.5.1
|
113
125
|
signing_key:
|
114
126
|
specification_version: 4
|
115
|
-
summary: Watir extension
|
127
|
+
summary: Watir extension which provides with method to check for DOM changes.
|
116
128
|
test_files:
|
117
129
|
- spec/spec_helper.rb
|
118
130
|
- spec/support/html/wait_for_dom.html
|
131
|
+
- spec/support/travis.sh
|
119
132
|
- spec/watir-dom-wait/element_spec.rb
|
data/lib/watir/dom/decorator.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Watir
|
2
|
-
#
|
3
|
-
# Wraps an Element so that any subsequent method calls are
|
4
|
-
# put on hold until the DOM subtree is modified within the element.
|
5
|
-
#
|
6
|
-
class WhenDOMChangedDecorator
|
7
|
-
|
8
|
-
def initialize(element, opts, message)
|
9
|
-
@element = element
|
10
|
-
@opts = opts
|
11
|
-
@message = message
|
12
|
-
end
|
13
|
-
|
14
|
-
def method_missing(m, *args, &block)
|
15
|
-
unless @element.respond_to?(m)
|
16
|
-
raise NoMethodError, "undefined method `#{m}' for #{@element.inspect}:#{@element.class}"
|
17
|
-
end
|
18
|
-
|
19
|
-
Dom::Wait.wait_for_dom(@element, @opts, @message)
|
20
|
-
@element.__send__(m, *args, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def respond_to?(*args)
|
24
|
-
@element.respond_to?(*args)
|
25
|
-
end
|
26
|
-
|
27
|
-
end # WhenDOMChangedDecorator
|
28
|
-
end # Watir
|
data/lib/watir/dom/wait.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
require "watir-webdriver"
|
2
|
-
require "watir/dom/wait/version"
|
3
|
-
require "watir/dom/decorator"
|
4
|
-
require "watir/dom/elements/element"
|
5
|
-
|
6
|
-
module Watir
|
7
|
-
module Dom
|
8
|
-
module Wait
|
9
|
-
|
10
|
-
JAVASCRIPT = File.read("#{File.dirname(__FILE__)}/extensions/js/waitForDom.js")
|
11
|
-
DOM_READY = "return watir.domReady;"
|
12
|
-
|
13
|
-
|
14
|
-
class << self
|
15
|
-
|
16
|
-
attr_writer :interval
|
17
|
-
attr_writer :delay
|
18
|
-
attr_writer :timeout
|
19
|
-
|
20
|
-
def interval
|
21
|
-
@interval ||= 0.5
|
22
|
-
end
|
23
|
-
|
24
|
-
def delay
|
25
|
-
@delay ||= 1
|
26
|
-
end
|
27
|
-
|
28
|
-
def timeout
|
29
|
-
@timeout ||= 30
|
30
|
-
end
|
31
|
-
|
32
|
-
#
|
33
|
-
# Waits until DOM is changed.
|
34
|
-
# @param [Watir::Element] element
|
35
|
-
# @param [Hash] opts
|
36
|
-
# @option opts [Float] interval How long to wait between DOM nodes adding/removing in seconds. Defaults to 0.5
|
37
|
-
# @option opts [Float] delay How long to wait for DOM modifications to start
|
38
|
-
# @option opts [Fixnum] timeout seconds to wait before timing out
|
39
|
-
# @api private
|
40
|
-
#
|
41
|
-
|
42
|
-
def wait_for_dom(element, opts, message)
|
43
|
-
response = self.rescue do
|
44
|
-
js = JAVASCRIPT.dup
|
45
|
-
driver = element.browser.driver
|
46
|
-
# TODO make sure we rollback to user-defined timeout
|
47
|
-
# blocked by https://code.google.com/p/selenium/issues/detail?id=6608
|
48
|
-
driver.manage.timeouts.script_timeout = opts[:timeout] + 1
|
49
|
-
response = driver.execute_async_script(js, element.wd, opts[:interval], opts[:delay], opts[:timeout])
|
50
|
-
driver.manage.timeouts.script_timeout = 1
|
51
|
-
|
52
|
-
response
|
53
|
-
end
|
54
|
-
# Response statuses:
|
55
|
-
# 0: DOM modifications have started and successfully finished
|
56
|
-
# 1: DOM modifications have started but exceeded timeout
|
57
|
-
# 2: DOM modifications have not started
|
58
|
-
if response == 1
|
59
|
-
message = "timed out after #{opts[:timeout]} seconds, #{message}"
|
60
|
-
raise Watir::Wait::TimeoutError, message
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
#
|
65
|
-
# Executes block rescuing all necessary exceptions.
|
66
|
-
# @param [Proc] block
|
67
|
-
# @api private
|
68
|
-
#
|
69
|
-
|
70
|
-
def rescue(&block)
|
71
|
-
block.call
|
72
|
-
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Exception::UnknownObjectException => error
|
73
|
-
msg = 'Element not found in the cache - perhaps the page has changed since it was looked up'
|
74
|
-
if error.is_a?(Exception::UnknownObjectException) && !error.message.include?(msg)
|
75
|
-
raise error
|
76
|
-
else
|
77
|
-
# element became stale so we just retry DOM waiting
|
78
|
-
retry
|
79
|
-
end
|
80
|
-
rescue Selenium::WebDriver::Error::JavascriptError
|
81
|
-
# in rare cases, args passed to execute script are not correct, for example:
|
82
|
-
# correct: [#<Selenium::WebDriver::Element:0x..fd5f048838948a830 id="{bdfa905e-b666-354c-9bf1-4dc693fd15a8}">, 300, 3000] [el, interval, timeout]
|
83
|
-
# incorrect: [0.3, 3000, nil] [interval, timeout, ??]
|
84
|
-
# TODO there might be some logic (bug?) in Selenium which does this
|
85
|
-
retry
|
86
|
-
end
|
87
|
-
|
88
|
-
end # << self
|
89
|
-
end # Wait
|
90
|
-
end # Dom
|
91
|
-
end # Watir
|