watir 6.14.0 → 6.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +24 -6
  3. data/CHANGES.md +10 -0
  4. data/Gemfile +0 -2
  5. data/README.md +1 -1
  6. data/Rakefile +2 -2
  7. data/lib/watir.rb +2 -3
  8. data/lib/watir/adjacent.rb +2 -2
  9. data/lib/watir/alert.rb +5 -9
  10. data/lib/watir/attribute_helper.rb +2 -3
  11. data/lib/watir/browser.rb +5 -17
  12. data/lib/watir/capabilities.rb +11 -0
  13. data/lib/watir/cell_container.rb +2 -2
  14. data/lib/watir/container.rb +7 -8
  15. data/lib/watir/cookies.rb +2 -12
  16. data/lib/watir/element_collection.rb +2 -2
  17. data/lib/watir/elements/button.rb +2 -11
  18. data/lib/watir/elements/element.rb +43 -25
  19. data/lib/watir/elements/hidden.rb +1 -1
  20. data/lib/watir/elements/iframe.rb +7 -5
  21. data/lib/watir/elements/option.rb +2 -13
  22. data/lib/watir/elements/select.rb +6 -22
  23. data/lib/watir/elements/table.rb +2 -2
  24. data/lib/watir/exception.rb +1 -2
  25. data/lib/watir/generator/base/idl_sorter.rb +1 -1
  26. data/lib/watir/generator/base/spec_extractor.rb +2 -2
  27. data/lib/watir/generator/base/visitor.rb +1 -1
  28. data/lib/watir/generator/html/generator.rb +0 -1
  29. data/lib/watir/generator/html/spec_extractor.rb +1 -1
  30. data/lib/watir/generator/html/visitor.rb +1 -1
  31. data/lib/watir/generator/svg/spec_extractor.rb +1 -1
  32. data/lib/watir/generator/svg/visitor.rb +1 -1
  33. data/lib/watir/js_execution.rb +11 -0
  34. data/lib/watir/js_snippets.rb +1 -1
  35. data/lib/watir/js_snippets/elementObscured.js +14 -0
  36. data/lib/watir/js_snippets/selectedText.js +17 -0
  37. data/lib/watir/legacy_wait.rb +5 -5
  38. data/lib/watir/locators.rb +16 -5
  39. data/lib/watir/locators/anchor/selector_builder.rb +38 -0
  40. data/lib/watir/locators/button/locator.rb +14 -12
  41. data/lib/watir/locators/button/selector_builder.rb +0 -22
  42. data/lib/watir/locators/button/selector_builder/xpath.rb +67 -12
  43. data/lib/watir/locators/button/validator.rb +2 -1
  44. data/lib/watir/locators/cell/selector_builder.rb +0 -14
  45. data/lib/watir/locators/cell/selector_builder/xpath.rb +21 -0
  46. data/lib/watir/locators/element/locator.rb +60 -153
  47. data/lib/watir/locators/element/selector_builder.rb +103 -84
  48. data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +66 -0
  49. data/lib/watir/locators/element/selector_builder/xpath.rb +195 -82
  50. data/lib/watir/locators/element/selector_builder/xpath_support.rb +27 -0
  51. data/lib/watir/locators/element/validator.rb +2 -9
  52. data/lib/watir/locators/row/selector_builder.rb +5 -22
  53. data/lib/watir/locators/row/selector_builder/xpath.rb +53 -0
  54. data/lib/watir/locators/text_area/selector_builder.rb +1 -1
  55. data/lib/watir/locators/text_area/selector_builder/xpath.rb +19 -0
  56. data/lib/watir/locators/text_field/locator.rb +11 -8
  57. data/lib/watir/locators/text_field/selector_builder.rb +0 -23
  58. data/lib/watir/locators/text_field/selector_builder/xpath.rb +33 -4
  59. data/lib/watir/locators/text_field/validator.rb +4 -4
  60. data/lib/watir/radio_set.rb +5 -5
  61. data/lib/watir/row_container.rb +2 -2
  62. data/lib/watir/user_editable.rb +2 -2
  63. data/lib/watir/version.rb +1 -1
  64. data/lib/watir/wait.rb +24 -37
  65. data/lib/watir/window.rb +11 -8
  66. data/lib/watirspec/remote_server.rb +3 -1
  67. data/spec/locator_spec_helper.rb +1 -1
  68. data/spec/spec_helper.rb +25 -1
  69. data/spec/unit/anchor_locator_spec.rb +68 -0
  70. data/spec/unit/capabilities_spec.rb +27 -0
  71. data/spec/unit/element_locator_spec.rb +184 -101
  72. data/spec/unit/logger_spec.rb +5 -0
  73. data/spec/watirspec/adjacent_spec.rb +34 -34
  74. data/spec/watirspec/after_hooks_spec.rb +78 -35
  75. data/spec/watirspec/alert_spec.rb +10 -0
  76. data/spec/watirspec/browser_spec.rb +27 -1
  77. data/spec/watirspec/element_hidden_spec.rb +6 -0
  78. data/spec/watirspec/elements/button_spec.rb +5 -11
  79. data/spec/watirspec/elements/buttons_spec.rb +1 -1
  80. data/spec/watirspec/elements/checkbox_spec.rb +2 -15
  81. data/spec/watirspec/elements/date_time_field_spec.rb +6 -1
  82. data/spec/watirspec/elements/dd_spec.rb +0 -17
  83. data/spec/watirspec/elements/del_spec.rb +0 -14
  84. data/spec/watirspec/elements/div_spec.rb +0 -18
  85. data/spec/watirspec/elements/dl_spec.rb +0 -17
  86. data/spec/watirspec/elements/dt_spec.rb +0 -17
  87. data/spec/watirspec/elements/element_spec.rb +177 -17
  88. data/spec/watirspec/elements/elements_spec.rb +7 -6
  89. data/spec/watirspec/elements/em_spec.rb +0 -13
  90. data/spec/watirspec/elements/filefield_spec.rb +0 -11
  91. data/spec/watirspec/elements/form_spec.rb +6 -0
  92. data/spec/watirspec/elements/hn_spec.rb +0 -14
  93. data/spec/watirspec/elements/iframe_spec.rb +15 -0
  94. data/spec/watirspec/elements/ins_spec.rb +0 -14
  95. data/spec/watirspec/elements/labels_spec.rb +1 -1
  96. data/spec/watirspec/elements/li_spec.rb +0 -14
  97. data/spec/watirspec/elements/link_spec.rb +22 -14
  98. data/spec/watirspec/elements/links_spec.rb +13 -0
  99. data/spec/watirspec/elements/list_spec.rb +15 -0
  100. data/spec/watirspec/elements/ol_spec.rb +0 -14
  101. data/spec/watirspec/elements/option_spec.rb +0 -10
  102. data/spec/watirspec/elements/p_spec.rb +0 -14
  103. data/spec/watirspec/elements/pre_spec.rb +0 -14
  104. data/spec/watirspec/elements/radio_spec.rb +0 -14
  105. data/spec/watirspec/elements/select_list_spec.rb +0 -10
  106. data/spec/watirspec/elements/span_spec.rb +4 -15
  107. data/spec/watirspec/elements/strong_spec.rb +4 -15
  108. data/spec/watirspec/elements/table_nesting_spec.rb +1 -1
  109. data/spec/watirspec/elements/table_spec.rb +7 -0
  110. data/spec/watirspec/elements/text_field_spec.rb +10 -2
  111. data/spec/watirspec/elements/text_fields_spec.rb +1 -1
  112. data/spec/watirspec/elements/tr_spec.rb +1 -1
  113. data/spec/watirspec/elements/ul_spec.rb +0 -14
  114. data/spec/watirspec/html/closeable.html +8 -0
  115. data/spec/watirspec/html/forms_with_input_elements.html +28 -23
  116. data/spec/watirspec/html/nested_elements.html +9 -9
  117. data/spec/watirspec/html/obscured.html +34 -0
  118. data/spec/watirspec/html/tables.html +13 -13
  119. data/spec/watirspec/radio_set_spec.rb +5 -0
  120. data/spec/watirspec/selector_builder/button_spec.rb +254 -0
  121. data/spec/watirspec/selector_builder/cell_spec.rb +93 -0
  122. data/spec/watirspec/selector_builder/element_spec.rb +639 -0
  123. data/spec/watirspec/selector_builder/row_spec.rb +150 -0
  124. data/spec/watirspec/selector_builder/text_spec.rb +170 -0
  125. data/spec/watirspec/support/rspec_matchers.rb +6 -1
  126. data/spec/watirspec/user_editable_spec.rb +4 -0
  127. data/spec/watirspec/wait_spec.rb +65 -14
  128. data/spec/watirspec/window_switching_spec.rb +54 -1
  129. data/spec/watirspec_helper.rb +2 -0
  130. data/watir.gemspec +7 -1
  131. metadata +86 -8
  132. data/lib/watir/locators/text_area/locator.rb +0 -13
  133. data/lib/watir/xpath_support.rb +0 -18
