watir 6.16.0 → 6.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/CHANGES.md +6 -0
  4. data/LICENSE +1 -0
  5. data/README.md +1 -0
  6. data/appveyor.yml +0 -1
  7. data/lib/watir.rb +7 -12
  8. data/lib/watir/browser.rb +4 -1
  9. data/lib/watir/element_collection.rb +22 -4
  10. data/lib/watir/elements/element.rb +1 -1
  11. data/lib/watir/elements/iframe.rb +1 -0
  12. data/lib/watir/elements/select.rb +2 -1
  13. data/lib/watir/js_snippets/getElementTags.js +3 -0
  14. data/lib/watir/legacy_wait.rb +6 -5
  15. data/lib/watir/locators/element/matcher.rb +4 -4
  16. data/lib/watir/locators/element/selector_builder.rb +2 -0
  17. data/lib/watir/locators/element/selector_builder/xpath.rb +0 -5
  18. data/lib/watir/version.rb +1 -1
  19. data/spec/spec_helper.rb +15 -15
  20. data/spec/unit/match_elements/element_spec.rb +57 -1
  21. data/spec/unit/selector_builder/element_spec.rb +6 -4
  22. data/spec/watirspec/after_hooks_spec.rb +22 -0
  23. data/spec/watirspec/alert_spec.rb +1 -1
  24. data/spec/watirspec/browser_spec.rb +1 -1
  25. data/spec/watirspec/elements/button_spec.rb +7 -2
  26. data/spec/watirspec/elements/checkbox_spec.rb +20 -0
  27. data/spec/watirspec/elements/checkboxes_spec.rb +1 -1
  28. data/spec/watirspec/elements/collections_spec.rb +49 -0
  29. data/spec/watirspec/elements/div_spec.rb +11 -6
  30. data/spec/watirspec/elements/element_spec.rb +16 -10
  31. data/spec/watirspec/elements/iframe_spec.rb +2 -1
  32. data/spec/watirspec/elements/labels_spec.rb +1 -1
  33. data/spec/watirspec/elements/table_spec.rb +0 -1
  34. data/spec/watirspec/html/forms_with_input_elements.html +11 -0
  35. data/spec/watirspec/relaxed_locate_spec.rb +1 -1
  36. data/spec/watirspec/support/rspec_matchers.rb +3 -0
  37. data/spec/watirspec/window_switching_spec.rb +4 -4
  38. data/spec/watirspec_helper.rb +10 -4
  39. data/watir.gemspec +3 -3
  40. metadata +7 -7
  41. data/spec/watirspec/click_spec.rb +0 -19
  42. data/support/appveyor.cmd +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63d608d81ce067739aacf522e62047450f0c0599
4
- data.tar.gz: 135b27602f2a190dd6aa15401d93ecb0fbbd68a9
3
+ metadata.gz: d2b4db146f289ef46ceb5bf9b9faabdad94743ba
4
+ data.tar.gz: 4b54ec483198de8c748bffdfda298770c4c9c40e
5
5
  SHA512:
6
- metadata.gz: b294891e79600c34327a05b06f01929f136a18400695b7ff03428ed264c8f66c4fae06e48e7879d691eac491029af5913ba275515eb319596c410f1cc98ba6c9
7
- data.tar.gz: f258febcb8fbe41ff1ceacb3c96ada0ef27a8d19787e51bc45dd2d8f1901a64f5b76047a94446f427ce8338e4e4e5b4a85de12c9e83fe90283824cc40aeca402
6
+ metadata.gz: f1c78b53e3d1243c9a6dc0aa94d6844f174460798da81b76488449e34b2ca695b61e18bc8739a8ee2095d430a6d904bd8cd0cb3b6f8464129d7b1c5f3670c068
7
+ data.tar.gz: 26147c5fa67a6b6289488ad39eae1ec3ad2f82af18a886d6d13935658fdaf138a8a8278a8dda58a5a71b82f9467a3aa9bfc96e0e80aa5f0a321a4317c4202605
@@ -75,6 +75,7 @@ Metrics/ClassLength:
75
75
  - 'lib/watir/elements/element.rb'
