watir 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/chrome.yml +29 -16
  3. data/.github/workflows/edge.yml +19 -11
  4. data/.github/workflows/firefox.yml +28 -16
  5. data/.github/workflows/ie.yml +13 -7
  6. data/.github/workflows/safari.yml +22 -11
  7. data/.github/workflows/unit.yml +31 -23
  8. data/.rubocop.yml +14 -7
  9. data/.rubocop_todo.yml +0 -26
  10. data/CHANGES.md +16 -1
  11. data/Gemfile +6 -1
  12. data/README.md +15 -11
  13. data/Rakefile +9 -7
  14. data/lib/watir/adjacent.rb +3 -1
  15. data/lib/watir/after_hooks.rb +5 -3
  16. data/lib/watir/alert.rb +2 -0
  17. data/lib/watir/aliases.rb +2 -0
  18. data/lib/watir/attribute_helper.rb +4 -2
  19. data/lib/watir/browser.rb +10 -14
  20. data/lib/watir/capabilities.rb +56 -33
  21. data/lib/watir/cell_container.rb +2 -0
  22. data/lib/watir/container.rb +2 -0
  23. data/lib/watir/cookies.rb +5 -5
  24. data/lib/watir/element_collection.rb +3 -1
  25. data/lib/watir/elements/button.rb +2 -0
  26. data/lib/watir/elements/cell.rb +2 -0
  27. data/lib/watir/elements/checkbox.rb +2 -0
  28. data/lib/watir/elements/date_field.rb +2 -0
  29. data/lib/watir/elements/date_time_field.rb +2 -0
  30. data/lib/watir/elements/dlist.rb +3 -1
  31. data/lib/watir/elements/element.rb +29 -105
  32. data/lib/watir/elements/file_field.rb +2 -0
  33. data/lib/watir/elements/font.rb +2 -0
  34. data/lib/watir/elements/form.rb +2 -0
  35. data/lib/watir/elements/hidden.rb +2 -0
  36. data/lib/watir/elements/iframe.rb +2 -0
  37. data/lib/watir/elements/image.rb +2 -0
  38. data/lib/watir/elements/input.rb +2 -0
  39. data/lib/watir/elements/link.rb +2 -0
  40. data/lib/watir/elements/list.rb +2 -0
  41. data/lib/watir/elements/option.rb +2 -0
  42. data/lib/watir/elements/radio.rb +2 -0
  43. data/lib/watir/elements/row.rb +2 -0
  44. data/lib/watir/elements/select.rb +2 -0
  45. data/lib/watir/elements/table.rb +3 -1
  46. data/lib/watir/elements/table_cell.rb +2 -0
  47. data/lib/watir/elements/table_row.rb +2 -0
  48. data/lib/watir/elements/table_section.rb +2 -0
  49. data/lib/watir/elements/text_area.rb +2 -0
  50. data/lib/watir/elements/text_field.rb +2 -0
  51. data/lib/watir/exception.rb +2 -0
  52. data/lib/watir/extensions/nokogiri.rb +2 -0
  53. data/lib/watir/generator/base/generator.rb +2 -0
  54. data/lib/watir/generator/base/idl_sorter.rb +3 -1
  55. data/lib/watir/generator/base/spec_extractor.rb +6 -4
  56. data/lib/watir/generator/base/util.rb +2 -0
  57. data/lib/watir/generator/base/visitor.rb +5 -5
  58. data/lib/watir/generator/base.rb +2 -1
  59. data/lib/watir/generator/html/generator.rb +2 -0
  60. data/lib/watir/generator/html/spec_extractor.rb +2 -0
  61. data/lib/watir/generator/html/visitor.rb +2 -0
  62. data/lib/watir/generator/html.rb +2 -0
  63. data/lib/watir/generator/svg/generator.rb +2 -0
  64. data/lib/watir/generator/svg/spec_extractor.rb +2 -0
  65. data/lib/watir/generator/svg/visitor.rb +2 -0
  66. data/lib/watir/generator/svg.rb +2 -0
  67. data/lib/watir/generator.rb +2 -0
  68. data/lib/watir/has_window.rb +3 -1
  69. data/lib/watir/http_client.rb +2 -0
  70. data/lib/watir/js_execution.rb +2 -0
  71. data/lib/watir/js_snippets.rb +2 -0
  72. data/lib/watir/locators/anchor/selector_builder.rb +2 -0
  73. data/lib/watir/locators/button/matcher.rb +2 -0
  74. data/lib/watir/locators/button/selector_builder/xpath.rb +15 -19
  75. data/lib/watir/locators/button/selector_builder.rb +2 -0
  76. data/lib/watir/locators/cell/selector_builder/xpath.rb +2 -0
  77. data/lib/watir/locators/cell/selector_builder.rb +2 -0
  78. data/lib/watir/locators/element/locator.rb +2 -0
  79. data/lib/watir/locators/element/matcher.rb +2 -0
  80. data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -0
  81. data/lib/watir/locators/element/selector_builder/xpath.rb +16 -15
  82. data/lib/watir/locators/element/selector_builder/xpath_support.rb +4 -2
  83. data/lib/watir/locators/element/selector_builder.rb +16 -6
  84. data/lib/watir/locators/option/matcher.rb +2 -0
  85. data/lib/watir/locators/option/selector_builder/xpath.rb +2 -0
  86. data/lib/watir/locators/option/selector_builder.rb +2 -0
  87. data/lib/watir/locators/row/selector_builder/xpath.rb +2 -0
  88. data/lib/watir/locators/row/selector_builder.rb +2 -0
  89. data/lib/watir/locators/text_area/selector_builder/xpath.rb +2 -0
  90. data/lib/watir/locators/text_area/selector_builder.rb +2 -0
  91. data/lib/watir/locators/text_field/matcher.rb +2 -0
  92. data/lib/watir/locators/text_field/selector_builder/xpath.rb +2 -0
  93. data/lib/watir/locators/text_field/selector_builder.rb +2 -0
  94. data/lib/watir/locators.rb +2 -0
  95. data/lib/watir/logger.rb +2 -0
  96. data/lib/watir/navigation.rb +3 -1
  97. data/lib/watir/radio_set.rb +2 -0
  98. data/lib/watir/row_container.rb +2 -0
  99. data/lib/watir/screenshot.rb +2 -0
  100. data/lib/watir/scroll.rb +27 -2
  101. data/lib/watir/search_context.rb +96 -0
  102. data/lib/watir/shadow_root.rb +60 -0
  103. data/lib/watir/user_editable.rb +3 -1
  104. data/lib/watir/version.rb +3 -1
  105. data/lib/watir/wait/timer.rb +3 -1
  106. data/lib/watir/wait.rb +5 -5
  107. data/lib/watir/window.rb +7 -3
  108. data/lib/watir/window_collection.rb +4 -1
  109. data/lib/watir.rb +4 -0
  110. data/lib/watirspec/guards.rb +2 -0
  111. data/lib/watirspec/implementation.rb +14 -10
  112. data/lib/watirspec/rake_tasks.rb +4 -4
  113. data/lib/watirspec/remote_server.rb +5 -3
  114. data/lib/watirspec/runner.rb +3 -1
  115. data/lib/watirspec/server/app.rb +2 -0
  116. data/lib/watirspec/server.rb +2 -0
  117. data/lib/watirspec.rb +7 -4
  118. data/spec/locator_spec_helper.rb +2 -0
  119. data/spec/spec_helper.rb +2 -0
  120. data/spec/unit/capabilities_spec.rb +77 -58
  121. data/spec/unit/element_locator_spec.rb +2 -0
  122. data/spec/unit/match_elements/button_spec.rb +2 -0
  123. data/spec/unit/match_elements/element_spec.rb +10 -8
  124. data/spec/unit/match_elements/text_field_spec.rb +2 -0
  125. data/spec/unit/selector_builder/anchor_spec.rb +2 -0
  126. data/spec/unit/selector_builder/button_spec.rb +31 -28
  127. data/spec/unit/selector_builder/cell_spec.rb +3 -1
  128. data/spec/unit/selector_builder/element_spec.rb +61 -60
  129. data/spec/unit/selector_builder/row_spec.rb +21 -10
  130. data/spec/unit/selector_builder/text_field_spec.rb +29 -21
  131. data/spec/unit/selector_builder/textarea_spec.rb +2 -0
  132. data/spec/unit/unit_helper.rb +2 -0
  133. data/spec/unit/wait_spec.rb +2 -0
  134. data/spec/watirspec/adjacent_spec.rb +8 -6
  135. data/spec/watirspec/after_hooks_spec.rb +19 -21
  136. data/spec/watirspec/alert_spec.rb +2 -0
  137. data/spec/watirspec/attributes_spec.rb +2 -0
  138. data/spec/watirspec/browser_spec.rb +16 -12
  139. data/spec/watirspec/capabilities_spec.rb +569 -0
  140. data/spec/watirspec/cookies_spec.rb +4 -2
  141. data/spec/watirspec/drag_and_drop_spec.rb +2 -0
  142. data/spec/watirspec/element_hidden_spec.rb +2 -0
  143. data/spec/watirspec/elements/area_spec.rb +2 -0
  144. data/spec/watirspec/elements/areas_spec.rb +2 -0
  145. data/spec/watirspec/elements/button_spec.rb +2 -0
  146. data/spec/watirspec/elements/buttons_spec.rb +2 -0
  147. data/spec/watirspec/elements/checkbox_spec.rb +2 -0
  148. data/spec/watirspec/elements/checkboxes_spec.rb +2 -0
  149. data/spec/watirspec/elements/collections_spec.rb +5 -3
  150. data/spec/watirspec/elements/date_field_spec.rb +2 -0
  151. data/spec/watirspec/elements/date_fields_spec.rb +2 -0
  152. data/spec/watirspec/elements/date_time_field_spec.rb +2 -0
  153. data/spec/watirspec/elements/date_time_fields_spec.rb +2 -0
  154. data/spec/watirspec/elements/dd_spec.rb +2 -0
  155. data/spec/watirspec/elements/dds_spec.rb +2 -0
  156. data/spec/watirspec/elements/del_spec.rb +2 -0
  157. data/spec/watirspec/elements/dels_spec.rb +2 -0
  158. data/spec/watirspec/elements/div_spec.rb +2 -1
  159. data/spec/watirspec/elements/divs_spec.rb +2 -0
  160. data/spec/watirspec/elements/dl_spec.rb +6 -6
  161. data/spec/watirspec/elements/dls_spec.rb +2 -0
  162. data/spec/watirspec/elements/dt_spec.rb +2 -0
  163. data/spec/watirspec/elements/dts_spec.rb +2 -0
  164. data/spec/watirspec/elements/element_spec.rb +9 -1
  165. data/spec/watirspec/elements/elements_spec.rb +2 -0
  166. data/spec/watirspec/elements/em_spec.rb +2 -0
  167. data/spec/watirspec/elements/ems_spec.rb +2 -0
  168. data/spec/watirspec/elements/filefield_spec.rb +2 -0
  169. data/spec/watirspec/elements/filefields_spec.rb +2 -0
  170. data/spec/watirspec/elements/font_spec.rb +2 -0
  171. data/spec/watirspec/elements/form_spec.rb +2 -0
  172. data/spec/watirspec/elements/forms_spec.rb +2 -0
  173. data/spec/watirspec/elements/frame_spec.rb +2 -0
  174. data/spec/watirspec/elements/frames_spec.rb +2 -0
  175. data/spec/watirspec/elements/hidden_spec.rb +2 -0
  176. data/spec/watirspec/elements/hiddens_spec.rb +2 -0
  177. data/spec/watirspec/elements/hn_spec.rb +2 -0
  178. data/spec/watirspec/elements/hns_spec.rb +2 -0
  179. data/spec/watirspec/elements/iframe_spec.rb +3 -1
  180. data/spec/watirspec/elements/iframes_spec.rb +2 -0
  181. data/spec/watirspec/elements/image_spec.rb +2 -0
  182. data/spec/watirspec/elements/images_spec.rb +2 -0
  183. data/spec/watirspec/elements/input_spec.rb +2 -0
  184. data/spec/watirspec/elements/ins_spec.rb +2 -0
  185. data/spec/watirspec/elements/inses_spec.rb +2 -0
  186. data/spec/watirspec/elements/label_spec.rb +2 -0
  187. data/spec/watirspec/elements/labels_spec.rb +2 -0
  188. data/spec/watirspec/elements/li_spec.rb +2 -0
  189. data/spec/watirspec/elements/link_spec.rb +4 -4
  190. data/spec/watirspec/elements/links_spec.rb +2 -0
  191. data/spec/watirspec/elements/lis_spec.rb +2 -0
  192. data/spec/watirspec/elements/list_spec.rb +2 -0
  193. data/spec/watirspec/elements/map_spec.rb +2 -0
  194. data/spec/watirspec/elements/maps_spec.rb +2 -0
  195. data/spec/watirspec/elements/meta_spec.rb +2 -0
  196. data/spec/watirspec/elements/metas_spec.rb +2 -0
  197. data/spec/watirspec/elements/ol_spec.rb +2 -0
  198. data/spec/watirspec/elements/ols_spec.rb +2 -0
  199. data/spec/watirspec/elements/option_spec.rb +2 -0
  200. data/spec/watirspec/elements/p_spec.rb +2 -0
  201. data/spec/watirspec/elements/pre_spec.rb +2 -0
  202. data/spec/watirspec/elements/pres_spec.rb +2 -0
  203. data/spec/watirspec/elements/ps_spec.rb +2 -0
  204. data/spec/watirspec/elements/radio_spec.rb +2 -0
  205. data/spec/watirspec/elements/radios_spec.rb +2 -0
  206. data/spec/watirspec/elements/select_list_spec.rb +7 -1
  207. data/spec/watirspec/elements/select_lists_spec.rb +2 -0
  208. data/spec/watirspec/elements/span_spec.rb +2 -0
  209. data/spec/watirspec/elements/spans_spec.rb +2 -0
  210. data/spec/watirspec/elements/strong_spec.rb +2 -0
  211. data/spec/watirspec/elements/strongs_spec.rb +2 -0
  212. data/spec/watirspec/elements/table_nesting_spec.rb +2 -0
  213. data/spec/watirspec/elements/table_spec.rb +2 -0
  214. data/spec/watirspec/elements/tables_spec.rb +2 -0
  215. data/spec/watirspec/elements/tbody_spec.rb +2 -0
  216. data/spec/watirspec/elements/tbodys_spec.rb +2 -0
  217. data/spec/watirspec/elements/td_spec.rb +2 -0
  218. data/spec/watirspec/elements/tds_spec.rb +2 -0
  219. data/spec/watirspec/elements/text_field_spec.rb +2 -0
  220. data/spec/watirspec/elements/text_fields_spec.rb +2 -0
  221. data/spec/watirspec/elements/textarea_spec.rb +2 -0
  222. data/spec/watirspec/elements/textareas_spec.rb +2 -0
  223. data/spec/watirspec/elements/tfoot_spec.rb +2 -0
  224. data/spec/watirspec/elements/tfoots_spec.rb +2 -0
  225. data/spec/watirspec/elements/thead_spec.rb +2 -0
  226. data/spec/watirspec/elements/theads_spec.rb +2 -0
  227. data/spec/watirspec/elements/tr_spec.rb +2 -0
  228. data/spec/watirspec/elements/trs_spec.rb +2 -0
  229. data/spec/watirspec/elements/ul_spec.rb +2 -0
  230. data/spec/watirspec/elements/uls_spec.rb +2 -0
  231. data/spec/watirspec/html/child_frame.html +29 -0
  232. data/spec/watirspec/html/class_locator.html +2 -0
  233. data/spec/watirspec/html/scroll_nested.html +17 -0
  234. data/spec/watirspec/html/scroll_nested_offscreen.html +18 -0
  235. data/spec/watirspec/html/shadow_dom.html +28 -0
  236. data/spec/watirspec/radio_set_spec.rb +2 -0
  237. data/spec/watirspec/screenshot_spec.rb +4 -2
  238. data/spec/watirspec/scroll_spec.rb +75 -7
  239. data/spec/watirspec/shadow_root_spec.rb +103 -0
  240. data/spec/watirspec/special_chars_spec.rb +2 -0
  241. data/spec/watirspec/support/rspec_matchers.rb +35 -32
  242. data/spec/watirspec/user_editable_spec.rb +2 -0
  243. data/spec/watirspec/wait_spec.rb +2 -0
  244. data/spec/watirspec/window_switching_spec.rb +48 -38
  245. data/spec/watirspec_helper.rb +24 -18
  246. data/support/doctest_helper.rb +2 -0
  247. data/support/version_differ.rb +2 -0
  248. data/watir.gemspec +11 -8
  249. metadata +54 -215
  250. data/.github/actions/enable-safari/action.yml +0 -11
  251. data/.github/actions/install-chrome/action.yml +0 -12
  252. data/.github/actions/setup-linux/action.yml +0 -8
  253. data/lib/watir-webdriver.rb +0 -2
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class TableSection < HTMLElement
3
5
  include RowContainer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class TextArea < HTMLElement
