watir 1.4.1 → 7.3.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 (422) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.github/ISSUE_TEMPLATE.md +16 -0
  4. data/.github/workflows/chrome.yml +55 -0
  5. data/.github/workflows/edge.yml +44 -0
  6. data/.github/workflows/firefox.yml +55 -0
  7. data/.github/workflows/ie.yml +30 -0
  8. data/.github/workflows/safari.yml +38 -0
  9. data/.github/workflows/unit.yml +60 -0
  10. data/.gitignore +21 -0
  11. data/.rubocop.yml +114 -0
  12. data/.rubocop_todo.yml +17 -0
  13. data/CHANGES.md +2212 -0
  14. data/Gemfile +15 -0
  15. data/LICENSE +24 -0
  16. data/README.md +113 -0
  17. data/Rakefile +173 -0
  18. data/lib/watir/adjacent.rb +128 -0
  19. data/lib/watir/after_hooks.rb +135 -0
  20. data/lib/watir/alert.rb +113 -0
  21. data/lib/watir/aliases.rb +8 -0
  22. data/lib/watir/attribute_helper.rb +97 -0
  23. data/lib/watir/browser.rb +323 -0
  24. data/lib/watir/capabilities.rb +179 -0
  25. data/lib/watir/cell_container.rb +25 -0
  26. data/lib/watir/container.rb +33 -0
  27. data/lib/watir/cookies.rb +130 -0
  28. data/lib/watir/element_collection.rb +223 -0
  29. data/lib/watir/elements/button.rb +28 -0
  30. data/lib/watir/elements/cell.rb +18 -0
  31. data/lib/watir/elements/checkbox.rb +56 -0
  32. data/lib/watir/elements/date_field.rb +42 -0
  33. data/lib/watir/elements/date_time_field.rb +42 -0
  34. data/lib/watir/elements/dlist.rb +12 -0
  35. data/lib/watir/elements/element.rb +807 -0
  36. data/lib/watir/elements/file_field.rb +43 -0
  37. data/lib/watir/elements/font.rb +26 -0
  38. data/lib/watir/elements/form.rb +16 -0
  39. data/lib/watir/elements/hidden.rb +26 -0
  40. data/lib/watir/elements/html_elements.rb +1981 -0
  41. data/lib/watir/elements/iframe.rb +156 -0
  42. data/lib/watir/elements/image.rb +22 -0
  43. data/lib/watir/elements/input.rb +15 -0
  44. data/lib/watir/elements/link.rb +8 -0
  45. data/lib/watir/elements/list.rb +51 -0
  46. data/lib/watir/elements/option.rb +60 -0
  47. data/lib/watir/elements/radio.rb +65 -0
  48. data/lib/watir/elements/row.rb +18 -0
  49. data/lib/watir/elements/select.rb +214 -0
  50. data/lib/watir/elements/svg_elements.rb +497 -0
  51. data/lib/watir/elements/table.rb +77 -0
  52. data/lib/watir/elements/table_cell.rb +32 -0
  53. data/lib/watir/elements/table_row.rb +34 -0
  54. data/lib/watir/elements/table_section.rb +17 -0
  55. data/lib/watir/elements/text_area.rb +7 -0
  56. data/lib/watir/elements/text_field.rb +39 -0
  57. data/lib/watir/exception.rb +16 -0
  58. data/lib/watir/extensions/nokogiri.rb +14 -0
  59. data/lib/watir/generator/base/generator.rb +114 -0
  60. data/lib/watir/generator/base/idl_sorter.rb +51 -0
  61. data/lib/watir/generator/base/spec_extractor.rb +158 -0
  62. data/lib/watir/generator/base/util.rb +21 -0
  63. data/lib/watir/generator/base/visitor.rb +133 -0
  64. data/lib/watir/generator/base.rb +12 -0
  65. data/lib/watir/generator/html/generator.rb +36 -0
  66. data/lib/watir/generator/html/spec_extractor.rb +52 -0
  67. data/lib/watir/generator/html/visitor.rb +23 -0
  68. data/lib/watir/generator/html.rb +17 -0
  69. data/lib/watir/generator/svg/generator.rb +38 -0
  70. data/lib/watir/generator/svg/spec_extractor.rb +55 -0
  71. data/lib/watir/generator/svg/visitor.rb +23 -0
  72. data/lib/watir/generator/svg.rb +9 -0
  73. data/lib/watir/generator.rb +5 -0
  74. data/lib/watir/has_window.rb +72 -0
  75. data/lib/watir/http_client.rb +11 -0
  76. data/lib/watir/js_execution.rb +165 -0
  77. data/lib/watir/js_snippets/attributeValues.js +11 -0
  78. data/lib/watir/js_snippets/backgroundColor.js +7 -0
  79. data/lib/watir/js_snippets/elementObscured.js +14 -0
  80. data/lib/watir/js_snippets/fireEvent.js +31 -0
  81. data/lib/watir/js_snippets/focus.js +3 -0
  82. data/lib/watir/js_snippets/getElementTags.js +3 -0
  83. data/lib/watir/js_snippets/getInnerHtml.js +19 -0
  84. data/lib/watir/js_snippets/getInnerText.js +19 -0
  85. data/lib/watir/js_snippets/getOuterHtml.js +20 -0
  86. data/lib/watir/js_snippets/getTextContent.js +19 -0
  87. data/lib/watir/js_snippets/isElementInViewport.js +20 -0
  88. data/lib/watir/js_snippets/isImageLoaded.js +3 -0
  89. data/lib/watir/js_snippets/selectOptionsLabel.js +10 -0
  90. data/lib/watir/js_snippets/selectOptionsText.js +10 -0
  91. data/lib/watir/js_snippets/selectOptionsValue.js +10 -0
  92. data/lib/watir/js_snippets/selectText.js +64 -0
  93. data/lib/watir/js_snippets/selectedOptions.js +11 -0
  94. data/lib/watir/js_snippets/selectedText.js +17 -0
  95. data/lib/watir/js_snippets/setText.js +3 -0
  96. data/lib/watir/js_snippets/setValue.js +3 -0
  97. data/lib/watir/js_snippets.rb +18 -0
  98. data/lib/watir/locators/anchor/selector_builder.rb +43 -0
  99. data/lib/watir/locators/button/matcher.rb +19 -0
  100. data/lib/watir/locators/button/selector_builder/xpath.rb +69 -0
  101. data/lib/watir/locators/button/selector_builder.rb +10 -0
  102. data/lib/watir/locators/cell/selector_builder/xpath.rb +23 -0
  103. data/lib/watir/locators/cell/selector_builder.rb +13 -0
  104. data/lib/watir/locators/element/locator.rb +81 -0
  105. data/lib/watir/locators/element/matcher.rb +118 -0
  106. data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +69 -0
  107. data/lib/watir/locators/element/selector_builder/xpath.rb +268 -0
  108. data/lib/watir/locators/element/selector_builder/xpath_support.rb +29 -0
  109. data/lib/watir/locators/element/selector_builder.rb +164 -0
  110. data/lib/watir/locators/option/matcher.rb +26 -0
  111. data/lib/watir/locators/option/selector_builder/xpath.rb +39 -0
  112. data/lib/watir/locators/option/selector_builder.rb +10 -0
  113. data/lib/watir/locators/row/selector_builder/xpath.rb +53 -0
  114. data/lib/watir/locators/row/selector_builder.rb +18 -0
  115. data/lib/watir/locators/text_area/selector_builder/xpath.rb +21 -0
  116. data/lib/watir/locators/text_area/selector_builder.rb +10 -0
  117. data/lib/watir/locators/text_field/matcher.rb +37 -0
  118. data/lib/watir/locators/text_field/selector_builder/xpath.rb +50 -0
  119. data/lib/watir/locators/text_field/selector_builder.rb +10 -0
  120. data/lib/watir/locators.rb +77 -0
  121. data/lib/watir/logger.rb +30 -0
  122. data/lib/watir/navigation.rb +51 -0
  123. data/lib/watir/radio_set.rb +230 -0
  124. data/lib/watir/row_container.rb +36 -0
  125. data/lib/watir/screenshot.rb +51 -0
  126. data/lib/watir/scroll.rb +95 -0
  127. data/lib/watir/search_context.rb +96 -0
  128. data/lib/watir/shadow_root.rb +60 -0
  129. data/lib/watir/user_editable.rb +85 -0
  130. data/lib/watir/version.rb +5 -0
  131. data/lib/watir/wait/timer.rb +52 -0
  132. data/lib/watir/wait.rb +171 -0
  133. data/lib/watir/window.rb +276 -0
  134. data/lib/watir/window_collection.rb +82 -0
  135. data/lib/watir.rb +108 -0
  136. data/lib/watirspec/guards.rb +65 -0
  137. data/lib/watirspec/implementation.rb +56 -0
  138. data/lib/watirspec/rake_tasks.rb +118 -0
  139. data/lib/watirspec/remote_server.rb +39 -0
  140. data/lib/watirspec/runner.rb +64 -0
  141. data/lib/watirspec/server/app.rb +86 -0
  142. data/lib/watirspec/server.rb +104 -0
  143. data/lib/watirspec.rb +93 -0
  144. data/spec/locator_spec_helper.rb +88 -0
  145. data/spec/spec_helper.rb +24 -0
  146. data/spec/unit/capabilities_spec.rb +670 -0
  147. data/spec/unit/element_locator_spec.rb +97 -0
  148. data/spec/unit/match_elements/button_spec.rb +76 -0
  149. data/spec/unit/match_elements/element_spec.rb +424 -0
  150. data/spec/unit/match_elements/text_field_spec.rb +84 -0
  151. data/spec/unit/selector_builder/anchor_spec.rb +59 -0
  152. data/spec/unit/selector_builder/button_spec.rb +217 -0
  153. data/spec/unit/selector_builder/cell_spec.rb +71 -0
  154. data/spec/unit/selector_builder/element_spec.rb +804 -0
  155. data/spec/unit/selector_builder/row_spec.rb +128 -0
  156. data/spec/unit/selector_builder/text_field_spec.rb +203 -0
  157. data/spec/unit/selector_builder/textarea_spec.rb +35 -0
  158. data/spec/unit/unit_helper.rb +4 -0
  159. data/spec/unit/wait_spec.rb +99 -0
  160. data/spec/watirspec/adjacent_spec.rb +256 -0
  161. data/spec/watirspec/after_hooks_spec.rb +204 -0
  162. data/spec/watirspec/alert_spec.rb +89 -0
  163. data/spec/watirspec/browser_spec.rb +536 -0
  164. data/spec/watirspec/capabilities_spec.rb +556 -0
  165. data/spec/watirspec/cookies_spec.rb +196 -0
  166. data/spec/watirspec/drag_and_drop_spec.rb +38 -0
  167. data/spec/watirspec/element_hidden_spec.rb +86 -0
  168. data/spec/watirspec/elements/area_spec.rb +69 -0
  169. data/spec/watirspec/elements/areas_spec.rb +44 -0
  170. data/spec/watirspec/elements/button_spec.rb +265 -0
  171. data/spec/watirspec/elements/buttons_spec.rb +57 -0
  172. data/spec/watirspec/elements/checkbox_spec.rb +290 -0
  173. data/spec/watirspec/elements/checkboxes_spec.rb +46 -0
  174. data/spec/watirspec/elements/collections_spec.rb +132 -0
  175. data/spec/watirspec/elements/date_field_spec.rb +209 -0
  176. data/spec/watirspec/elements/date_fields_spec.rb +46 -0
  177. data/spec/watirspec/elements/date_time_field_spec.rb +223 -0
  178. data/spec/watirspec/elements/date_time_fields_spec.rb +47 -0
  179. data/spec/watirspec/elements/dd_spec.rb +108 -0
  180. data/spec/watirspec/elements/dds_spec.rb +44 -0
  181. data/spec/watirspec/elements/del_spec.rb +113 -0
  182. data/spec/watirspec/elements/dels_spec.rb +42 -0
  183. data/spec/watirspec/elements/div_spec.rb +232 -0
  184. data/spec/watirspec/elements/divs_spec.rb +56 -0
  185. data/spec/watirspec/elements/dl_spec.rb +117 -0
  186. data/spec/watirspec/elements/dls_spec.rb +45 -0
  187. data/spec/watirspec/elements/dt_spec.rb +107 -0
  188. data/spec/watirspec/elements/dts_spec.rb +44 -0
  189. data/spec/watirspec/elements/element_spec.rb +1069 -0
  190. data/spec/watirspec/elements/elements_spec.rb +60 -0
  191. data/spec/watirspec/elements/em_spec.rb +85 -0
  192. data/spec/watirspec/elements/ems_spec.rb +45 -0
  193. data/spec/watirspec/elements/filefield_spec.rb +135 -0
  194. data/spec/watirspec/elements/filefields_spec.rb +45 -0
  195. data/spec/watirspec/elements/font_spec.rb +31 -0
  196. data/spec/watirspec/elements/form_spec.rb +70 -0
  197. data/spec/watirspec/elements/forms_spec.rb +46 -0
  198. data/spec/watirspec/elements/frame_spec.rb +117 -0
  199. data/spec/watirspec/elements/frames_spec.rb +43 -0
  200. data/spec/watirspec/elements/hidden_spec.rb +106 -0
  201. data/spec/watirspec/elements/hiddens_spec.rb +45 -0
  202. data/spec/watirspec/elements/hn_spec.rb +80 -0
  203. data/spec/watirspec/elements/hns_spec.rb +42 -0
  204. data/spec/watirspec/elements/iframe_spec.rb +244 -0
  205. data/spec/watirspec/elements/iframes_spec.rb +49 -0
  206. data/spec/watirspec/elements/image_spec.rb +160 -0
  207. data/spec/watirspec/elements/images_spec.rb +42 -0
  208. data/spec/watirspec/elements/input_spec.rb +17 -0
  209. data/spec/watirspec/elements/ins_spec.rb +113 -0
  210. data/spec/watirspec/elements/inses_spec.rb +42 -0
  211. data/spec/watirspec/elements/label_spec.rb +77 -0
  212. data/spec/watirspec/elements/labels_spec.rb +42 -0
  213. data/spec/watirspec/elements/li_spec.rb +99 -0
  214. data/spec/watirspec/elements/link_spec.rb +180 -0
  215. data/spec/watirspec/elements/links_spec.rb +66 -0
  216. data/spec/watirspec/elements/lis_spec.rb +44 -0
  217. data/spec/watirspec/elements/list_spec.rb +50 -0
  218. data/spec/watirspec/elements/map_spec.rb +78 -0
  219. data/spec/watirspec/elements/maps_spec.rb +43 -0
  220. data/spec/watirspec/elements/meta_spec.rb +27 -0
  221. data/spec/watirspec/elements/metas_spec.rb +42 -0
  222. data/spec/watirspec/elements/ol_spec.rb +63 -0
  223. data/spec/watirspec/elements/ols_spec.rb +42 -0
  224. data/spec/watirspec/elements/option_spec.rb +113 -0
  225. data/spec/watirspec/elements/p_spec.rb +102 -0
  226. data/spec/watirspec/elements/pre_spec.rb +100 -0
  227. data/spec/watirspec/elements/pres_spec.rb +42 -0
  228. data/spec/watirspec/elements/ps_spec.rb +42 -0
  229. data/spec/watirspec/elements/radio_spec.rb +259 -0
  230. data/spec/watirspec/elements/radios_spec.rb +45 -0
  231. data/spec/watirspec/elements/select_list_spec.rb +701 -0
  232. data/spec/watirspec/elements/select_lists_spec.rb +49 -0
  233. data/spec/watirspec/elements/span_spec.rb +119 -0
  234. data/spec/watirspec/elements/spans_spec.rb +42 -0
  235. data/spec/watirspec/elements/strong_spec.rb +78 -0
  236. data/spec/watirspec/elements/strongs_spec.rb +45 -0
  237. data/spec/watirspec/elements/table_spec.rb +210 -0
  238. data/spec/watirspec/elements/tables_spec.rb +44 -0
  239. data/spec/watirspec/elements/tbody_spec.rb +94 -0
  240. data/spec/watirspec/elements/tbodys_spec.rb +64 -0
  241. data/spec/watirspec/elements/td_spec.rb +92 -0
  242. data/spec/watirspec/elements/tds_spec.rb +55 -0
  243. data/spec/watirspec/elements/text_field_spec.rb +223 -0
  244. data/spec/watirspec/elements/text_fields_spec.rb +47 -0
  245. data/spec/watirspec/elements/textarea_spec.rb +30 -0
  246. data/spec/watirspec/elements/textareas_spec.rb +28 -0
  247. data/spec/watirspec/elements/tfoot_spec.rb +89 -0
  248. data/spec/watirspec/elements/tfoots_spec.rb +72 -0
  249. data/spec/watirspec/elements/thead_spec.rb +88 -0
  250. data/spec/watirspec/elements/theads_spec.rb +72 -0
  251. data/spec/watirspec/elements/tr_spec.rb +69 -0
  252. data/spec/watirspec/elements/trs_spec.rb +63 -0
  253. data/spec/watirspec/elements/ul_spec.rb +63 -0
  254. data/spec/watirspec/elements/uls_spec.rb +42 -0
  255. data/spec/watirspec/html/alerts.html +12 -0
  256. data/spec/watirspec/html/aria_attributes.html +9 -0
  257. data/spec/watirspec/html/child_frame.html +29 -0
  258. data/spec/watirspec/html/class_locator.html +11 -0
  259. data/spec/watirspec/html/clicks.html +19 -0
  260. data/spec/watirspec/html/closeable.html +21 -0
  261. data/spec/watirspec/html/collections.html +15 -0
  262. data/spec/watirspec/html/css/jquery-ui-1.8.17.custom.css +287 -0
  263. data/spec/watirspec/html/data_attributes.html +10 -0
  264. data/spec/watirspec/html/definition_lists.html +48 -0
  265. data/spec/watirspec/html/drag_and_drop.html +106 -0
  266. data/spec/watirspec/html/font.html +10 -0
  267. data/spec/watirspec/html/forms_with_input_elements.html +194 -0
  268. data/spec/watirspec/html/frame_1.html +22 -0
  269. data/spec/watirspec/html/frame_2.html +16 -0
  270. data/spec/watirspec/html/frames.html +11 -0
  271. data/spec/watirspec/html/iframe_1.html +22 -0
  272. data/spec/watirspec/html/iframes.html +15 -0
  273. data/spec/watirspec/html/images/button.png +0 -0
  274. data/spec/watirspec/html/images/circle.png +0 -0
  275. data/spec/watirspec/html/images/map.gif +0 -0
  276. data/spec/watirspec/html/images/map2.gif +0 -0
  277. data/spec/watirspec/html/images/originaltriangle.png +0 -0
  278. data/spec/watirspec/html/images/square.png +0 -0
  279. data/spec/watirspec/html/images/triangle.png +0 -0
  280. data/spec/watirspec/html/images.html +28 -0
  281. data/spec/watirspec/html/inner_outer.html +5 -0
  282. data/spec/watirspec/html/javascript/angular.min.js +332 -0
  283. data/spec/watirspec/html/javascript/helpers.js +16 -0
  284. data/spec/watirspec/html/javascript/jquery-1.7.1.min.js +4 -0
  285. data/spec/watirspec/html/javascript/jquery-ui-1.8.17.custom.min.js +68 -0
  286. data/spec/watirspec/html/keylogger.html +15 -0
  287. data/spec/watirspec/html/modal_dialog.html +9 -0
  288. data/spec/watirspec/html/multiple_ids.html +15 -0
  289. data/spec/watirspec/html/nested_elements.html +44 -0
  290. data/spec/watirspec/html/nested_frame_1.html +1 -0
  291. data/spec/watirspec/html/nested_frame_2.html +9 -0
  292. data/spec/watirspec/html/nested_frame_3.html +14 -0
  293. data/spec/watirspec/html/nested_frames.html +10 -0
  294. data/spec/watirspec/html/nested_iframe_2.html +12 -0
  295. data/spec/watirspec/html/nested_iframes.html +13 -0
  296. data/spec/watirspec/html/nested_tables.html +203 -0
  297. data/spec/watirspec/html/non_control_elements.html +145 -0
  298. data/spec/watirspec/html/obscured.html +36 -0
  299. data/spec/watirspec/html/removed_element.html +24 -0
  300. data/spec/watirspec/html/right_click.html +23 -0
  301. data/spec/watirspec/html/scroll.html +15 -0
  302. data/spec/watirspec/html/scroll_nested.html +17 -0
  303. data/spec/watirspec/html/scroll_nested_offscreen.html +18 -0
  304. data/spec/watirspec/html/shadow_dom.html +28 -0
  305. data/spec/watirspec/html/special_chars.html +15 -0
  306. data/spec/watirspec/html/sticky_elements.html +10 -0
  307. data/spec/watirspec/html/tables.html +121 -0
  308. data/spec/watirspec/html/timeout_window_location.html +19 -0
  309. data/spec/watirspec/html/uneven_table.html +20 -0
  310. data/spec/watirspec/html/wait.html +99 -0
  311. data/spec/watirspec/html/watirspec.css +0 -0
  312. data/spec/watirspec/html/window_switching.html +22 -0
  313. data/spec/watirspec/radio_set_spec.rb +346 -0
  314. data/spec/watirspec/screenshot_spec.rb +33 -0
  315. data/spec/watirspec/scroll_spec.rb +208 -0
  316. data/spec/watirspec/shadow_root_spec.rb +108 -0
  317. data/spec/watirspec/support/rspec_matchers.rb +161 -0
  318. data/spec/watirspec/user_editable_spec.rb +207 -0
  319. data/spec/watirspec/wait_spec.rb +345 -0
  320. data/spec/watirspec/window_switching_spec.rb +580 -0
  321. data/spec/watirspec_helper.rb +163 -0
  322. data/support/doctest_helper.rb +101 -0
  323. data/support/version_differ.rb +60 -0
  324. data/watir.gemspec +50 -0
  325. metadata +652 -148
  326. data/readme.rb +0 -211
  327. data/unittests/WindowLogonExample.rb +0 -30
  328. data/unittests/WindowLogonExtra.rb +0 -7
  329. data/unittests/all_tests.rb +0 -10
  330. data/unittests/all_tests_concurrent.rb +0 -57
  331. data/unittests/attachToExistingWindow_test.rb +0 -40
  332. data/unittests/buttons_test.rb +0 -131
  333. data/unittests/checkbox_test.rb +0 -149
  334. data/unittests/core_tests.rb +0 -9
  335. data/unittests/css_test.rb +0 -60
  336. data/unittests/div_test.rb +0 -179
  337. data/unittests/errorchecker_test.rb +0 -29
  338. data/unittests/filefield_test.rb +0 -35
  339. data/unittests/form_test.rb +0 -279
  340. data/unittests/frame_test.rb +0 -141
  341. data/unittests/html/blankpage.html +0 -12
  342. data/unittests/html/buttons1.html +0 -40
  343. data/unittests/html/checkboxes1.html +0 -69
  344. data/unittests/html/complex_table.html +0 -36
  345. data/unittests/html/cssTest.html +0 -42
  346. data/unittests/html/div.html +0 -105
  347. data/unittests/html/fileupload.html +0 -45
  348. data/unittests/html/formTest1.html +0 -39
  349. data/unittests/html/forms2.html +0 -45
  350. data/unittests/html/forms3.html +0 -132
  351. data/unittests/html/forms4.html +0 -27
  352. data/unittests/html/frame_buttons.html +0 -4
  353. data/unittests/html/frame_links.html +0 -4
  354. data/unittests/html/frame_multi.html +0 -5
  355. data/unittests/html/iframeTest.html +0 -13
  356. data/unittests/html/iframeTest1.html +0 -7
  357. data/unittests/html/iframeTest2.html +0 -6
  358. data/unittests/html/images/button.jpg +0 -0
  359. data/unittests/html/images/circle.jpg +0 -0
  360. data/unittests/html/images/originaltriangle.jpg +0 -0
  361. data/unittests/html/images/square.jpg +0 -0
  362. data/unittests/html/images/triangle.jpg +0 -0
  363. data/unittests/html/images1.html +0 -52
  364. data/unittests/html/javascriptevents.html +0 -39
  365. data/unittests/html/link_pass.html +0 -11
  366. data/unittests/html/links1.html +0 -37
  367. data/unittests/html/links2.html +0 -11
  368. data/unittests/html/nestedFrames.html +0 -6
  369. data/unittests/html/pass.html +0 -10
  370. data/unittests/html/popups1.html +0 -60
  371. data/unittests/html/radioButtons1.html +0 -71
  372. data/unittests/html/select_tealeaf.html +0 -54
  373. data/unittests/html/selectboxes1.html +0 -55
  374. data/unittests/html/simple_table.html +0 -26
  375. data/unittests/html/simple_table_buttons.html +0 -104
  376. data/unittests/html/simple_table_columns.html +0 -76
  377. data/unittests/html/table1.html +0 -142
  378. data/unittests/html/textarea.html +0 -30
  379. data/unittests/html/textfields1.html +0 -87
  380. data/unittests/html/textsearch.html +0 -44
  381. data/unittests/ie_mock.rb +0 -93
  382. data/unittests/ie_test.rb +0 -50
  383. data/unittests/images_test.rb +0 -179
  384. data/unittests/iostring.rb +0 -30
  385. data/unittests/iostring_test.rb +0 -48
  386. data/unittests/js_events_test.rb +0 -77
  387. data/unittests/jscriptExtraAlert.rb +0 -6
  388. data/unittests/jscriptExtraConfirmCancel.rb +0 -7
  389. data/unittests/jscriptExtraConfirmOk.rb +0 -7
  390. data/unittests/jscriptPushButton.rb +0 -5
  391. data/unittests/jscript_test.rb +0 -57
  392. data/unittests/links_test.rb +0 -169
  393. data/unittests/minmax_test.rb +0 -31
  394. data/unittests/navigate_test.rb +0 -56
  395. data/unittests/non_core_tests.rb +0 -9
  396. data/unittests/pagecontainstext_test.rb +0 -49
  397. data/unittests/popups_test.rb +0 -44
  398. data/unittests/radios_test.rb +0 -164
  399. data/unittests/screen_capture_test.rb +0 -53
  400. data/unittests/selectbox_test.rb +0 -197
  401. data/unittests/send_keys_test.rb +0 -29
  402. data/unittests/setup.rb +0 -47
  403. data/unittests/table_test.rb +0 -306
  404. data/unittests/textAreafields_test.rb +0 -81
  405. data/unittests/textfields_test.rb +0 -239
  406. data/watir/AutoItX3.dll +0 -0
  407. data/watir/WindowHelper.rb +0 -47
  408. data/watir/camel_case.rb +0 -37
  409. data/watir/clickJSDialog.rb +0 -19
  410. data/watir/cookiemanager.rb +0 -53
  411. data/watir/exceptions.rb +0 -60
  412. data/watir/screen_capture.rb +0 -115
  413. data/watir/setFileDialog.rb +0 -16
  414. data/watir/testUnitAddons.rb +0 -47
  415. data/watir/watir_simple.rb +0 -475
  416. data/watir/winClicker.rb +0 -505
  417. data/watir.rb +0 -3744
  418. /data/{unittests → spec/watirspec}/html/images/1.gif +0 -0
  419. /data/{unittests/html/images/2.GIF → spec/watirspec/html/images/2.gif} +0 -0
  420. /data/{unittests/html/images/3.GIF → spec/watirspec/html/images/3.gif} +0 -0
  421. /data/{unittests/html/images/minus.GIF → spec/watirspec/html/images/minus.gif} +0 -0
  422. /data/{unittests → spec/watirspec}/html/images/plus.gif +0 -0
