watir 7.1.0 → 7.2.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 (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
@@ -0,0 +1,569 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'watirspec_helper'
4
+
5
+ Options = Selenium::WebDriver::Options
6
+ Service = Selenium::WebDriver::Service
7
+ Platform = Selenium::WebDriver::Platform
8
+ Remote = Selenium::WebDriver::Remote
9
+
10
+ class BrowserDouble
11
+ def closed?
12
+ false
13
+ end
14
+ end
15
+
16
+ module Watir
17
+ describe Browser do
18
+ let(:selenium_browser) { @browser.capabilities.selenium_browser }
19
+ let(:selenium_args) { @browser.capabilities.selenium_args }
20
+ let(:generated_options) { selenium_args[:options] }
21
+ let(:browser_symbol) { WatirSpec.implementation.browser_args.first }
22
+ let(:actual_capabilities) { @browser.wd.capabilities }
23
+ let(:actual_http) { @browser.wd.instance_variable_get(:@bridge).instance_variable_get(:@http) }
24
+ let(:actual_service) { @browser.wd.instance_variable_get(:@service) }
25
+ let(:actual_listener) { @browser.wd.instance_variable_get(:@bridge).instance_variable_get(:@listener) }
26
+
27
+ before(:all) do
28
+ browser&.close
29
+ $browser = BrowserDouble.new
30
+ Watir.logger.ignore(:watir_client)
31
+ end
32
+
33
+ after(:each) { @browser&.close }
34
+
35
+ after(:all) { $browser = nil }
36
+
37
+ def browser_name
38
+ case browser_symbol
39
+ when :ie
40
+ 'internet explorer'
41
+ when :edge
42
+ 'MicrosoftEdge'
43
+ else
44
+ browser_symbol.to_s
45
+ end
46
+ end
47
+
48
+ # Options:
49
+ # :url Errors
50
+ # :listener (default nil; Selenium object)
51
+ # :service (default nil; Selenium object or Built from Hash)
52
+ # :http_client (default Generated; Selenium object, or Built from Hash)
53
+ # :proxy (default nil; Selenium object, or Built from Hash and added to :options)
54
+ # :options (default nil; Selenium object, or Built from Hash)
55
+ # :capabilities (default Generated; Selenium object, or built from Hash; incompatible with options)
56
+
57
+ context 'when local', exclusive: {driver: :local_driver} do
58
+ context 'all browsers' do
59
+ it 'accepts driver instance' do
60
+ driver = Selenium::WebDriver.for browser_symbol
61
+ @browser = Watir::Browser.new(driver)
62
+
63
+ expect(actual_http).not_to be_a(Watir::HttpClient)
64
+ end
65
+
66
+ it 'accepts watir capabilities object' do
67
+ service = Service.send(browser_symbol, port: 1234)
68
+ client = Remote::Http::Default.new
69
+ capabilities = Watir::Capabilities.new(browser_symbol, service: service, http_client: client)
70
+
71
+ @browser = Browser.new(capabilities)
72
+
73
+ expect(actual_service.instance_variable_get(:@port)).to eq 1234
74
+ expect(actual_http).to eq client
75
+ end
76
+
77
+ it 'browser symbol uses designated options and watir client without service' do
78
+ @browser = Browser.new(browser_symbol)
79
+
80
+ expect(generated_options).to be_a Options.send(browser_symbol).class
81
+ expect(selenium_args).not_to include(:service)
82
+ expect(actual_http).to be_a HttpClient
83
+ end
84
+
85
+ describe 'capabilities' do
86
+ it 'just options object has options and watir client without capabilities or service' do
87
+ @browser = Browser.new(options: Options.send(browser_symbol))
88
+
89
+ expect(generated_options).to be_a Options.send(browser_symbol).class
90
+ expect(selenium_args).not_to include(:service)
91
+ expect(actual_http).to be_a HttpClient
92
+ end
93
+
94
+ it 'without browser argument, just Hash with options service and client' do
95
+ service = Service.send(browser_symbol, port: 1234)
96
+ client = Remote::Http::Default.new
97
+ options = {browser_name: browser_name, unhandled_prompt_behavior: :accept_and_notify}
98
+ @browser = Browser.new(options: options, service: service, http_client: client)
99
+
100
+ expect(generated_options).to be_a Options.send(browser_symbol).class
101
+ expect(selenium_args[:service]).to eq service
102
+ expect(actual_capabilities.unhandled_prompt_behavior).to eq 'accept and notify'
103
+ expect(actual_http).to eq client
104
+ end
105
+
106
+ it 'just capabilities has capabilities and watir client without service' do
107
+ caps = Remote::Capabilities.new(browser_name: browser_name)
108
+
109
+ expect {
110
+ @browser = Browser.new(capabilities: caps)
111
+ }.to have_deprecated(:capabilities)
112
+
113
+ expect(selenium_args[:capabilities]).to eq(caps)
114
+ expect(selenium_args).not_to include(:service)
115
+ expect(actual_http).to be_a HttpClient
116
+ end
117
+
118
+ it 'accepts page load and script timeouts in seconds' do
119
+ options = {page_load_timeout: 11,
120
+ script_timeout: 12}
121
+ @browser = Browser.new(browser_symbol, options: options)
122
+
123
+ expect(actual_capabilities.timeouts[:page_load]).to eq 11_000
124
+ expect(actual_capabilities.timeouts[:script]).to eq 12_000
125
+ end
126
+
127
+ it 'unhandled prompt behavior defaults to ignore' do
128
+ @browser = Browser.new(browser_symbol)
129
+
130
+ expect(actual_capabilities.unhandled_prompt_behavior).to eq 'ignore'
131
+ end
132
+
133
+ it 'unhandled prompt behavior can be overridden' do
134
+ @browser = Browser.new(browser_symbol, options: {unhandled_prompt_behavior: :accept_and_notify})
135
+
136
+ expect(actual_capabilities.unhandled_prompt_behavior).to eq 'accept and notify'
137
+ end
138
+
139
+ it 'generates options from Hash', except: {browser: :safari,
140
+ reason: 'Does not accept unrecognized args'} do
141
+ options = {page_load_strategy: 'eager', args: %w[--foo --bar]}
142
+ @browser = Browser.new(browser_symbol, options: options)
143
+
144
+ expect(generated_options).to be_a Options.send(browser_symbol).class
145
+ expect(generated_options.page_load_strategy).to eq 'eager'
146
+ expect(generated_options.args).to include '--foo', '--bar'
147
+ end
148
+ end
149
+
150
+ describe 'service' do
151
+ it 'uses provided service' do
152
+ service = Service.send(browser_symbol, port: 1234)
153
+ @browser = Browser.new(browser_symbol, service: service)
154
+
155
+ expect(selenium_browser).to eq browser_symbol
156
+ expect(selenium_args[:service]).to eq service
157
+ expect(actual_service.instance_variable_get(:@port)).to eq 1234
158
+ end
159
+
160
+ it 'builds service from a Hash' do
161
+ @service = {port: 1234}
162
+ @browser = Browser.new(browser_symbol, service: @service)
163
+
164
+ expect(selenium_browser).to eq browser_symbol
165
+ expect(selenium_args[:service]).to be_a Service
166
+ expect(actual_service.instance_variable_get(:@port)).to eq 1234
167
+ end
168
+ end
169
+
170
+ describe 'http_client' do
171
+ it 'uses default HTTP Client' do
172
+ @browser = Browser.new(browser_symbol)
173
+
174
+ expect(actual_http).to be_a HttpClient
175
+ end
176
+
177
+ it 'accepts an HTTP Client object' do
178
+ client = Remote::Http::Default.new
179
+ @browser = Browser.new(browser_symbol, http_client: client)
180
+
181
+ expect(actual_http).to eq client
182
+ end
183
+
184
+ it 'builds an HTTP Client from Hash' do
185
+ client_opts = {open_timeout: 9, read_timeout: 11}
186
+ @browser = Browser.new(browser_symbol, http_client: client_opts)
187
+
188
+ expect(actual_http).to be_a HttpClient
189
+ expect(actual_http.instance_variable_get(:@open_timeout)).to eq 9
190
+ expect(actual_http.instance_variable_get(:@read_timeout)).to eq 11
191
+ end
192
+ end
193
+
194
+ it 'uses a listener' do
195
+ listener = Selenium::WebDriver::Support::AbstractEventListener.new
196
+ @browser = Browser.new(browser_symbol, listener: listener)
197
+
198
+ expect(actual_listener).to eq listener
199
+ end
200
+
201
+ describe 'proxy' do
202
+ it 'adds Selenium Proxy to empty Options', except: {browser: :safari,
203
+ reason: 'Safari does not like proxies'} do
204
+ proxy = Selenium::WebDriver::Proxy.new(http: '127.0.0.1:8080', ssl: '127.0.0.1:443')
205
+ @browser = Browser.new(browser_symbol, proxy: proxy)
206
+
207
+ expect(actual_capabilities.proxy).to eq proxy
208
+ end
209
+
210
+ it 'builds a Proxy from Hash for Options', except: {browser: :safari,
211
+ reason: 'Safari does not like proxies'} do
212
+ proxy = {http: '127.0.0.1:8080', ssl: '127.0.0.1:443'}
213
+ @browser = Browser.new(browser_symbol, proxy: proxy)
214
+
215
+ expect(actual_capabilities.proxy).to be_a Selenium::WebDriver::Proxy
216
+ expect(actual_capabilities.proxy.type).to eq(:manual)
217
+ expect(actual_capabilities.proxy.http).to eq('127.0.0.1:8080')
218
+ expect(actual_capabilities.proxy.ssl).to eq('127.0.0.1:443')
219
+ end
220
+
221
+ it 'builds a Proxy from Hash and adds to Options Hash', except: {browser: :safari,
222
+ reason: 'Safari does not like proxies'} do
223
+ proxy = {http: '127.0.0.1:8080', ssl: '127.0.0.1:443'}
224
+ options = {unhandled_prompt_behavior: :accept,
225
+ page_load_strategy: :eager}
226
+
227
+ @browser = Browser.new(browser_symbol, options: options, proxy: proxy)
228
+
229
+ expect(actual_capabilities.proxy).to be_a Selenium::WebDriver::Proxy
230
+ expect(actual_capabilities.proxy.type).to eq(:manual)
231
+ expect(actual_capabilities.proxy.http).to eq('127.0.0.1:8080')
232
+ expect(actual_capabilities.proxy.ssl).to eq('127.0.0.1:443')
233
+ expect(actual_capabilities.unhandled_prompt_behavior).to eq 'accept'
234
+ expect(actual_capabilities.page_load_strategy).to eq 'eager'
235
+ end
236
+
237
+ it 'builds a Proxy from Hash and adds to Options Class', except: {browser: :safari,
238
+ reason: 'Safari does not like proxies'} do
239
+ proxy = {http: '127.0.0.1:8080', ssl: '127.0.0.1:443'}
240
+ options = Options.send(browser_symbol, unhandled_prompt_behavior: :accept, page_load_strategy: :eager)
241
+
242
+ @browser = Browser.new(browser_symbol, options: options, proxy: proxy)
243
+
244
+ expect(actual_capabilities.proxy).to be_a Selenium::WebDriver::Proxy
245
+ expect(actual_capabilities.proxy.type).to eq(:manual)
246
+ expect(actual_capabilities.proxy.http).to eq('127.0.0.1:8080')
247
+ expect(actual_capabilities.proxy.ssl).to eq('127.0.0.1:443')
248
+ expect(actual_capabilities.unhandled_prompt_behavior).to eq 'accept'
249
+ expect(actual_capabilities.page_load_strategy).to eq 'eager'
250
+ end
251
+ end
252
+ end
253
+
254
+ context 'chrome', exclusive: {browser: :chrome} do
255
+ it 'by default uses chrome, has client, options, but not capabilities' do
256
+ @browser = Browser.new
257
+
258
+ expect(generated_options).to be_a Selenium::WebDriver::Chrome::Options
259
+ expect(actual_http).to be_a HttpClient
260
+ expect(selenium_args).not_to include(:service)
261
+ end
262
+
263
+ it 'sets headless by creating options' do
264
+ @browser = Browser.new(:chrome, headless: true)
265
+
266
+ expect(generated_options.args).to include '--headless'
267
+ end
268
+
269
+ it 'sets headless in existing options class' do
270
+ @browser = Browser.new(:chrome,
271
+ options: Options.chrome,
272
+ headless: true)
273
+
274
+ expect(generated_options.args).to include '--headless'
275
+ end
276
+
277
+ it 'sets headless when existing options is a Hash' do
278
+ options = {args: ['--foo']}
279
+ @browser = Browser.new(:chrome,
280
+ options: options,
281
+ headless: true)
282
+
283
+ expect(generated_options.args).to include '--headless'
284
+ end
285
+ end
286
+
287
+ context 'edge', exclusive: {browser: :edge} do
288
+ it 'sets headless by creating options' do
289
+ @browser = Browser.new(:edge, headless: true)
290
+
291
+ expect(generated_options.args).to include '--headless'
292
+ end
293
+
294
+ it 'sets headless in existing options class' do
295
+ @browser = Browser.new(:edge,
296
+ options: Options.edge,
297
+ headless: true)
298
+
299
+ expect(generated_options.args).to include '--headless'
300
+ end
301
+
302
+ it 'sets headless when existing options is a Hash' do
303
+ options = {args: ['--foo']}
304
+ @browser = Browser.new(:edge,
305
+ options: options,
306
+ headless: true)
307
+
308
+ expect(generated_options.args).to include '--headless'
309
+ end
310
+ end
311
+
312
+ context 'firefox', exclusive: {browser: :firefox} do
313
+ it 'puts Profile inside Options as Hash' do
314
+ profile = Selenium::WebDriver::Firefox::Profile.new
315
+ options = {args: ['--foo'], profile: profile}
316
+
317
+ @browser = Browser.new(:firefox, options: options)
318
+
319
+ expect(generated_options.args).to include '--foo'
320
+ expect(generated_options.profile).to eq profile
321
+ end
322
+
323
+ it 'puts Profile inside Hash options' do
324
+ profile = Selenium::WebDriver::Firefox::Profile.new
325
+ options = {args: ['--foo'], profile: profile}
326
+
327
+ @browser = Browser.new(:firefox, options: options)
328
+
329
+ expect(generated_options.args).to include '--foo'
330
+ expect(generated_options.profile).to eq profile
331
+ end
332
+
333
+ it 'sets headless by creating options' do
334
+ @browser = Browser.new(:firefox, headless: true)
335
+
336
+ expect(generated_options.args).to include '-headless'
337
+ end
338
+
339
+ it 'sets headless in existing options class' do
340
+ @browser = Browser.new(:firefox,
341
+ options: Options.firefox,
342
+ headless: true)
343
+
344
+ expect(generated_options.args).to include '-headless'
345
+ end
346
+
347
+ it 'sets headless when existing options is a Hash' do
348
+ options = {args: ['-foo']}
349
+ @browser = Browser.new(:firefox,
350
+ options: options,
351
+ headless: true)
352
+
353
+ expect(generated_options.args).to include '-headless', '-foo'
354
+ end
355
+ end
356
+
357
+ context 'safari', exclusive: {browser: :safari} do
358
+ after(:each) { Selenium::WebDriver::Safari.use_technology_preview = false }
359
+
360
+ it 'sets Technology Preview', exclude: {browser: :safari,
361
+ reason: 'Broken in Selenium'} do
362
+ @browser = Browser.new(:safari, technology_preview: true)
363
+
364
+ expect(Selenium::WebDriver::Safari.technology_preview?).to eq true
365
+ end
366
+
367
+ it 'generates options from Hash with custom option' do
368
+ options = {page_load_strategy: 'eager', automatic_inspection: true}
369
+ @browser = Browser.new(browser_symbol, options: options)
370
+
371
+ expect(generated_options).to be_a Options.send(browser_symbol).class
372
+ expect(actual_capabilities.page_load_strategy).to eq 'eager'
373
+ expect(actual_capabilities['safari:automaticInspection']).to eq true
374
+ end
375
+ end
376
+ end
377
+
378
+ # Options:
379
+ # :url (Required)
380
+ # :service (Errors)
381
+ # :listener
382
+ # :http_client (Generated or Built from Hash)
383
+ # :proxy (Built from Hash and added to :options)
384
+ # :options (Generated or Built from Hash)
385
+ # :capabilities (incompatible with options)
386
+
387
+ context 'when remote', exclusive: {driver: :remote_driver} do
388
+ let(:url) { "#{WatirSpec.implementation.browser_args.last[:url]}/" }
389
+
390
+ it 'with just url' do
391
+ @browser = Browser.new(url: url)
392
+
393
+ expect(selenium_browser).to eq :remote
394
+ expect(selenium_args).not_to include(:service)
395
+ expect(generated_options).to be_a Options.send(browser_symbol).class
396
+ expect(actual_capabilities.browser_name).to eq browser_name
397
+ expect(actual_http).to be_a HttpClient
398
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
399
+ end
400
+
401
+ it 'just url & browser name has options and client but not service' do
402
+ @browser = Browser.new(browser_symbol, url: url)
403
+
404
+ expect(selenium_browser).to eq :remote
405
+ expect(selenium_args).not_to include(:service)
406
+ expect(generated_options).to be_a Options.send(browser_symbol).class
407
+ expect(actual_capabilities.browser_name).to eq browser_name
408
+ expect(actual_http).to be_a HttpClient
409
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
410
+ end
411
+
412
+ it 'accepts a listener' do
413
+ listener = Selenium::WebDriver::Support::AbstractEventListener.new
414
+ @browser = Browser.new(browser_symbol,
415
+ url: url,
416
+ listener: listener)
417
+
418
+ expect(actual_listener).to eq listener
419
+
420
+ expect(selenium_browser).to eq :remote
421
+ expect(selenium_args).not_to include(:service)
422
+ expect(generated_options).to be_a Options.send(browser_symbol).class
423
+ expect(actual_capabilities.browser_name).to eq browser_name
424
+ end
425
+
426
+ it 'accepts http client object' do
427
+ client = HttpClient.new
428
+ @browser = Browser.new(browser_symbol,
429
+ url: url,
430
+ http_client: client)
431
+
432
+ expect(actual_http).to eq client
433
+
434
+ expect(selenium_browser).to eq :remote
435
+ expect(selenium_args).not_to include(:service)
436
+ expect(generated_options).to be_a Options.send(browser_symbol).class
437
+ expect(actual_capabilities.browser_name).to eq browser_name
438
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
439
+ end
440
+
441
+ it 'accepts http client Hash' do
442
+ @browser = Watir::Browser.new(browser_symbol,
443
+ url: url,
444
+ http_client: {read_timeout: 30})
445
+
446
+ expect(actual_http.instance_variable_get(:@read_timeout)).to eq 30
447
+
448
+ expect(selenium_browser).to eq :remote
449
+ expect(selenium_args).not_to include(:service)
450
+ expect(generated_options).to be_a Options.send(browser_symbol).class
451
+ expect(actual_capabilities.browser_name).to eq browser_name
452
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
453
+ end
454
+
455
+ it 'accepts proxy object' do
456
+ proxy = Selenium::WebDriver::Proxy.new(http: '127.0.0.1:8080', ssl: '127.0.0.1:443')
457
+ @browser = Watir::Browser.new(browser_symbol,
458
+ url: url,
459
+ proxy: proxy)
460
+
461
+ expect(actual_capabilities.proxy).to eq proxy
462
+
463
+ expect(selenium_browser).to eq :remote
464
+ expect(selenium_args).not_to include(:service)
465
+ expect(generated_options).to be_a Options.send(browser_symbol).class
466
+ expect(actual_capabilities.browser_name).to eq browser_name
467
+ expect(actual_http).to be_a HttpClient
468
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
469
+ end
470
+
471
+ it 'accepts proxy Hash' do
472
+ proxy = {http: '127.0.0.1:8080', ssl: '127.0.0.1:443'}
473
+ @browser = Browser.new(browser_symbol,
474
+ url: url,
475
+ proxy: proxy)
476
+
477
+ expect(actual_capabilities.proxy).to be_a Selenium::WebDriver::Proxy
478
+ expect(actual_capabilities.proxy.type).to eq(:manual)
479
+ expect(actual_capabilities.proxy.http).to eq('127.0.0.1:8080')
480
+ expect(actual_capabilities.proxy.ssl).to eq('127.0.0.1:443')
481
+
482
+ expect(selenium_browser).to eq :remote
483
+ expect(selenium_args).not_to include(:service)
484
+ expect(generated_options).to be_a Options.send(browser_symbol).class
485
+ expect(actual_capabilities.browser_name).to eq browser_name
486
+ expect(actual_http).to be_a HttpClient
487
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
488
+ end
489
+
490
+ it 'accepts options object' do
491
+ @browser = Browser.new(browser_symbol,
492
+ url: url,
493
+ options: Options.send(browser_symbol, args: ['--foo']))
494
+
495
+ expect(generated_options.args).to include('--foo')
496
+
497
+ expect(selenium_browser).to eq :remote
498
+ expect(selenium_args).not_to include(:service)
499
+ expect(generated_options).to be_a Options.send(browser_symbol).class
500
+ expect(actual_capabilities.browser_name).to eq browser_name
501
+ expect(actual_http).to be_a HttpClient
502
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
503
+ end
504
+
505
+ it 'accepts options hash' do
506
+ options = {prefs: {foo: 'bar'}}
507
+ @browser = Browser.new(browser_symbol,
508
+ url: url,
509
+ options: options)
510
+
511
+ expect(selenium_browser).to eq :remote
512
+ expect(selenium_args).not_to include(:service)
513
+ expect(generated_options).to be_a Options.send(browser_symbol).class
514
+ expect(generated_options.prefs).to eq(foo: 'bar')
515
+ expect(actual_capabilities.browser_name).to eq browser_name
516
+ expect(actual_http).to be_a HttpClient
517
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
518
+ end
519
+
520
+ it 'accepts capabilities object' do
521
+ capabilities = Remote::Capabilities.send(browser_symbol)
522
+ @browser = Browser.new(browser_symbol,
523
+ url: url,
524
+ capabilities: capabilities)
525
+
526
+ expect(selenium_browser).to eq :remote
527
+ expect(selenium_args).not_to include(:service)
528
+ expect(selenium_args[:capabilities]).to eq(capabilities)
529
+ expect(actual_capabilities.browser_name).to eq browser_name
530
+ expect(actual_http).to be_a HttpClient
531
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
532
+ end
533
+
534
+ it 'accepts http client & capabilities objects' do
535
+ client = HttpClient.new
536
+ capabilities = Remote::Capabilities.send(browser_symbol)
537
+ @browser = Browser.new(browser_symbol,
538
+ url: url,
539
+ capabilities: capabilities,
540
+ http_client: client)
541
+
542
+ expect(selenium_browser).to eq :remote
543
+ expect(selenium_args).not_to include(:service)
544
+ expect(selenium_args[:capabilities]).to eq capabilities
545
+ expect(actual_capabilities.browser_name).to eq browser_name
546
+ expect(actual_http).to be_a HttpClient
547
+ expect(actual_http.instance_variable_get(:@server_url).to_s).to eq url
548
+ end
549
+
550
+ it 'accepts http client & proxy & options objects' do
551
+ client = HttpClient.new
552
+ proxy = Selenium::WebDriver::Proxy.new(http: '127.0.0.1:8080', ssl: '127.0.0.1:443')
553
+ options = Options.send(browser_symbol, prefs: {foo: 'bar'})
554
+ @browser = Browser.new(browser_symbol,
555
+ url: url,
556
+ proxy: proxy,
557
+ options: options,
558
+ http_client: client)
559
+
560
+ expect(selenium_browser).to eq :remote
561
+ expect(selenium_args).not_to include :service
562
+ expect(generated_options).to eq options
563
+ expect(actual_capabilities.browser_name).to eq browser_name
564
+ expect(actual_capabilities.proxy).to eq proxy
565
+ expect(actual_http).to eq client
566
+ end
567
+ end
568
+ end
569
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Browser#cookies' do
@@ -133,7 +135,7 @@ describe 'Browser#cookies' do
133
135
 
134
136
  describe '#save' do
135
137
  it 'saves cookies to file' do
136
- expect(IO.read(file)).to eq(browser.cookies.to_a.to_yaml)
138
+ expect(File.read(file)).to eq(browser.cookies.to_a.to_yaml)
137
139
  end
138
140
  end
139
141
 
@@ -142,7 +144,7 @@ describe 'Browser#cookies' do
142
144
  browser.cookies.clear
143
145
  browser.cookies.load file
144
146
  expected = browser.cookies.to_a
145
- actual = YAML.safe_load(IO.read(file), [::Symbol])
147
+ actual = YAML.safe_load(File.read(file), permitted_classes: [Symbol])
146
148
 
147
149
  expected.each { |cookie| cookie.delete(:expires) }
148
150
  actual.each { |cookie| cookie.delete(:expires) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Element' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe Watir::Locators::Element::Locator do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Area' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Areas' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Button' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Buttons' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'CheckBox' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'CheckBoxes' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'Collections' do
@@ -14,7 +16,7 @@ describe 'Collections' do
14
16
  it 'returns correct subtype of elements' do
15
17
  browser.goto(WatirSpec.url_for('collections.html'))
16
18
  collection = browser.span(id: 'a_span').spans
17
- expect(collection.all? { |el| el.is_a? Watir::Span }).to eq true
19
+ expect(collection.all?(Watir::Span)).to eq true
18
20
  end
19
21
 
20
22
  it 'returns correct subtype of elements without tag_name' do
@@ -28,8 +30,8 @@ describe 'Collections' do
28
30
  it 'can contain more than one type of element' do
29
31
  browser.goto(WatirSpec.url_for('nested_elements.html'))
30
32
  collection = browser.div(id: 'parent').children
31
- expect(collection.any? { |el| el.is_a? Watir::Span }).to eq true
32
- expect(collection.any? { |el| el.is_a? Watir::Div }).to eq true
33
+ expect(collection.any?(Watir::Span)).to eq true
34
+ expect(collection.any?(Watir::Div)).to eq true
33
35
  end
34
36
 
35
37
  it 'relocates the same element' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'DateField' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'watirspec_helper'
2
4
 
3
5
  describe 'DateFields' do