@@ -0,0 +1,27 @@
1
+ module Watir
2
+ module Locators
3
+ class Element
4
+ class SelectorBuilder
5
+ module XpathSupport
6
+ UPPERCASE_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'.freeze
7
+ LOWERCASE_LETTERS = 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'.freeze
8
+
9
+ def self.escape(value)
10
+ if value.include? "'"
11
+ parts = value.split("'", -1).map { |part| "'#{part}'" }
12
+ string = parts.join(%(,"'",))
13
+
14
+ "concat(#{string})"
15
+ else
16
+ "'#{value}'"
17
+ end
18
+ end
19
+
20
+ def self.downcase(value)
21
+ "translate(#{value},'#{UPPERCASE_LETTERS}','#{LOWERCASE_LETTERS}')"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end # XpathSupport
27
+ end # Watir
@@ -2,15 +2,8 @@ module Watir
2
2
  module Locators
3
3
  class Element
4
4
  class Validator
5
- def validate(element, selector)
6
- selector_tag_name = selector[:tag_name]
7
- element_tag_name = element.tag_name.downcase
8
-
9
- if selector_tag_name
10
- return unless element_tag_name =~ /#{selector_tag_name}/
11
- end
12
-
13
- element
5
+ def validate(element, tag_name)
6
+ element.tag_name.downcase =~ /#{tag_name}/
14
7
  end
