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
data/lib/watir/scroll.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Scrolling
3
5
  def scroll
@@ -7,7 +9,9 @@ module Watir
7
9
 
8
10
  class Scroll
9
11
  def initialize(object)
12
+ @driver = object.browser.wd
10
13
  @object = object
14
+ @origin = nil
11
15
  end
12
16
 
13
17
  # Scrolls by offset.
@@ -15,15 +19,20 @@ module Watir
15
19
  # @param [Fixnum] top Vertical offset
16
20
  #
17
21
  def by(left, top)
18
- @object.browser.execute_script('window.scrollBy(arguments[0], arguments[1]);', Integer(left), Integer(top))
22
+ if @origin
23
+ @driver.action.scroll_from(@origin, left, top).perform
24
+ else
25
+ @object.browser.execute_script('window.scrollBy(arguments[0], arguments[1]);', Integer(left), Integer(top))
26
+ end
19
27
  self
20
28
  end
21
29
 
22
- #
23
30
  # Scrolls to specified location.
24
31
  # @param [Symbol] param
25
32
  #
26
33
  def to(param = :top)
34
+ return scroll_to_element if param == :viewport
35
+
27
36
  args = @object.is_a?(Watir::Element) ? element_scroll(param) : browser_scroll(param)
28
37
  raise ArgumentError, "Don't know how to scroll #{@object} to: #{param}!" if args.nil?
29
38
 
@@ -31,8 +40,24 @@ module Watir
31
40
  self
32
41
  end
33
42
 
43
+ # Sets an origin point for a future scroll
44
+ # @param [Integer] x_offset
45
+ # @param [Integer] y_offset
46
+ def from(x_offset = 0, y_offset = 0)
47
+ @origin = if @object.is_a?(Watir::Element)
48
+ Selenium::WebDriver::WheelActions::ScrollOrigin.element(@object.we, x_offset, y_offset)
49
+ else
50
+ Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(x_offset, y_offset)
51
+ end
52
+ self
53
+ end
54
+
34
55
  private
35
56
 
57
+ def scroll_to_element
58
+ @driver.action.scroll_to(@object.we).perform
59
+ end
60
+
36
61
  def element_scroll(param)
37
62
  script = case param