@@ -0,0 +1,1069 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'watirspec_helper'
4
+
5
+ module Watir
6
+ describe Element do
7
+ before do
8
+ @c = Selenium::WebDriver::Platform.mac? ? :command : :control
9
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
10
+ end
11
+
12
+ describe '.new' do
13
+ it "finds elements matching the conditions when given a hash of :how => 'what' arguments" do
14
+ expect(browser.checkbox(name: 'new_user_interests', title: 'Dancing is fun!').value).to eq 'dancing'
15
+ expect(browser.text_field(class_name: 'name', index: 1).id).to eq 'new_user_last_name'
16
+ end
17
+
18
+ it "raises UnknownObjectException when given a hash of :how => 'what' arguments (non-existing object)" do
19
+ expect { browser.text_field(index: 100, name: 'foo').id }.to raise_unknown_object_exception
20
+ end
21
+
22
+ it 'raises ArgumentError if given the wrong number of arguments' do
23
+ expect { described_class.new(browser.wd, 'foo') }.to raise_error(ArgumentError)
24
+ end
25
+ end
26
+
27
+ describe '#element_call' do
28
+ it 'handles exceptions when taking an action on a stale element' do
29
+ browser.goto WatirSpec.url_for('removed_element.html')
30
+
31
+ element = browser.div(id: 'text').locate
32
+
33
+ browser.refresh
34
+
35
+ expect(element).to be_stale
36
+ expect { element.text }.not_to raise_error
37
+ end
38
+
39
+ it 'relocates stale element when taking an action on it' do
40
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
41
+ element = browser.text_field(id: 'new_user_first_name').locate
42
+ browser.refresh
43
+ expect { element.click }.not_to raise_exception
44
+ end
45
+ end
46
+
47
+ describe '#eq and #eql?' do
48
+ before { browser.goto WatirSpec.url_for('definition_lists.html') }
49
+
50
+ it 'returns true if the two elements point to the same DOM element' do
51
+ a = browser.dl(id: 'experience-list')
52
+ b = browser.dl
53
+
54
+ expect(a).to eq b
55
+ expect(a).to eql(b)
56
+ end
57
+
58
+ it 'returns false if the two elements are not the same' do
59
+ a = browser.dls[0]
60
+ b = browser.dls[1]
61
+
62
+ expect(a).not_to eq b
63
+ expect(a).not_to eql(b)
64
+ end
65
+
66
+ it 'returns false if the other object is not an Element' do
67
+ expect(browser.dl).not_to eq 1
68
+ end
69
+ end
70
+
71
+ describe 'data-* attributes' do
72
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
73
+
74
+ it 'finds elements by a data-* attribute' do
75
+ expect(browser.p(data_type: 'ruby-library')).to exist
76
+ end
77
+
78
+ it 'returns the value of a data-* attribute' do
79
+ expect(browser.p.data_type).to eq 'ruby-library'
80
+ end
81
+ end
82
+
83
+ describe 'aria-* attributes' do
84
+ before { browser.goto WatirSpec.url_for('aria_attributes.html') }
85
+
86
+ it 'finds elements by a aria-* attribute' do
87
+ expect(browser.p(aria_label: 'ruby-library')).to exist
88
+ end
89
+
90
+ it 'returns the value of a aria-* attribute' do
91
+ expect(browser.p.aria_label).to eq 'ruby-library'
92
+ end
93
+ end
94
+
95
+ describe 'visible text' do
96
+ it 'finds elements by visible text' do
97
+ browser.goto WatirSpec.url_for('non_control_elements.html')
98
+
99
+ expect(browser.element(visible_text: 'all visible')).to exist
100
+ expect(browser.element(visible_text: /all visible/)).to exist
101
+ expect(browser.element(visible_text: /some visible/)).to exist
102
+ expect(browser.element(visible_text: 'Link 2', class: 'external')).to exist
103
+ expect(browser.element(visible_text: /Link 2/, class: 'external')).to exist
104
+ end
105
+
106
+ it 'finds elements by visible text in spite of hidden text',
107
+ except: {browser: :safari, reason: 'Safari is not filtering out hidden text'} do
108
+ browser.goto WatirSpec.url_for('non_control_elements.html')
109
+
110
+ expect(browser.element(visible_text: 'some visible')).to exist
111
+ expect(browser.element(visible_text: 'none visible')).not_to exist
112
+ expect(browser.element(visible_text: /none visible/)).not_to exist
113
+ end
114
+
115
+ it 'raises exception unless value is a String or a RegExp' do
116
+ browser.goto WatirSpec.url_for('non_control_elements.html')
117
+ msg = /expected one of \[String, Regexp\], got 7:Integer/
118
+ expect { browser.element(visible_text: 7).exists? }.to raise_exception(TypeError, msg)
119
+ end
120
+
121
+ it 'raises exception unless key is valid' do
122
+ browser.goto WatirSpec.url_for('non_control_elements.html')
123
+ msg = /Unable to build XPath using 7:Integer/
124
+ expect { browser.element(7 => /foo/).exists? }.to raise_exception(Watir::Exception::Error, msg)
125
+ end
126
+ end
127
+
128
+ describe 'finding with unknown tag name' do
129
+ it 'finds an element without arguments' do
130
+ expect(browser.element).to exist
131
+ end
132
+
133
+ it 'finds an element by xpath' do
134
+ expect(browser.element(xpath: "//*[@for='new_user_first_name']")).to exist
135
+ end
136
+
137
+ it 'finds an element by arbitrary attribute' do
138
+ expect(browser.element(title: 'no title')).to exist
139
+ end
140
+
141
+ it 'finds several elements by xpath' do
142
+ expect(browser.elements(xpath: '//a').length).to eq 1
143
+ end
144
+
145
+ it 'finds several elements by arbitrary attribute' do
146
+ expect(browser.elements(id: /^new_user/).length).to eq 33
147
+ end
148
+
149
+ it "finds an element from an element's subtree" do
150
+ expect(browser.fieldset.element(id: 'first_label')).to exist
151
+ expect(browser.field_set.element(id: 'first_label')).to exist
152
+ end
153
+
154
+ it "finds several elements from an element's subtree" do
155
+ expect(browser.fieldset.elements(xpath: './/label').length).to eq 23
156
+ end
157
+ end
158
+
159
+ describe '#to_subtype' do
160
+ it 'returns a CheckBox instance' do
161
+ e = browser.input(xpath: "//input[@type='checkbox']").to_subtype
162
+ expect(e).to be_a(Watir::CheckBox)
163
+ end
164
+
165
+ it 'returns a Radio instance' do
166
+ e = browser.input(xpath: "//input[@type='radio']").to_subtype
167
+ expect(e).to be_a(Watir::Radio)
168
+ end
169
+
170
+ it 'returns a Button instance' do
171
+ es = [
172
+ browser.input(xpath: "//input[@type='button']").to_subtype,
173
+ browser.input(xpath: "//input[@type='submit']").to_subtype,
174
+ browser.input(xpath: "//input[@type='reset']").to_subtype,
175
+ browser.input(xpath: "//input[@type='image']").to_subtype
176
+ ]
177
+
178
+ es.all? { |e| expect(e).to be_a(Watir::Button) }
179
+ end
180
+
181
+ it 'returns a TextField instance' do
182
+ e = browser.input(xpath: "//input[@type='text']").to_subtype
183
+ expect(e).to be_a(Watir::TextField)
184
+ end
185
+
186
+ it 'returns a FileField instance' do
187
+ e = browser.input(xpath: "//input[@type='file']").to_subtype
188
+ expect(e).to be_a(Watir::FileField)
189
+ end
190
+
191
+ it 'returns a Div instance' do
192
+ el = browser.element(xpath: "//*[@id='messages']").to_subtype
193
+ expect(el).to be_a(Watir::Div)
194
+ end
195
+ end
196
+
197
+ describe '#focus' do
198
+ it 'fires the onfocus event for the given element' do
199
+ tf = browser.text_field(id: 'new_user_occupation')
200
+ expect(tf.value).to eq 'Developer'
201
+ tf.focus
202
+ expect(browser.div(id: 'onfocus_test').text).to eq 'changed by onfocus event'
203
+ end
204
+ end
205
+
206
+ describe '#focused?',
207
+ except: {browser: :firefox,
208
+ driver: :remote_driver,
209
+ reason: 'https://github.com/SeleniumHQ/selenium/issues/2555'} do
210
+ it 'knows if the element is focused' do
211
+ expect(browser.element(id: 'new_user_first_name')).to be_focused
212
+ expect(browser.element(id: 'new_user_last_name')).not_to be_focused
213
+ end
214
+ end
215
+
216
+ describe '#fire_event' do
217
+ it 'fires the given event' do
218
+ expect(browser.div(id: 'onfocus_test').text).to be_empty
219
+ browser.text_field(id: 'new_user_occupation').fire_event('onfocus')
220
+ expect(browser.div(id: 'onfocus_test').text).to eq 'changed by onfocus event'
221
+ end
222
+ end
223
+
224
+ describe '#cache=' do
225
+ it 'bypasses selector location' do
226
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
227
+
228
+ wd = browser.div.wd
229
+ element = described_class.new(browser, id: 'not_valid')
230
+ element.cache = wd
231
+
232
+ expect(element).to exist
233
+ end
234
+
235
+ it 'can be cleared' do
236
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
237
+
238
+ wd = browser.div.wd
239
+ element = described_class.new(browser, id: 'not_valid')
240
+ element.cache = wd
241
+
242
+ browser.refresh
243
+ expect(element).not_to exist
244
+ end
245
+ end
246
+
247
+ describe '#exists?' do
248
+ before do
249
+ browser.goto WatirSpec.url_for('removed_element.html')
250
+ end
251
+
252
+ it 'element from a collection is re-looked up after it becomes stale',
253
+ except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
254
+ element = browser.divs(id: 'text').first.locate
255
+
256
+ browser.refresh
257
+
258
+ expect(element).to be_stale
259
+ expect(element).to exist
260
+ end
261
+
262
+ it 'element from a selenium element throws an exception when relocated',
263
+ except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
264
+ div = browser.div.locate
265
+ element = browser.element(element: div.wd)
266
+
267
+ browser.refresh
268
+ expect(element).to be_stale
269
+
270
+ msg = 'Can not relocate a Watir element initialized by a Selenium element'
271
+ expect { element.exists? }.to raise_exception(Watir::Exception::LocatorException, msg)
272
+ end
273
+
274
+ it 'element from a selenium element with other locators throws an exception' do
275
+ div = browser.div.locate
276
+ element = browser.element(element: div.wd, id: 'foo')
277
+
278
+ browser.refresh
279
+
280
+ msg = 'Can not relocate a Watir element initialized by a Selenium element'
281
+ expect { element.exists? }.to raise_exception(Watir::Exception::LocatorException, msg)
282
+ end
283
+
284
+ it 'returns false when tag name does not match id' do
285
+ watir_element = browser.span(id: 'text')
286
+ expect(watir_element).not_to exist
287
+ end
288
+ end
289
+
290
+ describe '#present?' do
291
+ before do
292
+ browser.goto(WatirSpec.url_for('wait.html'))
293
+ end
294
+
295
+ it 'returns true if the element exists and is visible' do
296
+ expect(browser.div(id: 'foo')).to be_present
297
+ end
298
+
299
+ it 'returns false if the element exists but is not visible' do
300
+ expect(browser.div(id: 'bar')).not_to be_present
301
+ end
302
+
303
+ it 'returns false if the element does not exist' do
304
+ expect(browser.div(id: 'should-not-exist')).not_to be_present
305
+ end
306
+
307
+ it 'handles staleness' do
308
+ element = browser.div(id: 'foo').locate
309
+
310
+ allow(element).to receive(:stale?).and_return(true)
311
+
312
+ expect(element).to be_present
313
+ end
314
+ end
315
+
316
+ describe '#enabled?' do
317
+ before do
318
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
319
+ end
320
+
321
+ it 'returns true if the element is enabled' do
322
+ expect(browser.button(name: 'new_user_submit')).to be_enabled
323
+ end
324
+
325
+ it 'returns false if the element is disabled' do
326
+ expect(browser.button(name: 'new_user_submit_disabled')).not_to be_enabled
327
+ end
328
+
329
+ it "raises UnknownObjectException if the element doesn't exist" do
330
+ expect { browser.button(name: 'no_such_name').enabled? }.to raise_unknown_object_exception
331
+ end
332
+ end
333
+
334
+ describe '#stale?' do
335
+ it 'returns true if the element is stale' do
336
+ element = browser.button(name: 'new_user_submit_disabled').locate
337
+
338
+ browser.refresh
339
+
340
+ expect(element).to be_stale
341
+ end
342
+
343
+ it 'returns true the second time if the element is stale',
344
+ except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
345
+ element = browser.div.locate
346
+
347
+ browser.refresh
348
+
349
+ expect(element).to be_stale
350
+ expect(element).to be_stale
351
+ end
352
+
353
+ it 'returns false if the element is not stale' do
354
+ element = browser.button(name: 'new_user_submit_disabled').locate
355
+
356
+ expect(element).not_to be_stale
357
+ end
358
+ end
359
+
360
+ describe '#exist?' do
361
+ context 'when using :class locator' do
362
+ before do
363
+ browser.goto(WatirSpec.url_for('class_locator.html'))
364
+ end
365
+
366
+ it 'matches when the element has a single class' do
367
+ e = browser.div(class: 'a')
368
+ expect(e).to exist
369
+ expect(e.class_name).to eq 'a'
370
+ end
371
+
372
+ it 'matches when the element has several classes' do
373
+ e = browser.div(class: 'b')
374
+ expect(e).to exist
375
+ expect(e.class_name).to eq 'a b c'
376
+ end
377
+
378
+ it 'does not match only part of the class name' do
379
+ expect(browser.div(class: 'bc')).not_to exist
380
+ end
381
+
382
+ it 'matches part of the class name when given a regexp' do
383
+ expect(browser.div(class: /c/)).to exist
384
+ end
385
+
386
+ context 'with multiple classes' do
387
+ it 'matches when the element has a single class' do
388
+ e = browser.div(class: ['a'])
389
+ expect(e).to exist
390
+ expect(e.class_name).to eq 'a'
391
+ end
392
+
393
+ it 'matches a non-ordered subset' do
394
+ e = browser.div(class: %w[c a])
395
+ expect(e).to exist
396
+ expect(e.class_name).to eq 'a b c'
397
+ end
398
+
399
+ it 'matches one with a negation' do
400
+ e = browser.div(class: ['!a'])
401
+ expect(e).to exist
402
+ expect(e.class_name).to eq 'abc'
403
+ end
404
+
405
+ it 'matches multiple with a negation' do
406
+ e = browser.div(class: ['a', '!c', 'b'])
407
+ expect(e).to exist
408
+ expect(e.class_name).to eq 'a b'
409
+ end
410
+
411
+ it 'matches with any whitespace' do
412
+ e = browser.div(class: %w[newline tabbed])
413
+ expect(e).to exist
414
+ expect(e.class_name).to eq "first\nnewline\ttabbed last"
415
+ end
416
+ end
417
+ end
418
+
419
+ context 'when using attribute presence' do
420
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
421
+
422
+ it 'finds element by attribute presence' do
423
+ expect(browser.p(data_type: true)).to exist
424
+ expect(browser.p(class: true)).not_to exist
425
+ end
426
+
427
+ it 'finds element by attribute absence' do
428
+ expect(browser.p(data_type: false)).not_to exist
429
+ expect(browser.p(class: false)).to exist
430
+ end
431
+ end
432
+
433
+ context 'when using :index locator' do
434
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
435
+
436
+ it 'finds the first element by index: 0' do
437
+ expect(browser.element(index: 0).tag_name).to eq 'html'
438
+ end
439
+
440
+ it 'finds the second element by index: 1' do
441
+ expect(browser.element(index: 1).tag_name).to eq 'head'
442
+ end
443
+
444
+ it 'finds the last element by index: -1' do
445
+ expect(browser.element(index: -1).tag_name).to eq 'div'
446
+ end
447
+ end
448
+
449
+ it "doesn't raise when called on nested elements" do
450
+ expect(browser.div(id: 'no_such_div').link(id: 'no_such_id')).not_to exist
451
+ end
452
+
453
+ it "doesn't raise when selector has with :xpath has :index" do
454
+ expect(browser.div(xpath: '//div', index: 1)).to exist
455
+ end
456
+
457
+ it "doesn't raise when selector has with :css has :index" do
458
+ expect(browser.div(css: 'div', index: 1)).to exist
459
+ end
460
+
461
+ it 'finds element by Selenium name locator' do
462
+ expect(browser.element(name: 'new_user_first_name')).to exist
463
+ expect(browser.element(name: /new_user_first_name/)).to exist
464
+ end
465
+
466
+ it 'returns false when tag name does not match id' do
467
+ watir_element = browser.span(id: 'text')
468
+ expect(watir_element).not_to exist
469
+ end
470
+ end
471
+
472
+ describe '#send_keys' do
473
+ before do
474
+ browser.goto(WatirSpec.url_for('keylogger.html'))
475
+ end
476
+
477
+ let(:receiver) { browser.text_field(id: 'receiver') }
478
+ let(:events) { browser.element(id: 'output').ps.size }
479
+
480
+ it 'sends keystrokes to the element' do
481
+ receiver.send_keys 'hello world'
482
+ expect(receiver.value).to eq 'hello world'
483
+ expect(events).to eq 11
484
+ end
485
+
486
+ it 'accepts arbitrary list of arguments' do
487
+ receiver.send_keys 'hello', 'world'
488
+ expect(receiver.value).to eq 'helloworld'
489
+ expect(events).to eq 10
490
+ end
491
+
492
+ context 'with key combinations',
493
+ except: [{browser: :firefox, reason: 'https://github.com/mozilla/geckodriver/issues/245'},
494
+ {browser: :safari}] do
495
+ it 'performs from array' do
496
+ receiver.send_keys 'foo'
497
+ receiver.send_keys [@c, 'a']
498
+ receiver.send_keys :backspace
499
+ expect(receiver.value).to be_empty
500
+ expect(events).to eq 6
501
+ end
502
+
503
+ it 'performs from multiple arrays' do
504
+ receiver.send_keys 'foo'
505
+ receiver.send_keys [@c, 'a'], [@c, 'x']
506
+ expect(receiver.value).to be_empty
507
+ expect(events).to eq 7
508
+ end
509
+
510
+ it 'supports combination of strings and arrays' do
511
+ receiver.send_keys 'foo', [@c, 'a'], :backspace
512
+ expect(receiver.value).to be_empty
513
+ expect(events).to eq 6
514
+ end
515
+ end
516
+ end
517
+
518
+ describe '#click' do
519
+ it 'accepts modifiers', except: {browser: :ie} do
520
+ browser.a.click(@c)
521
+ expect { browser.windows.wait_until(size: 2) }.not_to raise_exception
522
+ ensure
523
+ browser.windows.restore!
524
+ end
525
+ end
526
+
527
+ describe '#set' do
528
+ it 'clicks an element by default that does not define #set' do
529
+ browser.goto(WatirSpec.url_for('non_control_elements.html'))
530
+ browser.element(id: 'best_language').set
531
+ expect(browser.div(id: 'best_language').text).to eq 'Ruby!'
532
+ end
533
+
534
+ it 'clicks an element that does not define #set with provided modifiers', except: {browser: :ie} do
535
+ browser.a.set(@c)
536
+ browser.wait_until { |b| b.windows.size > 1 }
537
+ expect(browser.windows.size).to eq 2
538
+ ensure
539
+ browser.windows.restore!
540
+ end
541
+
542
+ it 'does not click an element that does not define #set when passed false' do
543
+ browser.goto(WatirSpec.url_for('non_control_elements.html'))
544
+ browser.element(id: 'best_language').set(false)
545
+ expect(browser.div(id: 'best_language').text).not_to eq 'Ruby!'
546
+ end
547
+
548
+ it 'clicks a Button' do
549
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
550
+ browser.button(id: 'delete_user_submit').set
551
+ browser.wait_until { |b| !b.url.include? 'forms_with_input_elements.html' }
552
+ expect(browser.text).to include('Semantic table')
553
+ end
554
+
555
+ it 'sends keys to text element' do
556
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
557
+ browser.element(id: 'new_user_email').set('Bye Cruel World')
558
+ expect(browser.text_field(id: 'new_user_email').value).to eq 'Bye Cruel World'
559
+ end
560
+
561
+ it 'sends keys to text area' do
562
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
563
+ browser.element(id: 'delete_user_comment').set('Hello Cruel World')
564
+ expect(browser.textarea(id: 'delete_user_comment').value).to eq 'Hello Cruel World'
565
+ end
566
+
567
+ it 'checks a checkbox' do
568
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
569
+ browser.element(id: 'new_user_interests_cars').set
570
+ expect(browser.checkbox(id: 'new_user_interests_cars')).to be_set
571
+ end
572
+
573
+ it 'unchecks a checkbox' do
574
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
575
+ browser.element(id: 'new_user_interests_books').set(false)
576
+ expect(browser.checkbox(id: 'new_user_interests_books')).not_to be_set
577
+ end
578
+
579
+ it 'clicks a Radio' do
580
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
581
+ browser.radio(id: 'new_user_newsletter_no').set
582
+ expect(browser.radio(id: 'new_user_newsletter_no')).to be_set
583
+ expect(messages.size).to eq 1
584
+ end
585
+
586
+ it 'does not click a Radio when false or already clicked' do
587
+ browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
588
+ browser.element(id: 'new_user_newsletter_no').set(false)
589
+ browser.element(id: 'new_user_newsletter_yes').set(true)
590
+ expect(messages.size).to eq 0
591
+ end
592
+
593
+ it 'uploads a file' do
594
+ browser.element(name: 'new_user_portrait').set __FILE__
595
+
596
+ expect(browser.file_field(name: 'new_user_portrait').value).to include(File.basename(__FILE__))
597
+ end
598
+
599
+ it 'selects an option' do
600
+ browser.select_list(name: 'new_user_languages').clear
601
+ browser.element(name: 'new_user_languages').set('2')
602
+ expect(browser.select_list(name: 'new_user_languages').selected_options.map(&:text)).to eq %w[EN]
603
+ end
604
+
605
+ it 'sends keys to content editable element' do
606
+ browser.element(id: 'contenteditable').set('Bar')
607
+ expect(browser.div(id: 'contenteditable').text).to eq 'Bar'
608
+ end
609
+ end
610
+
611
+ describe '#flash' do
612
+ let(:h2) { browser.h2(text: 'Add user') }
613
+ let(:h1) { browser.h1(text: 'User administration') }
614
+
615
+ it 'returns the element on which it was called' do
616
+ expect(h2.flash).to eq h2
617
+ end
618
+
619
+ it 'keeps the element background color after flashing' do
620
+ expect(h2.style('background-color')).to eq h2.flash(:rainbow).style('background-color')
621
+ expect(h1.style('background-color')).to eq h1.flash.style('background-color')
622
+ end
623
+
624
+ it 'responds to preset symbols like :fast and :slow' do
625
+ expect(h1.flash(:rainbow)).to eq h1
626
+ expect(h2.flash(:slow)).to eq h2
627
+ expect(h1.flash(:fast)).to eq h1
628
+ expect(h2.flash(:long)).to eq h2
629
+ end
630
+ end
631
+
632
+ describe '#hover' do
633
+ def element_color(element)
634
+ case element.style('color')
635
+ when 'rgba(0, 0, 255, 1)'
636
+ :blue
637
+ when 'rgba(255, 165, 0, 1)', 'rgb(255, 165, 0)'
638
+ :orange
639
+ else
640
+ raise rgba
641
+ end
642
+ end
643
+
644
+ it 'allows scrolling to top', except: {browser: :ie} do
645
+ browser.goto(WatirSpec.url_for('scroll.html'))
646
+ element = browser.div(id: 'center')
647
+
648
+ element.hover(scroll_to: :top)
649
+ expect(element_color(element)).to eq :orange
650
+
651
+ element_top = browser.execute_script('return arguments[0].getBoundingClientRect().top', element)
652
+ expect(element_top).to be_within(1).of(0)
653
+ end
654
+
655
+ it 'scrolls to center by default', except: {browser: :ie} do
656
+ browser.goto(WatirSpec.url_for('scroll.html'))
657
+ element = browser.div(id: 'center')
658
+
659
+ element.hover
660
+ expect(element_color(element)).to eq :orange
661
+
662
+ element_rect = browser.execute_script('return arguments[0].getBoundingClientRect()', element)
663
+
664
+ expect(element_rect['top']).to eq(element_rect['bottom'] - element_rect['height'])
665
+ end
666
+
667
+ it 'allows scrolling to bottom', except: {browser: :ie} do
668
+ browser.goto(WatirSpec.url_for('scroll.html'))
669
+ element = browser.div(id: 'center')
670
+
671
+ element.hover(scroll_to: :bottom)
672
+ expect(element_color(element)).to eq :orange
673
+
674
+ element_bottom = browser.execute_script('return arguments[0].getBoundingClientRect().bottom', element)
675
+ window_height = browser.execute_script('return window.innerHeight')
676
+
677
+ expect(element_bottom).to be_within(1).of(window_height)
678
+ end
679
+
680
+ it 'allows not scrolling', except: {browser: %i[chrome edge],
681
+ reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=3955'} do
682
+ browser.goto(WatirSpec.url_for('scroll.html'))
683
+ element = browser.div(id: 'center')
684
+
685
+ browser.execute_script('return window.pageYOffset;')
686
+ browser.execute_script('return window.innerHeight;')
687
+
688
+ expect {
689
+ element.hover(scroll_to: nil)
690
+ }.to raise_exception Selenium::WebDriver::Error::MoveTargetOutOfBoundsError
691
+ end
692
+ end
693
+
694
+ describe '#inspect' do
695
+ before { browser.goto(WatirSpec.url_for('nested_iframes.html')) }
696
+
697
+ it 'does displays specified element type' do
698
+ expect(browser.div.inspect).to include('Watir::Div')
699
+ end
700
+
701
+ it 'does not display element type if not specified' do
702
+ element = browser.element(index: 4)
703
+ expect(element.inspect).to include('Watir::HTMLElement')
704
+ end
705
+
706
+ it 'displays keyword if specified' do
707
+ element = browser.h3
708
+ element.keyword = 'foo'
709
+ expect(element.inspect).to include('keyword: foo')
710
+ end
711
+
712
+ it 'does not display keyword if not specified' do
713
+ element = browser.h3
714
+ expect(element.inspect).not_to include('keyword')
715
+ end
716
+
717
+ it 'locate is false when not located' do
718
+ element = browser.div(id: 'not_present')
719
+ expect(element.inspect).to include('located: false')
720
+ end
721
+
722
+ it 'locate is true when located' do
723
+ element = browser.h3
724
+ element.exists?
725
+ expect(element.inspect).to include('located: true')
726
+ end
727
+
728
+ it 'displays selector string for element from colection' do
729
+ elements = browser.frames
730
+ expect(elements.last.inspect).to include '{:tag_name=>"frame", :index=>-1}'
731
+ end
732
+
733
+ it 'displays selector string for nested element' do
734
+ browser.goto(WatirSpec.url_for('wait.html'))
735
+ element = browser.div(index: 1).div(id: 'div2')
736
+ expect(element.inspect).to include '{:index=>1, :tag_name=>"div"} --> {:id=>"div2", :tag_name=>"div"}'
737
+ end
738
+
739
+ it 'displays selector string for nested element under frame' do
740
+ element = browser.iframe(id: 'one').iframe(id: 'three')
741
+ expect(element.inspect).to include '{:id=>"one", :tag_name=>"iframe"} --> {:id=>"three", :tag_name=>"iframe"}'
742
+ end
743
+ end
744
+
745
+ describe '#text_content' do
746
+ it 'returns inner Text code of element' do
747
+ browser.goto WatirSpec.url_for('non_control_elements.html')
748
+ expect(browser.div(id: 'shown').text_content).to eq('Not shownNot hidden')
749
+ end
750
+ end
751
+
752
+ describe '#inner_text' do
753
+ it 'returns inner HTML code of element',
754
+ except: {browser: :ie, reason: 'also returning explicitly hidden results'} do
755
+ browser.goto WatirSpec.url_for('non_control_elements.html')
756
+ div = browser.div(id: 'shown')
757
+ expect(div.inner_text).to eq('Not hidden')
758
+ end
759
+ end
760
+
761
+ describe '#inner_html' do
762
+ it 'returns inner HTML code of element' do
763
+ browser.goto WatirSpec.url_for('non_control_elements.html')
764
+ div = browser.div(id: 'shown')
765
+ expected_text = '<div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div>'
766
+ expect(div.inner_html).to eq expected_text
767
+ end
768
+ end
769
+
770
+ describe '#outer_html' do
771
+ it 'returns outer (inner + element itself) HTML code of element' do
772
+ browser.goto WatirSpec.url_for('non_control_elements.html')
773
+ div = browser.div(id: 'shown')
774
+ text = '<div id="shown"><div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div></div>'
775
+ expect(div.outer_html).to eq text
776
+ end
777
+ end
778
+
779
+ describe '#select_text and #selected_text' do
780
+ it 'selects text and returns selected text',
781
+ except: {browser: :ie, reason: 'Select Text atom appears broken in IE 11'} do
782
+ browser.goto WatirSpec.url_for('non_control_elements.html')
783
+ element = browser.element(visible_text: 'all visible')
784
+ element.select_text('all visible')
785
+ expect(element.selected_text).to eq 'all visible'
786
+ end
787
+ end
788
+
789
+ describe '#location' do
790
+ it 'returns coordinates for element location' do
791
+ location = browser.button(name: 'new_user_image').location
792
+
793
+ expect(location).to be_a Selenium::WebDriver::Point
794
+ expect(location['y']).to be > 0
795
+ expect(location['x']).to be > 0
796
+ end
797
+ end
798
+
799
+ describe '#size' do
800
+ it 'returns size of element' do
801
+ size = browser.button(name: 'new_user_image').size
802
+ expect(size).to be_a Selenium::WebDriver::Dimension
803
+
804
+ expected_width = browser.name == :safari ? 105 : 104
805
+ expected_height = browser.name == :safari ? 71 : 70
806
+
807
+ expect(size['width']).to eq expected_width
808
+ expect(size['height']).to eq expected_height
809
+ end
810
+ end
811
+
812
+ describe '#height' do
813
+ it 'returns height of element' do
814
+ height = browser.button(name: 'new_user_image').height
815
+
816
+ expected_height = browser.name == :safari ? 71 : 70
817
+ expect(height).to eq expected_height
818
+ end
819
+ end
820
+
821
+ describe '#width' do
822
+ it 'returns width of element' do
823
+ width = browser.button(name: 'new_user_image').width
824
+
825
+ expected_width = browser.name == :safari ? 105 : 104
826
+ expect(width).to eq expected_width
827
+ end
828
+ end
829
+
830
+ describe '#center' do
831
+ it 'returns center of element' do
832
+ center = browser.button(name: 'new_user_image').center
833
+
834
+ expect(center).to be_a Selenium::WebDriver::Point
835
+ expect(center['y']).to be > 0.0
836
+ expect(center['x']).to be > 0.0
837
+ end
838
+ end
839
+
840
+ describe '#attribute_value' do
841
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
842
+
843
+ it 'returns attribute value by string attribute name' do
844
+ expect(browser.p.attribute_value('data-type')).to eq 'ruby-library'
845
+ end
846
+
847
+ it 'returns attribute value by symbol attribute name' do
848
+ expect(browser.p.attribute_value(:data_type)).to eq 'ruby-library'
849
+ end
850
+ end
851
+
852
+ describe '#attribute_values' do
853
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
854
+
855
+ it 'returns a Hash object' do
856
+ expect(browser.p.attribute_values).to be_an_instance_of(Hash)
857
+ end
858
+
859
+ it 'returns attribute values from an element' do
860
+ expected = {data_type: 'ruby-library'}
861
+ expect(browser.p.attribute_values).to eq expected
862
+ end
863
+
864
+ it 'returns attribute with special characters' do
865
+ expected = {data_type: 'description', 'data-type_$p3c!a1' => 'special-description'}
866
+ expect(browser.div.attribute_values).to eq expected
867
+ end
868
+
869
+ it 'returns attribute with special characters as a String' do
870
+ expect(browser.div.attribute_values.keys[0]).to be_an_instance_of(String)
871
+ end
872
+ end
873
+
874
+ describe '#attribute_list' do
875
+ before { browser.goto WatirSpec.url_for('data_attributes.html') }
876
+
877
+ it 'returns an Array object' do
878
+ expect(browser.div.attribute_list).to be_an_instance_of(Array)
879
+ end
880
+
881
+ it 'returns list of attributes from an element' do
882
+ expect(browser.p.attribute_list).to eq [:data_type]
883
+ end
884
+
885
+ it 'returns attribute name with special characters as a String' do
886
+ expect(browser.div.attribute_list[0]).to be_an_instance_of(String)
887
+ end
888
+ end
889
+
890
+ describe '#located?' do
891
+ it 'returns true if element has been located' do
892
+ expect(browser.form(id: 'new_user')).not_to be_located
893
+ end
894
+
895
+ it 'returns false if element has not been located' do
896
+ expect(browser.form(id: 'new_user').locate).to be_located
897
+ end
898
+ end
899
+
900
+ describe '#wd' do
901
+ it 'returns a Selenium::WebDriver::Element instance' do
902
+ element = browser.text_field(id: 'new_user_email')
903
+ expect(element.wd).to be_a(Selenium::WebDriver::Element)
904
+ end
905
+ end
906
+
907
+ describe '#hash' do
908
+ it 'returns a hash' do
909
+ element = browser.text_field(id: 'new_user_email')
910
+ hash1 = element.hash
911
+ hash2 = element.locate.hash
912
+ expect(hash1).to be_a Integer
913
+ expect(hash2).to be_a Integer
914
+ expect(hash1).not_to eq hash2
915
+ end
916
+ end
917
+
918
+ describe 'Numeric Attribute' do
919
+ it 'returns Float value',
920
+ except: {browser: :ie, reason: 'not recognizing the value of the element'} do
921
+ element = browser.text_field(id: 'number')
922
+ expect(element.valueasnumber).to be_a Float
923
+ end
924
+
925
+ it 'returns nil for unspecified value' do
926
+ element = browser.input
927
+ expect(element.valueasnumber).to be_nil
928
+ end
929
+
930
+ it 'returns Integer value' do
931
+ element = browser.form
932
+ expect(element.length).to be_a Integer
933
+ end
934
+ end
935
+
936
+ describe 'Special Characters' do
937
+ before do
938
+ browser.goto WatirSpec.url_for('special_chars.html')
939
+ end
940
+
941
+ it 'finds elements with single quotes' do
942
+ expect(browser.div(text: "single 'quotes'")).to exist
943
+ end
944
+
945
+ it 'finds elements with non-standard character locators' do
946
+ expect(browser.div('we{ird' => 'foo')).to exist
947
+ expect(browser.div('we{ird': 'foo')).to exist
948
+ end
949
+
950
+ it 'finds element with underscored attribute' do
951
+ expect(browser.div('underscored_attribute' => 'true')).to exist
952
+ expect(browser.div('underscored_attribute' => true)).to exist
953
+ end
954
+ end
955
+
956
+ describe '#class_name' do
957
+ it 'returns single class name' do
958
+ expect(browser.form(id: 'new_user').class_name).to eq 'user'
959
+ end
960
+
961
+ it 'returns multiple class names in a String' do
962
+ expect(browser.div(id: 'messages').class_name).to eq 'multiple classes here'
963
+ end
964
+
965
+ it 'returns an empty string if the element exists but there is no class attribute' do
966
+ expect(browser.div(id: 'changed_language').class_name).to eq ''
967
+ end
968
+
969
+ it 'raises UnknownObjectException if the element does not exist' do
970
+ expect { browser.div(id: 'no_such_id').class_name }.to raise_unknown_object_exception
971
+ end
972
+ end
973
+
974
+ describe '#classes' do
975
+ it 'returns the class attribute if the element exists' do
976
+ expect(browser.div(id: 'messages').classes).to eq %w[multiple classes here]
977
+ end
978
+
979
+ it 'returns an empty array if the element exists but there is no class attribute' do
980
+ expect(browser.div(id: 'changed_language').classes).to eq []
981
+ end
982
+
983
+ it 'raises UnknownObjectException if the element does not exist' do
984
+ expect { browser.div(id: 'no_such_id').classes }.to raise_unknown_object_exception
985
+ end
986
+ end
987
+
988
+ describe '#obscured?' do
989
+ before { browser.goto WatirSpec.url_for('obscured.html') }
990
+
991
+ it 'returns false if element center is not covered' do
992
+ btn = browser.button(id: 'not_obscured')
993
+ btn.scroll.to :center
994
+ expect { btn.click }.not_to raise_exception
995
+ expect(btn).not_to be_obscured
996
+ end
997
+
998
+ it 'returns false if element center is covered by its descendant' do
999
+ btn = browser.button(id: 'has_descendant')
1000
+ btn.scroll.to :center
1001
+ expect { btn.click }.not_to raise_exception
1002
+ expect(btn).not_to be_obscured
1003
+ end
1004
+
1005
+ it 'returns true if element center is covered by a non-descendant',
1006
+ except: {browser: :safari, reason: 'not getting element click intercepted'} do
1007
+ btn = browser.button(id: 'obscured')
1008
+ btn.scroll.to :center
1009
+ expect { btn.click }.to raise_exception(Selenium::WebDriver::Error::ElementClickInterceptedError)
1010
+ expect(btn).to be_obscured
1011
+ end
1012
+
1013
+ it 'returns false if element center is surrounded by non-descendants' do
1014
+ btn = browser.button(id: 'surrounded')
1015
+ btn.scroll.to :center
1016
+ expect { btn.click }.not_to raise_exception
1017
+ expect(btn).not_to be_obscured
1018
+ end
1019
+
1020
+ it 'correctly scrolls element below viewport' do
1021
+ browser.goto WatirSpec.url_for('sticky_elements.html')
1022
+
1023
+ element = browser.div(id: 'center')
1024
+
1025
+ browser.scroll.to :top
1026
+ expect { element.click }.not_to raise_exception
1027
+
1028
+ browser.scroll.to :top
1029
+ expect(element).not_to be_obscured
1030
+ end
1031
+
1032
+ it 'correctly scrolls element above viewport',
1033
+ except: {browser: %i[chrome edge],
1034
+ reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=3954'} do
1035
+ browser.goto WatirSpec.url_for('sticky_elements.html')
1036
+ element = browser.div(id: 'center')
1037
+
1038
+ browser.scroll.to :bottom
1039
+ expect { element.click }.not_to raise_exception
1040
+
1041
+ browser.scroll.to :bottom
1042
+ expect(element).not_to be_obscured
1043
+ end
1044
+
1045
+ it 'scrolls non-interactive element into view before checking if obscured' do
1046
+ div = browser.div(id: 'requires_scrolling_container')
1047
+ expect { div.click }.not_to raise_exception
1048
+ browser.scroll.to :top
1049
+ expect(div).not_to be_obscured
1050
+ end
1051
+
1052
+ it 'returns true if element cannot be scrolled into view' do
1053
+ btn = browser.button(id: 'off_screen')
1054
+ expect(btn).to be_obscured
1055
+ expect { btn.click }.to raise_unknown_object_exception
1056
+ end
1057
+
1058
+ it 'returns true if element is hidden' do
1059
+ btn = browser.button(id: 'hidden')
1060
+ expect(btn).to be_obscured
1061
+ expect { btn.click }.to raise_unknown_object_exception
1062
+ end
1063
+
1064
+ it 'raises UnknownObjectException if element does not exist' do
1065
+ expect { browser.button(id: 'does_not_exist').obscured? }.to raise_unknown_object_exception
1066
+ end
1067
+ end
1068
+ end
1069
+ end