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
  require_relative '../unit_helper'
2
4
 
3
5
  describe Watir::Locators::Button::SelectorBuilder do
@@ -8,9 +10,9 @@ describe Watir::Locators::Button::SelectorBuilder do
8
10
  let(:lowercase) { 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ' }
9
11
  let(:default_types) do
10
12
  "translate(@type,'#{uppercase}','#{lowercase}')=translate('button','#{uppercase}','#{lowercase}') or " \
11
- "translate(@type,'#{uppercase}','#{lowercase}')=translate('reset','#{uppercase}','#{lowercase}') or "\
12
- "translate(@type,'#{uppercase}','#{lowercase}')=translate('submit','#{uppercase}','#{lowercase}') or "\
13
- "translate(@type,'#{uppercase}','#{lowercase}')=translate('image','#{uppercase}','#{lowercase}')"
13
+ "translate(@type,'#{uppercase}','#{lowercase}')=translate('reset','#{uppercase}','#{lowercase}') or " \
14
+ "translate(@type,'#{uppercase}','#{lowercase}')=translate('submit','#{uppercase}','#{lowercase}') or " \
15
+ "translate(@type,'#{uppercase}','#{lowercase}')=translate('image','#{uppercase}','#{lowercase}')"
14
16
  end
15
17
 
16
18
  describe '#build' do
@@ -30,7 +32,7 @@ describe Watir::Locators::Button::SelectorBuilder do
30
32
  it 'true locates button or input with a type' do
31
33
  selector = {type: true}
32
34
  built = {xpath: ".//*[(local-name()='button' and @type) or " \
33
- "(local-name()='input' and (#{default_types}))]"}
35
+ "(local-name()='input' and (#{default_types}))]"}
34
36
  expect(selector_builder.build(selector)).to eq built
35
37
  end
36
38
 
@@ -38,8 +40,8 @@ describe Watir::Locators::Button::SelectorBuilder do
38
40
  selector = {type: 'reset'}
39
41
  type = "translate('reset','#{uppercase}','#{lowercase}')"
40
42
  built = {xpath: ".//*[(local-name()='button' and " \
41
- "translate(@type,'#{uppercase}','#{lowercase}')=#{type}) or " \
42
- "(local-name()='input' and (translate(@type,'#{uppercase}','#{lowercase}')=#{type}))]"}
43
+ "translate(@type,'#{uppercase}','#{lowercase}')=#{type}) or " \
44
+ "(local-name()='input' and (translate(@type,'#{uppercase}','#{lowercase}')=#{type}))]"}
43
45
  expect(selector_builder.build(selector)).to eq built
44
46
  end
45
47
 
@@ -63,49 +65,49 @@ describe Watir::Locators::Button::SelectorBuilder do
63
65
  it 'locates value of input element with String' do
64
66
  selector = {text: 'Button'}
65
67
  built = {xpath: ".//*[(local-name()='button' and normalize-space()='Button') or " \
66
- "(local-name()='input' and (#{default_types}) and @value='Button')]"}
68
+ "(local-name()='input' and (#{default_types}) and @value='Button')]"}
67
69
  expect(selector_builder.build(selector)).to eq built
68
70
  end
69
71
 
70
72
  it 'locates text of button element with String' do
71
73
  selector = {text: 'Button 2'}
72
74
  built = {xpath: ".//*[(local-name()='button' and normalize-space()='Button 2') or " \
73
- "(local-name()='input' and (#{default_types}) and @value='Button 2')]"}
75
+ "(local-name()='input' and (#{default_types}) and @value='Button 2')]"}
74
76
  expect(selector_builder.build(selector)).to eq built
75
77
  end
76
78
 
77
79
  it 'locates value of input element with simple Regexp' do
78
80
  selector = {text: /Button/}
79
- built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), 'Button')) or " \
80
- "(local-name()='input' and (#{default_types}) and contains(@value, 'Button'))]"}
81
+ built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), \"Button\")) or " \
82
+ "(local-name()='input' and (#{default_types}) and contains(@value, \"Button\"))]"}
81
83
  expect(selector_builder.build(selector)).to eq built
82
84
  end
83
85
 
84
86
  it 'locates text of button element with simple Regexp' do
85
87
  selector = {text: /Button 2/}