38
63
  when :top, :start
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Watir
4
+ module SearchContext
5
+ #
6
+ # Returns true if element exists.
7
+ # Checking for staleness is deprecated
8
+ #
9
+ # @return [Boolean]
10
+ #
11
+
12
+ def exists?
13
+ if located? && stale?
14
+ reset!
15
+ elsif located?
16
+ return true
17
+ end
18
+
19
+ assert_exists
20
+ true
21
+ rescue Exception::UnknownObjectException, Exception::UnknownFrameException
22
+ false
23
+ end
24
+ alias exist? exists?
25
+
26
+ def assert_exists
27
+ locate unless located?
28
+ return if located?
29
+
30
+ raise unknown_exception, "unable to locate: #{inspect}"
31
+ end
32
+
33
+ def wait_for_exists
34
+ return if located? # Performance shortcut
35
+
36
+ begin
37
+ @query_scope.wait_for_exists unless @query_scope.is_a? Browser
38
+ wait_until(element_reset: true, &:exists?)
39
+ rescue Wait::TimeoutError
40
+ msg = "timed out after #{Watir.default_timeout} seconds, waiting for #{inspect} to be located"
41
+ raise unknown_exception, msg
42
+ end
43
+ end
44
+
45
+ # TODO: - this will get addressed with Watir::Executor implementation
46
+ # rubocop:disable Metrics/AbcSize
47
+ # rubocop:disable Metrics/MethodLength # : # ::
48
+ def element_call(precondition = nil, &block)
49
+ caller = caller_locations(1, 1)[0].label
50
+ already_locked = browser.timer.locked?
51
+ browser.timer = Wait::Timer.new(timeout: Watir.default_timeout) unless already_locked
52
+
53
+ begin
54
+ check_condition(precondition, caller)
55
+ Watir.logger.debug "-> `Executing #{inspect}##{caller}`"
56
+ yield
57
+ rescue unknown_exception => e
58
+ element_call(:wait_for_exists, &block) if precondition.nil?
59
+ raise unknown_exception, e.message + custom_message
60
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::NoSuchElementError
61
+ reset!
62
+ retry
63
+ # TODO: - InvalidElementStateError is deprecated, so no longer calling `raise_disabled`
64
+ # need a better way to handle this
65
+ rescue Selenium::WebDriver::Error::ElementNotInteractableError
66
+ raise_present unless browser.timer.remaining_time.positive?
67
+ raise_present unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
68
+ retry
69
+ rescue Selenium::WebDriver::Error::NoSuchWindowError
70
+ raise Exception::NoMatchingWindowFoundException, 'browser window was closed'
71
+ ensure
72
+ Watir.logger.debug "<- `Completed #{inspect}##{caller}`"
73
+ browser.timer.reset! unless already_locked
74
+ end
75
+ end
76
+
77
+ # rubocop:enable Metrics/AbcSize
78
+ # rubocop:enable Metrics/MethodLength
79
+ def check_condition(condition, caller)
80
+ Watir.logger.debug "<- `Verifying precondition #{inspect}##{condition} for #{caller}`"
81
+ begin
82
+ condition.nil? ? assert_exists : send(condition)
83
+ Watir.logger.debug "<- `Verified precondition #{inspect}##{condition || 'assert_exists'}`"
84
+ rescue unknown_exception
85
+ raise unless condition.nil?
86
+
87
+ Watir.logger.debug "<- `Unable to satisfy precondition #{inspect}##{condition}`"
88
+ check_condition(:wait_for_exists, caller)
89
+ end
90
+ end
91
+
92
+ def unknown_exception
93
+ Exception::UnknownObjectException
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Watir
4
+ class ShadowRoot
5
+ include Container
6
+ include Exception
7
+ include SearchContext
8
+ include Waitable
9
+
10
+ def initialize(element)
11
+ @query_scope = element
12
+ end
13
+
14
+ def browser
15
+ @query_scope.browser
16
+ end
17
+
18
+ def located?
19
+ !!@shadow_root
20
+ end
21
+
22
+ def wd
23
+ assert_exists
24
+ @shadow_root
25
+ end
26
+
27
+ def execute_script(script, *args, function_name: nil)
28
+ browser.execute_script(script, *args, function_name: function_name)
29
+ end
30
+
31
+ def stale?
32
+ @shadow_root.find_elements(css: 'checking_stale_shadow_root')
33
+ false
34
+ rescue Selenium::WebDriver::Error::DetachedShadowRootError
35
+ true
36
+ end
37
+
38
+ def reset!
39
+ @shadow_root = nil
40
+ end
41
+
42
+ def locate
43
+ @shadow_root = @query_scope.wd.shadow_root
44
+ rescue Selenium::WebDriver::Error::NoSuchShadowRootError
45
+ nil
46
+ end
47
+
48
+ #
49
+ # @api private
50
+ #
51
+
52
+ def selector_string
53
+ "#{@query_scope.selector_string} --> shadow_root"
54
+ end
55
+
56
+ def custom_message
57
+ ''
58
+ end
59
+ end
60
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module UserEditable
3
5
  #
@@ -34,7 +36,7 @@ module Watir
34
36
 
35
37
  def set!(*args)
36
38
  msg = '#set! does not support special keys, use #set instead'
37
- raise ArgumentError, msg if args.any? { |v| v.is_a?(::Symbol) }
39
+ raise ArgumentError, msg if args.any?(::Symbol)
38
40
 
39
41
  input_value = args.join
40
42
  set input_value[0]
data/lib/watir/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
- VERSION = '7.1.0'.freeze
4
+ VERSION = '7.2.0'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  module Wait
3
5
  class Timer
@@ -14,7 +16,7 @@ module Watir
14
16
  #
15
17
 
16
18
  def wait(timeout, &block)
17
- end_time = @end_time || current_time + timeout
19
+ end_time = @end_time || (current_time + timeout)
18
20
  loop do
19
21
  yield(block)