3
5
  include UserEditable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class TextField < Input
3
5
  include UserEditable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Exception
3
5
  class Error < StandardError; end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
 
3
5
  module Watir
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tsort'
2
4
 
3
5
  module Watir
@@ -40,7 +42,7 @@ module Watir
40
42
  return if @visited.include?(node)
41
43
 
42
44
  @visited << node
43
- puts ' ' * indent + node
45
+ puts (' ' * indent) + node
44
46
  tsort_each_child(node) { |child| print_node(child, indent + 2) }
45
47
  end
46
48
  end # IDLSorter
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class Base
4
6
  class SpecExtractor
5
- IDL_SELECTOR = "//pre[contains(@class, 'idl')]".freeze
7
+ IDL_SELECTOR = "//pre[contains(@class, 'idl')]"
6
8
 
7
9
  class InterfaceNotFound < StandardError; end
8
10
 
@@ -32,9 +34,9 @@ module Watir
32
34
  def sorted_interfaces
33
35
  process if @interfaces.nil?
34
36
 
35
- idl_sorter.sort.map { |name|
37
+ idl_sorter.sort.filter_map do |name|
36
38
  @interfaces.find { |i| i.name == name } || puts("ignoring interface: #{name}")
37
- }.compact
39
+ end
38
40
  end