86
- built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), 'Button 2')) or " \
87
- "(local-name()='input' and (#{default_types}) and contains(@value, 'Button 2'))]"}
88
+ built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), \"Button 2\")) or " \
89
+ "(local-name()='input' and (#{default_types}) and contains(@value, \"Button 2\"))]"}
88
90
  expect(selector_builder.build(selector)).to eq built
89
91
  end
90
92
 
91
93
  it 'Simple Regexp for text' do
92
94
  selector = {text: /n 2/}
93
- built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), 'n 2')) or " \
94
- "(local-name()='input' and (#{default_types}) and contains(@value, 'n 2'))]"}
95
+ built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), \"n 2\")) or " \
96
+ "(local-name()='input' and (#{default_types}) and contains(@value, \"n 2\"))]"}
95
97
  expect(selector_builder.build(selector)).to eq built
96
98
  end
97
99
 
98
100
  it 'Simple Regexp for value' do
99
101
  selector = {text: /Prev/}
100
- built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), 'Prev')) or " \
101
- "(local-name()='input' and (#{default_types}) and contains(@value, 'Prev'))]"}
102
+ built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), \"Prev\")) or " \
103
+ "(local-name()='input' and (#{default_types}) and contains(@value, \"Prev\"))]"}
102
104
  expect(selector_builder.build(selector)).to eq built
103
105
  end
104
106
 
105
107
  it 'returns complex Regexp to the locator' do
106
108
  selector = {text: /^foo$/}
107
- built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), 'foo')) or " \
108
- "(local-name()='input' and (#{default_types}) and contains(@value, 'foo'))]", text: /^foo$/}
109
+ built = {xpath: ".//*[(local-name()='button' and contains(normalize-space(), \"foo\")) or " \
110
+ "(local-name()='input' and (#{default_types}) and contains(@value, \"foo\"))]", text: /^foo$/}
109
111
  expect(selector_builder.build(selector)).to eq built
110
112
  end
111
113
  end
@@ -114,49 +116,49 @@ describe Watir::Locators::Button::SelectorBuilder do
114
116
  it 'input element value with String' do
115
117
  selector = {value: 'Preview'}
116
118
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
117
- "[normalize-space()='Preview' or @value='Preview']"}
119
+ "[normalize-space()='Preview' or @value='Preview']"}
118
120
  expect(selector_builder.build(selector)).to eq built
119
121
  end
120
122
 
121
123
  it 'button element value with String' do
122
124
  selector = {value: 'button_2'}
123
125
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
124
- "[normalize-space()='button_2' or @value='button_2']"}
126
+ "[normalize-space()='button_2' or @value='button_2']"}
125
127
  expect(selector_builder.build(selector)).to eq built
126
128
  end
127
129
 
128
130
  it 'input element value with simple Regexp' do
129
131
  selector = {value: /Prev/}
130
132
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
131
- "[contains(normalize-space(), 'Prev') or contains(@value, 'Prev')]"}
133
+ '[contains(normalize-space(), "Prev") or contains(@value, "Prev")]'}
132
134
  expect(selector_builder.build(selector)).to eq built
133
135
  end
134
136
 
135
137
  it 'button element value with simple Regexp' do
136
138
  selector = {value: /on_2/}
137
139
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
138
- "[contains(normalize-space(), 'on_2') or contains(@value, 'on_2')]"}
140
+ '[contains(normalize-space(), "on_2") or contains(@value, "on_2")]'}
139
141
  expect(selector_builder.build(selector)).to eq built
140
142
  end
141
143
 
142
144
  it 'button element text with String' do
143
145
  selector = {value: 'Button 2'}
144
146
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
145
- "[normalize-space()='Button 2' or @value='Button 2']"}
147
+ "[normalize-space()='Button 2' or @value='Button 2']"}
146
148
  expect(selector_builder.build(selector)).to eq built
147
149
  end
148
150
 
149
151
  it 'button element text with simple Regexp' do
150
152
  selector = {value: /ton 2/}
151
153
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
152
- "[contains(normalize-space(), 'ton 2') or contains(@value, 'ton 2')]"}
154
+ '[contains(normalize-space(), "ton 2") or contains(@value, "ton 2")]'}
153
155
  expect(selector_builder.build(selector)).to eq built
154
156
  end
155
157
 
156
158
  it 'returns complex Regexp to the locator' do
157
159
  selector = {value: /^foo$/}