20
22
  @remaining_time = end_time - current_time
data/lib/watir/wait.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watir/wait/timer'
2
4
 
3
5
  module Watir
@@ -62,11 +64,9 @@ module Watir
62
64
  private
63
65
 
64
66
  def message_for(timeout, object, message)
65
- message = message.call(object) if message.is_a?(Proc)
66
- err = "timed out after #{timeout} seconds"
67
- err << ", #{message}" if message
68
-
69
- err
67
+ message = message.is_a?(Proc) ? message.call(object) : message || ''
68
+ additional = message.empty? ? '' : ", #{message}"
69
+ "timed out after #{timeout} seconds#{additional}"
70
70
  end
71
71
 
72
72
  def run_with_timer(timeout, interval)
data/lib/watir/window.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class Window
3
5
  include Waitable
@@ -15,14 +17,16 @@ module Watir
15
17
  elsif selector.key? :handle
16
18
  @handle = selector.delete :handle
17
19
  else
18
- return if selector.keys.all? { |k| %i[title url element].include? k }
20
+ types = %i[title url element]
21
+ return if selector.keys.all? { |k| types.include? k }
19
22
 
20
23
  raise ArgumentError, "invalid window selector: #{selector_string}"
21
24
  end
22
25
  end
23
26
 
24
27
  def inspect
25
- format('#<%s:0x%x located=%s>', self.class, hash * 2, !!@handle)
28
+ format('#<%<class>s:0x%<hash>x located=%<handle>s>',
29
+ class: self.class, hash: hash * 2, handle: !!@handle)
26
30
  end
27
31
 
28
32
  #
@@ -148,7 +152,7 @@ module Watir
148
152
  alias eql? ==
149
153
 
150
154
  def hash
151
- handle.hash ^ self.class.hash
155
+ [handle, self.class].hash
152
156
  end
153
157
 
154
158
  #
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Watir
2
4
  class WindowCollection
3
5
  include Enumerable
4
6
  include Waitable
5
7
 
6
8
  def initialize(browser, selector = {})
7
- unless selector.keys.all? { |k| %i[title url element].include? k }
9
+ types = %i[title url element]
10
+ unless selector.keys.all? { |k| types.include? k }
8
11
  raise ArgumentError, "invalid window selector: #{selector.inspect}"
9
12
  end
10
13
 
data/lib/watir.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'selenium-webdriver'
2
4
  require 'time'
3
5
 
6
+ require 'watir/search_context'
4
7
  require 'watir/scroll'
5
8
  require 'watir/wait'
6
9
  require 'watir/exception'
@@ -99,5 +102,6 @@ require 'watir/elements/text_area'
99
102
  require 'watir/elements/text_field'
100
103
  require 'watir/elements/input'
101
104
  require 'watir/radio_set'
105
+ require 'watir/shadow_root'
102
106
 
103
107
  require 'watir/aliases'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WatirSpec
2
4
  module Guards
3
5
  class << self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WatirSpec
2
4
  class Implementation
3
5
  attr_writer :name, :guard_proc, :browser_class
@@ -37,16 +39,18 @@ module WatirSpec
37
39
  end
38
40
 
39
41
  def inspect_args
40
- hash = browser_args.last
41
- desired_capabilities = hash.delete(:desired_capabilities)
42
- string = ''
43
- hash.each { |arg| string << "#{arg.inspect}\n" }
44
- return "#{string} default capabilities" unless desired_capabilities
45
-
46
- string << "\tcapabilities:\n"
47
- caps.each { |k, v| string << "\t\t#{k}: #{v}\n" }
48
- hash[:desired_capabilities] = desired_capabilities
49
- string
42
+ selenium_opts = browser_args.last
43
+
44
+ options = selenium_opts.delete(:options)
45
+ args = ["#{browser_args.first} tests:\n"]
46
+ selenium_opts.each { |opt| args << "#{opt.inspect}\n" }
47
+
48
+ return "#{browser_args.first} default options" if selenium_opts.empty? && options.nil?
49
+
50
+ args << "\toptions:\n"
51
+ options.each { |k, v| args << "\t\t#{k}: #{v}\n" }
52
+
53
+ args.join
50
54
  end