39
41
 
40
42
  def print_hierarchy
@@ -53,7 +55,7 @@ module Watir
53
55
  end
54
56
 
55
57
  def extract_idl_parts
56
- parsed = @doc.search(IDL_SELECTOR).map { |e| parse_idl(e.inner_text) }.compact
58
+ parsed = @doc.search(IDL_SELECTOR).filter_map { |e| parse_idl(e.inner_text) }
57
59
 
58
60
  implements = []
59
61
  includes = []
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class Base
@@ -9,7 +11,7 @@ module Watir
9
11
  'DOMStringMap', 'HTMLPropertiesCollection', /HTML.*Element/, /HTML.*Collection/,
10
12
  'CSSStyleDeclaration', /.+List$/, 'Date', 'Element', /DOM.+ReadOnly/,
11
13
  /SVGAnimated.+/, /SVG.*Element/, /SVG.*Collection/, 'SVGViewSpec',
12
- 'Object', 'USVString'].freeze
14
+ 'Object', 'USVString', 'DOMString', 'any'].freeze
13
15
  def initialize
14
16
  super
15
17
 
@@ -111,7 +113,8 @@ module Watir
111
113
 
112
114
  def ruby_type_for(type)
113
115
  case type.name.to_s
114
- when 'DOMString', 'any'
116
+ when *STRING_TYPES
117
+ # probably completely wrong.
115
118
  String