15
8
  end
16
9
  end
@@ -2,30 +2,13 @@ module Watir
2
2
  module Locators
3
3
  class Row
4
4
  class SelectorBuilder < Element::SelectorBuilder
5
- def build_wd_selector(selectors)
6
- return if selectors.values.any? { |e| e.is_a? Regexp }
7
-
8
- selectors.delete(:tag_name) || raise('internal error: no tag_name?!')
9
-
10
- expressions = generate_expressions(@query_scope.tag_name.downcase)
11
-
12
- attr_expr = xpath_builder.attribute_expression(nil, selectors)
13
-
14
- expressions.map! { |e| "#{e}[#{attr_expr}]" } unless attr_expr.empty?
15
-
16
- xpath = expressions.join(' | ')
17
-
18
- p build_wd_selector: xpath if $DEBUG
19
-
20
- [:xpath, xpath]
5
+ def initialize(valid_attributes, scope_tag_name)
6
+ @scope_tag_name = scope_tag_name
7
+ super(valid_attributes)
21
8
  end
22
9
 
23
- protected
24
-
25
- def generate_expressions(tag_name)
26
- expressions = %w[./tr]
27
- expressions += %w[./tbody/tr ./thead/tr ./tfoot/tr] unless %w[tbody tfoot thead].include?(tag_name)
28
- expressions
10
+ def build_wd_selector(selector)
11
+ Kernel.const_get("#{self.class.name}::XPath").new.build(selector, @scope_tag_name)
29
12
  end
30
13
  end
31
14
  end
@@ -0,0 +1,53 @@
1
+ module Watir
2
+ module Locators
3
+ class Row
4
+ class SelectorBuilder
5
+ class XPath < Element::SelectorBuilder::XPath
6
+ def build(selector, scope_tag_name)
7
+ return super(selector) if selector.key?(:adjacent)
8
+
9
+ index = selector.delete(:index)
10
+
11
+ common_string = super(selector)[:xpath]
12
+ expressions = generate_expressions(scope_tag_name)
13
+ expressions.map! { |e| "#{e}#{common_string}" } unless common_string.empty?
14
+
15
+ xpath = expressions.join(' | ').to_s
16
+
17
+ xpath = index ? add_index(xpath, index) : xpath
18
+
19
+ @selector.merge! @requires_matches
20
+
21
+ {xpath: xpath}
22
+ end
23
+
24
+ private
25
+
26
+ def start_string
27
+ @adjacent ? './' : ''
28
+ end
29
+
30
+ def text_string
31
+ return super if @adjacent
32
+
33
+ # Can not directly locate a Row with Text because all text is in the Cells;
34
+ # needs to use Locator#locate_matching_elements
35
+ @requires_matches[:text] = @selector.delete(:text) if @selector.key?(:text)
36
+ ''
37
+ end
38
+
39
+ def generate_expressions(scope_tag_name)
40
+ if %w[tbody tfoot thead].include?(scope_tag_name)
41
+ ["./*[local-name()='tr']"]
42
+ else
43
+ ["./*[local-name()='tr']",
44
+ "./*[local-name()='tbody']/*[local-name()='tr']",
45
+ "./*[local-name()='thead']/*[local-name()='tr']",
46
+ "./*[local-name()='tfoot']/*[local-name()='tr']"]
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -4,7 +4,7 @@ module Watir
4
4
  class SelectorBuilder < Element::SelectorBuilder
