watir-dom-wait 0.1.1 → 0.1.2
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/README.md +31 -3
- data/lib/watir/dom/elements/element.rb +10 -6
- data/lib/watir/dom/wait.rb +20 -0
- data/lib/watir/dom/wait/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/html/wait_for_dom.html +46 -0
- data/spec/{watir-dom-wait_spec.rb → watir-dom-wait/element_spec.rb} +27 -8
- metadata +8 -8
- data/spec/html/wait_for_dom.html +0 -29
data/README.md
CHANGED
@@ -6,18 +6,36 @@ Watir extension which provides DOM-based waiting.
|
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
gem 'watir-dom-wait'
|
11
|
+
```
|
10
12
|
|
11
13
|
And then execute:
|
12
14
|
|
13
|
-
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
14
18
|
|
15
19
|
Or install it yourself as:
|
16
20
|
|
17
|
-
|
21
|
+
```bash
|
22
|
+
$ gem install watir-dom-wait
|
23
|
+
```
|
18
24
|
|
19
25
|
## Usage
|
20
26
|
|
27
|
+
Require to monkey patch `Watir::Element` instance:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'watir-dom-wait'
|
31
|
+
```
|
32
|
+
|
33
|
+
Simple DOM waiting:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
browser.div(class: 'test').wait_until_dom_changed
|
37
|
+
```
|
38
|
+
|
21
39
|
With element returned:
|
22
40
|
|
23
41
|
```ruby
|
@@ -50,10 +68,20 @@ With 5 seconds delay of how long to waiting for DOM to start modifying:
|
|
50
68
|
browser.div(class: 'test').when_dom_changed(delay: 5).a(class: 'link').click
|
51
69
|
```
|
52
70
|
|
71
|
+
Timeouts can also be specified statically:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
Watir::Dom::Wait.timeout = 1
|
75
|
+
Watir::Dom::Wait.delay = 1
|
76
|
+
Watir::Dom::Wait.interval = 0.15
|
77
|
+
```
|
78
|
+
|
53
79
|
## How it works
|
54
80
|
|
55
81
|
By attaching `DOMSubtreeModified` event to element. It's supported in all major browsers (except Presto-powered Opera).
|
56
82
|
|
83
|
+
Note, that it also rescues `Selenium::WebDriver::Error::StaleElementReferenceError` when waits for DOM.
|
84
|
+
|
57
85
|
## Contributors
|
58
86
|
|
59
87
|
* [Alex Rodionov](https://github.com/p0deje)
|
@@ -29,18 +29,21 @@ module Watir
|
|
29
29
|
|
30
30
|
def when_dom_changed(opts = {})
|
31
31
|
message = "waiting for DOM subtree to finish modifying in #{selector_string}"
|
32
|
-
opts[:timeout] ||=
|
33
|
-
opts[:interval] ||=
|
34
|
-
opts[:delay] ||=
|
32
|
+
opts[:timeout] ||= Dom::Wait.timeout
|
33
|
+
opts[:interval] ||= Dom::Wait.interval
|
34
|
+
opts[:delay] ||= Dom::Wait.delay
|
35
35
|
|
36
36
|
if block_given?
|
37
37
|
js = Dom::Wait::JAVASCRIPT.dup
|
38
38
|
browser.execute_script js, self, opts[:interval], opts[:delay]
|
39
|
-
|
39
|
+
Wait.until(opts[:timeout], message) { browser.execute_script(Dom::Wait::DOM_READY) == 0 }
|
40
40
|
yield self
|
41
41
|
else
|
42
42
|
WhenDOMChangedDecorator.new(self, opts, message)
|
43
43
|
end
|
44
|
+
|
45
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
46
|
+
locate
|
44
47
|
end
|
45
48
|
|
46
49
|
#
|
@@ -53,8 +56,9 @@ module Watir
|
|
53
56
|
#
|
54
57
|
|
55
58
|
def wait_until_dom_changed(opts = {})
|
56
|
-
when_dom_changed(opts)
|
57
|
-
|
59
|
+
when_dom_changed(opts) do
|
60
|
+
# just trigger waiting
|
61
|
+
end
|
58
62
|
end
|
59
63
|
|
60
64
|
end # Element
|
data/lib/watir/dom/wait.rb
CHANGED
@@ -9,6 +9,26 @@ module Watir
|
|
9
9
|
JAVASCRIPT = File.read("#{File.dirname(__FILE__)}/extensions/js/waitForDom.js")
|
10
10
|
DOM_READY = "return watir.domReady;"
|
11
11
|
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
attr_writer :timeout
|
16
|
+
attr_writer :interval
|
17
|
+
attr_writer :delay
|
18
|
+
|
19
|
+
def timeout
|
20
|
+
@timeout ||= 30
|
21
|
+
end
|
22
|
+
|
23
|
+
def interval
|
24
|
+
@interval ||= 0.5
|
25
|
+
end
|
26
|
+
|
27
|
+
def delay
|
28
|
+
@delay ||= 1
|
29
|
+
end
|
30
|
+
|
31
|
+
end # << self
|
12
32
|
end # Wait
|
13
33
|
end # Dom
|
14
34
|
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,7 @@ require "watir/dom/wait"
|
|
3
3
|
RSpec.configure do |spec|
|
4
4
|
spec.before(:all) do
|
5
5
|
@browser = Watir::Browser.new
|
6
|
-
@browser.goto "data:text/html,#{File.read('spec/html/wait_for_dom.html')}"
|
6
|
+
@browser.goto "data:text/html,#{File.read('spec/support/html/wait_for_dom.html')}"
|
7
7
|
end
|
8
8
|
|
9
9
|
spec.after(:all) do
|
@@ -0,0 +1,46 @@
|
|
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(id, number, timeout) {
|
7
|
+
var timer = setInterval(function() {
|
8
|
+
var div = document.getElementById(id);
|
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
|
+
|
20
|
+
function staleDiv(parent_id, child_id) {
|
21
|
+
var parent = document.getElementById(parent_id);
|
22
|
+
var child = document.getElementById(child_id);
|
23
|
+
var new_div = document.createElement("div");
|
24
|
+
new_div.id = child_id;
|
25
|
+
new_div.style = 'display: block;';
|
26
|
+
|
27
|
+
setTimeout(function() {
|
28
|
+
parent.removeChild(child);
|
29
|
+
parent.appendChild(new_div);
|
30
|
+
}, 1000);
|
31
|
+
}
|
32
|
+
</script>
|
33
|
+
</head>
|
34
|
+
|
35
|
+
<body>
|
36
|
+
<div id="container1">
|
37
|
+
<div id="container2"></div>
|
38
|
+
</div>
|
39
|
+
<br />
|
40
|
+
<button onclick="modifySubtree('container1', 5, 1000);" id="long">Start modifying subtree with 5 node operations and 1000 ms delay between them</button>
|
41
|
+
<br />
|
42
|
+
<button onclick="modifySubtree('container1', 20, 100);" id="quick">Start modifying subtree with 20 node operations and 100 ms delay between them</button>
|
43
|
+
<br />
|
44
|
+
<button onclick="modifySubtree('container2', 20, 100); staleDiv('container1', 'container2');" id="stale">Start modifying and then update child div</button>
|
45
|
+
</body>
|
46
|
+
</html>
|
@@ -5,52 +5,52 @@ 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 event handler" do
|
8
|
-
@browser.button(:id
|
8
|
+
@browser.button(:id => "quick").click
|
9
9
|
@browser.div.when_dom_changed.should have(20).spans
|
10
10
|
end
|
11
11
|
|
12
12
|
it "may be run more than one time" do
|
13
13
|
3.times do |i|
|
14
|
-
@browser.button(:id
|
14
|
+
@browser.button(:id => "quick").click
|
15
15
|
@browser.div.when_dom_changed.should have(20 * (i + 1)).spans
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
it "waits using custom interval" do
|
20
|
-
@browser.button(:id
|
20
|
+
@browser.button(:id => "long").click
|
21
21
|
@browser.div.when_dom_changed(:interval => 1.1).should have(5).spans
|
22
22
|
end
|
23
23
|
|
24
24
|
it "raises timeout error" do
|
25
|
-
@browser.button(:id
|
25
|
+
@browser.button(:id => "quick").click
|
26
26
|
lambda { @browser.div.when_dom_changed(:timeout => 2).spans }.should raise_error(Watir::Wait::TimeoutError)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
context "when block given" do
|
31
31
|
it "waits using event handler" do
|
32
|
-
@browser.button(:id
|
32
|
+
@browser.button(:id => "quick").click
|
33
33
|
@browser.div.when_dom_changed do |div|
|
34
34
|
div.should have(20).spans
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
it "waits using custom interval" do
|
39
|
-
@browser.button(:id
|
39
|
+
@browser.button(:id => "long").click
|
40
40
|
@browser.div.when_dom_changed(:interval => 1.1) do |div|
|
41
41
|
div.should have(5).spans
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
it "raises timeout error" do
|
46
|
-
@browser.button(:id
|
46
|
+
@browser.button(:id => "quick").click
|
47
47
|
lambda do
|
48
48
|
@browser.div.when_dom_changed(:timeout => 2) { |div| div.spans }
|
49
49
|
end.should raise_error(Watir::Wait::TimeoutError)
|
50
50
|
end
|
51
51
|
|
52
52
|
it "returns block evaluation" do
|
53
|
-
@browser.button(:id
|
53
|
+
@browser.button(:id => "quick").click
|
54
54
|
@browser.div.when_dom_changed do |div|
|
55
55
|
div.spans.size
|
56
56
|
end.should == 20
|
@@ -63,6 +63,25 @@ describe Watir::Element do
|
|
63
63
|
@browser.div.when_dom_changed.should have(0).spans
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
context "when element goes stale" do
|
68
|
+
before(:all) do
|
69
|
+
Watir.always_locate = false
|
70
|
+
end
|
71
|
+
|
72
|
+
after(:all) do
|
73
|
+
Watir.always_locate = true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "relocates element" do
|
77
|
+
div = @browser.div(:id => 'container2')
|
78
|
+
div.exists?
|
79
|
+
@browser.refresh
|
80
|
+
lambda do
|
81
|
+
div.when_dom_changed.text
|
82
|
+
end.should_not raise_error(Selenium::WebDriver::Error::StaleElementReferenceError)
|
83
|
+
end
|
84
|
+
end
|
66
85
|
end
|
67
86
|
|
68
87
|
describe "#wait_until_dom_changed" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watir-dom-wait
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: watir-webdriver
|
@@ -92,9 +92,9 @@ files:
|
|
92
92
|
- lib/watir/dom/extensions/js/waitForDom.js
|
93
93
|
- lib/watir/dom/wait.rb
|
94
94
|
- lib/watir/dom/wait/version.rb
|
95
|
-
- spec/html/wait_for_dom.html
|
96
95
|
- spec/spec_helper.rb
|
97
|
-
- spec/
|
96
|
+
- spec/support/html/wait_for_dom.html
|
97
|
+
- spec/watir-dom-wait/element_spec.rb
|
98
98
|
- watir-dom-wait.gemspec
|
99
99
|
homepage: https://github.com/p0deje/watir-dom-wait
|
100
100
|
licenses:
|
@@ -111,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
111
|
version: '0'
|
112
112
|
segments:
|
113
113
|
- 0
|
114
|
-
hash:
|
114
|
+
hash: 3291543436130083017
|
115
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
120
|
version: '0'
|
121
121
|
segments:
|
122
122
|
- 0
|
123
|
-
hash:
|
123
|
+
hash: 3291543436130083017
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project:
|
126
126
|
rubygems_version: 1.8.23
|
@@ -128,6 +128,6 @@ signing_key:
|
|
128
128
|
specification_version: 3
|
129
129
|
summary: Watir extension providing with DOM-based waiting
|
130
130
|
test_files:
|
131
|
-
- spec/html/wait_for_dom.html
|
132
131
|
- spec/spec_helper.rb
|
133
|
-
- spec/
|
132
|
+
- spec/support/html/wait_for_dom.html
|
133
|
+
- spec/watir-dom-wait/element_spec.rb
|
data/spec/html/wait_for_dom.html
DELETED
@@ -1,29 +0,0 @@
|
|
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>
|