116
119
  when 'UnsignedLong', 'Long', 'Integer', 'Short', 'UnsignedShort',
117
120
  'SVGAnimatedLength'
@@ -120,9 +123,6 @@ module Watir
120
123
  Float
121
124
  when 'Boolean'
122
125
  'Boolean'
123
- when *STRING_TYPES
124
- # probably completely wrong.
125
- String
126
126
  else
127
127
  raise "unknown type: #{type.name}"
128
128
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
  require 'open-uri'
3
- require 'pp'
4
5
  require 'webidl'
5
6
  require 'active_support/inflector'
6
7
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class HTML < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class HTML
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class HTML
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveSupport::Inflector.inflections do |inflect|
2
4
  inflect.plural 'body', 'bodys'
3
5
  inflect.plural 'tbody', 'tbodys'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class SVG < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class SVG
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Generator
3
5
  class SVG
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveSupport::Inflector.inflections do |inflect|
2
4
  inflect.plural 'defs', 'defss'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watir/generator/base'
2
4
  require 'watir/generator/html'
3
5
  require 'watir/generator/svg'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module HasWindow
3
5
  attr_writer :original_window
@@ -27,7 +29,7 @@ module Watir
27
29
  def window(opts = {}, &blk)
28
30
  win = Window.new self, opts