158
160
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
159
- "[contains(normalize-space(), 'foo') or contains(@value, 'foo')]", value: /^foo$/}
161
+ '[contains(normalize-space(), "foo") or contains(@value, "foo")]', value: /^foo$/}
160
162
  expect(selector_builder.build(selector)).to eq built
161
163
  end
162
164
  end
@@ -171,14 +173,14 @@ describe Watir::Locators::Button::SelectorBuilder do
171
173
  it 'negative' do
172
174
  selector = {index: -4}
173
175
  built = {xpath: "(.//*[(local-name()='button') or " \
174
- "(local-name()='input' and (#{default_types}))])[last()-3]"}
176
+ "(local-name()='input' and (#{default_types}))])[last()-3]"}
175
177
  expect(selector_builder.build(selector)).to eq built
176
178
  end
177
179
 
178
180
  it 'last' do
179
181
  selector = {index: -1}
180
182
  built = {xpath: "(.//*[(local-name()='button') or " \
181
- "(local-name()='input' and (#{default_types}))])[last()]"}
183
+ "(local-name()='input' and (#{default_types}))])[last()]"}
182
184
  expect(selector_builder.build(selector)).to eq built
183
185
  end
184
186
 
@@ -199,7 +201,8 @@ describe Watir::Locators::Button::SelectorBuilder do
199
201
  it 'locates using class and attributes' do
200
202
  selector = {class: 'image', name: 'new_user_image', src: true}
201
203
  built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
202
- "[contains(concat(' ', @class, ' '), ' image ')][@name='new_user_image' and @src]"}
204
+ "[contains(concat(' ', normalize-space(@class), ' '), ' image ')]" \
205
+ "[@name='new_user_image' and @src]"}
203
206
  expect(selector_builder.build(selector)).to eq built
204
207
  end
205
208
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../unit_helper'
2
4
 
3
5
  describe Watir::Locators::Cell::SelectorBuilder do
@@ -54,7 +56,7 @@ describe Watir::Locators::Cell::SelectorBuilder do
54
56
  it 'attribute and text' do
55
57
  selector = {headers: /before_tax/, text: '5 934'}
56
58
  built = {xpath: "./*[local-name()='th' or local-name()='td']" \
57
- "[normalize-space()='5 934'][contains(@headers, 'before_tax')]"}
59
+ "[normalize-space()='5 934'][contains(@headers, \"before_tax\")]"}
58
60
 
59
61
  expect(selector_builder.build(selector)).to eq built
60
62
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../unit_helper'
2
4
 
3
5
  describe Watir::Locators::Element::SelectorBuilder do
@@ -67,7 +69,7 @@ describe Watir::Locators::Element::SelectorBuilder do
67
69
 
68
70
  it 'with simple Regexp contains' do
69
71
  selector = {tag_name: /div/}
70
- built = {xpath: ".//*[contains(local-name(), 'div')]"}
72
+ built = {xpath: './/*[contains(local-name(), "div")]'}
71
73
 
72
74
  expect(selector_builder.build(selector)).to eq built
73
75
  end
@@ -90,51 +92,51 @@ describe Watir::Locators::Element::SelectorBuilder do
90
92
  context 'with class names' do
91
93
  it 'class_name is converted to class' do
92
94
  selector = {class_name: 'user'}
93
- built = {xpath: ".//*[contains(concat(' ', @class, ' '), ' user ')]"}
95
+ built = {xpath: ".//*[contains(concat(' ', normalize-space(@class), ' '), ' user ')]"}
94
96
 
95
97
  expect(selector_builder.build(selector)).to eq built
96
98
  end
97
99
 
98
100
  it 'single String concatenates' do
99
101
  selector = {class: 'user'}
100
- built = {xpath: ".//*[contains(concat(' ', @class, ' '), ' user ')]"}
102
+ built = {xpath: ".//*[contains(concat(' ', normalize-space(@class), ' '), ' user ')]"}
101
103
 
102
104
  expect(selector_builder.build(selector)).to eq built
103
105
  end
104
106
 
105
107
  it 'Array of String concatenates with and' do
106
108
  selector = {class: %w[multiple here]}
107
- built = {xpath: ".//*[contains(concat(' ', @class, ' '), ' multiple ') and " \
108
- "contains(concat(' ', @class, ' '), ' here ')]"}
109
+ built = {xpath: ".//*[contains(concat(' ', normalize-space(@class), ' '), ' multiple ') and " \
110
+ "contains(concat(' ', normalize-space(@class), ' '), ' here ')]"}
109
111
 