5
5
  private
6
6
 
7
- def normalize_selector(how, what)
7
+ def normalize_locator(how, what)
8
8
  # We need to iterate through located elements and fetch
9
9
  # attribute value using Selenium because XPath doesn't understand
10
10
  # difference between IDL vs content attribute.
@@ -0,0 +1,19 @@
1
+ module Watir
2
+ module Locators
3
+ class TextArea
4
+ class SelectorBuilder
5
+ class XPath < Element::SelectorBuilder::XPath
6
+ private
7
+
8
+ # value always requires a wire call since we want the property not the attribute
9
+ def predicate_conversion(key, regexp)
10
+ return super unless key == :value
11
+
12
+ @requires_matches[:value] = regexp
13
+ nil
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -8,20 +8,23 @@ module Watir
8
8
  # force Watir usage
9
9
  end
10
10
 
11
- def matches_selector?(element, rx_selector)
12
- rx_selector = rx_selector.dup
11
+ def matches_values?(element, rx_selector)
12
+ conversions = %i[text value label visible_text] & rx_selector.keys
13
13
 
14
- tag_name = element.tag_name.downcase
14
+ tag_name = nil
15
15
 
16
- %i[text value label].each do |key|
17
- if rx_selector.key?(key)
18
- correct_key = tag_name == 'input' ? :value : :text
19
- rx_selector[correct_key] = rx_selector.delete(key)
20
- end
16
+ conversions.each do |key|
17
+ tag_name ||= element.tag_name.downcase
18
+ correct_key = tag_name == 'input' ? :value : :text
19
+ rx_selector[correct_key] = rx_selector.delete(key)
21
20
  end
22
21
 
23
22
  super
24
23
  end
24
+
25
+ def text_regexp_deprecation(*)
26
+ # does not apply to text_field
27
+ end
25
28
  end
26
29
  end
27
30
  end
@@ -2,29 +2,6 @@ module Watir
2
2
  module Locators
3
3
  class TextField
4
4
  class SelectorBuilder < Element::SelectorBuilder
5
- def build_wd_selector(selectors)
6
- return if selectors.values.any? { |e| e.is_a? Regexp }
7
-
8
- selectors.delete(:tag_name)
9
-
10
- input_attr_exp = xpath_builder.attribute_expression(:input, selectors)
11
-
12
- xpath = ".//input[(not(@type) or (#{negative_type_expr}))"
13
- xpath << " and #{input_attr_exp}" unless input_attr_exp.empty?
14
- xpath << ']'
15
-
16
- p build_wd_selector: xpath if $DEBUG
17
-
18
- [:xpath, xpath]
19
- end
20
-
21
- private
22
-
23
- def negative_type_expr
24
- Watir::TextField::NON_TEXT_TYPES.map { |type|
25
- format('%s!=%s', XpathSupport.downcase('@type'), type.inspect)
26
- }.join(' and ')
27
- end
28
5
  end
29
6
  end
30
7
  end
@@ -3,13 +3,42 @@ module Watir
3
3
  class TextField
4
4
  class SelectorBuilder
5
5
  class XPath < Element::SelectorBuilder::XPath
6
- def lhs_for(building, key)
7
- if building == :input && key == :text
8
- '@value'
6
+ def text_string
7
+ return super if @adjacent
8
+
9
+ @requires_matches[:text] = @selector.delete(:text) if @selector.key?(:text)
10
+ ''
11
+ end
12
+
13
+ def additional_string
14
+ return '' if @adjacent
15
+
16
+ type_string(@selector.delete(:type))
17
+ end
18
+
19
+ def tag_string
20
+ @selector[:tag_name] = 'input' unless @adjacent
21
+ super
22
+ end
23
+
24
+ def type_string(type)
25
+ if type.eql?(true)
26
+ "[#{negative_type_text}]"
27
+ elsif Watir::TextField::NON_TEXT_TYPES.include?(type)
28
+ msg = "TextField Elements can not be located by type: #{type}"
29
+ raise LocatorException, msg
30
+ elsif type.nil?
31
+ "[not(@type) or (#{negative_type_text})]"
9
32
  else