51
55
  end # Implementation
52
56
  end # WatirSpec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/tasklib'
2
4
 
3
5
  module WatirSpec
@@ -27,12 +29,10 @@ module WatirSpec
27
29
  private
28
30
 
29
31
  def init_watirspec
30
- Dir.mkdir('spec') unless Dir.exist?('spec')
32
+ FileUtils.mkdir_p('spec')
31
33
  return if File.exist?('spec/watirspec_helper.rb')
32
34
 
33
- File.open('spec/watirspec_helper.rb', 'w') do |file|
34
- file.write(watirspec_helper_template)
35
- end
35
+ File.write('spec/watirspec_helper.rb', watirspec_helper_template)
36
36
  end
37
37
 
38
38
  def print_specs
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WatirSpec
2
4
  class RemoteServer
3
5
  include Watir::Exception
@@ -21,17 +23,17 @@ module WatirSpec
21
23
 
22
24
  def jar
23
25
  if File.exist?(ENV['REMOTE_SERVER_BINARY'] || '')
24
- ENV['REMOTE_SERVER_BINARY']
26
+ ENV.fetch('REMOTE_SERVER_BINARY', nil)
25
27
  elsif ENV['LOCAL_SELENIUM']
26
28
  File.expand_path('../selenium/bazel-bin/java/server/src/org/openqa/selenium/grid/selenium_server_deploy.jar')
27
29
  elsif !Dir.glob('*selenium*.jar').empty?
28
30
  Dir.glob('*selenium*.jar').first
29
31
  else
30
- Selenium::Server.download :latest
32
+ Selenium::Server.download
31
33
  end
32
34
  rescue SocketError
33
35
  # not connected to internet
34
- raise Error, 'unable to find or download selenium-server-standalone jar'
36
+ raise Error, 'unable to find or download selenium-server jar'
35
37
  end
36
38
  end
37
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WatirSpec
2
4
  module Runner
3
5
  module BrowserHelper
@@ -25,7 +27,7 @@ module WatirSpec
25
27
  end
26
28
 
27
29
  def execute
28
- start_server
30
+ start_server unless ENV['WATIR_PUBLIC_SERVER']
29
31
  configure
30
32
  add_guard_hook
31
33
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WatirSpec
2
4
  class Server
3
5
  class App
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'socket'
2
4
  require 'watirspec/server/app'
3
5
 
data/lib/watirspec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tmpdir'
2
4
  require 'watirspec/guards'
3
5
  require 'watirspec/implementation'
@@ -22,7 +24,7 @@ module WatirSpec
22
24
  end
23
25
 
24
26
  def host
25
- @host ||= "http://#{Server.bind}:#{Server.port}"
27
+ @host ||= ENV['WATIR_PUBLIC_SERVER'] ? 'http://watir.com/examples' : "http://#{Server.bind}:#{Server.port}"
26
28
  end
27
29
 
28
30
  def unguarded?
@@ -61,6 +63,7 @@ module WatirSpec
61
63
 
62
64
  instance = klass.new(*args)
63
65
  print_browser_info_once(instance)
66
+ instance.window.maximize
64
67
 
65
68
  instance
66
69
  end
@@ -78,13 +81,13 @@ module WatirSpec
78
81
  caps = instance.driver.capabilities
79
82
 
80
83
  info << caps.browser_name.to_s
81
- info << caps.version.to_s
84
+ info << caps.browser_version.to_s
82
85
  info << @implementation.driver_info
83
86
 
84
87
  Watir.logger.warn "running watirspec against #{info.join ' '} using:\n#{WatirSpec.implementation.inspect_args}",
85
88
  id: [:browser_info]
86
- rescue StandardError
87
- # ignored
89
+ rescue StandardError => e
90
+ Watir.logger.warn("Unable to print browser info: #{e}")
88
91
  end
89
92
  end # class << WatirSpec
90
93
  end # WatirSpec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LocatorSpecHelper
2
4
  def browser
3
5
  @browser ||= instance_double(Watir::Browser, wd: driver)
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
5