110
112
  expect(selector_builder.build(selector)).to eq built
111
113
  end
112
114
 
113
115
  it 'merges values when class and class_name are both used' do
114
116
  selector = {class: 'foo', class_name: 'bar'}
115
- built = {xpath: ".//*[contains(concat(' ', @class, ' '), ' foo ') and " \
116
- "contains(concat(' ', @class, ' '), ' bar ')]"}
117
+ built = {xpath: ".//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ') and " \
118
+ "contains(concat(' ', normalize-space(@class), ' '), ' bar ')]"}
117
119
 
118
120
  expect(selector_builder.build(selector)).to eq built
119
121
  end
120
122
 
121
123
  it 'simple Regexp contains' do
122
124
  selector = {class_name: /use/}
123
- built = {xpath: ".//*[contains(@class, 'use')]"}
125
+ built = {xpath: './/*[contains(@class, "use")]'}
124
126
 
125
127
  expect(selector_builder.build(selector)).to eq built
126
128
  end
127
129
 
128
130
  it 'Array of Regexp contains with and' do
129
131
  selector = {class: [/mult/, /her/]}
130
- built = {xpath: ".//*[contains(@class, 'mult') and contains(@class, 'her')]"}
132
+ built = {xpath: './/*[contains(@class, "mult") and contains(@class, "her")]'}
131
133
 
132
134
  expect(selector_builder.build(selector)).to eq built
133
135
  end
134
136
 
135
137
  it 'single negated String concatenates with not' do
136
138
  selector = {class: '!multiple'}
137
- built = {xpath: ".//*[not(contains(concat(' ', @class, ' '), ' multiple '))]"}
139
+ built = {xpath: ".//*[not(contains(concat(' ', normalize-space(@class), ' '), ' multiple '))]"}
138
140
 
139
141
  expect(selector_builder.build(selector)).to eq built
140
142
  end
@@ -155,8 +157,9 @@ describe Watir::Locators::Element::SelectorBuilder do
155
157
 
156
158
  it 'Array of mixed String, Regexp and Boolean contains and concatenates with and and not' do
157
159
  selector = {class: [/mult/, 'classes', '!here']}
158
- built = {xpath: ".//*[contains(@class, 'mult') and contains(concat(' ', @class, ' '), ' classes ') " \
159
- "and not(contains(concat(' ', @class, ' '), ' here '))]"}
160
+ built = {xpath: './/*[contains(@class, "mult") ' \
161
+ "and contains(concat(' ', normalize-space(@class), ' '), ' classes ') " \
162
+ "and not(contains(concat(' ', normalize-space(@class), ' '), ' here '))]"}
160
163
 
161
164
  expect(selector_builder.build(selector)).to eq built
162
165
  end
@@ -251,14 +254,14 @@ describe Watir::Locators::Element::SelectorBuilder do
251
254
  context 'with attributes as partials' do
252
255
  it 'with Regexp' do
253
256
  selector = {name: /user/}
254
- built = {xpath: ".//*[contains(@name, 'user')]"}
257
+ built = {xpath: './/*[contains(@name, "user")]'}
255
258
 
256
259
  expect(selector_builder.build(selector)).to eq built
257
260
  end
258
261
 
259
262
  it 'with multiple Regexp attributes separated by and' do
260
263
  selector = {readonly: /read/, id: /good/}
261
- built = {xpath: ".//*[contains(@readonly, 'read') and contains(@id, 'good')]"}
264
+ built = {xpath: './/*[contains(@readonly, "read") and contains(@id, "good")]'}
262
265
 
263
266
  expect(selector_builder.build(selector)).to eq built
264
267
  end
@@ -274,7 +277,7 @@ describe Watir::Locators::Element::SelectorBuilder do
274
277
 
275
278
  it 'Regexp uses contains normalize space' do
276
279
  selector = {text: /Add/}
277
- built = {xpath: ".//*[contains(normalize-space(), 'Add')]"}
280
+ built = {xpath: './/*[contains(normalize-space(), "Add")]'}
278
281
 
279
282
  expect(selector_builder.build(selector)).to eq built
280
283
  end
@@ -327,8 +330,8 @@ describe Watir::Locators::Element::SelectorBuilder do
327
330
  context 'with labels' do
328
331
  it 'locates the element associated with the label element located by the text of the provided label key' do