76
76
  - 'lib/watir/elements/select.rb'
77
77
  - 'lib/watir/generator/base/spec_extractor.rb'
78
+ - 'lib/watir/element_collection.rb'
78
79
 
79
80
  Metrics/PerceivedComplexity:
80
81
  Max: 10
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  Copyright (c) 2009-2015 Jari Bakken
4
4
  Copyright (c) 2015-2018 Alex Rodionov, Titus Fortner
5
+ Copyright (c) 2018 Justin Ko
5
6
 
6
7
  Permission is hereby granted, free of charge, to any person obtaining
7
8
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -109,4 +109,5 @@ on wire calls.
109
109
 
110
110
  Copyright (c) 2009-2015 Jari Bakken
111
111
  Copyright (c) 2015-2018 Alex Rodionov, Titus Fortner
112
+ Copyright (c) 2018 Justin Ko
112
113
  See LICENSE for details
@@ -4,7 +4,6 @@ clone_depth: 100
4
4
  install:
5
5
  - set PATH=C:\Ruby23\bin;%PATH%
6
6
  - bundle install
7
- - support/appveyor.cmd
8
7
  test_script:
9
8
  - bundle exec rake %RAKE_TASK%
10
9
  environment:
@@ -46,12 +46,9 @@ module Watir
46
46
  end
47
47
 
48
48
  def always_locate_message
49
- msg = <<~ALWAYS_LOCATE.tr("\n", ' ')
50
- Watir#always_locate is deprecated; elements are always cached and will always
51
- be re-located if they go stale before use.
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 = <<~PREFER_CSS.tr("\n", ' ')
68
- Watir#prefer_css is deprecated; all elements that can not be passed directly
69
- as Selenium locators will be translated to XPath. To continue using CSS Selectors
70
- require the watir_css gem - https://github.com/watir/watir_css
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
  #
@@ -263,8 +263,11 @@ module Watir
263
263
  end
264
264
 
265
265
  def ensure_context
266
- driver.switch_to.default_content unless @default_context
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
- elements.map.with_index do |el, idx|
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 exists? # Performance shortcut
673
+ return if located? # Performance shortcut
674
674
 
675
675
  begin
676
676
  @query_scope.wait_for_exists unless @query_scope.is_a? Browser
@@ -128,6 +128,7 @@ module Watir
128
128
  def switch!
129
129
  @driver.switch_to.frame @element
130
130
  @browser.default_context = false
131
+ @browser.after_hooks.run
131
132
  rescue Selenium::WebDriver::Error::NoSuchFrameError => e
132
133
  raise UnknownFrameException, e.message
133
134
  end
@@ -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
- elements.first.exist? ? elements.first.text : ''
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
 
@@ -0,0 +1,3 @@
1
+ function(){
2
+ return arguments[0].map(function(e) {return e.localName});
3
+ }
@@ -77,9 +77,9 @@ module Watir
77
77
  #
78
78
 
79
79
  def when_present(timeout = nil)
80
- warning = '#when_present has been deprecated and is unlikely to be needed; '
81
- warning << 'replace this with #wait_until_present if a wait is still needed'
82
- Watir.logger.warn warning, ids: %i[when_present deprecations]
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
- Watir.logger.warn '#when_enabled has been deprecated and is unlikely to be needed',
109
- ids: %i[when_enabled deprecations]
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, matches) if values_to_match[:text]
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, matches)
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
- text_content_matches = text_content =~ /#{selector[:text]}/
117
- return if matches == !!text_content_matches
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
@@ -1,3 +1,3 @@
1
1
  module Watir
2
- VERSION = '6.16.0'.freeze
2
+ VERSION = '6.16.1'.freeze
3
3
  end