29
31
 
30
- win.use(&blk) if block_given?
32
+ win.use(&blk) if blk
31
33
 
32
34
  win
33
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class HttpClient < Selenium::WebDriver::Remote::Http::Default
3
5
  def request(verb, url, headers, payload, redirects = 0)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module JSExecution
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module JSSnippets
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Anchor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Button
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Button
@@ -14,27 +16,23 @@ module Watir
14
16
  type = @selector.delete(:type)
15
17
  text = @selector.delete(:text)
16
18
 
17
- string = "(#{button_string(text: text, type: type)})"
18
- string << " or (#{input_string(text: text, type: type)})" unless type.eql?(false)
19
- "[#{string}]"
19
+ button = "(#{button_string(text: text, type: type)})"
20
+ input = type.eql?(false) ? '' : " or (#{input_string(text: text, type: type)})"
21
+
22
+ "[#{button}#{input}]"
20
23
  end
21
24
 
22
25
  def button_string(text: nil, type: nil)
23
- string = process_attribute(:tag_name, 'button')
24
- string << " and #{process_attribute(:text, text)}" unless text.nil?
25
- string << " and #{input_types(type)}" unless type.nil?
26
- string
26
+ input = type.nil? ? '' : " and #{input_types(type)}"
27
+ attribute = text.nil? ? '' : " and #{process_attribute(:text, text)}"
28
+ "#{process_attribute(:tag_name, 'button')}#{input}#{attribute}"
27
29
  end
