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.
- checksums.yaml +4 -4
- data/.github/workflows/chrome.yml +29 -16
- data/.github/workflows/edge.yml +19 -11
- data/.github/workflows/firefox.yml +28 -16
- data/.github/workflows/ie.yml +13 -7
- data/.github/workflows/safari.yml +22 -11
- data/.github/workflows/unit.yml +31 -23
- data/.rubocop.yml +14 -7
- data/.rubocop_todo.yml +0 -26
- data/CHANGES.md +16 -1
- data/Gemfile +6 -1
- data/README.md +15 -11
- data/Rakefile +9 -7
- data/lib/watir/adjacent.rb +3 -1
- data/lib/watir/after_hooks.rb +5 -3
- data/lib/watir/alert.rb +2 -0
- data/lib/watir/aliases.rb +2 -0
- data/lib/watir/attribute_helper.rb +4 -2
- data/lib/watir/browser.rb +10 -14
- data/lib/watir/capabilities.rb +56 -33
- data/lib/watir/cell_container.rb +2 -0
- data/lib/watir/container.rb +2 -0
- data/lib/watir/cookies.rb +5 -5
- data/lib/watir/element_collection.rb +3 -1
- data/lib/watir/elements/button.rb +2 -0
- data/lib/watir/elements/cell.rb +2 -0
- data/lib/watir/elements/checkbox.rb +2 -0
- data/lib/watir/elements/date_field.rb +2 -0
- data/lib/watir/elements/date_time_field.rb +2 -0
- data/lib/watir/elements/dlist.rb +3 -1
- data/lib/watir/elements/element.rb +29 -105
- data/lib/watir/elements/file_field.rb +2 -0
- data/lib/watir/elements/font.rb +2 -0
- data/lib/watir/elements/form.rb +2 -0
- data/lib/watir/elements/hidden.rb +2 -0
- data/lib/watir/elements/iframe.rb +2 -0
- data/lib/watir/elements/image.rb +2 -0
- data/lib/watir/elements/input.rb +2 -0
- data/lib/watir/elements/link.rb +2 -0
- data/lib/watir/elements/list.rb +2 -0
- data/lib/watir/elements/option.rb +2 -0
- data/lib/watir/elements/radio.rb +2 -0
- data/lib/watir/elements/row.rb +2 -0
- data/lib/watir/elements/select.rb +2 -0
- data/lib/watir/elements/table.rb +3 -1
- data/lib/watir/elements/table_cell.rb +2 -0
- data/lib/watir/elements/table_row.rb +2 -0
- data/lib/watir/elements/table_section.rb +2 -0
- data/lib/watir/elements/text_area.rb +2 -0
- data/lib/watir/elements/text_field.rb +2 -0
- data/lib/watir/exception.rb +2 -0
- data/lib/watir/extensions/nokogiri.rb +2 -0
- data/lib/watir/generator/base/generator.rb +2 -0
- data/lib/watir/generator/base/idl_sorter.rb +3 -1
- data/lib/watir/generator/base/spec_extractor.rb +6 -4
- data/lib/watir/generator/base/util.rb +2 -0
- data/lib/watir/generator/base/visitor.rb +5 -5
- data/lib/watir/generator/base.rb +2 -1
- data/lib/watir/generator/html/generator.rb +2 -0
- data/lib/watir/generator/html/spec_extractor.rb +2 -0
- data/lib/watir/generator/html/visitor.rb +2 -0
- data/lib/watir/generator/html.rb +2 -0
- data/lib/watir/generator/svg/generator.rb +2 -0
- data/lib/watir/generator/svg/spec_extractor.rb +2 -0
- data/lib/watir/generator/svg/visitor.rb +2 -0
- data/lib/watir/generator/svg.rb +2 -0
- data/lib/watir/generator.rb +2 -0
- data/lib/watir/has_window.rb +3 -1
- data/lib/watir/http_client.rb +2 -0
- data/lib/watir/js_execution.rb +2 -0
- data/lib/watir/js_snippets.rb +2 -0
- data/lib/watir/locators/anchor/selector_builder.rb +2 -0
- data/lib/watir/locators/button/matcher.rb +2 -0
- data/lib/watir/locators/button/selector_builder/xpath.rb +15 -19
- data/lib/watir/locators/button/selector_builder.rb +2 -0
- data/lib/watir/locators/cell/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/cell/selector_builder.rb +2 -0
- data/lib/watir/locators/element/locator.rb +2 -0
- data/lib/watir/locators/element/matcher.rb +2 -0
- data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -0
- data/lib/watir/locators/element/selector_builder/xpath.rb +16 -15
- data/lib/watir/locators/element/selector_builder/xpath_support.rb +4 -2
- data/lib/watir/locators/element/selector_builder.rb +16 -6
- data/lib/watir/locators/option/matcher.rb +2 -0
- data/lib/watir/locators/option/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/option/selector_builder.rb +2 -0
- data/lib/watir/locators/row/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/row/selector_builder.rb +2 -0
- data/lib/watir/locators/text_area/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/text_area/selector_builder.rb +2 -0
- data/lib/watir/locators/text_field/matcher.rb +2 -0
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/text_field/selector_builder.rb +2 -0
- data/lib/watir/locators.rb +2 -0
- data/lib/watir/logger.rb +2 -0
- data/lib/watir/navigation.rb +3 -1
- data/lib/watir/radio_set.rb +2 -0
- data/lib/watir/row_container.rb +2 -0
- data/lib/watir/screenshot.rb +2 -0
- data/lib/watir/scroll.rb +27 -2
- data/lib/watir/search_context.rb +96 -0
- data/lib/watir/shadow_root.rb +60 -0
- data/lib/watir/user_editable.rb +3 -1
- data/lib/watir/version.rb +3 -1
- data/lib/watir/wait/timer.rb +3 -1
- data/lib/watir/wait.rb +5 -5
- data/lib/watir/window.rb +7 -3
- data/lib/watir/window_collection.rb +4 -1
- data/lib/watir.rb +4 -0
- data/lib/watirspec/guards.rb +2 -0
- data/lib/watirspec/implementation.rb +14 -10
- data/lib/watirspec/rake_tasks.rb +4 -4
- data/lib/watirspec/remote_server.rb +5 -3
- data/lib/watirspec/runner.rb +3 -1
- data/lib/watirspec/server/app.rb +2 -0
- data/lib/watirspec/server.rb +2 -0
- data/lib/watirspec.rb +7 -4
- data/spec/locator_spec_helper.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/capabilities_spec.rb +77 -58
- data/spec/unit/element_locator_spec.rb +2 -0
- data/spec/unit/match_elements/button_spec.rb +2 -0
- data/spec/unit/match_elements/element_spec.rb +10 -8
- data/spec/unit/match_elements/text_field_spec.rb +2 -0
- data/spec/unit/selector_builder/anchor_spec.rb +2 -0
- data/spec/unit/selector_builder/button_spec.rb +31 -28
- data/spec/unit/selector_builder/cell_spec.rb +3 -1
- data/spec/unit/selector_builder/element_spec.rb +61 -60
- data/spec/unit/selector_builder/row_spec.rb +21 -10
- data/spec/unit/selector_builder/text_field_spec.rb +29 -21
- data/spec/unit/selector_builder/textarea_spec.rb +2 -0
- data/spec/unit/unit_helper.rb +2 -0
- data/spec/unit/wait_spec.rb +2 -0
- data/spec/watirspec/adjacent_spec.rb +8 -6
- data/spec/watirspec/after_hooks_spec.rb +19 -21
- data/spec/watirspec/alert_spec.rb +2 -0
- data/spec/watirspec/attributes_spec.rb +2 -0
- data/spec/watirspec/browser_spec.rb +16 -12
- data/spec/watirspec/capabilities_spec.rb +569 -0
- data/spec/watirspec/cookies_spec.rb +4 -2
- data/spec/watirspec/drag_and_drop_spec.rb +2 -0
- data/spec/watirspec/element_hidden_spec.rb +2 -0
- data/spec/watirspec/elements/area_spec.rb +2 -0
- data/spec/watirspec/elements/areas_spec.rb +2 -0
- data/spec/watirspec/elements/button_spec.rb +2 -0
- data/spec/watirspec/elements/buttons_spec.rb +2 -0
- data/spec/watirspec/elements/checkbox_spec.rb +2 -0
- data/spec/watirspec/elements/checkboxes_spec.rb +2 -0
- data/spec/watirspec/elements/collections_spec.rb +5 -3
- data/spec/watirspec/elements/date_field_spec.rb +2 -0
- data/spec/watirspec/elements/date_fields_spec.rb +2 -0
- data/spec/watirspec/elements/date_time_field_spec.rb +2 -0
- data/spec/watirspec/elements/date_time_fields_spec.rb +2 -0
- data/spec/watirspec/elements/dd_spec.rb +2 -0
- data/spec/watirspec/elements/dds_spec.rb +2 -0
- data/spec/watirspec/elements/del_spec.rb +2 -0
- data/spec/watirspec/elements/dels_spec.rb +2 -0
- data/spec/watirspec/elements/div_spec.rb +2 -1
- data/spec/watirspec/elements/divs_spec.rb +2 -0
- data/spec/watirspec/elements/dl_spec.rb +6 -6
- data/spec/watirspec/elements/dls_spec.rb +2 -0
- data/spec/watirspec/elements/dt_spec.rb +2 -0
- data/spec/watirspec/elements/dts_spec.rb +2 -0
- data/spec/watirspec/elements/element_spec.rb +9 -1
- data/spec/watirspec/elements/elements_spec.rb +2 -0
- data/spec/watirspec/elements/em_spec.rb +2 -0
- data/spec/watirspec/elements/ems_spec.rb +2 -0
- data/spec/watirspec/elements/filefield_spec.rb +2 -0
- data/spec/watirspec/elements/filefields_spec.rb +2 -0
- data/spec/watirspec/elements/font_spec.rb +2 -0
- data/spec/watirspec/elements/form_spec.rb +2 -0
- data/spec/watirspec/elements/forms_spec.rb +2 -0
- data/spec/watirspec/elements/frame_spec.rb +2 -0
- data/spec/watirspec/elements/frames_spec.rb +2 -0
- data/spec/watirspec/elements/hidden_spec.rb +2 -0
- data/spec/watirspec/elements/hiddens_spec.rb +2 -0
- data/spec/watirspec/elements/hn_spec.rb +2 -0
- data/spec/watirspec/elements/hns_spec.rb +2 -0
- data/spec/watirspec/elements/iframe_spec.rb +3 -1
- data/spec/watirspec/elements/iframes_spec.rb +2 -0
- data/spec/watirspec/elements/image_spec.rb +2 -0
- data/spec/watirspec/elements/images_spec.rb +2 -0
- data/spec/watirspec/elements/input_spec.rb +2 -0
- data/spec/watirspec/elements/ins_spec.rb +2 -0
- data/spec/watirspec/elements/inses_spec.rb +2 -0
- data/spec/watirspec/elements/label_spec.rb +2 -0
- data/spec/watirspec/elements/labels_spec.rb +2 -0
- data/spec/watirspec/elements/li_spec.rb +2 -0
- data/spec/watirspec/elements/link_spec.rb +4 -4
- data/spec/watirspec/elements/links_spec.rb +2 -0
- data/spec/watirspec/elements/lis_spec.rb +2 -0
- data/spec/watirspec/elements/list_spec.rb +2 -0
- data/spec/watirspec/elements/map_spec.rb +2 -0
- data/spec/watirspec/elements/maps_spec.rb +2 -0
- data/spec/watirspec/elements/meta_spec.rb +2 -0
- data/spec/watirspec/elements/metas_spec.rb +2 -0
- data/spec/watirspec/elements/ol_spec.rb +2 -0
- data/spec/watirspec/elements/ols_spec.rb +2 -0
- data/spec/watirspec/elements/option_spec.rb +2 -0
- data/spec/watirspec/elements/p_spec.rb +2 -0
- data/spec/watirspec/elements/pre_spec.rb +2 -0
- data/spec/watirspec/elements/pres_spec.rb +2 -0
- data/spec/watirspec/elements/ps_spec.rb +2 -0
- data/spec/watirspec/elements/radio_spec.rb +2 -0
- data/spec/watirspec/elements/radios_spec.rb +2 -0
- data/spec/watirspec/elements/select_list_spec.rb +7 -1
- data/spec/watirspec/elements/select_lists_spec.rb +2 -0
- data/spec/watirspec/elements/span_spec.rb +2 -0
- data/spec/watirspec/elements/spans_spec.rb +2 -0
- data/spec/watirspec/elements/strong_spec.rb +2 -0
- data/spec/watirspec/elements/strongs_spec.rb +2 -0
- data/spec/watirspec/elements/table_nesting_spec.rb +2 -0
- data/spec/watirspec/elements/table_spec.rb +2 -0
- data/spec/watirspec/elements/tables_spec.rb +2 -0
- data/spec/watirspec/elements/tbody_spec.rb +2 -0
- data/spec/watirspec/elements/tbodys_spec.rb +2 -0
- data/spec/watirspec/elements/td_spec.rb +2 -0
- data/spec/watirspec/elements/tds_spec.rb +2 -0
- data/spec/watirspec/elements/text_field_spec.rb +2 -0
- data/spec/watirspec/elements/text_fields_spec.rb +2 -0
- data/spec/watirspec/elements/textarea_spec.rb +2 -0
- data/spec/watirspec/elements/textareas_spec.rb +2 -0
- data/spec/watirspec/elements/tfoot_spec.rb +2 -0
- data/spec/watirspec/elements/tfoots_spec.rb +2 -0
- data/spec/watirspec/elements/thead_spec.rb +2 -0
- data/spec/watirspec/elements/theads_spec.rb +2 -0
- data/spec/watirspec/elements/tr_spec.rb +2 -0
- data/spec/watirspec/elements/trs_spec.rb +2 -0
- data/spec/watirspec/elements/ul_spec.rb +2 -0
- data/spec/watirspec/elements/uls_spec.rb +2 -0
- data/spec/watirspec/html/child_frame.html +29 -0
- data/spec/watirspec/html/class_locator.html +2 -0
- data/spec/watirspec/html/scroll_nested.html +17 -0
- data/spec/watirspec/html/scroll_nested_offscreen.html +18 -0
- data/spec/watirspec/html/shadow_dom.html +28 -0
- data/spec/watirspec/radio_set_spec.rb +2 -0
- data/spec/watirspec/screenshot_spec.rb +4 -2
- data/spec/watirspec/scroll_spec.rb +75 -7
- data/spec/watirspec/shadow_root_spec.rb +103 -0
- data/spec/watirspec/special_chars_spec.rb +2 -0
- data/spec/watirspec/support/rspec_matchers.rb +35 -32
- data/spec/watirspec/user_editable_spec.rb +2 -0
- data/spec/watirspec/wait_spec.rb +2 -0
- data/spec/watirspec/window_switching_spec.rb +48 -38
- data/spec/watirspec_helper.rb +24 -18
- data/support/doctest_helper.rb +2 -0
- data/support/version_differ.rb +2 -0
- data/watir.gemspec +11 -8
- metadata +54 -215
- data/.github/actions/enable-safari/action.yml +0 -11
- data/.github/actions/install-chrome/action.yml +0 -12
- data/.github/actions/setup-linux/action.yml +0 -8
- data/lib/watir-webdriver.rb +0 -2
data/lib/watir/aliases.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
#
|
|
3
5
|
# @private
|
|
@@ -29,9 +31,9 @@ module Watir
|
|
|
29
31
|
|
|
30
32
|
def attribute_list
|
|
31
33
|
@attribute_list ||= (typed_attributes.values.flatten +
|
|
32
|
-
ancestors[1..].
|
|
34
|
+
ancestors[1..].filter_map { |e|
|
|
33
35
|
e.attribute_list if e.respond_to?(:attribute_list)
|
|
34
|
-
}.
|
|
36
|
+
}.flatten
|
|
35
37
|
).uniq
|
|
36
38
|
end
|
|
37
39
|
|
data/lib/watir/browser.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
#
|
|
3
5
|
# The main class through which you control the browser.
|
|
@@ -40,15 +42,8 @@ module Watir
|
|
|
40
42
|
#
|
|
41
43
|
|
|
42
44
|
def initialize(browser = :chrome, *args)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@capabilities = Capabilities.new(browser, *args)
|
|
46
|
-
@driver = Selenium::WebDriver.for(*@capabilities.to_args)
|
|
47
|
-
when Selenium::WebDriver::Driver
|
|
48
|
-
@driver = browser
|
|
49
|
-
else
|
|
50
|
-
raise ArgumentError, "expected Symbol or Selenium::WebDriver::Driver, got #{browser.class}"
|
|
51
|
-
end
|
|
45
|
+
@capabilities = browser.is_a?(Capabilities) ? browser : Capabilities.new(browser, *args)
|
|
46
|
+
@driver = browser.is_a?(Selenium::WebDriver::Driver) ? browser : Selenium::WebDriver.for(*@capabilities.to_args)
|
|
52
47
|
|
|
53
48
|
@after_hooks = AfterHooks.new(self)
|
|
54
49
|
@closed = false
|
|
@@ -56,17 +51,18 @@ module Watir
|
|
|
56
51
|
end
|
|
57
52
|
|
|
58
53
|
# rubocop:disable Metrics/AbcSize
|
|
59
|
-
# TODO: w3c default behavior does not like checking if alert exists
|
|
60
54
|
def inspect
|
|
61
55
|
if alert.exists?
|
|
62
|
-
format('
|
|
56
|
+
format('#<%<class>s:0x%<hash>x alert=true>', class: self.class, hash: hash * 2)
|
|
63
57
|
else
|
|
64
|
-
format('
|
|
58
|
+
format('#<%<class>s:0x%<hash>x url=%<url>s title=%<title>s>',
|
|
59
|
+
class: self.class, hash: hash * 2, url: url.inspect, title: title.inspect)
|
|
65
60
|
end
|
|
66
61
|
rescue Selenium::WebDriver::Error::NoSuchWindowError
|
|
67
|
-
format('
|
|
62
|
+
format('#<%<class>s:0x%<hash>x closed=%<closed>s>',
|
|
63
|
+
class: self.class, hash: hash * 2, closed: closed?)
|
|
68
64
|
rescue Errno::ECONNREFUSED
|
|
69
|
-
format('
|
|
65
|
+
format('#<%<class>s:0x%<hash>x closed=true>', class: self.class, hash: hash * 2)
|
|
70
66
|
end
|
|
71
67
|
alias selector_string inspect
|
|
72
68
|
# rubocop:enable Metrics/AbcSize
|
data/lib/watir/capabilities.rb
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
class Capabilities
|
|
3
|
-
attr_reader :options
|
|
5
|
+
attr_reader :options, :selenium_browser, :selenium_args
|
|
4
6
|
|
|
5
7
|
def initialize(browser = nil, options = {})
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
@options, @browser = case browser
|
|
9
|
+
when Selenium::WebDriver::Driver
|
|
10
|
+
return
|
|
11
|
+
when ::Symbol, String
|
|
12
|
+
[options.dup, browser&.to_sym]
|
|
13
|
+
when Hash
|
|
14
|
+
[browser.dup, infer_browser(browser)]
|
|
15
|
+
when nil
|
|
16
|
+
[{}, infer_browser]
|
|
17
|
+
else
|
|
18
|
+
raise ArgumentError,
|
|
19
|
+
"expected Driver, String, Symbol or Hash, but received: #{browser.class}"
|
|
20
|
+
end
|
|
21
|
+
validate_options
|
|
20
22
|
|
|
21
23
|
@selenium_browser = @options.key?(:url) ? :remote : @browser
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def to_args
|
|
25
|
-
|
|
27
|
+
Watir.logger.info "Creating Browser instance of #{@browser} with user provided options: #{@options.inspect}"
|
|
28
|
+
@selenium_args = process_arguments
|
|
29
|
+
raise ArgumentError, "#{@options} are unrecognized arguments for Browser constructor" unless @options.empty?
|
|
30
|
+
|
|
31
|
+
Watir.logger.info "Selenium options generated by Watir: #{@selenium_args.inspect}"
|
|
32
|
+
[@selenium_browser, @selenium_args]
|
|
26
33
|
end
|
|
27
34
|
|
|
28
35
|
private
|
|
@@ -39,9 +46,15 @@ module Watir
|
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
selenium_opts[:http_client] = process_http_client
|
|
42
|
-
|
|
49
|
+
if @options.key?(:capabilities)
|
|
50
|
+
Watir.logger.deprecate(':capabilities argument in Browser constructor',
|
|
51
|
+
':options argument with Selenium Options instance or Hash',
|
|
52
|
+
id: :capabilities)
|
|
53
|
+
selenium_opts[:capabilities] = @options.delete(:capabilities)
|
|
54
|
+
else
|
|
55
|
+
selenium_opts[:options] = process_browser_options
|
|
56
|
+
end
|
|
43
57
|
|
|
44
|
-
Watir.logger.info "Creating Browser instance with Watir processed options: #{selenium_opts.inspect}"
|
|
45
58
|
selenium_opts
|
|
46
59
|
end
|
|
47
60
|
|
|
@@ -64,7 +77,6 @@ module Watir
|
|
|
64
77
|
|
|
65
78
|
def process_browser_options
|
|
66
79
|
browser_options = @options.delete(:options).dup || {}
|
|
67
|
-
vendor_caps = process_vendor_capabilities(browser_options)
|
|
68
80
|
|
|
69
81
|
options = if browser_options.is_a? Selenium::WebDriver::Options
|
|
70
82
|
browser_options
|
|
@@ -76,9 +88,11 @@ module Watir
|
|
|
76
88
|
options.unhandled_prompt_behavior ||= :ignore
|
|
77
89
|
process_proxy_options(options)
|
|
78
90
|
browser_specific_options(options)
|
|
79
|
-
raise ArgumentError, "#{@options} are unrecognized arguments for Browser constructor" unless @options.empty?
|
|
80
91
|
|
|
81
|
-
|
|
92
|
+
vendor_opts = process_vendor_options(browser_options)
|
|
93
|
+
vendor_opts.each { |opts| options.add_option(opts) }
|
|
94
|
+
|
|
95
|
+
options
|
|
82
96
|
end
|
|
83
97
|
|
|
84
98
|
def process_proxy_options(options)
|
|
@@ -94,7 +108,7 @@ module Watir
|
|
|
94
108
|
options.proxy = proxy
|
|
95
109
|
end
|
|
96
110
|
|
|
97
|
-
def
|
|
111
|
+
def process_vendor_options(opts)
|
|
98
112
|
return [] unless opts.is_a? Hash
|
|
99
113
|
|
|
100
114
|
vendor = opts.select { |key, _val| key.to_s.include?(':') && opts.delete(key) }
|
|
@@ -103,12 +117,12 @@ module Watir
|
|
|
103
117
|
|
|
104
118
|
def convert_timeouts(browser_options)
|
|
105
119
|
browser_options[:timeouts] ||= {}
|
|
106
|
-
browser_options[:timeouts].
|
|
120
|
+
browser_options[:timeouts].each_key do |key|
|
|
107
121
|
raise(ArgumentError, 'do not set implicit wait, Watir handles waiting automatically') if key.to_s == 'implicit'
|
|
108
122
|
|
|
109
123
|
Watir.logger.deprecate('using timeouts directly in options',
|
|
110
124
|
":#{key}_timeout",
|
|
111
|
-
id:
|
|
125
|
+
id: :timeouts)
|
|
112
126
|
end
|
|
113
127
|
if browser_options.key?(:page_load_timeout)
|
|
114
128
|
browser_options[:timeouts][:page_load] = browser_options.delete(:page_load_timeout) * 1000
|
|
@@ -151,16 +165,25 @@ module Watir
|
|
|
151
165
|
end
|
|
152
166
|
end
|
|
153
167
|
|
|
154
|
-
def infer_browser
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
def infer_browser(options = nil)
|
|
169
|
+
options ||= {}
|
|
170
|
+
inferred = if options.key?(:capabilities)
|
|
171
|
+
options[:capabilities].browser_name.tr(' ', '_').downcase.to_sym
|
|
172
|
+
elsif options[:options].is_a?(Selenium::WebDriver::Options)
|
|
173
|
+
options[:options].class.to_s.split('::')[-2].downcase.to_sym
|
|
174
|
+
elsif options.key?(:options)
|
|
175
|
+
options.dig(:options, :browser_name).downcase.to_sym
|
|
176
|
+
else
|
|
177
|
+
:chrome
|
|
178
|
+
end
|
|
179
|
+
%i[msedge microsoftedge].include?(inferred) ? :edge : inferred
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def validate_options
|
|
183
|
+
if @options.key?(:capabilities) && @options.key?(:options)
|
|
184
|
+
raise(ArgumentError, ':capabilities and :options are not both allowed')
|
|
163
185
|
end
|
|
186
|
+
raise(ArgumentError, ':url and :service are not both allowed') if @options.key?(:service) && @options.key?(:url)
|
|
164
187
|
end
|
|
165
188
|
end
|
|
166
189
|
end
|
data/lib/watir/cell_container.rb
CHANGED
data/lib/watir/container.rb
CHANGED
data/lib/watir/cookies.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'yaml'
|
|
2
4
|
|
|
3
5
|
module Watir
|
|
@@ -18,7 +20,7 @@ module Watir
|
|
|
18
20
|
|
|
19
21
|
def to_a
|
|
20
22
|
@control.all_cookies.map do |e|
|
|
21
|
-
e.merge(expires: e[:expires]
|
|
23
|
+
e.merge(expires: e[:expires]&.to_time)
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
@@ -102,11 +104,9 @@ module Watir
|
|
|
102
104
|
#
|
|
103
105
|
|
|
104
106
|
def save(file = '.cookies')
|
|
105
|
-
|
|
107
|
+
File.write(file, to_a.to_yaml)
|
|
106
108
|
end
|
|
107
109
|
|
|
108
|
-
#
|
|
109
|
-
# TODO: Use :permitted_classes keyword when minimum supported Ruby is 2.6
|
|
110
110
|
#
|
|
111
111
|
# Load cookies from file
|
|
112
112
|
#
|
|
@@ -117,7 +117,7 @@ module Watir
|
|
|
117
117
|
#
|
|
118
118
|
|
|
119
119
|
def load(file = '.cookies')
|
|
120
|
-
YAML.safe_load(
|
|
120
|
+
YAML.safe_load(File.read(file), permitted_classes: [::Symbol, ::Time]).each do |c|
|
|
121
121
|
add(c.delete(:name), c.delete(:value), c)
|
|
122
122
|
end
|
|
123
123
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
#
|
|
3
5
|
# Base class for element collections.
|
|
@@ -193,7 +195,7 @@ module Watir
|
|
|
193
195
|
end
|
|
194
196
|
|
|
195
197
|
def ensure_context
|
|
196
|
-
if @query_scope.is_a?(Browser) || !@query_scope.located? && @query_scope.is_a?(IFrame)
|
|
198
|
+
if @query_scope.is_a?(Browser) || (!@query_scope.located? && @query_scope.is_a?(IFrame))
|
|
197
199
|
@query_scope.browser.locate
|
|
198
200
|
elsif @query_scope.located? && @query_scope.stale?
|
|
199
201
|
@query_scope.locate
|
data/lib/watir/elements/cell.rb
CHANGED
data/lib/watir/elements/dlist.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
#
|
|
3
5
|
# Base class for HTML elements.
|
|
@@ -13,6 +15,7 @@ module Watir
|
|
|
13
15
|
include JSExecution
|
|
14
16
|
include Locators::ClassHelpers
|
|
15
17
|
include Scrolling
|
|
18
|
+
include SearchContext
|
|
16
19
|
|
|
17
20
|
attr_accessor :keyword
|
|
18
21
|
attr_reader :selector
|
|
@@ -54,38 +57,11 @@ module Watir
|
|
|
54
57
|
build unless @element
|
|
55
58
|
end
|
|
56
59
|
|
|
57
|
-
#
|
|
58
|
-
# Returns true if element exists.
|
|
59
|
-
# Checking for staleness is deprecated
|
|
60
|
-
#
|
|
61
|
-
# @return [Boolean]
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
def exists?
|
|
65
|
-
if located? && stale?
|
|
66
|
-
reset!
|
|
67
|
-
elsif located?
|
|
68
|
-
return true
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
assert_exists
|
|
72
|
-
true
|
|
73
|
-
rescue UnknownObjectException, UnknownFrameException
|
|
74
|
-
false
|
|
75
|
-
end
|
|
76
|
-
alias exist? exists?
|
|
77
|
-
|
|
78
60
|
def inspect
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
'{element: (selenium element)}'
|
|
84
|
-
else
|
|
85
|
-
selector_string
|
|
86
|
-
end
|
|
87
|
-
string << '>'
|
|
88
|
-
string
|
|
61
|
+
keyword_string = keyword ? "keyword: #{keyword} " : ''
|
|
62
|
+
located = "located: #{located?}; "
|
|
63
|
+
element_string = @selector.empty? ? '{element: (selenium element)}' : selector_string
|
|
64
|
+
"#<#{self.class}: #{keyword_string}#{located}#{element_string}>"
|
|
89
65
|
end
|
|
90
66
|
|
|
91
67
|
#
|
|
@@ -372,7 +348,7 @@ module Watir
|
|
|
372
348
|
def attribute_values
|
|
373
349
|
result = element_call { execute_js(:attributeValues, @element) }
|
|
374
350
|
result.keys.each do |key|
|
|
375
|
-
next unless key == key[/[a-zA-Z
|
|
351
|
+
next unless key == key[/[a-zA-Z-]*/]
|
|
376
352
|
|
|
377
353
|
result[key.tr('-', '_').to_sym] = result.delete(key)
|
|
378
354
|
end
|
|
@@ -505,6 +481,17 @@ module Watir
|
|
|
505
481
|
assert_exists
|
|
506
482
|
@element
|
|
507
483
|
end
|
|
484
|
+
alias we wd
|
|
485
|
+
|
|
486
|
+
#
|
|
487
|
+
# Returns shadow root of element
|
|
488
|
+
#
|
|
489
|
+
# @return [Watir::ShadowRoot]
|
|
490
|
+
#
|
|
491
|
+
|
|
492
|
+
def shadow_root
|
|
493
|
+
ShadowRoot.new(self)
|
|
494
|
+
end
|
|
508
495
|
|
|
509
496
|
#
|
|
510
497
|
# Returns true if this element is present and enabled on the page.
|
|
@@ -700,18 +687,6 @@ module Watir
|
|
|
700
687
|
|
|
701
688
|
protected
|
|
702
689
|
|
|
703
|
-
def wait_for_exists
|
|
704
|
-
return if located? # Performance shortcut
|
|
705
|
-
|
|
706
|
-
begin
|
|
707
|
-
@query_scope.wait_for_exists unless @query_scope.is_a? Browser
|
|
708
|
-
wait_until(element_reset: true, &:exists?)
|
|
709
|
-
rescue Wait::TimeoutError
|
|
710
|
-
msg = "timed out after #{Watir.default_timeout} seconds, waiting for #{inspect} to be located"
|
|
711
|
-
raise unknown_exception, msg
|
|
712
|
-
end
|
|
713
|
-
end
|
|
714
|
-
|
|
715
690
|
def wait_for_present
|
|
716
691
|
return true if present?
|
|
717
692
|
|
|
@@ -758,7 +733,7 @@ module Watir
|
|
|
758
733
|
end
|
|
759
734
|
|
|
760
735
|
def ensure_context
|
|
761
|
-
if @query_scope.is_a?(Browser) || !@query_scope.located? && @query_scope.is_a?(IFrame)
|
|
736
|
+
if @query_scope.is_a?(Browser) || (!@query_scope.located? && @query_scope.is_a?(IFrame))
|
|
762
737
|
@query_scope.browser.locate
|
|
763
738
|
elsif @query_scope.located? && @query_scope.stale?
|
|
764
739
|
@query_scope.locate
|
|
@@ -772,10 +747,6 @@ module Watir
|
|
|
772
747
|
|
|
773
748
|
private
|
|
774
749
|
|
|
775
|
-
def unknown_exception
|
|
776
|
-
UnknownObjectException
|
|
777
|
-
end
|
|
778
|
-
|
|
779
750
|
def raise_writable
|
|
780
751
|
message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds, " \
|
|
781
752
|
"waiting for #{inspect} to not be readonly"
|
|
@@ -790,7 +761,7 @@ module Watir
|
|
|
790
761
|
|
|
791
762
|
def raise_present
|
|
792
763
|
message = "element located, but timed out after #{Watir.default_timeout} seconds, " \
|
|
793
|
-
|
|
764
|
+
"waiting for #{inspect} to be present"
|
|
794
765
|
raise unknown_exception, message
|
|
795
766
|
end
|
|
796
767
|
|
|
@@ -806,66 +777,19 @@ module Watir
|
|
|
806
777
|
raise TypeError, "expected Watir::Element, got #{obj.inspect}:#{obj.class}" unless obj.is_a? Element
|
|
807
778
|
end
|
|
808
779
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
caller = caller_locations(1, 1)[0].label
|
|
816
|
-
already_locked = browser.timer.locked?
|
|
817
|
-
browser.timer = Wait::Timer.new(timeout: Watir.default_timeout) unless already_locked
|
|
818
|
-
|
|
819
|
-
begin
|
|
820
|
-
check_condition(precondition, caller)
|
|
821
|
-
Watir.logger.debug "-> `Executing #{inspect}##{caller}`"
|
|
822
|
-
yield
|
|
823
|
-
rescue unknown_exception => e
|
|
824
|
-
element_call(:wait_for_exists, &block) if precondition.nil?
|
|
825
|
-
msg = e.message
|
|
826
|
-
msg += '; Maybe look in an iframe?' if @query_scope.iframe.exists?
|
|
827
|
-
custom_attributes = !defined?(@locator) || @locator.nil? ? [] : selector_builder.custom_attributes
|
|
828
|
-
unless custom_attributes.empty?
|
|
829
|
-
msg += "; Watir treated #{custom_attributes} as a non-HTML compliant attribute, ensure that was intended"
|
|
830
|
-
end
|
|
831
|
-
raise unknown_exception, msg
|
|
832
|
-
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::NoSuchElementError
|
|
833
|
-
reset!
|
|
834
|
-
retry
|
|
835
|
-
# TODO: - InvalidElementStateError is deprecated, so no longer calling `raise_disabled`
|
|
836
|
-
# need a better way to handle this
|
|
837
|
-
rescue Selenium::WebDriver::Error::ElementNotInteractableError
|
|
838
|
-
raise_present unless browser.timer.remaining_time.positive?
|
|
839
|
-
raise_present unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
|
|
840
|
-
retry
|
|
841
|
-
rescue Selenium::WebDriver::Error::NoSuchWindowError
|
|
842
|
-
raise NoMatchingWindowFoundException, 'browser window was closed'
|
|
843
|
-
ensure
|
|
844
|
-
Watir.logger.debug "<- `Completed #{inspect}##{caller}`"
|
|
845
|
-
browser.timer.reset! unless already_locked
|
|
846
|
-
end
|
|
847
|
-
end
|
|
848
|
-
# rubocop:enable Metrics/AbcSize
|
|
849
|
-
# rubocop:enable Metrics/MethodLength
|
|
850
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
851
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
852
|
-
|
|
853
|
-
def check_condition(condition, caller)
|
|
854
|
-
Watir.logger.debug "<- `Verifying precondition #{inspect}##{condition} for #{caller}`"
|
|
855
|
-
begin
|
|
856
|
-
condition.nil? ? assert_exists : send(condition)
|
|
857
|
-
Watir.logger.debug "<- `Verified precondition #{inspect}##{condition || 'assert_exists'}`"
|
|
858
|
-
rescue unknown_exception
|
|
859
|
-
raise unless condition.nil?
|
|
860
|
-
|
|
861
|
-
Watir.logger.debug "<- `Unable to satisfy precondition #{inspect}##{condition}`"
|
|
862
|
-
check_condition(:wait_for_exists, caller)
|
|
780
|
+
def custom_message
|
|
781
|
+
msg = ''
|
|
782
|
+
msg += '; Maybe look in an iframe?' if @query_scope.iframe.exists?
|
|
783
|
+
custom_attributes = !defined?(@locator) || @locator.nil? ? [] : selector_builder.custom_attributes
|
|
784
|
+
unless custom_attributes.empty?
|
|
785
|
+
msg += "; Watir treated #{custom_attributes} as a non-HTML compliant attribute, ensure that was intended"
|
|
863
786
|
end
|
|
787
|
+
msg
|
|
864
788
|
end
|
|
865
789
|
|
|
866
790
|
def method_missing(meth, *args, &blk)
|
|
867
791
|
method = meth.to_s
|
|
868
|
-
if
|
|
792
|
+
if Locators::Element::SelectorBuilder::WILDCARD_ATTRIBUTE.match?(method)
|
|
869
793
|
attribute_value(meth, *args)
|
|
870
794
|
elsif UserEditable.instance_methods(false).include?(meth) && content_editable?
|
|
871
795
|
@content_editable = true
|
data/lib/watir/elements/font.rb
CHANGED
data/lib/watir/elements/form.rb
CHANGED
data/lib/watir/elements/image.rb
CHANGED
data/lib/watir/elements/input.rb
CHANGED
data/lib/watir/elements/link.rb
CHANGED
data/lib/watir/elements/list.rb
CHANGED
data/lib/watir/elements/radio.rb
CHANGED
data/lib/watir/elements/row.rb
CHANGED
data/lib/watir/elements/table.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Watir
|
|
2
4
|
class Table < HTMLElement
|
|
3
5
|
include RowContainer
|
|
@@ -31,7 +33,7 @@ module Watir
|
|
|
31
33
|
|
|
32
34
|
all_rows.entries[1..].map do |row|
|
|
33
35
|
cell_size_check(header_row, row)
|
|
34
|
-
|
|
36
|
+
headers(header_row).map(&:text).zip(row.cells.map(&:text)).to_h
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|