@@ -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
- require 'coveralls'
5
- require 'simplecov'
6
- require 'simplecov-console'
7
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [
8
- Coveralls::SimpleCov::Formatter,
9
- SimpleCov::Formatter::HTMLFormatter,
10
- SimpleCov::Formatter::Console
11
- ]
12
- SimpleCov.start do
13
- add_filter %r{/spec/}
14
- add_filter 'lib/watir/elements/html_elements.rb'
15
- add_filter 'lib/watir/elements/svg_elements.rb'
16
- add_filter 'lib/watir/legacy_wait.rb'
17
- add_filter 'lib/watirspec'
18
- refuse_coverage_drop
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(selector_builder.build(selector)).to eq built
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(selector_builder.build(selector)).to eq built
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
- not_compliant_on :not_relaxed_locate do
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
@@ -151,7 +151,7 @@ describe 'Browser' do
151
151
  end
152
152
 
153
153
  describe '#new' do
154
- not_compliant_on :remote do
154
+ not_compliant_on :remote, :appveyor do
155
155
  context 'with parameters' do
156
156
  let(:url) { 'http://localhost:4544/wd/hub/' }
157
157
 
@@ -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(browser.button(caption: 'Button 2')).to exist
44
- expect(browser.button(caption: /Button 2/)).to exist
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
@@ -13,7 +13,7 @@ describe 'CheckBoxes' do
13
13
 
14
14
  describe '#length' do
15
15
  it 'returns the number of checkboxes' do
16
- expect(browser.checkboxes.length).to eq 8
16
+ expect(browser.checkboxes.length).to eq 11
17
17
  end
18
18
  end
19
19
 
@@ -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/).exists? }.not_to have_deprecated_text_regexp
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$/).exists? }.to have_deprecated_text_regexp
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 'throws deprecation when begins to be matched by text content' do
143
- expect { browser.div(text: /some hidden/).exists? }.to have_deprecated_text_regexp
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
- it 'does not throw deprecation when still not matched by text content' do
148
- expect { browser.div(text: /does not exist/).exists? }.not_to have_deprecated_text_regexp
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
- it 'relocates stale element when taking an action on it' do
44
- browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
45
- element = browser.text_field(id: 'new_user_first_name').locate
46
- browser.refresh
47
- expect { element.click }.not_to raise_exception
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(element).to_not exist
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
- it 'returns false if element\'s center is surrounded by non-descendants' do
925
- btn = browser.button(id: 'surrounded')
926
- expect(btn).not_to be_obscured
927
- expect { btn.click }.not_to raise_exception
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, apperas to be working in Nightly', %i[firefox linux] do
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
 
@@ -13,7 +13,7 @@ describe 'Labels' do
13
13
 
14
14
  describe '#length' do
15
15
  it 'returns the number of labels' do
16
- expect(browser.labels.length).to eq 42
16
+ expect(browser.labels.length).to eq 45
17
17
  end
18
18
  end
19
19
 
@@ -103,7 +103,6 @@ describe 'Table' do
103
103
 
104
104
  it 'finds rows belonging to this table' do
105
105
  expect(table.row(id: 'outer_last')).to exist
106
- table.row(text: 'Table 1, Row 1, Cell 1').locate
107
106
  expect(table.row(text: /Table 1, Row 1, Cell 1/)).to exist
108
107
  end
109
108
 
@@ -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>
@@ -1,7 +1,7 @@
1
1
  require 'watirspec_helper'
2
2
 
3
3
  describe 'Watir#relaxed_locate?' do
4
- not_compliant_on :not_relaxed_locate do
4
+ compliant_on :relaxed_locate do
5
5
  context 'when true' do
6
6
  before :each do
7
7
  browser.goto(WatirSpec.url_for('wait.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 be > 0
407
- expect(size.height).to be > 0
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 be >= 0
415
- expect(pos.y).to be >= 0
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
@@ -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 = [:webdriver]
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
@@ -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.4.2'
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.0
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-16 00:00:00.000000000 Z
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.4.2
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.4.2
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
@@ -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
- )