10
- super
33
+ "[#{process_attribute(:type, type)}]"
11
34
  end
12
35
  end
36
+
37
+ def negative_type_text
38
+ Watir::TextField::NON_TEXT_TYPES.map { |type|
39
+ "#{lhs_for(:type, true)}!=#{SelectorBuilder::XpathSupport.escape type}"
40
+ }.join(' and ')
41
+ end
13
42
  end
14
43
  end
15
44
  end
@@ -2,10 +2,10 @@ module Watir
2
2
  module Locators
3
3
  class TextField
4
4
  class Validator < Element::Validator
5
- def validate(element, _selector)
6
- return unless element.tag_name.casecmp('input').zero?
7
-
8
- element
5
+ def validate(element, _tag_name)
6
+ # Zero for Ruby 2.3, Ruby 2.4+ this evaluates true/false
7
+ result = element.tag_name.casecmp('input')
8
+ result.zero? || result.eq(true)
9
9
  end
10
10
  end
11
11
  end
@@ -1,7 +1,7 @@
1
1
  module Watir
2
2
  class RadioSet
3
3
  extend Forwardable
4
- include Watir::Exception
4
+ include Exception
5
5
  include Enumerable
6
6
 
7
7
  delegate %i[exists? present? visible? browser] => :source
@@ -12,7 +12,7 @@ module Watir
12
12
  raise ArgumentError, "invalid argument: #{selector.inspect}" unless selector.is_a? Hash
13
13
 
14
14
  @source = Radio.new(query_scope, selector)
15
- @frame = @source.parent(tag_name: :form)
15
+ @frame = @source.parent(tag_name: 'form')
16
16
  end
17
17
 
18
18
  #
@@ -52,7 +52,7 @@ module Watir
52
52
  elsif n.empty?
53
53
  return source
54
54
  else
55
- raise Watir::Exception::UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}"
55
+ raise UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}"
56
56
  end
57
57
  end
58
58
 
@@ -65,9 +65,9 @@ module Watir
65
65
  if !n.empty? && (!opt[:name] || opt[:name] == n)
66
66
  element_call(:wait_for_present) { frame.radios(opt.merge(name: n)) }
67
67
  elsif n.empty?
68
- Watir::RadioCollection.new(frame, element: source.wd)
68
+ RadioCollection.new(frame, element: source.wd)
69
69
  else
70
- raise Watir::Exception::UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}"
70
+ raise UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}"
71
71
  end
72
72
  end
73
73
 
@@ -5,7 +5,7 @@ module Watir
5
5
  #
6
6
 
7
7
  def row(*args)
8
- Row.new(self, extract_selector(args).merge(tag_name: 'tr'))
8
+ Row.new(self, extract_selector(args))
9
9
  end
10
10
 
11
11
  #
@@ -13,7 +13,7 @@ module Watir
13
13
  #
14
14
 
15
15
  def rows(*args)
16
- RowCollection.new(self, extract_selector(args).merge(tag_name: 'tr'))
16
+ RowCollection.new(self, extract_selector(args))
17
17
  end
18
18
 
19
19
  #
@@ -33,7 +33,7 @@ module Watir
33
33
  append(input_value[-1])
34
34
  return if value == input_value
35
35
 
36
- raise Watir::Exception::Error, "#set! value: '#{value}' does not match expected input: '#{input_value}'"
36
+ raise Exception::Error, "#set! value: '#{value}' does not match expected input: '#{input_value}'"
37
37
  end
38
38
 
39
39
  #
@@ -66,7 +66,7 @@ module Watir
66
66
  element_call { execute_js(:setText, @element, input_text) }
67
67
  return if text == input_text
68
68
 
69
- raise Watir::Exception::Error, "#set! text: '#{text}' does not match expected input: '#{input_text}'"
69
+ raise Exception::Error, "#set! text: '#{text}' does not match expected input: '#{input_text}'"
70
70
  end
71
71
  end # UserEditable
72
72
  end # Watir
@@ -1,3 +1,3 @@
1
1
  module Watir
2
- VERSION = '6.14.0'.freeze
2
+ VERSION = '6.15.0'.freeze
3
3
  end
