watir 6.14.0 → 6.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -45,7 +45,14 @@ module Watir
45
45
  #
46
46
 
47
47
  def exists?
48
- return false if located? && stale?
48
+ if located? && stale?
49
+ Watir.logger.deprecate 'Checking `#exists? == false` to determine a stale element',
50
+ '`#stale? == true`',
51
+ reference: 'http://watir.com/staleness-changes',
52
+ ids: [:stale_exists]
53
+ # TODO: Change this to `reset!` after removing deprecation
54
+ return false
55
+ end
49
56
 
50
57
  assert_exists
51
58
  true
@@ -246,15 +253,13 @@ module Watir
246
253
  end
247
254
 
248
255
  #
249
- # Returns value of the element.
256
+ # Returns list of class values.
250
257
  #
251
- # @return [String]
258
+ # @return [Array]
252
259
  #
253
260
 
254
- def value
255
- attribute_value('value') || ''
256
- rescue Selenium::WebDriver::Error::InvalidElementStateError
257
- ''
261
+ def classes
262
+ class_name.split
258
263
  end
259
264
 
260
265
  #
@@ -448,7 +453,7 @@ module Watir
448
453
  Watir.logger.warn msg, ids: [:visible_element]
449
454
  displayed = display_check
450
455
  if displayed.nil? && display_check
451
- Watir.logger.deprecate 'Checking `#present? == false` to determine a stale element',
456
+ Watir.logger.deprecate 'Checking `#visible? == false` to determine a stale element',
452
457
  '`#stale? == true`',
453
458
  reference: 'http://watir.com/staleness-changes',
454
459
  ids: [:stale_visible]
@@ -490,6 +495,21 @@ module Watir
490
495
  false
491
496
  end
492
497
 
498
+ #
499
+ # Returns true if the element's center point is covered by a non-descendant element.
500
+ #
501
+ # @return [Boolean]
502
+ #
503
+
504
+ def obscured?
505
+ element_call do
506
+ return true unless present?
507
+
508
+ scroll_into_view
509
+ execute_js(:elementObscured, self)
510
+ end
511
+ end
512
+
493
513
  #
494
514
  # Returns given style property of this element.
495
515
  #
@@ -557,7 +577,7 @@ module Watir
557
577
  #
558
578
 
559
579
  def stale?
560
- raise Watir::Exception::Error, 'Can not check staleness of unused element' unless @element
580
+ raise Error, 'Can not check staleness of unused element' unless @element
561
581
 
562
582
  ensure_context
563
583
  stale_in_context?
@@ -581,6 +601,7 @@ module Watir
581
601
  def locate
582
602
  ensure_context
583
603
  locate_in_context
604
+ self
584
605
  end
585
606
 
586
607
  #
@@ -627,7 +648,7 @@ module Watir
627
648
  begin
628
649
  @query_scope.wait_for_exists unless @query_scope.is_a? Browser
629
650
  wait_until(&:exists?)
630
- rescue Watir::Wait::TimeoutError
651
+ rescue Wait::TimeoutError
631
652
  msg = "timed out after #{Watir.default_timeout} seconds, waiting for #{inspect} to be located"
632
653
  raise unknown_exception, msg
633
654
  end
@@ -639,8 +660,8 @@ module Watir
639
660
 
640
661
  begin
641
662
  @query_scope.wait_for_present unless @query_scope.is_a? Browser
642
- wait_until_present
643
- rescue Watir::Wait::TimeoutError
663
+ wait_until(&:present?)
664
+ rescue Wait::TimeoutError
644
665
  msg = "element located, but timed out after #{Watir.default_timeout} seconds, " \
645
666
  "waiting for #{inspect} to be present"
646
667
  raise unknown_exception, msg
@@ -651,11 +672,12 @@ module Watir
651
672
  return assert_enabled unless Watir.relaxed_locate?
652
673
 
653
674
  wait_for_exists
654
- return if [Input, Button, Select, Option].none? { |c| is_a? c }
675
+ return unless [Input, Button, Select, Option].any? { |c| is_a? c } || @content_editable
676
+ return if enabled?
655
677
 