28
30
 
29
31
  def input_string(text: nil, type: nil)
30
- string = process_attribute(:tag_name, 'input')
31
32
  type = nil if type.eql?(true)
32
- string << " and (#{input_types(type)})"
33
- if text
34
- string << " and #{process_attribute(:value, text)}"
35
- @built.delete(:value)
36
- end
37
- string
33
+ text_value = text.nil? ? '' : " and #{process_attribute(:value, text)}"
34
+ @built.delete(:value) unless text.nil?
35
+ "#{process_attribute(:tag_name, 'input')} and (#{input_types(type)})#{text_value}"
38
36
  end
39
37
 
40
38
  # value locator needs to match input value, button text or button value
@@ -54,17 +52,15 @@ module Watir
54
52
  def input_types(type = nil)
55
53
  types = if type.eql?(nil)
56
54
  Watir::Button::VALID_TYPES
57
- elsif Watir::Button::VALID_TYPES.include?(type)
58
- [type]
59
- elsif type.eql?(true) || type.eql?(false)
55
+ elsif Watir::Button::VALID_TYPES.include?(type) || type.eql?(true) || type.eql?(false)
60
56
  [type]
61
57
  else
62
58
  msg = "Button Elements can not be located by input type: #{type}"
63
59
  raise LocatorException, msg
