watir 6.16.0 → 6.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGES.md +6 -0
- data/LICENSE +1 -0
- data/README.md +1 -0
- data/appveyor.yml +0 -1
- data/lib/watir.rb +7 -12
- data/lib/watir/browser.rb +4 -1
- data/lib/watir/element_collection.rb +22 -4
- data/lib/watir/elements/element.rb +1 -1
- data/lib/watir/elements/iframe.rb +1 -0
- data/lib/watir/elements/select.rb +2 -1
- data/lib/watir/js_snippets/getElementTags.js +3 -0
- data/lib/watir/legacy_wait.rb +6 -5
- data/lib/watir/locators/element/matcher.rb +4 -4
- data/lib/watir/locators/element/selector_builder.rb +2 -0
- data/lib/watir/locators/element/selector_builder/xpath.rb +0 -5
- data/lib/watir/version.rb +1 -1
- data/spec/spec_helper.rb +15 -15
- data/spec/unit/match_elements/element_spec.rb +57 -1
- data/spec/unit/selector_builder/element_spec.rb +6 -4
- data/spec/watirspec/after_hooks_spec.rb +22 -0
- data/spec/watirspec/alert_spec.rb +1 -1
- data/spec/watirspec/browser_spec.rb +1 -1
- data/spec/watirspec/elements/button_spec.rb +7 -2
- data/spec/watirspec/elements/checkbox_spec.rb +20 -0
- data/spec/watirspec/elements/checkboxes_spec.rb +1 -1
- data/spec/watirspec/elements/collections_spec.rb +49 -0
- data/spec/watirspec/elements/div_spec.rb +11 -6
- data/spec/watirspec/elements/element_spec.rb +16 -10
- data/spec/watirspec/elements/iframe_spec.rb +2 -1
- data/spec/watirspec/elements/labels_spec.rb +1 -1
- data/spec/watirspec/elements/table_spec.rb +0 -1
- data/spec/watirspec/html/forms_with_input_elements.html +11 -0
- data/spec/watirspec/relaxed_locate_spec.rb +1 -1
- data/spec/watirspec/support/rspec_matchers.rb +3 -0
- data/spec/watirspec/window_switching_spec.rb +4 -4
- data/spec/watirspec_helper.rb +10 -4
- data/watir.gemspec +3 -3
- metadata +7 -7
- data/spec/watirspec/click_spec.rb +0 -19
- data/support/appveyor.cmd +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2b4db146f289ef46ceb5bf9b9faabdad94743ba
|
4
|
+
data.tar.gz: 4b54ec483198de8c748bffdfda298770c4c9c40e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1c78b53e3d1243c9a6dc0aa94d6844f174460798da81b76488449e34b2ca695b61e18bc8739a8ee2095d430a6d904bd8cd0cb3b6f8464129d7b1c5f3670c068
|
7
|
+
data.tar.gz: 26147c5fa67a6b6289488ad39eae1ec3ad2f82af18a886d6d13935658fdaf138a8a8278a8dda58a5a71b82f9467a3aa9bfc96e0e80aa5f0a321a4317c4202605
|
data/.rubocop.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### 6.16.1 (2018-12-23)
|
2
|
+
|
3
|
+
* Improve collection performance with JavaScript (thanks Lucas Tierney)
|
4
|
+
* Update deprecation warnings
|
5
|
+
* Improve performance when using previously located elements
|
6
|
+
|
1
7
|
### 6.16.0 (2018-12-16)
|
2
8
|
|
3
9
|
* Fix bug that did not re-locate Stale elements when taking an action on them (#814)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
data/appveyor.yml
CHANGED
data/lib/watir.rb
CHANGED
@@ -46,12 +46,9 @@ module Watir
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def always_locate_message
|
49
|
-
msg =
|
50
|
-
|
51
|
-
|
52
|
-
Use Element#stale? or Element#wait_until(&:stale?) if needed for flow control.
|
53
|
-
ALWAYS_LOCATE
|
54
|
-
Watir.logger.warn msg, ids: %i[always_locate deprecations]
|
49
|
+
msg = 'Watir#always_locate'
|
50
|
+
repl_msg = 'Element#stale? or Element#wait_until(&:stale?) if needed for flow control'
|
51
|
+
Watir.logger.deprecate msg, repl_msg, ids: [:always_locate]
|
55
52
|
end
|
56
53
|
|
57
54
|
#
|
@@ -64,12 +61,10 @@ module Watir
|
|
64
61
|
end
|
65
62
|
|
66
63
|
def prefer_css_message
|
67
|
-
msg =
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
PREFER_CSS
|
72
|
-
Watir.logger.warn msg, ids: %i[prefer_css deprecations]
|
64
|
+
msg = 'Watir#prefer_css'
|
65
|
+
repl_msg = 'watir_css gem - https://github.com/watir/watir_css'
|
66
|
+
|
67
|
+
Watir.logger.deprecate msg, repl_msg, ids: [:prefer_css]
|
73
68
|
end
|
74
69
|
|
75
70
|
#
|
data/lib/watir/browser.rb
CHANGED
@@ -263,8 +263,11 @@ module Watir
|
|
263
263
|
end
|
264
264
|
|
265
265
|
def ensure_context
|
266
|
-
|
266
|
+
return if @default_context
|
267
|
+
|
268
|
+
driver.switch_to.default_content
|
267
269
|
@default_context = true
|
270
|
+
after_hooks.run
|
268
271
|
end
|
269
272
|
|
270
273
|
#
|
@@ -5,6 +5,8 @@ module Watir
|
|
5
5
|
|
6
6
|
class ElementCollection
|
7
7
|
include Enumerable
|
8
|
+
include Exception
|
9
|
+
include JSSnippets
|
8
10
|
include Locators::ClassHelpers
|
9
11
|
|
10
12
|
def initialize(query_scope, selector)
|
@@ -92,12 +94,12 @@ module Watir
|
|
92
94
|
def to_a
|
93
95
|
hash = {}
|
94
96
|
@to_a ||=
|
95
|
-
|
97
|
+
elements_with_tags.map.with_index do |(el, tag_name), idx|
|
96
98
|
selector = @selector.dup
|
97
99
|
selector[:index] = idx unless idx.zero?
|
98
100
|
element = element_class.new(@query_scope, selector)
|
99
101
|
if [HTMLElement, Input].include? element.class
|
100
|
-
construct_subtype(element, hash).tap { |e| e.cache = el }
|
102
|
+
construct_subtype(element, hash, tag_name).tap { |e| e.cache = el }
|
101
103
|
else
|
102
104
|
element.tap { |e| e.cache = el }
|
103
105
|
end
|
@@ -162,6 +164,23 @@ module Watir
|
|
162
164
|
end
|
163
165
|
end
|
164
166
|
|
167
|
+
def elements_with_tags
|
168
|
+
els = elements
|
169
|
+
if @selector[:tag_name]
|
170
|
+
els.map { |e| [e, @selector[:tag_name]] }
|
171
|
+
else
|
172
|
+
retries = 0
|
173
|
+
begin
|
174
|
+
els.zip(execute_js(:getElementTags, els))
|
175
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
176
|
+
retries += 1
|
177
|
+
sleep 0.5
|
178
|
+
retry unless retries > 2
|
179
|
+
raise LocatorException, "Unable to locate element collection from #{@selector} due to changing page"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
165
184
|
def ensure_context
|
166
185
|
@query_scope.locate if @query_scope.relocate?
|
167
186
|
@query_scope.switch_to! if @query_scope.is_a?(IFrame)
|
@@ -175,9 +194,8 @@ module Watir
|
|
175
194
|
Kernel.const_get(self.class.name.sub(/Collection$/, ''))
|
176
195
|
end
|
177
196
|
|
178
|
-
def construct_subtype(element, hash)
|
197
|
+
def construct_subtype(element, hash, tag_name)
|
179
198
|
selector = element.selector
|
180
|
-
tag_name = selector[:tag_name] || element.tag_name
|
181
199
|
hash[tag_name] ||= 0
|
182
200
|
hash[tag_name] += 1
|
183
201
|
selector[:index] = hash[tag_name] - 1
|
@@ -670,7 +670,7 @@ module Watir
|
|
670
670
|
|
671
671
|
def wait_for_exists
|
672
672
|
return assert_exists unless Watir.relaxed_locate?
|
673
|
-
return if
|
673
|
+
return if located? # Performance shortcut
|
674
674
|
|
675
675
|
begin
|
676
676
|
@query_scope.wait_for_exists unless @query_scope.is_a? Browser
|
@@ -226,7 +226,8 @@ module Watir
|
|
226
226
|
def select_matching(elements)
|
227
227
|
elements = [elements.first] unless multiple?
|
228
228
|
elements.each { |e| e.click unless e.selected? }
|
229
|
-
|
229
|
+
# TODO: this can go back to #exist? after `:stale_exists` deprecation removed
|
230
|
+
elements.first.stale? ? '' : elements.first.text
|
230
231
|
end
|
231
232
|
end # Select
|
232
233
|
|
data/lib/watir/legacy_wait.rb
CHANGED
@@ -77,9 +77,9 @@ module Watir
|
|
77
77
|
#
|
78
78
|
|
79
79
|
def when_present(timeout = nil)
|
80
|
-
|
81
|
-
|
82
|
-
Watir.logger.
|
80
|
+
msg = '#when_present'
|
81
|
+
repl_msg = '#wait_until_present if a wait is still needed'
|
82
|
+
Watir.logger.deprecate msg, repl_msg, ids: [:when_present]
|
83
83
|
|
84
84
|
timeout ||= Watir.default_timeout
|
85
85
|
message = "waiting for #{selector_string} to become present"
|
@@ -105,8 +105,9 @@ module Watir
|
|
105
105
|
#
|
106
106
|
|
107
107
|
def when_enabled(timeout = nil)
|
108
|
-
|
109
|
-
|
108
|
+
msg = '#when_enabled'
|
109
|
+
repl_msg = 'wait_until(&:enabled?)'
|
110
|
+
Watir.logger.deprecate msg, repl_msg, ids: [:when_enabled]
|
110
111
|
|
111
112
|
timeout ||= Watir.default_timeout
|
112
113
|
message = "waiting for #{selector_string} to become enabled"
|
@@ -71,7 +71,7 @@ module Watir
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
deprecate_text_regexp(element, values_to_match
|
74
|
+
deprecate_text_regexp(element, values_to_match) if values_to_match[:text] && matches
|
75
75
|
|
76
76
|
matches
|
77
77
|
end
|
@@ -110,11 +110,11 @@ module Watir
|
|
110
110
|
matches_values?(element.tag_name.downcase, tag_name)
|
111
111
|
end
|
112
112
|
|
113
|
-
def deprecate_text_regexp(element, selector
|
113
|
+
def deprecate_text_regexp(element, selector)
|
114
114
|
new_element = Watir::Element.new(@query_scope, element: element)
|
115
115
|
text_content = new_element.text_content
|
116
|
-
|
117
|
-
return if
|
116
|
+
|
117
|
+
return if text_content =~ /#{selector[:text]}/
|
118
118
|
|
119
119
|
key = @selector.key?(:text) ? 'text' : 'label'
|
120
120
|
selector_text = selector[:text].inspect
|
@@ -126,6 +126,8 @@ module Watir
|
|
126
126
|
end
|
127
127
|
when :caption
|
128
128
|
# This allows any element to be located with 'caption' instead of 'text'
|
129
|
+
# It is deprecated because caption is a valid attribute on a Table
|
130
|
+
# It is also a valid Element, so it also needs to be removed from the Table attributes list
|
129
131
|
Watir.logger.deprecate('Locating elements with :caption', ':text locator', ids: [:caption])
|
130
132
|
[:text, what]
|
131
133
|
else
|
@@ -142,11 +142,6 @@ module Watir
|
|
142
142
|
|
143
143
|
# TODO: This conditional can be removed when we remove this deprecation
|
144
144
|
if label.is_a?(Regexp)
|
145
|
-
if @built.key?(:label_element)
|
146
|
-
dep = "Using :label locator with RegExp #{label} to match an element that includes hidden text"
|
147
|
-
Watir.logger.deprecate(dep, ":visible_#{key}", ids: [:text_regexp])
|
148
|
-
end
|
149
|
-
|
150
145
|
@built[:label_element] = label
|
151
146
|
''
|
152
147
|
else
|
data/lib/watir/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
|
4
|
-
|
5
|
-
require '
|
6
|
-
require 'simplecov
|
7
|
-
|
8
|
-
Coveralls::SimpleCov::Formatter,
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
4
|
+
if ENV['TRAVIS'] || ENV['COVERAGE']
|
5
|
+
require 'coveralls'
|
6
|
+
require 'simplecov'
|
7
|
+
require 'simplecov-console'
|
8
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [Coveralls::SimpleCov::Formatter,
|
9
|
+
SimpleCov::Formatter::HTMLFormatter,
|
10
|
+
SimpleCov::Formatter::Console]
|
11
|
+
SimpleCov.start do
|
12
|
+
add_filter %r{/spec/}
|
13
|
+
add_filter 'lib/watir/elements/html_elements.rb'
|
14
|
+
add_filter 'lib/watir/elements/svg_elements.rb'
|
15
|
+
add_filter 'lib/watir/legacy_wait.rb'
|
16
|
+
add_filter 'lib/watirspec'
|
17
|
+
refuse_coverage_drop
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
21
|
require 'watir'
|
@@ -5,7 +5,7 @@ describe Watir::Locators::Element::Matcher do
|
|
5
5
|
|
6
6
|
let(:query_scope) { @query_scope || browser }
|
7
7
|
let(:values_to_match) { @values_to_match || {} }
|
8
|
-
let(:matcher) { described_class.new(query_scope) }
|
8
|
+
let(:matcher) { described_class.new(query_scope, values_to_match) }
|
9
9
|
|
10
10
|
describe '#match' do
|
11
11
|
context 'a label element' do
|
@@ -364,5 +364,61 @@ describe Watir::Locators::Element::Matcher do
|
|
364
364
|
expect(matcher.match(elements, values_to_match, @filter)).to eq [elements[0], elements[2]]
|
365
365
|
end
|
366
366
|
end
|
367
|
+
|
368
|
+
# TODO: These should have the same tests for label locators, but the mocking is more complex
|
369
|
+
# See equivalent tests in checkbox_spec
|
370
|
+
context 'text_regexp deprecations' do
|
371
|
+
let(:filter) { :first }
|
372
|
+
let(:elements) do
|
373
|
+
[wd_element(text: 'all visible'),
|
374
|
+
wd_element(text: 'some visible')]
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'not thrown when still matched by text content' do
|
378
|
+
@values_to_match = {text: /some visible/}
|
379
|
+
allow(browser).to receive(:execute_script).and_return('some visible some hidden')
|
380
|
+
|
381
|
+
expect {
|
382
|
+
expect(matcher.match(elements, values_to_match, filter)).to eq elements[1]
|
383
|
+
}.not_to have_deprecated_text_regexp
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'not thrown with complex regexp matched by text content' do
|
387
|
+
@values_to_match = {text: /some (in|)visible/}
|
388
|
+
allow(browser).to receive(:execute_script).and_return('some visible some hidden')
|
389
|
+
|
390
|
+
expect {
|
391
|
+
expect(matcher.match(elements, values_to_match, filter)).to eq elements[1]
|
392
|
+
}.not_to have_deprecated_text_regexp
|
393
|
+
end
|
394
|
+
|
395
|
+
not_compliant_on :watigiri do
|
396
|
+
it 'thrown when no longer matched by text content' do
|
397
|
+
@values_to_match = {text: /some visible$/}
|
398
|
+
allow(browser).to receive(:execute_script).and_return('some visible some hidden')
|
399
|
+
|
400
|
+
expect {
|
401
|
+
expect(matcher.match(elements, values_to_match, filter)).to eq elements[1]
|
402
|
+
}.to have_deprecated_text_regexp
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
not_compliant_on :watigiri do
|
407
|
+
it 'not thrown when element does not exist' do
|
408
|
+
@values_to_match = {text: /definitely not there/}
|
409
|
+
|
410
|
+
expect {
|
411
|
+
expect(matcher.match(elements, values_to_match, filter)).to eq elements[1]
|
412
|
+
}.to_not have_deprecated_text_regexp
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
# Note: This will work after:text_regexp deprecation removed
|
417
|
+
it 'keeps element from being located' do
|
418
|
+
@values_to_match = {text: /some visible some hidden/}
|
419
|
+
|
420
|
+
expect(matcher.match(elements, values_to_match, filter)).to be_nil
|
421
|
+
end
|
422
|
+
end
|
367
423
|
end
|
368
424
|
end
|
@@ -95,12 +95,13 @@ describe Watir::Locators::Element::SelectorBuilder do
|
|
95
95
|
expect(selector_builder.build(selector)).to eq built
|
96
96
|
end
|
97
97
|
|
98
|
-
# TODO: This functionality is deprecated with "class_array"
|
99
98
|
it 'values with spaces' do
|
100
99
|
selector = {class_name: 'multiple classes here'}
|
101
100
|
built = {xpath: ".//*[contains(concat(' ', @class, ' '), ' multiple classes here ')]"}
|
102
101
|
|
103
|
-
expect
|
102
|
+
expect {
|
103
|
+
expect(selector_builder.build(selector)).to eq built
|
104
|
+
}.to have_deprecated_class_array
|
104
105
|
end
|
105
106
|
|
106
107
|
it 'single String concatenates' do
|
@@ -280,12 +281,13 @@ describe Watir::Locators::Element::SelectorBuilder do
|
|
280
281
|
expect(selector_builder.build(selector)).to eq built
|
281
282
|
end
|
282
283
|
|
283
|
-
# Deprecated with :caption
|
284
284
|
it 'with caption attribute' do
|
285
285
|
selector = {caption: 'Add user'}
|
286
286
|
built = {xpath: ".//*[normalize-space()='Add user']"}
|
287
287
|
|
288
|
-
expect
|
288
|
+
expect {
|
289
|
+
expect(selector_builder.build(selector)).to eq built
|
290
|
+
}.to have_deprecated_caption
|
289
291
|
end
|
290
292
|
|
291
293
|
it 'raises exception when text is not a String or Regexp' do
|
@@ -113,6 +113,28 @@ describe 'Browser::AfterHooks' do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
it 'runs after_hooks after FramedDriver#switch!' do
|
117
|
+
browser.goto(WatirSpec.url_for('iframes.html'))
|
118
|
+
@page_after_hook = proc { @yield = browser.title == 'Iframes' }
|
119
|
+
browser.after_hooks.add @page_after_hook
|
120
|
+
|
121
|
+
browser.iframe.element(css: '#senderElement').exists?
|
122
|
+
|
123
|
+
expect(@yield).to be true
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'runs after_hooks after Browser#ensure_context if not @default_context' do
|
127
|
+
browser.goto(WatirSpec.url_for('iframes.html'))
|
128
|
+
browser.iframe.element(css: '#senderElement').locate
|
129
|
+
|
130
|
+
@page_after_hook = proc { @yield = browser.title == 'Iframes' }
|
131
|
+
browser.after_hooks.add @page_after_hook
|
132
|
+
|
133
|
+
browser.locate
|
134
|
+
|
135
|
+
expect(@yield).to be true
|
136
|
+
end
|
137
|
+
|
116
138
|
not_compliant_on :headless do
|
117
139
|
it 'runs after_hooks after Alert#ok' do
|
118
140
|
browser.goto(WatirSpec.url_for('alerts.html'))
|
@@ -10,7 +10,7 @@ not_compliant_on :headless do
|
|
10
10
|
browser.alert.ok if browser.alert.exists?
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
compliant_on :relaxed_locate do
|
14
14
|
context 'Relaxed Waits' do
|
15
15
|
context 'when acting on an alert' do
|
16
16
|
it 'raises exception after timing out' do
|
@@ -40,8 +40,13 @@ describe 'Button' do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'returns true if the button exists (how = :caption)' do
|
43
|
-
expect
|
44
|
-
|
43
|
+
expect {
|
44
|
+
expect(browser.button(caption: 'Button 2')).to exist
|
45
|
+
}.to have_deprecated_caption
|
46
|
+
|
47
|
+
expect {
|
48
|
+
expect(browser.button(caption: /Button 2/)).to exist
|
49
|
+
}.to have_deprecated_caption
|
45
50
|
end
|
46
51
|
|
47
52
|
it 'returns the first button if given no args' do
|
@@ -26,6 +26,26 @@ describe 'CheckBox' do
|
|
26
26
|
expect(browser.checkbox(xpath: "//input[@id='new_user_interests_books']")).to exist
|
27
27
|
end
|
28
28
|
|
29
|
+
it 'handles text_regexp deprecations for label locators' do
|
30
|
+
expect {
|
31
|
+
expect(browser.checkbox(label: /some visible/)).to exist
|
32
|
+
}.to_not have_deprecated_text_regexp
|
33
|
+
|
34
|
+
expect {
|
35
|
+
expect(browser.checkbox(label: /some (visible|Jeff)/)).to exist
|
36
|
+
}.to_not have_deprecated_text_regexp
|
37
|
+
|
38
|
+
expect {
|
39
|
+
expect(browser.checkbox(label: /this will not match/)).to exist
|
40
|
+
}.to_not have_deprecated_text_regexp
|
41
|
+
|
42
|
+
expect(browser.checkbox(label: /some visible some hidden/)).to_not exist
|
43
|
+
|
44
|
+
expect {
|
45
|
+
expect(browser.checkbox(label: /some visible$/)).to exist
|
46
|
+
}.to have_deprecated_text_regexp
|
47
|
+
end
|
48
|
+
|
29
49
|
it 'returns true if the checkbox button exists (search by name and value)' do
|
30
50
|
expect(browser.checkbox(name: 'new_user_interests', value: 'cars')).to exist
|
31
51
|
browser.checkbox(xpath: "//input[@name='new_user_interests' and @value='cars']").set
|
@@ -17,6 +17,14 @@ describe 'Collections' do
|
|
17
17
|
expect(collection.all? { |el| el.is_a? Watir::Span }).to eq true
|
18
18
|
end
|
19
19
|
|
20
|
+
it 'returns correct subtype of elements without tag_name' do
|
21
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
22
|
+
collection = browser.span(id: 'a_span').elements
|
23
|
+
collection.locate
|
24
|
+
expect(collection.first).to be_a Watir::Div
|
25
|
+
expect(collection.last).to be_a Watir::Span
|
26
|
+
end
|
27
|
+
|
20
28
|
it 'can contain more than one type of element' do
|
21
29
|
browser.goto(WatirSpec.url_for('nested_elements.html'))
|
22
30
|
collection = browser.div(id: 'parent').children
|
@@ -71,4 +79,45 @@ describe 'Collections' do
|
|
71
79
|
expect(elements[1]).to be_stale
|
72
80
|
expect { elements[1] }.to_not raise_unknown_object_exception
|
73
81
|
end
|
82
|
+
|
83
|
+
it 'does not retrieve tag_name on elements when specifying tag_name' do
|
84
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
85
|
+
collection = browser.span(id: 'a_span').spans
|
86
|
+
|
87
|
+
expect_any_instance_of(Selenium::WebDriver::Element).to_not receive(:tag_name)
|
88
|
+
collection.locate
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'does not retrieve tag_name on elements without specifying tag_name' do
|
92
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
93
|
+
collection = browser.span(id: 'a_span').elements
|
94
|
+
|
95
|
+
expect_any_instance_of(Selenium::WebDriver::Element).to_not receive(:tag_name)
|
96
|
+
collection.locate
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'does not execute_script to retrieve tag_names when specifying tag_name' do
|
100
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
101
|
+
collection = browser.span(id: 'a_span').spans
|
102
|
+
|
103
|
+
expect(browser.wd).to_not receive(:execute_script)
|
104
|
+
collection.locate
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns correct containers without specifying tag_name' do
|
108
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
109
|
+
elements = browser.span(id: 'a_span').elements.to_a
|
110
|
+
expect(elements[0]).to be_a(Watir::Div)
|
111
|
+
expect(elements[-1]).to be_a(Watir::Span)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'Raises Exception if any element in collection continues to go stale' do
|
115
|
+
browser.goto(WatirSpec.url_for('collections.html'))
|
116
|
+
|
117
|
+
stale_exception = Selenium::WebDriver::Error::StaleElementReferenceError
|
118
|
+
expect(browser.wd).to receive(:execute_script).and_raise(stale_exception).exactly(3).times
|
119
|
+
|
120
|
+
msg = 'Unable to locate element collection from {:xpath=>".//span"} due to changing page'
|
121
|
+
expect { browser.span.elements(xpath: './/span').to_a }.to raise_exception Watir::Exception::LocatorException, msg
|
122
|
+
end
|
74
123
|
end
|
@@ -129,23 +129,28 @@ describe 'Div' do
|
|
129
129
|
describe 'Deprecation Warnings' do
|
130
130
|
describe 'text locator with RegExp values' do
|
131
131
|
it 'does not throw deprecation when still matched by text content' do
|
132
|
-
expect { browser.div(text: /some visible/).
|
132
|
+
expect { browser.div(text: /some visible/).locate }.not_to have_deprecated_text_regexp
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'does not throw deprecation with complex regexp matched by text content' do
|
136
|
+
expect { browser.div(text: /some (in|)visible/).locate }.not_to have_deprecated_text_regexp
|
133
137
|
end
|
134
138
|
|
135
139
|
not_compliant_on :watigiri do
|
136
140
|
it 'throws deprecation when no longer matched by text content' do
|
137
|
-
expect { browser.div(text: /some visible$/).
|
141
|
+
expect { browser.div(text: /some visible$/).locate }.to have_deprecated_text_regexp
|
138
142
|
end
|
139
143
|
end
|
140
144
|
|
141
145
|
not_compliant_on :watigiri do
|
142
|
-
it '
|
143
|
-
expect { browser.div(text: /
|
146
|
+
it 'does not throw deprecation when element does not exist' do
|
147
|
+
expect { browser.div(text: /definitely not there/).locate }.not_to have_deprecated_text_regexp
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
147
|
-
|
148
|
-
|
151
|
+
# Note: This will work after:text_regexp deprecation removed
|
152
|
+
it 'does not locate entire content with regular expressions' do
|
153
|
+
expect(browser.div(text: /some visible some hidden/)).to_not exist
|
149
154
|
end
|
150
155
|
end
|
151
156
|
end
|
@@ -40,11 +40,13 @@ describe 'Element' do
|
|
40
40
|
expect { element.text }.to_not raise_error
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
compliant_on :relaxed_locate do
|
44
|
+
it 'relocates stale element when taking an action on it' do
|
45
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
46
|
+
element = browser.text_field(id: 'new_user_first_name').locate
|
47
|
+
browser.refresh
|
48
|
+
expect { element.click }.not_to raise_exception
|
49
|
+
end
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -293,7 +295,9 @@ describe 'Element' do
|
|
293
295
|
element.cache = wd
|
294
296
|
|
295
297
|
browser.refresh
|
296
|
-
expect
|
298
|
+
expect {
|
299
|
+
expect(element).to_not exist
|
300
|
+
}.to have_deprecated_stale_exists
|
297
301
|
end
|
298
302
|
end
|
299
303
|
|
@@ -921,10 +925,12 @@ describe 'Element' do
|
|
921
925
|
end
|
922
926
|
end
|
923
927
|
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
+
not_compliant_on %i[firefox appveyor] do
|
929
|
+
it 'returns false if element\'s center is surrounded by non-descendants' do
|
930
|
+
btn = browser.button(id: 'surrounded')
|
931
|
+
expect(btn).not_to be_obscured
|
932
|
+
expect { btn.click }.not_to raise_exception
|
933
|
+
end
|
928
934
|
end
|
929
935
|
|
930
936
|
it 'scrolls interactive element into view before checking if obscured' do
|
@@ -10,7 +10,8 @@ describe 'IFrame' do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
not_compliant_on :safari do
|
13
|
-
bug 'Firefox 58 broke this,
|
13
|
+
bug 'Firefox 58 broke this, appears to be working in Nightly',
|
14
|
+
%i[firefox linux], %i[firefox appveyor] do
|
14
15
|
it 'handles crossframe javascript' do
|
15
16
|
browser.goto WatirSpec.url_for('iframes.html')
|
16
17
|
|
@@ -178,5 +178,16 @@
|
|
178
178
|
<select id="single-quote">
|
179
179
|
<option>'foo'</option>
|
180
180
|
</select>
|
181
|
+
|
182
|
+
<fieldset id="visible_label">
|
183
|
+
<label for="all_visible_label">all visible</label>
|
184
|
+
<input type="checkbox" id="all_visible_label">
|
185
|
+
|
186
|
+
<label for="some_visible_label">some visible<span style="display:none;"> some hidden</span></label>
|
187
|
+
<input type="checkbox" id="some_visible_label">
|
188
|
+
|
189
|
+
<label for="no_visible_label" style="display:none;">none visible</label>
|
190
|
+
<input type="checkbox" id="no_visible_label">
|
191
|
+
</fieldset>
|
181
192
|
</body>
|
182
193
|
</html>
|
@@ -2,6 +2,7 @@ if defined?(RSpec)
|
|
2
2
|
DEPRECATION_WARNINGS = %i[selector_parameters
|
3
3
|
element_cache
|
4
4
|
ready_state
|
5
|
+
caption
|
5
6
|
class_array
|
6
7
|
use_capabilities
|
7
8
|
visible_text
|
@@ -26,6 +27,8 @@ if defined?(RSpec)
|
|
26
27
|
end
|
27
28
|
|
28
29
|
failure_message do |_actual|
|
30
|
+
return 'unexpected exception in the custom matcher block' unless @stdout_message
|
31
|
+
|
29
32
|
deprecations_found = @stdout_message[/WARN Watir \[DEPRECATION\] ([^.*\ ]*)/, 1]
|
30
33
|
but_message = if deprecations_found.nil?
|
31
34
|
'no Warnings were found'
|
@@ -403,16 +403,16 @@ describe 'Window' do
|
|
403
403
|
it 'should get the size of the current window' do
|
404
404
|
size = browser.window.size
|
405
405
|
|
406
|
-
expect(size.width).to
|
407
|
-
expect(size.height).to
|
406
|
+
expect(size.width).to eq browser.execute_script('return window.outerWidth;')
|
407
|
+
expect(size.height).to eq browser.execute_script('return window.outerHeight;')
|
408
408
|
end
|
409
409
|
end
|
410
410
|
|
411
411
|
it 'should get the position of the current window' do
|
412
412
|
pos = browser.window.position
|
413
413
|
|
414
|
-
expect(pos.x).to
|
415
|
-
expect(pos.y).to
|
414
|
+
expect(pos.x).to eq browser.execute_script('return window.screenX;')
|
415
|
+
expect(pos.y).to eq browser.execute_script('return window.screenY;')
|
416
416
|
end
|
417
417
|
|
418
418
|
not_compliant_on :headless do
|
data/spec/watirspec_helper.rb
CHANGED
@@ -29,9 +29,13 @@ class LocalConfig
|
|
29
29
|
def load_webdrivers
|
30
30
|
case browser
|
31
31
|
when :chrome
|
32
|
+
Webdrivers::Chromedriver.version = 2.44 if ENV['APPVEYOR']
|
32
33
|
Webdrivers::Chromedriver.update
|
34
|
+
Watir.logger.info "chromedriver version: #{Webdrivers::Chromedriver.current_version.version}"
|
33
35
|
when :firefox
|
36
|
+
Webdrivers::Geckodriver.version = '0.20.1' if ENV['APPVEYOR']
|
34
37
|
Webdrivers::Geckodriver.update
|
38
|
+
Watir.logger.info "geckodriver version: #{Webdrivers::Geckodriver.current_version.version}"
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
@@ -78,13 +82,15 @@ class LocalConfig
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def common_guards
|
81
|
-
matching_guards = [
|
82
|
-
|
83
|
-
matching_guards << browser
|
85
|
+
matching_guards = [browser]
|
84
86
|
matching_guards << [browser, Selenium::WebDriver::Platform.os]
|
85
87
|
matching_guards << :relaxed_locate if Watir.relaxed_locate?
|
86
|
-
matching_guards << :not_relaxed_locate unless Watir.relaxed_locate?
|
87
88
|
matching_guards << :headless if @imp.browser_args.last[:headless]
|
89
|
+
# TODO: Replace this with Selenium::WebDriver::Platform.ci after next Selenium Release
|
90
|
+
if ENV['APPVEYOR']
|
91
|
+
matching_guards << :appveyor
|
92
|
+
matching_guards << [browser, :appveyor]
|
93
|
+
end
|
88
94
|
|
89
95
|
if !Selenium::WebDriver::Platform.linux? || ENV['DESKTOP_SESSION']
|
90
96
|
# some specs (i.e. Window#maximize) needs a window manager on linux
|
data/watir.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.required_ruby_version = '>= 2.3.0'
|
10
10
|
|
11
11
|
s.platform = Gem::Platform::RUBY
|
12
|
-
s.authors = ['Alex Rodionov', 'Titus Fortner']
|
13
|
-
s.email = ['p0deje@gmail.com', 'titusfortner@gmail.com']
|
12
|
+
s.authors = ['Alex Rodionov', 'Titus Fortner', 'Justin Ko']
|
13
|
+
s.email = ['p0deje@gmail.com', 'titusfortner@gmail.com', 'jkotests@gmail.com ']
|
14
14
|
s.homepage = 'http://github.com/watir/watir'
|
15
15
|
s.summary = 'Watir powered by Selenium'
|
16
16
|
s.description = <<~DESCRIPTION_MESSAGE
|
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
s.add_development_dependency 'selenium_statistics'
|
42
42
|
s.add_development_dependency 'simplecov'
|
43
43
|
s.add_development_dependency 'simplecov-console'
|
44
|
-
s.add_development_dependency 'webdrivers', '~> 3.
|
44
|
+
s.add_development_dependency 'webdrivers', '~> 3.5.2'
|
45
45
|
s.add_development_dependency 'webidl', '>= 0.2.2'
|
46
46
|
s.add_development_dependency 'yard', '> 0.8.2.1'
|
47
47
|
s.add_development_dependency 'yard-doctest', '>= 0.1.8'
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.16.
|
4
|
+
version: 6.16.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Rodionov
|
8
8
|
- Titus Fortner
|
9
|
+
- Justin Ko
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2018-12-
|
13
|
+
date: 2018-12-23 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: selenium-webdriver
|
@@ -219,14 +220,14 @@ dependencies:
|
|
219
220
|
requirements:
|
220
221
|
- - "~>"
|
221
222
|
- !ruby/object:Gem::Version
|
222
|
-
version: 3.
|
223
|
+
version: 3.5.2
|
223
224
|
type: :development
|
224
225
|
prerelease: false
|
225
226
|
version_requirements: !ruby/object:Gem::Requirement
|
226
227
|
requirements:
|
227
228
|
- - "~>"
|
228
229
|
- !ruby/object:Gem::Version
|
229
|
-
version: 3.
|
230
|
+
version: 3.5.2
|
230
231
|
- !ruby/object:Gem::Dependency
|
231
232
|
name: webidl
|
232
233
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,6 +276,7 @@ description: |
|
|
275
276
|
email:
|
276
277
|
- p0deje@gmail.com
|
277
278
|
- titusfortner@gmail.com
|
279
|
+
- 'jkotests@gmail.com '
|
278
280
|
executables: []
|
279
281
|
extensions: []
|
280
282
|
extra_rdoc_files: []
|
@@ -357,6 +359,7 @@ files:
|
|
357
359
|
- lib/watir/js_snippets/elementObscured.js
|
358
360
|
- lib/watir/js_snippets/fireEvent.js
|
359
361
|
- lib/watir/js_snippets/focus.js
|
362
|
+
- lib/watir/js_snippets/getElementTags.js
|
360
363
|
- lib/watir/js_snippets/getInnerHtml.js
|
361
364
|
- lib/watir/js_snippets/getInnerText.js
|
362
365
|
- lib/watir/js_snippets/getOuterHtml.js
|
@@ -434,7 +437,6 @@ files:
|
|
434
437
|
- spec/watirspec/alert_spec.rb
|
435
438
|
- spec/watirspec/attributes_spec.rb
|
436
439
|
- spec/watirspec/browser_spec.rb
|
437
|
-
- spec/watirspec/click_spec.rb
|
438
440
|
- spec/watirspec/cookies_spec.rb
|
439
441
|
- spec/watirspec/drag_and_drop_spec.rb
|
440
442
|
- spec/watirspec/element_hidden_spec.rb
|
@@ -595,7 +597,6 @@ files:
|
|
595
597
|
- spec/watirspec/wait_spec.rb
|
596
598
|
- spec/watirspec/window_switching_spec.rb
|
597
599
|
- spec/watirspec_helper.rb
|
598
|
-
- support/appveyor.cmd
|
599
600
|
- support/doctest_helper.rb
|
600
601
|
- support/travis.sh
|
601
602
|
- support/version_differ.rb
|
@@ -649,7 +650,6 @@ test_files:
|
|
649
650
|
- spec/watirspec/alert_spec.rb
|
650
651
|
- spec/watirspec/attributes_spec.rb
|
651
652
|
- spec/watirspec/browser_spec.rb
|
652
|
-
- spec/watirspec/click_spec.rb
|
653
653
|
- spec/watirspec/cookies_spec.rb
|
654
654
|
- spec/watirspec/drag_and_drop_spec.rb
|
655
655
|
- spec/watirspec/element_hidden_spec.rb
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'watirspec_helper'
|
2
|
-
|
3
|
-
describe Watir::Element do
|
4
|
-
describe '#click' do
|
5
|
-
before do
|
6
|
-
browser.goto WatirSpec.url_for('clicks.html')
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:clicker) { browser.element(id: 'click-logger') }
|
10
|
-
let(:log) { browser.element(id: 'log').ps.map(&:text) }
|
11
|
-
|
12
|
-
bug 'https://github.com/watir/watir/issues/343', :webdriver do
|
13
|
-
it 'clicks an element with text in nested text node using text selector' do
|
14
|
-
browser.element(text: 'Can You Click This?').click
|
15
|
-
expect(browser.element(text: 'You Clicked It!')).to exist
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/support/appveyor.cmd
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
if "%RAKE_TASK%"=="spec:firefox" (
|
2
|
-
choco install -y curl
|
3
|
-
choco install -y 7zip.commandline
|
4
|
-
curl -L -O --insecure https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-win32.zip
|
5
|
-
7za e geckodriver-v0.11.1-win32.zip
|
6
|
-
move geckodriver.exe C:\Tools\WebDriver
|
7
|
-
|
8
|
-
geckodriver.exe --version
|
9
|
-
)
|