656
678
  begin
657
679
  wait_until(&:enabled?)
658
- rescue Watir::Wait::TimeoutError
680
+ rescue Wait::TimeoutError
659
681
  raise_disabled
660
682
  end
661
683
  end
@@ -666,12 +688,12 @@ module Watir
666
688
  raise_writable unless !respond_to?(:readonly?) || !readonly?
667
689
  end
668
690
 
691
+ return if !respond_to?(:readonly?) || !readonly?
692
+
669
693
  begin
670
694
  wait_until { !respond_to?(:readonly?) || !readonly? }
671
- rescue Watir::Wait::TimeoutError
672
- message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds, " \
673
- "waiting for #{inspect} to not be readonly"
674
- raise ObjectReadOnlyException, message
695
+ rescue Wait::TimeoutError
696
+ raise_writable
675
697
  end
676
698
  end
677
699
 
@@ -696,7 +718,7 @@ module Watir
696
718
  private
697
719
 
698
720
  def unknown_exception
699
- Watir::Exception::UnknownObjectException
721
+ UnknownObjectException
700
722
  end
701
723
 
702
724
  def raise_writable
@@ -721,16 +743,12 @@ module Watir
721
743
  self.class
722
744
  end
723
745
 
724
- def attribute?(attribute_name)
725
- !attribute_value(attribute_name).nil?
726
- end
727
-
728
746
  def assert_enabled
729
747
  raise ObjectDisabledException, "object is disabled #{inspect}" unless element_call { @element.enabled? }
730
748
  end
731
749
 
732
750
  def assert_is_element(obj)
733
- raise TypeError, "execpted Watir::Element, got #{obj.inspect}:#{obj.class}" unless obj.is_a? Watir::Element
751
+ raise TypeError, "execpted Watir::Element, got #{obj.inspect}:#{obj.class}" unless obj.is_a? Element
734
752
  end
735
753
 
736
754
  # Removes duplication in #present? & #visible? and makes setting deprecation notice easier
@@ -777,7 +795,7 @@ module Watir
777
795
  raise_disabled unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
778
796
  retry
779
797
  rescue Selenium::WebDriver::Error::NoSuchWindowError
780
- raise Exception::NoMatchingWindowFoundException, 'browser window was closed'
798
+ raise NoMatchingWindowFoundException, 'browser window was closed'
781
799
  ensure
782
800
  Watir.logger.info "<- `Completed #{inspect}##{caller}`"
783
801
  Wait.timer.reset! unless already_locked
@@ -5,7 +5,7 @@ module Watir
5
5
  end
6
6
 
7
7
  def click
8
- raise Watir::Exception::ObjectDisabledException, 'click is not available on the hidden field element'
8
+ raise ObjectDisabledException, 'click is not available on the hidden field element'
9
9
  end
10
10
  end
11
11
 
@@ -45,7 +45,7 @@ module Watir
45
45
  #
46
46
 
47
47
  def execute_script(script, *args)
48
- args.map! { |e| e.is_a?(Watir::Element) ? e.wd : e }
48
+ args.map! { |e| e.is_a?(Element) ? e.wd : e }
49
49
  returned = driver.execute_script(script, *args)
50
50
 
51
51
  browser.wrap_elements_in(self, returned)
@@ -77,7 +77,7 @@ module Watir
77
77
  private
78
78
 
79
79
  def unknown_exception
80
- Watir::Exception::UnknownFrameException
80
+ UnknownFrameException
81
81
  end
82
82
  end # IFrame
83
83
 
@@ -105,6 +105,8 @@ module Watir
105
105
  #
106
106
 
107
107
  class FramedDriver
108
+ include Exception
109
+
108
110
  def initialize(element, browser)
109
111
  @element = element
110
112
  @browser = browser
@@ -125,15 +127,15 @@ module Watir
125
127
  @driver.switch_to.frame @element
126
128
  @browser.default_context = false
127
129
  rescue Selenium::WebDriver::Error::NoSuchFrameError => e