@@ -121,7 +121,7 @@ module Watir
121
121
 
122
122
  raise ArgumentError, "Unknown keyword(s): #{opt.keys} " if block_given? && !opt.empty?
123
123
 
124
- proc = block_given? ? blk : create_proc(opt)
124
+ proc = create_proc(opt, &blk)
125
125
 
126
126
  Wait.until(timeout: timeout, message: message, interval: interval, object: self, &proc)
127
127
 
@@ -151,9 +151,7 @@ module Watir
151
151
  end
152
152
  message ||= proc { |obj| "waiting for false condition on #{obj.inspect}" }
153
153
 
154
- raise ArgumentError, "Unknown keyword(s): #{opt.keys} " if block_given? && !opt.empty?
155
-
156
- proc = block_given? ? blk : create_proc(opt)
154
+ proc = create_proc(opt, &blk)
157
155
 
158
156
  Wait.while(timeout: timeout, message: message, interval: interval, object: self, &proc)
159
157
 
@@ -176,22 +174,13 @@ module Watir
176
174
  #
177
175
 
178
176
  def wait_until_present(depr_timeout = nil, timeout: nil, interval: nil, message: nil)
179
- if depr_timeout
180
- Watir.logger.deprecate 'Using arguments for #wait_until_present', 'keywords', ids: [:timeout_arguments]
181
- timeout = depr_timeout
182
- end
183
- if is_a? Watir::Element
184
- message ||= proc { |obj| "waiting for element #{obj.inspect} to become present" }
185
- wait_until(timeout: timeout, interval: interval, message: message) do
186
- reset! if is_a? Watir::Element
187
- present?
188
- end
189
- else
190
- Watir.logger.deprecate "#{self.class}#wait_until_present",
191
- "#{self.class}#wait_until(&:present?)",
192
- ids: [:wait_until_present]
193
- wait_until(timeout: timeout, interval: interval, message: message, &:present?)
194
- end
177
+ timeout = depr_timeout if depr_timeout
178
+ Watir.logger.deprecate "#{self.class}#wait_until_present",
179
+ "#{self.class}#wait_until(&:present?)",
180
+ ids: [:wait_until_present]
181
+
182
+ message ||= proc { |obj| "waiting for #{obj.inspect} to become present" }
183
+ wait_until(timeout: timeout, interval: interval, message: message, &:present?)
195
184
  end
196
185
 
197
186
  #
@@ -210,31 +199,29 @@ module Watir
210
199
  #
211
200
 
212
201
  def wait_while_present(depr_timeout = nil, timeout: nil, interval: nil, message: nil)
213
- if depr_timeout
214
- Watir.logger.deprecate 'Using arguments for #wait_while_present', 'keywords', ids: [:timeout_arguments]
215
- timeout = depr_timeout
216
- end
217
- if is_a? Watir::Element
218
- message ||= proc { |obj| "waiting for element #{obj.inspect} not to be present" }
219
- wait_while(timeout: timeout, interval: interval, message: message) do
220
- reset! if is_a? Watir::Element
221
- present?
222
- end
223
- else
224
- Watir.logger.deprecate "#{self.class}#wait_while_present",
225
- "#{self.class}#wait_while(&:present?)",
226
- ids: [:wait_while_present]
227
- wait_while(timeout: timeout, interval: interval, message: message, &:present?)
228
- end
202
+ timeout = depr_timeout if depr_timeout
203
+ Watir.logger.deprecate "#{self.class}#wait_while_present",
204
+ "#{self.class}#wait_while(&:present?)",
205
+ ids: [:wait_while_present]
206
+
207
+ message ||= proc { |obj| "waiting for #{obj.inspect} not to be present" }
208
+ wait_while(timeout: timeout, interval: interval, message: message, &:present?)
229
209
  end
230
210
 
231
211
  private
232
212
 
233
213
  def create_proc(opt)
214
+ proc do
215
+ reset! if is_a?(Element)
216
+ (opt.empty? || match_attributes(opt).call) && (!block_given? || yield(self))
217
+ end
218
+ end
219
+
220
+ def match_attributes(opt)
234
221
  proc do
235
222
  opt.keys.all? do |key|
236
223
  expected = opt[key]
237
- actual = if is_a?(Watir::Element) && !respond_to?(key)
224
+ actual = if is_a?(Element) && !respond_to?(key)
238
225
  attribute_value(key)
239
226
  else
240
227
  send(key)