64
60
  end
65
- types.map { |button_type|
61
+ types.filter_map { |button_type|
66
62
  predicate_expression(:type, button_type)
67
- }.compact.join(' or ')
63
+ }.join(' or ')
68
64
  end
69
65
  end
70
66
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Button
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Cell
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Cell
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Element
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Element
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Source: https://github.com/teamcapybara/capybara/blob/xpath_regexp/lib/capybara/selector/regexp_disassembler.rb
2
4
  require 'regexp_parser'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Element
@@ -22,14 +24,14 @@ module Watir
22
24
  @adjacent = @selector.delete(:adjacent)
23
25
  @scope = @selector.delete(:scope)
24
26
 
25
- xpath = start_string
26
- xpath << adjacent_string
27
- xpath << tag_string
28
- xpath << class_string
29
- xpath << text_string
30
- xpath << additional_string
31
- xpath << label_element_string
32
- xpath << attribute_string
27
+ xpath = "#{start_string}" \
28
+ "#{adjacent_string}" \
29
+ "#{tag_string}" \
30
+ "#{class_string}" \
31
+ "#{text_string}" \
32
+ "#{additional_string}" \
33
+ "#{label_element_string}" \
34
+ "#{attribute_string}"
33
35
 
34
36
  @built[:xpath] = index ? add_index(xpath, index) : xpath
35
37
  @built
@@ -73,7 +75,7 @@ module Watir
73
75
  add_to_matching(key, regexp, results)
74
76
 
75
77
  results.map { |rhs|
76
- rhs = "'#{rhs}'"
78
+ rhs = "\"#{rhs}\""
77
79
  rhs = XpathSupport.downcase(rhs) if downcase
78
80
  "contains(#{lhs}, #{rhs})"
79
81
  }.flatten.compact.join(' and ')
@@ -112,7 +114,7 @@ module Watir
112
114
 
113
115
  @built[:class] = []
114
116
 
115
- predicates = [class_name].flatten.map { |value| process_attribute(:class, value) }.compact
117
+ predicates = [class_name].flatten.filter_map { |value| process_attribute(:class, value) }
116
118
 
117
119
  @built.delete(:class) if @built[:class].empty?
118
120
 
@@ -135,7 +137,7 @@ module Watir
135
137
  end
136
138
 
137
139
  def equal_or_contains(value)
138
- return nil if value.nil? || value.is_a?(String) && value.empty? || value.inspect == '//'
140
+ return nil if value.nil? || (value.is_a?(String) && value.empty?) || value.inspect == '//'
139
141
 
140
142
  process_attribute(:text, value)
141
143
  end
@@ -158,8 +160,7 @@ module Watir
158
160
  elsif index&.positive? && @built.empty?
159
161
  "(#{xpath})[#{index + 1}]"
160
162
  elsif index&.negative? && @built.empty?
161
- last_value = 'last()'
162
- last_value << (index + 1).to_s if index < -1
163
+ last_value = "last()#{index < -1 ? index + 1 : ''}"
163
164
  "(#{xpath})[#{last_value}]"
164
165
  else
165
166
  @built[:index] = index
@@ -220,7 +221,7 @@ module Watir
220
221
  if key == :class
221
222
  negate_xpath = value =~ /^!/
222
223
  value = value[1..] if negate_xpath
223
- expression = "contains(concat(' ', @class, ' '), #{XpathSupport.escape " #{value} "})"
224
+ expression = "contains(concat(' ', normalize-space(@class), ' '), #{XpathSupport.escape " #{value} "})"
224
225
 
225
226
  negate_xpath ? "not(#{expression})" : expression
226
227
  else
@@ -254,7 +255,7 @@ module Watir
254
255
  end
255
256
 
256
257
  def process_string(name)
257
- if name =~ /^[a-zA-Z_:][a-zA-Z0-9_:.\-]*$/
258
+ if /^[a-zA-Z_:][a-zA-Z0-9_:.-]*$/.match?(name)
258
259
  "@#{name}"
259
260
  else