329
332
  selector = {label: 'Cars'}
330
- built = {xpath: ".//*[@id=//label[normalize-space()='Cars']/@for "\
331
- "or parent::label[normalize-space()='Cars']]"}
333
+ built = {xpath: ".//*[@id=//label[normalize-space()='Cars']/@for " \
334
+ "or parent::label[normalize-space()='Cars']]"}
332
335
 
333
336
  expect(selector_builder.build(selector)).to eq built
334
337
  end
@@ -390,8 +393,8 @@ describe Watir::Locators::Element::SelectorBuilder do
390
393
 
391
394
  it 'with multiple locators' do
392
395
  selector = {adjacent: :ancestor, id: true, tag_name: 'div', class: 'ancestor', index: 1}
393
- built = {xpath: "./ancestor::*[local-name()='div']"\
394
- "[contains(concat(' ', @class, ' '), ' ancestor ')][@id][2]"}
396
+ built = {xpath: "./ancestor::*[local-name()='div']" \
397
+ "[contains(concat(' ', normalize-space(@class), ' '), ' ancestor ')][@id][2]"}
395
398
 
396
399
  expect(selector_builder.build(selector)).to eq built
397
400
  end
@@ -421,8 +424,8 @@ describe Watir::Locators::Element::SelectorBuilder do
421
424
 
422
425
  it 'with multiple locators' do
423
426
  selector = {adjacent: :following, tag_name: 'div', class: 'b', index: 0, id: true}
424
- built = {xpath: "./following-sibling::*[local-name()='div']"\
425
- "[contains(concat(' ', @class, ' '), ' b ')][@id][1]"}
427
+ built = {xpath: "./following-sibling::*[local-name()='div']" \
428
+ "[contains(concat(' ', normalize-space(@class), ' '), ' b ')][@id][1]"}
426
429
 
427
430
  expect(selector_builder.build(selector)).to eq built
428
431
  end
@@ -452,8 +455,8 @@ describe Watir::Locators::Element::SelectorBuilder do
452
455
 
453
456
  it 'with multiple locators' do
454
457
  selector = {adjacent: :preceding, tag_name: 'div', class: 'b', id: true, index: 0}
455
- built = {xpath: "./preceding-sibling::*[local-name()='div']"\
456
- "[contains(concat(' ', @class, ' '), ' b ')][@id][1]"}
458
+ built = {xpath: "./preceding-sibling::*[local-name()='div']" \
459
+ "[contains(concat(' ', normalize-space(@class), ' '), ' b ')][@id][1]"}
457
460
 
458
461
  expect(selector_builder.build(selector)).to eq built
459
462
  end
@@ -483,8 +486,8 @@ describe Watir::Locators::Element::SelectorBuilder do
483
486
 
484
487
  it 'with multiple locators' do
485
488
  selector = {adjacent: :child, tag_name: 'div', class: 'b', id: true, index: 0}
486
- built = {xpath: "./child::*[local-name()='div']"\
487
- "[contains(concat(' ', @class, ' '), ' b ')][@id][1]"}
489
+ built = {xpath: "./child::*[local-name()='div']" \
490
+ "[contains(concat(' ', normalize-space(@class), ' '), ' b ')][@id][1]"}
488
491
 
489
492
  expect(selector_builder.build(selector)).to eq built
490
493
  end
@@ -501,8 +504,8 @@ describe Watir::Locators::Element::SelectorBuilder do
501
504
  context 'with multiple locators' do
502
505
  it 'locates using tag name, class, attributes and text' do
503
506
  selector = {tag_name: 'div', class: 'content', contenteditable: 'true', text: 'Foo'}
504
- built = {xpath: ".//*[local-name()='div'][contains(concat(' ', @class, ' '), ' content ')]" \
505
- "[normalize-space()='Foo'][@contenteditable='true']"}
507
+ built = {xpath: ".//*[local-name()='div'][contains(concat(' ', normalize-space(@class), ' '), ' content ')]" \
508
+ "[normalize-space()='Foo'][@contenteditable='true']"}
506
509
 
507
510
  expect(selector_builder.build(selector)).to eq built
508
511
  end
@@ -511,14 +514,14 @@ describe Watir::Locators::Element::SelectorBuilder do
511
514
  context 'with simple Regexp' do
512
515
  it 'handles spaces' do