128
- raise Exception::UnknownFrameException, e.message
130
+ raise UnknownFrameException, e.message
129
131
  end
130
132
 
131
133
  def wd
132
134
  @element
133
135
  end
134
136
 
135
- def respond_to_missing?(meth)
136
- @driver.respond_to?(meth) || @element.respond_to?(meth)
137
+ def respond_to_missing?(meth, _include_private = false)
138
+ @driver.respond_to?(meth) || @element.respond_to?(meth) || super
137
139
  end
138
140
 
139
141
  def method_missing(meth, *args, &blk)
@@ -46,24 +46,13 @@ module Watir
46
46
  #
47
47
  # Returns the text of option.
48
48
  #
49
- # Note that the text is either one of the following respectively:
50
- # * label attribute
51
- # * text attribute
52
- # * inner element text
49
+ # getAttribute atom pulls the text value if the label does not exist
53
50
  #
54
51
  # @return [String]
55
52
  #
56
53
 
57
54
  def text
58
- # A little unintuitive - we'll return the 'label' or 'text' attribute if
59
- # they exist, otherwise the inner text of the element
60
-
61
- %i[label text].each do |a|
62
- val = attribute_value(a)
63
- return val unless val.nil?
64
- end
65
-
66
- super
55
+ attribute_value(:label)
67
56
  end
68
57
  end # Option
69
58
  end # Watir
@@ -1,13 +1,11 @@
1
1
  module Watir
2
2
  class Select < HTMLElement
3
- include Watir::Exception
4
-
5
3
  #
6
4
  # Clears all selected options.
7
5
  #
8
6
 
9
7
  def clear
10
- raise Error, 'you can only clear multi-selects' unless multiple?
8
+ raise Exception::Error, 'you can only clear multi-selects' unless multiple?
11
9
 
12
10
  selected_options.each(&:click)
13
11
  end
@@ -146,13 +144,11 @@ module Watir
146
144
  def select_by(str_or_rx)
147
145
  found = find_options(:value, str_or_rx)
148
146
 
149
- if found && found.size > 1
147
+ if found.size > 1
150
148
  Watir.logger.deprecate 'Selecting Multiple Options with #select', '#select_all',
151
149
  ids: [:select_by]
152
150
  end
153
- return select_matching(found) if found&.any?
154
-
155
- raise NoValueFoundException, "#{str_or_rx.inspect} not found in select list"
151
+ select_matching(found)
156
152
  end
157
153
 
158
154
  def select_by!(str_or_rx, number)
@@ -189,7 +185,7 @@ module Watir
189
185
  next unless what.is_a?(String) ? value == what : value =~ what
190
186
  return true if opt.enabled?
191
187
 
192
- raise Watir::Exception::ObjectDisabledException, "option matching #{what} by #{how} on #{inspect} is disabled"
188
+ raise ObjectDisabledException, "option matching #{what} by #{how} on #{inspect} is disabled"
193
189
  end
194
190
  false
195
191
  end
@@ -199,9 +195,7 @@ module Watir
199
195
 
200
196
  found = find_options :text, str_or_rx
201
197
 
202
- return select_matching(found) if found
203
-
204
- raise NoValueFoundException, "#{str_or_rx.inspect} not found in select list"
198
+ select_matching(found)
205
199
  end
206
200
 
207
201
  def find_options(how, str_or_rx)
@@ -216,6 +210,7 @@ module Watir
216
210
  raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
217
211
  end
218
212
  end
213
+ # TODO: Remove conditional when remove relaxed_locate toggle
219
214
  return @found unless @found.empty?
220
215
 
221
216
  raise NoValueFoundException, "#{str_or_rx.inspect} not found in select list"
@@ -228,17 +223,6 @@ module Watir
228
223
  elements.each { |e| e.click unless e.selected? }
229
224
  elements.first.exist? ? elements.first.text : ''
230
225
  end
231
-
232
- def matches_regexp?(how, element, exp)
233
- case how
234
- when :text
235
- element.text =~ exp || element.label =~ exp
236
- when :value
237
- element.value =~ exp
238
- else
239
- raise Error, "unknown how: #{how.inspect}"
240
- end
241
- end
242
226
  end # Select