260
261
  "(attribute::*[local-name(.) = '#{name}'])"
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Element
4
6
  class SelectorBuilder
5
7
  module XpathSupport
6
- UPPERCASE_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'.freeze
7
- LOWERCASE_LETTERS = 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'.freeze
8
+ UPPERCASE_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'
9
+ LOWERCASE_LETTERS = 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'
8
10
 
9
11
  def self.escape(value)
10
12
  if value.include? "'"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Element
@@ -22,6 +24,7 @@ module Watir
22
24
  @query_scope = query_scope
23
25
  end
24
26
 
27
+ # rubocop:disable Metrics/PerceivedComplexity:
25
28
  def build(selector)
26
29
  @selector = selector
27
30
 
@@ -29,13 +32,22 @@ module Watir
29
32
  inspected = selector.inspect
30
33
  scope = @query_scope unless @selector.key?(:scope) || @query_scope.is_a?(Watir::Browser)
31
34
 
32
- @built = wd_locators.empty? ? build_wd_selector(@selector) : @selector
35
+ @built =
36
+ if scope.is_a? Watir::ShadowRoot
37
+ raise ArgumentError, ':xpath not supported when locating elements from shadow root' if @selector[:xpath]
38
+
39
+ @selector[:css] ||= '*'
40
+ @selector
41
+ else
42
+ wd_locators.empty? ? build_wd_selector(@selector) : @selector
43
+ end
33
44
  @built.delete(:index) if @built[:index]&.zero?
34
45
  @built[:scope] = scope if scope
35
46
 
36
47
  Watir.logger.info "Converted #{inspected} to #{@built.inspect}"
37
48
  @built
38
49
  end
50
+ # rubocop:enable Metrics/PerceivedComplexity:
39
51
 
40
52
  def wd_locators
41
53
  Watir::Locators::W3C_FINDERS & @selector.keys
@@ -66,9 +78,9 @@ module Watir
66
78
  end
67
79
 
68
80
  def merge_scope?
69
- return false unless (Watir::Locators::W3C_FINDERS + [:adjacent] & @selector.keys).empty?
81
+ return false unless ((Watir::Locators::W3C_FINDERS + [:adjacent]) & @selector.keys).empty?
70
82
 
71
- return false if [Watir::Browser, Watir::IFrame].any? { |k| @query_scope.is_a?(k) }
83
+ return false if [Watir::Browser, Watir::IFrame, Watir::ShadowRoot].any? { |k| @query_scope.is_a?(k) }
72
84
 
73
85
  scope_invalid_locators = @query_scope.selector_builder.built.keys.reject { |key| key == wd_locator }
74
86
  scope_invalid_locators.empty?
@@ -136,10 +148,8 @@ module Watir
136
148
  keys.reject! { |key| %i[visible visible_text index].include? key }
137
149
  if (keys - [:tag_name]).empty?
138
150
  true
139
- elsif selector[:tag_name] == 'input' && keys == %i[tag_name type]
140
- true
141
151
  else
142
- false
152
+ selector[:tag_name] == 'input' && keys == %i[tag_name type]
143
153
  end
144
154
  end
145
155
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Option
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Option
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Option
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Row
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class Row
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class TextArea
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class TextArea
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class TextField
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class TextField
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Locators
3
5
  class TextField
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watir/locators/element/locator'
2
4
  require 'watir/locators/element/selector_builder'
3
5
  require 'watir/locators/element/selector_builder/xpath_support'
data/lib/watir/logger.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  require 'logger'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Navigation
3
5
  #
@@ -11,7 +13,7 @@ module Watir
11
13
  #
12
14
 
13
15
  def goto(uri)
14
- uri = "http://#{uri}" unless uri =~ URI::DEFAULT_PARSER.make_regexp
16
+ uri = "http://#{uri}" unless uri&.match?(URI::DEFAULT_PARSER.make_regexp)
15
17
 
16
18
  @driver.navigate.to uri
17
19
  @after_hooks.run
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class RadioSet
3
5
  extend Forwardable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module RowContainer
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class Screenshot
3
5
  def initialize(browser)