513
516
  selector = {title: /od Lu/}
514
- built = {xpath: ".//*[contains(@title, 'od Lu')]"}
517
+ built = {xpath: './/*[contains(@title, "od Lu")]'}
515
518
 
516
519
  expect(selector_builder.build(selector)).to eq built
517
520
  end
518
521
 
519
522
  it 'handles escaped characters' do
520
523
  selector = {src: %r{ages/but}}
521
- built = {xpath: ".//*[contains(@src, 'ages/but')]"}
524
+ built = {xpath: './/*[contains(@src, "ages/but")]'}
522
525
 
523
526
  expect(selector_builder.build(selector)).to eq built
524
527
  end
@@ -527,21 +530,21 @@ describe Watir::Locators::Element::SelectorBuilder do
527
530
  context 'with complex Regexp' do
528
531
  it 'handles wildcards' do
529
532
  selector = {src: /ages.*but/}
530
- built = {xpath: ".//*[contains(@src, 'ages') and contains(@src, 'but')]", src: /ages.*but/}
533
+ built = {xpath: './/*[contains(@src, "ages") and contains(@src, "but")]', src: /ages.*but/}
531
534
 
532
535
  expect(selector_builder.build(selector)).to eq built
533
536
  end
534
537
 
535
538
  it 'handles optional characters' do
536
539
  selector = {src: /ages ?but/}
537
- built = {xpath: ".//*[contains(@src, 'ages') and contains(@src, 'but')]", src: /ages ?but/}
540
+ built = {xpath: './/*[contains(@src, "ages") and contains(@src, "but")]', src: /ages ?but/}
538
541
 
539
542
  expect(selector_builder.build(selector)).to eq built
540
543
  end
541
544
 
542
545
  it 'handles anchors' do
543
546
  selector = {name: /^new_user_image$/}
544
- built = {xpath: ".//*[contains(@name, 'new_user_image')]", name: /^new_user_image$/}
547
+ built = {xpath: './/*[contains(@name, "new_user_image")]', name: /^new_user_image$/}
545
548
 
546
549
  expect(selector_builder.build(selector)).to eq built
547
550
  end
@@ -555,7 +558,7 @@ describe Watir::Locators::Element::SelectorBuilder do
555
558
 
556
559
  it 'does not use starts-with if visible locator used' do
557
560
  selector = {id: /^vis/, visible_text: 'shown div'}
558
- built = {xpath: ".//*[contains(@id, 'vis')]", id: /^vis/, visible_text: 'shown div'}
561
+ built = {xpath: './/*[contains(@id, "vis")]', id: /^vis/, visible_text: 'shown div'}
559
562
 
560
563
  expect(selector_builder.build(selector)).to eq built
561
564
  end
@@ -563,11 +566,11 @@ describe Watir::Locators::Element::SelectorBuilder do
563
566
  it 'handles case insensitive' do
564
567
  selector = {action: /ME/i}
565
568
  built = {xpath: './/*[contains(translate(@action,' \
566
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
567
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'), " \
568
- "translate('me'," \
569
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
570
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'))]"}
569
+ "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
570
+ "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'), " \
571
+ 'translate("me",' \
572
+ "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
573
+ "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'))]"}
571
574
 
572
575
  expect(selector_builder.build(selector)).to eq built
573
576
  end
@@ -606,14 +609,14 @@ describe Watir::Locators::Element::SelectorBuilder do
606
609
  context 'returns locators that can not be directly translated' do
607
610
  it 'attribute with complicated Regexp at end' do
608
611
  selector = {action: /me$/}
609
- built = {xpath: ".//*[contains(@action, 'me')]", action: /me$/}
612
+ built = {xpath: './/*[contains(@action, "me")]', action: /me$/}
610
613
 
611
614
  expect(selector_builder.build(selector)).to eq built
612
615
  end
613
616
 
614
617
  it 'class with complicated Regexp' do
615
618
  selector = {class: /he?r/}
616
- built = {xpath: ".//*[contains(@class, 'h') and contains(@class, 'r')]", class: [/he?r/]}
619
+ built = {xpath: './/*[contains(@class, "h") and contains(@class, "r")]', class: [/he?r/]}
617
620
 
618
621
  expect(selector_builder.build(selector)).to eq built
619
622
  end
@@ -738,6 +741,7 @@ describe Watir::Locators::Element::SelectorBuilder do
738
741
  allow(query_scope).to receive(:selector_builder).and_return(selector_builder)