243
227
 
244
228
  module Container
@@ -27,7 +27,7 @@ module Watir
27
27
 
28
28
  def hashes
29
29
  all_rows = rows.locate
30
- header_row = all_rows.first || raise(Exception::Error, 'no rows in table')
30
+ header_row = all_rows.first || raise(Error, 'no rows in table')
31
31
 
32
32
  all_rows.entries[1..-1].map do |row|
33
33
  cell_size_check(header_row, row)
@@ -69,7 +69,7 @@ module Watir
69
69
 
70
70
  index = cell_row.selector[:index]
71
71
  row_id = index ? "row at index #{index - 1}" : 'designated row'
72
- raise Exception::Error, "#{row_id} has #{row_size} cells, while header row has #{header_size}"
72
+ raise Error, "#{row_id} has #{row_size} cells, while header row has #{header_size}"
73
73
  end
74
74
  end # Table
75
75
  end # Watir
@@ -7,9 +7,8 @@ module Watir
7
7
  class ObjectDisabledException < Error; end
8
8
  class ObjectReadOnlyException < Error; end
9
9
  class NoValueFoundException < Error; end
10
- class UnknownCellException < Error; end
11
10
  class NoMatchingWindowFoundException < Error; end
12
11
  class UnknownFrameException < Error; end
13
- class UnknownRowException < Error; end
12
+ class LocatorException < Error; end
14
13
  end # Exception
15
14
  end # Watir
@@ -2,7 +2,7 @@ require 'tsort'
2
2
 
3
3
  module Watir
4
4
  module Generator
5
- module Base
5
+ class Base
6
6
  class IDLSorter
7
7
  include TSort
8
8
 
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module Base
3
+ class Base
4
4
  class SpecExtractor
5
5
  IDL_SELECTOR = "//pre[contains(@class, 'idl')]".freeze
6
6
 
@@ -49,7 +49,7 @@ module Watir
49
49
  private
50
50
 
51
51
  def download_and_parse
52
- URI.open(@uri) { |io| @doc = Nokogiri.HTML(io) }
52
+ File.open(@uri) { |io| @doc = Nokogiri.HTML(io) }
53
53
  end
54
54
 
55
55
  def extract_idl_parts
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module Base
3
+ class Base
4
4
  class Visitor < WebIDL::RubySexpVisitor
5
5
  STRING_TYPES = ['WindowProxy', 'ValidityState', 'TimeRanges', 'Location',
6
6
  'Any', 'TimedTrackArray', 'TimedTrack', 'TextTrackArray', 'TextTrack',
@@ -4,7 +4,6 @@ module Watir
4
4
  private
5
5
 
6
6
  def ignored_tags
7
- # ignore the link element for now
8
7
  %w[link]
9
8
  end
10
9
 
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module HTML
3
+ class HTML
4
4
  class SpecExtractor < Base::SpecExtractor
5
5
  private
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module HTML
3
+ class HTML
4
4
  class Visitor < Base::Visitor
5
5
  def classify_regexp
6
6
  /^HTML(.+)Element$/
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module SVG
3
+ class SVG
4
4
  class SpecExtractor < Base::SpecExtractor
5
5
  private
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Watir
2
2
  module Generator
3
- module SVG
3
+ class SVG
4
4
  class Visitor < Base::Visitor
5
5
  def classify_regexp
6
6
  /^SVG(.+)Element$/
@@ -148,5 +148,16 @@ module Watir
148
148
  def select_text(str)
149
149
  element_call { execute_js :selectText, @element, str }
150
150
  end
151
+
152
+ #
153
+ # Selects text on page (as if dragging clicked mouse across provided text).
154
+ #
155
+ # @example
156
+ # browser.li(id: 'non_link_1').selected_text
157
+ #
158
+
159
+ def selected_text
160
+ element_call { execute_js :selectedText }
161
+ end
151
162
  end # JSExecution
152
163
  end # Watir