739
742
  allow(query_scope).to receive(:browser).and_return(browser)
740
743
  allow(query_scope).to receive(:is_a?).with(Watir::Browser).and_return(false)
744
+ allow(query_scope).to receive(:is_a?).with(Watir::ShadowRoot).and_return(false)
741
745
  allow(query_scope).to receive(:is_a?).with(Watir::IFrame).and_return(true)
742
746
 
743
747
  selector = {tag_name: 'div'}
@@ -750,48 +754,45 @@ describe Watir::Locators::Element::SelectorBuilder do
750
754
  end
751
755
 
752
756
  context 'with case-insensitive attributes' do
757
+ let(:upper) { "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'" }
758
+ let(:lower) { "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'" }
759
+
753
760
  it 'respects case when locating uknown element with uknown attribute' do
754
761
  expect(selector_builder.build(hreflang: 'en')).to eq(xpath: ".//*[@hreflang='en']")
755
- expect(selector_builder.build(hreflang: /en/)).to eq(xpath: ".//*[contains(@hreflang, 'en')]")
762
+ expect(selector_builder.build(hreflang: /en/)).to eq(xpath: './/*[contains(@hreflang, "en")]')
756
763
  end
757
764
 
758
765
  it 'ignores case when locating uknown element with defined attribute' do
759
- lhs = 'translate(@lang,' \
760
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
761
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')"
762
- rhs = "translate('en'," \
763
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
764
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')"
766
+ lhs = "translate(@lang,#{upper},#{lower})"
767
+ rhs = "translate('en',#{upper},#{lower})"
768
+ rhs_regex = "translate(\"en\",#{upper},#{lower})"
765
769
  expect(selector_builder.build(lang: 'en')).to eq(xpath: ".//*[#{lhs}=#{rhs}]")
766
- expect(selector_builder.build(lang: /en/)).to eq(xpath: ".//*[contains(#{lhs}, #{rhs})]")
770
+ expect(selector_builder.build(lang: /en/)).to eq(xpath: ".//*[contains(#{lhs}, #{rhs_regex})]")
767
771
  expect(selector_builder.build(tag_name: /a/, lang: 'en'))
768
- .to eq(xpath: ".//*[contains(local-name(), 'a')][#{lhs}=#{rhs}]")
772
+ .to eq(xpath: ".//*[contains(local-name(), \"a\")][#{lhs}=#{rhs}]")
769
773
  expect(selector_builder.build(tag_name: /a/, lang: /en/))
770
- .to eq(xpath: ".//*[contains(local-name(), 'a')][contains(#{lhs}, #{rhs})]")
774
+ .to eq(xpath: ".//*[contains(local-name(), \"a\")][contains(#{lhs}, #{rhs_regex})]")
771
775
  end
772
776
 
773
777
  it 'ignores case when attribute is defined for element' do
774
- lhs = 'translate(@hreflang,' \
775
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
776
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')"
777
- rhs = "translate('en'," \
778
- "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'," \
779
- "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')"
778
+ lhs = "translate(@hreflang,#{upper},#{lower})"
779
+ rhs = "translate('en',#{upper},#{lower})"
780
+ rhs_regex = "translate(\"en\",#{upper},#{lower})"
780
781
  expect(selector_builder.build(tag_name: 'a', hreflang: 'en'))
781
782
  .to eq(xpath: ".//*[local-name()='a'][#{lhs}=#{rhs}]")
782
783
  expect(selector_builder.build(tag_name: 'a', hreflang: /en/))
783
- .to eq(xpath: ".//*[local-name()='a'][contains(#{lhs}, #{rhs})]")
784
+ .to eq(xpath: ".//*[local-name()='a'][contains(#{lhs}, #{rhs_regex})]")
784
785
  end
785
786
 
786
787
  it 'respects case when attribute is not defined for element' do
787
788
  expect(selector_builder.build(tag_name: 'table', hreflang: 'en'))
788
789
  .to eq(xpath: ".//*[local-name()='table'][@hreflang='en']")
789
790
  expect(selector_builder.build(tag_name: 'table', hreflang: /en/))
790
- .to eq(xpath: ".//*[local-name()='table'][contains(@hreflang, 'en')]")
791
+ .to eq(xpath: ".//*[local-name()='table'][contains(@hreflang, \"en\")]")
791
792
  expect(selector_builder.build(tag_name: /a/, hreflang: 'en'))
792
- .to eq(xpath: ".//*[contains(local-name(), 'a')][@hreflang='en']")
793
+ .to eq(xpath: ".//*[contains(local-name(), \"a\")][@hreflang='en']")
793
794
  expect(selector_builder.build(tag_name: /a/, hreflang: /en/))
794
- .to eq(xpath: ".//*[contains(local-name(), 'a')][contains(@hreflang, 'en')]")
795
+ .to eq(xpath: './/*[contains(local-name(), "a")][contains(@hreflang, "en")]')
795
796
  end
796
797
  end
797
798
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../unit_helper'
2
4
 
3
5
  describe Watir::Locators::Row::SelectorBuilder do
@@ -13,7 +15,8 @@ describe Watir::Locators::Row::SelectorBuilder do
13
15
  @query_scope = element(tag_name: 'table')
14
16
 
15
17
  built = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
16
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']"}
18
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
19
+ "./*[local-name()='tfoot']/*[local-name()='tr']"}
17
20
 
18
21
  expect(selector_built).to eq built
19
22
  end
@@ -49,7 +52,8 @@ describe Watir::Locators::Row::SelectorBuilder do
49
52
  it 'positive' do
50
53
  @selector = {index: 1}
51
54
  built = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
52
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[2]"}
55
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
56
+ "./*[local-name()='tfoot']/*[local-name()='tr'])[2]"}
53
57
 
54
58
  expect(selector_built).to eq built
55
59
  end
@@ -57,7 +61,8 @@ describe Watir::Locators::Row::SelectorBuilder do
57
61
  it 'negative' do
58
62
  @selector = {index: -3}
59
63
  built = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
60
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[last()-2]"}
64
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
65
+ "./*[local-name()='tfoot']/*[local-name()='tr'])[last()-2]"}
61
66
 
62
67
  expect(selector_built).to eq built
63
68
  end
@@ -65,7 +70,8 @@ describe Watir::Locators::Row::SelectorBuilder do
65
70
  it 'last' do
66
71
  @selector = {index: -1}
67
72
  built = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
68
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[last()]"}
73
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
74
+ "./*[local-name()='tfoot']/*[local-name()='tr'])[last()]"}
69
75
 
70
76
  expect(selector_built).to eq built
71
77
  end
@@ -73,7 +79,8 @@ describe Watir::Locators::Row::SelectorBuilder do
73
79
  it 'does not return index if it is zero' do
74
80
  @selector = {index: 0}
75
81
  built = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
76
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']"}
82
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
83
+ "./*[local-name()='tfoot']/*[local-name()='tr']"}
77
84
 
78
85
  expect(selector_built).to eq built
79
86
  end
@@ -88,10 +95,13 @@ describe Watir::Locators::Row::SelectorBuilder do
88
95
  context 'with multiple locators' do
89
96
  it 'attribute and class' do
90
97
  @selector = {id: 'gregory', class: /brick/}
91
- built = {xpath: "./*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
92
- "./*[local-name()='tbody']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
93
- "./*[local-name()='thead']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
94
- "./*[local-name()='tfoot']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory']"}
98
+ built = {xpath: "./*[local-name()='tr'][contains(@class, \"brick\")][@id='gregory'] | " \
99
+ "./*[local-name()='tbody']/*[local-name()='tr']" \
100
+ "[contains(@class, \"brick\")][@id='gregory'] | " \
101
+ "./*[local-name()='thead']/*[local-name()='tr']" \
102
+ "[contains(@class, \"brick\")][@id='gregory'] | " \
103
+ "./*[local-name()='tfoot']/*[local-name()='tr']" \
104
+ "[contains(@class, \"brick\")][@id='gregory']"}
95
105
 
96
106
  expect(selector_built).to eq built
97
107
  end
@@ -101,7 +111,8 @@ describe Watir::Locators::Row::SelectorBuilder do
101
111
  it 'any text value' do
102
112
  @selector = {text: 'Gregory'}
103
113
  built = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
104
- "./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']", text: 'Gregory'}
114
+ "./*[local-name()='thead']/*[local-name()='tr'] | " \
115
+ "./*[local-name()='tfoot']/*[local-name()='tr']", text: 'Gregory'}
105
116
 
106
117
  expect(selector_built).to eq built
107
118
  end