watir 6.13.0 → 6.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +141 -0
- data/.travis.yml +6 -0
- data/CHANGES.md +12 -0
- data/Gemfile +4 -10
- data/README.md +64 -49
- data/Rakefile +28 -16
- data/lib/watir.rb +13 -15
- data/lib/watir/adjacent.rb +15 -13
- data/lib/watir/after_hooks.rb +8 -10
- data/lib/watir/alert.rb +7 -8
- data/lib/watir/aliases.rb +2 -2
- data/lib/watir/attribute_helper.rb +18 -20
- data/lib/watir/browser.rb +42 -75
- data/lib/watir/capabilities.rb +19 -10
- data/lib/watir/cell_container.rb +0 -2
- data/lib/watir/container.rb +4 -4
- data/lib/watir/cookies.rb +7 -8
- data/lib/watir/element_collection.rb +37 -22
- data/lib/watir/elements/area.rb +0 -2
- data/lib/watir/elements/button.rb +1 -3
- data/lib/watir/elements/cell.rb +0 -1
- data/lib/watir/elements/checkbox.rb +5 -7
- data/lib/watir/elements/date_field.rb +5 -9
- data/lib/watir/elements/date_time_field.rb +6 -10
- data/lib/watir/elements/dlist.rb +2 -4
- data/lib/watir/elements/element.rb +201 -99
- data/lib/watir/elements/file_field.rb +3 -4
- data/lib/watir/elements/font.rb +2 -4
- data/lib/watir/elements/form.rb +0 -2
- data/lib/watir/elements/hidden.rb +3 -4
- data/lib/watir/elements/html_elements.rb +24 -76
- data/lib/watir/elements/iframe.rb +57 -71
- data/lib/watir/elements/image.rb +3 -4
- data/lib/watir/elements/input.rb +0 -2
- data/lib/watir/elements/link.rb +2 -5
- data/lib/watir/elements/list.rb +4 -4
- data/lib/watir/elements/option.rb +3 -6
- data/lib/watir/elements/radio.rb +4 -6
- data/lib/watir/elements/row.rb +0 -1
- data/lib/watir/elements/select.rb +41 -43
- data/lib/watir/elements/svg_elements.rb +0 -116
- data/lib/watir/elements/table.rb +1 -2
- data/lib/watir/elements/table_cell.rb +2 -3
- data/lib/watir/elements/text_field.rb +4 -6
- data/lib/watir/exception.rb +0 -1
- data/lib/watir/extensions/nokogiri.rb +2 -4
- data/lib/watir/generator.rb +3 -3
- data/lib/watir/generator/base.rb +10 -10
- data/lib/watir/generator/base/generator.rb +26 -29
- data/lib/watir/generator/base/idl_sorter.rb +34 -32
- data/lib/watir/generator/base/spec_extractor.rb +132 -114
- data/lib/watir/generator/base/util.rb +1 -3
- data/lib/watir/generator/base/visitor.rb +140 -140
- data/lib/watir/generator/html.rb +4 -4
- data/lib/watir/generator/html/generator.rb +2 -4
- data/lib/watir/generator/html/spec_extractor.rb +33 -33
- data/lib/watir/generator/html/visitor.rb +14 -14
- data/lib/watir/generator/svg.rb +3 -3
- data/lib/watir/generator/svg/generator.rb +1 -3
- data/lib/watir/generator/svg/spec_extractor.rb +35 -35
- data/lib/watir/generator/svg/visitor.rb +14 -14
- data/lib/watir/has_window.rb +2 -4
- data/lib/watir/js_execution.rb +7 -9
- data/lib/watir/js_snippets.rb +3 -3
- data/lib/watir/js_snippets/attributeValues.js +11 -0
- data/lib/watir/legacy_wait.rb +7 -12
- data/lib/watir/locators.rb +9 -11
- data/lib/watir/locators/button/locator.rb +2 -3
- data/lib/watir/locators/button/selector_builder.rb +9 -9
- data/lib/watir/locators/button/selector_builder/xpath.rb +1 -1
- data/lib/watir/locators/button/validator.rb +2 -2
- data/lib/watir/locators/cell/locator.rb +0 -2
- data/lib/watir/locators/cell/selector_builder.rb +3 -5
- data/lib/watir/locators/element/locator.rb +85 -64
- data/lib/watir/locators/element/selector_builder.rb +40 -38
- data/lib/watir/locators/element/selector_builder/xpath.rb +20 -18
- data/lib/watir/locators/element/validator.rb +1 -1
- data/lib/watir/locators/row/locator.rb +0 -2
- data/lib/watir/locators/row/selector_builder.rb +6 -9
- data/lib/watir/locators/text_area/selector_builder.rb +1 -1
- data/lib/watir/locators/text_field/locator.rb +1 -3
- data/lib/watir/locators/text_field/selector_builder.rb +5 -5
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +1 -1
- data/lib/watir/locators/text_field/validator.rb +3 -2
- data/lib/watir/logger.rb +11 -21
- data/lib/watir/navigation.rb +49 -0
- data/lib/watir/radio_set.rb +17 -18
- data/lib/watir/row_container.rb +3 -5
- data/lib/watir/screenshot.rb +2 -4
- data/lib/watir/user_editable.rb +13 -8
- data/lib/watir/version.rb +3 -0
- data/lib/watir/wait.rb +56 -55
- data/lib/watir/wait/timer.rb +1 -3
- data/lib/watir/window.rb +36 -45
- data/lib/watir/xpath_support.rb +1 -3
- data/lib/watirspec.rb +11 -11
- data/lib/watirspec/guards.rb +10 -7
- data/lib/watirspec/implementation.rb +3 -4
- data/lib/watirspec/rake_tasks.rb +30 -29
- data/lib/watirspec/remote_server.rb +3 -3
- data/lib/watirspec/runner.rb +1 -2
- data/lib/watirspec/server.rb +3 -0
- data/lib/watirspec/server/app.rb +14 -6
- data/spec/implementation_spec.rb +9 -9
- data/spec/locator_spec_helper.rb +3 -4
- data/spec/spec_helper.rb +3 -7
- data/spec/unit/container_spec.rb +9 -10
- data/spec/unit/element_locator_spec.rb +224 -219
- data/spec/unit/logger_spec.rb +4 -4
- data/spec/unit/unit_helper.rb +0 -2
- data/spec/unit/wait_spec.rb +26 -28
- data/spec/watirspec/adjacent_spec.rb +130 -130
- data/spec/watirspec/after_hooks_spec.rb +63 -63
- data/spec/watirspec/alert_spec.rb +6 -6
- data/spec/watirspec/attributes_spec.rb +6 -6
- data/spec/watirspec/browser_spec.rb +161 -162
- data/spec/watirspec/click_spec.rb +9 -9
- data/spec/watirspec/cookies_spec.rb +15 -14
- data/spec/watirspec/drag_and_drop_spec.rb +15 -16
- data/spec/watirspec/element_hidden_spec.rb +19 -21
- data/spec/watirspec/elements/area_spec.rb +18 -21
- data/spec/watirspec/elements/areas_spec.rb +13 -15
- data/spec/watirspec/elements/button_spec.rb +96 -99
- data/spec/watirspec/elements/buttons_spec.rb +17 -19
- data/spec/watirspec/elements/checkbox_spec.rb +102 -100
- data/spec/watirspec/elements/checkboxes_spec.rb +13 -15
- data/spec/watirspec/elements/collections_spec.rb +35 -37
- data/spec/watirspec/elements/date_field_spec.rb +46 -47
- data/spec/watirspec/elements/date_fields_spec.rb +13 -15
- data/spec/watirspec/elements/date_time_field_spec.rb +62 -57
- data/spec/watirspec/elements/date_time_fields_spec.rb +14 -15
- data/spec/watirspec/elements/dd_spec.rb +46 -48
- data/spec/watirspec/elements/dds_spec.rb +13 -15
- data/spec/watirspec/elements/del_spec.rb +27 -28
- data/spec/watirspec/elements/dels_spec.rb +13 -15
- data/spec/watirspec/elements/div_spec.rb +89 -91
- data/spec/watirspec/elements/divs_spec.rb +17 -19
- data/spec/watirspec/elements/dl_spec.rb +52 -54
- data/spec/watirspec/elements/dls_spec.rb +13 -15
- data/spec/watirspec/elements/dt_spec.rb +46 -48
- data/spec/watirspec/elements/dts_spec.rb +13 -15
- data/spec/watirspec/elements/element_spec.rb +240 -189
- data/spec/watirspec/elements/elements_spec.rb +16 -16
- data/spec/watirspec/elements/em_spec.rb +38 -40
- data/spec/watirspec/elements/ems_spec.rb +13 -15
- data/spec/watirspec/elements/filefield_spec.rb +45 -46
- data/spec/watirspec/elements/filefields_spec.rb +13 -15
- data/spec/watirspec/elements/font_spec.rb +11 -13
- data/spec/watirspec/elements/form_spec.rb +13 -15
- data/spec/watirspec/elements/forms_spec.rb +13 -15
- data/spec/watirspec/elements/frame_spec.rb +48 -50
- data/spec/watirspec/elements/frames_spec.rb +13 -15
- data/spec/watirspec/elements/hidden_spec.rb +23 -25
- data/spec/watirspec/elements/hiddens_spec.rb +13 -15
- data/spec/watirspec/elements/hn_spec.rb +22 -24
- data/spec/watirspec/elements/hns_spec.rb +13 -13
- data/spec/watirspec/elements/iframe_spec.rb +106 -74
- data/spec/watirspec/elements/iframes_spec.rb +16 -18
- data/spec/watirspec/elements/image_spec.rb +30 -32
- data/spec/watirspec/elements/images_spec.rb +13 -15
- data/spec/watirspec/elements/input_spec.rb +4 -5
- data/spec/watirspec/elements/ins_spec.rb +27 -29
- data/spec/watirspec/elements/inses_spec.rb +13 -15
- data/spec/watirspec/elements/label_spec.rb +17 -19
- data/spec/watirspec/elements/labels_spec.rb +13 -15
- data/spec/watirspec/elements/li_spec.rb +23 -25
- data/spec/watirspec/elements/link_spec.rb +45 -48
- data/spec/watirspec/elements/links_spec.rb +14 -16
- data/spec/watirspec/elements/lis_spec.rb +13 -15
- data/spec/watirspec/elements/list_spec.rb +14 -15
- data/spec/watirspec/elements/map_spec.rb +19 -20
- data/spec/watirspec/elements/maps_spec.rb +13 -15
- data/spec/watirspec/elements/meta_spec.rb +10 -10
- data/spec/watirspec/elements/metas_spec.rb +13 -15
- data/spec/watirspec/elements/ol_spec.rb +20 -21
- data/spec/watirspec/elements/ols_spec.rb +13 -15
- data/spec/watirspec/elements/option_spec.rb +63 -63
- data/spec/watirspec/elements/p_spec.rb +27 -26
- data/spec/watirspec/elements/pre_spec.rb +24 -25
- data/spec/watirspec/elements/pres_spec.rb +13 -15
- data/spec/watirspec/elements/ps_spec.rb +13 -15
- data/spec/watirspec/elements/radio_spec.rb +96 -97
- data/spec/watirspec/elements/radios_spec.rb +13 -15
- data/spec/watirspec/elements/select_list_spec.rb +244 -237
- data/spec/watirspec/elements/select_lists_spec.rb +15 -16
- data/spec/watirspec/elements/span_spec.rb +32 -31
- data/spec/watirspec/elements/spans_spec.rb +13 -15
- data/spec/watirspec/elements/strong_spec.rb +23 -24
- data/spec/watirspec/elements/strongs_spec.rb +13 -15
- data/spec/watirspec/elements/table_nesting_spec.rb +15 -14
- data/spec/watirspec/elements/table_spec.rb +61 -62
- data/spec/watirspec/elements/tables_spec.rb +15 -17
- data/spec/watirspec/elements/tbody_spec.rb +25 -26
- data/spec/watirspec/elements/tbodys_spec.rb +17 -19
- data/spec/watirspec/elements/td_spec.rb +20 -22
- data/spec/watirspec/elements/tds_spec.rb +9 -11
- data/spec/watirspec/elements/text_field_spec.rb +55 -56
- data/spec/watirspec/elements/text_fields_spec.rb +15 -16
- data/spec/watirspec/elements/textarea_spec.rb +2 -2
- data/spec/watirspec/elements/textareas_spec.rb +1 -1
- data/spec/watirspec/elements/tfoot_spec.rb +22 -23
- data/spec/watirspec/elements/tfoots_spec.rb +19 -19
- data/spec/watirspec/elements/thead_spec.rb +21 -23
- data/spec/watirspec/elements/theads_spec.rb +19 -19
- data/spec/watirspec/elements/tr_spec.rb +20 -22
- data/spec/watirspec/elements/trs_spec.rb +17 -19
- data/spec/watirspec/elements/ul_spec.rb +17 -19
- data/spec/watirspec/elements/uls_spec.rb +13 -14
- data/spec/watirspec/html/data_attributes.html +1 -0
- data/spec/watirspec/radio_set_spec.rb +100 -99
- data/spec/watirspec/relaxed_locate_spec.rb +19 -43
- data/spec/watirspec/screenshot_spec.rb +4 -4
- data/spec/watirspec/special_chars_spec.rb +2 -4
- data/spec/watirspec/support/rspec_matchers.rb +85 -22
- data/spec/watirspec/user_editable_spec.rb +84 -85
- data/spec/watirspec/wait_spec.rb +74 -95
- data/spec/watirspec/window_switching_spec.rb +131 -132
- data/spec/watirspec_helper.rb +12 -9
- data/support/travis.sh +4 -0
- data/support/version_differ.rb +12 -13
- data/watir.gemspec +29 -22
- metadata +76 -50
data/lib/watir/capabilities.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Watir
|
2
2
|
class Capabilities
|
3
|
-
|
4
3
|
attr_reader :options
|
5
4
|
|
6
5
|
def initialize(browser, options = {})
|
@@ -48,10 +47,11 @@ module Watir
|
|
48
47
|
|
49
48
|
http_client = @options.delete(:http_client)
|
50
49
|
|
51
|
-
%i
|
50
|
+
%i[open_timeout read_timeout client_timeout].each do |t|
|
52
51
|
next if http_client.nil? || !respond_to?(t)
|
53
|
-
|
54
|
-
|
52
|
+
|
53
|
+
msg = "You can pass #{t} value directly into Watir::Browser opt without needing to use :http_client"
|
54
|
+
Watir.logger.warn msg, ids: %i[http_client use_capabilities]
|
55
55
|
end
|
56
56
|
|
57
57
|
http_client ||= Selenium::WebDriver::Remote::Http::Default.new
|
@@ -62,6 +62,11 @@ module Watir
|
|
62
62
|
@selenium_opts[:http_client] = http_client
|
63
63
|
end
|
64
64
|
|
65
|
+
# TODO: - this will get addressed with Capabilities Update
|
66
|
+
# rubocop:disable Metrics/AbcSize
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
68
|
+
# rubocop:disable Metrics/PerceivedComplexity:
|
69
|
+
# rubocop:disable Metrics/CyclomaticComplexity::
|
65
70
|
def process_browser_options
|
66
71
|
browser_options = @options.delete(:options) || {}
|
67
72
|
|
@@ -83,8 +88,8 @@ module Watir
|
|
83
88
|
if browser_options.is_a? Selenium::WebDriver::Firefox::Options
|
84
89
|
@selenium_opts[:options] = browser_options
|
85
90
|
if profile
|
86
|
-
|
87
|
-
|
91
|
+
msg = 'Initializing Browser with both :profile and :option', ':profile as a key inside :option'
|
92
|
+
Watir.logger.deprecate msg, ids: [:firefox_profile]
|
88
93
|
end
|
89
94
|
end
|
90
95
|
if @options.delete(:headless)
|
@@ -106,16 +111,21 @@ module Watir
|
|
106
111
|
@options[Selenium::WebDriver::Firefox::Options::KEY] = {'args' => args + ['--headless']}
|
107
112
|
end
|
108
113
|
if @browser == :safari && @options.delete(:technology_preview)
|
109
|
-
@options[
|
114
|
+
@options['safari.options'] = {'technologyPreview' => true}
|
110
115
|
end
|
111
116
|
end
|
112
117
|
end
|
118
|
+
# rubocop:enable Metrics/AbcSize
|
119
|
+
# rubocop:enable Metrics/MethodLength
|
120
|
+
# rubocop:enable Metrics/PerceivedComplexity:
|
121
|
+
# rubocop:enable Metrics/CyclomaticComplexity::
|
113
122
|
|
114
123
|
def process_capabilities
|
115
124
|
caps = @options.delete(:desired_capabilities)
|
116
125
|
|
117
126
|
if caps
|
118
|
-
|
127
|
+
msg = 'You can pass values directly into Watir::Browser opt without needing to use :desired_capabilities'
|
128
|
+
Watir.logger.warn msg,
|
119
129
|
ids: [:use_capabilities]
|
120
130
|
@selenium_opts.merge!(@options)
|
121
131
|
else
|
@@ -124,6 +134,5 @@ module Watir
|
|
124
134
|
|
125
135
|
@selenium_opts[:desired_capabilities] = caps
|
126
136
|
end
|
127
|
-
|
128
137
|
end
|
129
|
-
end
|
138
|
+
end
|
data/lib/watir/cell_container.rb
CHANGED
data/lib/watir/container.rb
CHANGED
@@ -36,19 +36,19 @@ module Watir
|
|
36
36
|
def extract_selector(selectors)
|
37
37
|
case selectors.size
|
38
38
|
when 2
|
39
|
-
|
39
|
+
msg = "Using ordered parameters to locate elements (:#{selectors.first}, #{selectors.last.inspect})"
|
40
|
+
Watir.logger.deprecate msg,
|
40
41
|
"{#{selectors.first}: #{selectors.last.inspect}}",
|
41
42
|
ids: [:selector_parameters]
|
42
|
-
return {
|
43
|
+
return {selectors[0] => selectors[1]}
|
43
44
|
when 1
|
44
45
|
obj = selectors.first
|
45
|
-
return obj if obj.
|
46
|
+
return obj if obj.is_a? Hash
|
46
47
|
when 0
|
47
48
|
return {}
|
48
49
|
end
|
49
50
|
|
50
51
|
raise ArgumentError, "expected Hash, got #{selectors.inspect}"
|
51
52
|
end
|
52
|
-
|
53
53
|
end # Container
|
54
54
|
end # Watir
|
data/lib/watir/cookies.rb
CHANGED
@@ -2,7 +2,6 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
module Watir
|
4
4
|
class Cookies
|
5
|
-
|
6
5
|
def initialize(control)
|
7
6
|
@control = control
|
8
7
|
end
|
@@ -56,7 +55,8 @@ module Watir
|
|
56
55
|
def add(name, value, opts = {})
|
57
56
|
cookie = {
|
58
57
|
name: name,
|
59
|
-
value: value
|
58
|
+
value: value
|
59
|
+
}
|
60
60
|
cookie[:secure] = opts[:secure] if opts.key?(:secure)
|
61
61
|
cookie[:path] = opts[:path] if opts.key?(:path)
|
62
62
|
expires = opts[:expires]
|
@@ -115,20 +115,19 @@ module Watir
|
|
115
115
|
#
|
116
116
|
|
117
117
|
def load(file = '.cookies')
|
118
|
-
YAML.
|
118
|
+
YAML.safe_load(IO.read(file), [::Symbol]).each do |c|
|
119
119
|
add(c.delete(:name), c.delete(:value), c)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
private
|
124
124
|
|
125
|
-
def to_time(
|
126
|
-
if
|
127
|
-
|
125
|
+
def to_time(time)
|
126
|
+
if time.respond_to?(:to_time)
|
127
|
+
time.to_time
|
128
128
|
else
|
129
|
-
::Time.local
|
129
|
+
::Time.local time.year, time.month, time.day, time.hour, time.min, time.sec
|
130
130
|
end
|
131
131
|
end
|
132
|
-
|
133
132
|
end # Cookies
|
134
133
|
end # Watir
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Watir
|
2
|
-
|
3
2
|
#
|
4
3
|
# Base class for element collections.
|
5
4
|
#
|
@@ -29,10 +28,10 @@ module Watir
|
|
29
28
|
to_a.each(&blk)
|
30
29
|
end
|
31
30
|
|
32
|
-
|
33
|
-
|
31
|
+
alias length count
|
32
|
+
alias size count
|
34
33
|
|
35
|
-
|
34
|
+
alias empty? none?
|
36
35
|
|
37
36
|
#
|
38
37
|
# Get the element at the given index or range.
|
@@ -50,7 +49,7 @@ module Watir
|
|
50
49
|
if value.is_a?(Range)
|
51
50
|
to_a[value]
|
52
51
|
elsif @selector.key? :adjacent
|
53
|
-
to_a[value] || element_class.new(@query_scope,
|
52
|
+
to_a[value] || element_class.new(@query_scope, invalid_locator: true)
|
54
53
|
elsif @to_a && @to_a[value]
|
55
54
|
@to_a[value]
|
56
55
|
else
|
@@ -87,19 +86,21 @@ module Watir
|
|
87
86
|
def to_a
|
88
87
|
hash = {}
|
89
88
|
@to_a ||=
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
89
|
+
elements.map.with_index do |e, idx|
|
90
|
+
selector = @selector.merge(element: e)
|
91
|
+
selector[:index] = idx
|
92
|
+
element = element_class.new(@query_scope, selector)
|
93
|
+
if [Watir::HTMLElement, Watir::Input].include? element.class
|
94
|
+
tag_name = @selector[:tag_name] || element.tag_name.to_sym
|
95
|
+
hash[tag_name] ||= 0
|
96
|
+
hash[tag_name] += 1
|
97
|
+
selector[:index] = hash[tag_name] - 1
|
98
|
+
selector[:tag_name] = tag_name
|
99
|
+
Watir.element_class_for(tag_name).new(@query_scope, selector)
|
100
|
+
else
|
101
|
+
element
|
102
102
|
end
|
103
|
+
end
|
103
104
|
end
|
104
105
|
|
105
106
|
#
|
@@ -138,26 +139,40 @@ module Watir
|
|
138
139
|
def ==(other)
|
139
140
|
to_a == other.to_a
|
140
141
|
end
|
141
|
-
|
142
|
+
alias eql? ==
|
142
143
|
|
143
144
|
#
|
144
145
|
# Creates a Collection containing elements of two collections.
|
145
146
|
#
|
146
147
|
# @example
|
147
|
-
#
|
148
|
+
# options = browser.select_list(name: "new_user_languages").options
|
149
|
+
# (options + browser.select_list(id: "new_user_role").options).size
|
148
150
|
# #=> 8
|
149
151
|
#
|
150
152
|
|
151
153
|
private
|
152
154
|
|
153
155
|
def elements
|
154
|
-
|
155
|
-
|
156
|
+
ensure_context
|
157
|
+
if @query_scope.is_a?(Browser)
|
158
|
+
locate_all
|
159
|
+
else
|
160
|
+
# This gives all of the standard Watir waiting behaviors to Collections
|
161
|
+
@query_scope.send(:element_call) { locate_all }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def ensure_context
|
166
|
+
@query_scope.locate if @query_scope.relocate?
|
167
|
+
@query_scope.switch_to! if @query_scope.is_a?(IFrame)
|
168
|
+
end
|
169
|
+
|
170
|
+
def locate_all
|
171
|
+
build_locator.locate_all
|
156
172
|
end
|
157
173
|
|
158
174
|
def element_class
|
159
175
|
Kernel.const_get(self.class.name.sub(/Collection$/, ''))
|
160
176
|
end
|
161
|
-
|
162
177
|
end # ElementCollection
|
163
178
|
end # Watir
|
data/lib/watir/elements/area.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Watir
|
2
|
-
|
3
2
|
#
|
4
3
|
# Class representing button elements.
|
5
4
|
#
|
@@ -7,10 +6,9 @@ module Watir
|
|
7
6
|
#
|
8
7
|
|
9
8
|
class Button < HTMLElement
|
10
|
-
|
11
9
|
inherit_attributes_from Watir::Input
|
12
10
|
|
13
|
-
VALID_TYPES = %w[button reset submit image]
|
11
|
+
VALID_TYPES = %w[button reset submit image].freeze
|
14
12
|
|
15
13
|
#
|
16
14
|
# Returns the text of the button.
|
data/lib/watir/elements/cell.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Watir
|
2
2
|
class CheckBox < Input
|
3
|
-
|
4
3
|
#
|
5
4
|
# Sets checkbox to the given value.
|
6
5
|
#
|
@@ -18,7 +17,7 @@ module Watir
|
|
18
17
|
def set(bool = true)
|
19
18
|
set? == bool ? assert_enabled : click
|
20
19
|
end
|
21
|
-
|
20
|
+
alias check set
|
22
21
|
|
23
22
|
#
|
24
23
|
# Returns true if the element is checked
|
@@ -28,7 +27,7 @@ module Watir
|
|
28
27
|
def set?
|
29
28
|
element_call { @element.selected? }
|
30
29
|
end
|
31
|
-
|
30
|
+
alias checked? set?
|
32
31
|
|
33
32
|
#
|
34
33
|
# Unsets checkbox.
|
@@ -37,17 +36,16 @@ module Watir
|
|
37
36
|
def clear
|
38
37
|
set false
|
39
38
|
end
|
40
|
-
|
41
|
-
|
39
|
+
alias uncheck clear
|
42
40
|
end # CheckBox
|
43
41
|
|
44
42
|
module Container
|
45
43
|
def checkbox(*args)
|
46
|
-
CheckBox.new(self, extract_selector(args).merge(tag_name:
|
44
|
+
CheckBox.new(self, extract_selector(args).merge(tag_name: 'input', type: 'checkbox'))
|
47
45
|
end
|
48
46
|
|
49
47
|
def checkboxes(*args)
|
50
|
-
CheckBoxCollection.new(self, extract_selector(args).merge(tag_name:
|
48
|
+
CheckBoxCollection.new(self, extract_selector(args).merge(tag_name: 'input', type: 'checkbox'))
|
51
49
|
end
|
52
50
|
end # Container
|
53
51
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Watir
|
2
2
|
class DateField < Input
|
3
|
-
|
4
3
|
#
|
5
4
|
# Enter the provided value.
|
6
5
|
#
|
@@ -11,23 +10,20 @@ module Watir
|
|
11
10
|
message = "DateField##{__callee__} only accepts instances of Date or Time"
|
12
11
|
raise ArgumentError, message unless [Date, ::Time].include?(date.class)
|
13
12
|
|
14
|
-
date_string = date.strftime(
|
13
|
+
date_string = date.strftime('%Y-%m-%d')
|
15
14
|
element_call(:wait_for_writable) { execute_js(:setValue, @element, date_string) }
|
16
15
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
16
|
+
alias set set!
|
17
|
+
alias value= set
|
22
18
|
end # DateField
|
23
19
|
|
24
20
|
module Container
|
25
21
|
def date_field(*args)
|
26
|
-
DateField.new(self, extract_selector(args).merge(tag_name:
|
22
|
+
DateField.new(self, extract_selector(args).merge(tag_name: 'input', type: 'date'))
|
27
23
|
end
|
28
24
|
|
29
25
|
def date_fields(*args)
|
30
|
-
DateFieldCollection.new(self, extract_selector(args).merge(tag_name:
|
26
|
+
DateFieldCollection.new(self, extract_selector(args).merge(tag_name: 'input', type: 'date'))
|
31
27
|
end
|
32
28
|
end # Container
|
33
29
|
|
@@ -1,33 +1,29 @@
|
|
1
1
|
module Watir
|
2
2
|
class DateTimeField < Input
|
3
|
-
|
4
3
|
#
|
5
4
|
# Enter the provided value.
|
6
5
|
#
|
7
6
|
|
8
7
|
def set!(date)
|
9
|
-
date =
|
8
|
+
date = ::Time.parse date if date.is_a?(String)
|
10
9
|
|
11
10
|
message = "DateTimeField##{__callee__} only accepts instances of DateTime or Time"
|
12
11
|
raise ArgumentError, message unless [DateTime, ::Time].include?(date.class)
|
13
12
|
|
14
|
-
date_time_string = date.strftime(
|
13
|
+
date_time_string = date.strftime('%Y-%m-%dT%H:%M')
|
15
14
|
element_call(:wait_for_writable) { execute_js(:setValue, @element, date_time_string) }
|
16
15
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
16
|
+
alias set set!
|
17
|
+
alias value= set
|
22
18
|
end # DateTimeField
|
23
19
|
|
24
20
|
module Container
|
25
21
|
def date_time_field(*args)
|
26
|
-
DateTimeField.new(self, extract_selector(args).merge(tag_name:
|
22
|
+
DateTimeField.new(self, extract_selector(args).merge(tag_name: 'input', type: 'datetime-local'))
|
27
23
|
end
|
28
24
|
|
29
25
|
def date_time_fields(*args)
|
30
|
-
DateTimeFieldCollection.new(self, extract_selector(args).merge(tag_name:
|
26
|
+
DateTimeFieldCollection.new(self, extract_selector(args).merge(tag_name: 'input', type: 'datetime-local'))
|
31
27
|
end
|
32
28
|
end # Container
|
33
29
|
|
data/lib/watir/elements/dlist.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Watir
|
2
|
-
|
3
2
|
#
|
4
3
|
# Base class for HTML elements.
|
5
4
|
#
|
@@ -32,9 +31,7 @@ module Watir
|
|
32
31
|
def initialize(query_scope, selector)
|
33
32
|
@query_scope = query_scope
|
34
33
|
|
35
|
-
unless selector.
|
36
|
-
raise ArgumentError, "invalid argument: #{selector.inspect}"
|
37
|
-
end
|
34
|
+
raise ArgumentError, "invalid argument: #{selector.inspect}" unless selector.is_a? Hash
|
38
35
|
|
39
36
|
@element = selector.delete(:element)
|
40
37
|
@selector = selector
|
@@ -42,28 +39,30 @@ module Watir
|
|
42
39
|
|
43
40
|
#
|
44
41
|
# Returns true if element exists.
|
42
|
+
# Checking for staleness is deprecated
|
45
43
|
#
|
46
44
|
# @return [Boolean]
|
47
45
|
#
|
48
46
|
|
49
47
|
def exists?
|
50
|
-
return false if
|
48
|
+
return false if located? && stale?
|
49
|
+
|
51
50
|
assert_exists
|
52
51
|
true
|
53
52
|
rescue UnknownObjectException, UnknownFrameException
|
54
53
|
false
|
55
54
|
end
|
56
|
-
|
55
|
+
alias exist? exists?
|
57
56
|
|
58
57
|
def inspect
|
59
58
|
string = "#<#{self.class}: "
|
60
59
|
string << "keyword: #{keyword} " if keyword
|
61
|
-
string << "located: #{
|
62
|
-
if @selector.empty?
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
60
|
+
string << "located: #{located?}; "
|
61
|
+
string << if @selector.empty?
|
62
|
+
'{element: (selenium element)}'
|
63
|
+
else
|
64
|
+
selector_string
|
65
|
+
end
|
67
66
|
string << '>'
|
68
67
|
string
|
69
68
|
end
|
@@ -71,6 +70,10 @@ module Watir
|
|
71
70
|
#
|
72
71
|
# Returns true if two elements are equal.
|
73
72
|
#
|
73
|
+
# TODO: Address how this is affected by stale elements
|
74
|
+
# TODO: Address how this is affected by HTMLElement vs subclass
|
75
|
+
# TODO: Address how this is affected by a non-located element
|
76
|
+
#
|
74
77
|
# @example
|
75
78
|
# browser.text_field(name: "new_user_first_name") == browser.text_field(name: "new_user_first_name")
|
76
79
|
# #=> true
|
@@ -79,10 +82,10 @@ module Watir
|
|
79
82
|
def ==(other)
|
80
83
|
other.is_a?(self.class) && wd == other.wd
|
81
84
|
end
|
82
|
-
|
85
|
+
alias eql? ==
|
83
86
|
|
84
87
|
def hash
|
85
|
-
|
88
|
+
located? ? @element.hash : super
|
86
89
|
end
|
87
90
|
|
88
91
|
#
|
@@ -176,7 +179,6 @@ module Watir
|
|
176
179
|
browser.after_hooks.run
|
177
180
|
end
|
178
181
|
|
179
|
-
|
180
182
|
#
|
181
183
|
# Right clicks the element.
|
182
184
|
# Note that browser support may vary.
|
@@ -216,9 +218,9 @@ module Watir
|
|
216
218
|
assert_is_element other
|
217
219
|
|
218
220
|
value = element_call(:wait_for_present) do
|
219
|
-
driver.action
|
220
|
-
|
221
|
-
|
221
|
+
driver.action
|
222
|
+
.drag_and_drop(@element, other.wd)
|
223
|
+
.perform
|
222
224
|
end
|
223
225
|
browser.after_hooks.run
|
224
226
|
value
|
@@ -237,9 +239,9 @@ module Watir
|
|
237
239
|
|
238
240
|
def drag_and_drop_by(right_by, down_by)
|
239
241
|
element_call(:wait_for_present) do
|
240
|
-
driver.action
|
241
|
-
|
242
|
-
|
242
|
+
driver.action
|
243
|
+
.drag_and_drop_by(@element, right_by, down_by)
|
244
|
+
.perform
|
243
245
|
end
|
244
246
|
end
|
245
247
|
|
@@ -270,7 +272,44 @@ module Watir
|
|
270
272
|
attribute_name = attribute_name.to_s.tr('_', '-') if attribute_name.is_a?(::Symbol)
|
271
273
|
element_call { @element.attribute attribute_name }
|
272
274
|
end
|
273
|
-
|
275
|
+
alias attribute attribute_value
|
276
|
+
|
277
|
+
#
|
278
|
+
# Returns all attribute values. Attributes with special characters are returned as String,
|
279
|
+
# rest are returned as a Symbol.
|
280
|
+
#
|
281
|
+
# @return [Hash]
|
282
|
+
#
|
283
|
+
# @example
|
284
|
+
# browser.pre(id: 'rspec').attribute_values
|
285
|
+
# #=> {class:'ruby', id: 'rspec' }
|
286
|
+
#
|
287
|
+
|
288
|
+
def attribute_values
|
289
|
+
result = element_call { execute_js(:attributeValues, @element) }
|
290
|
+
result.keys.each do |key|
|
291
|
+
next unless key == key[/[a-zA-Z\-]*/]
|
292
|
+
|
293
|
+
result[key.tr('-', '_').to_sym] = result.delete(key)
|
294
|
+
end
|
295
|
+
result
|
296
|
+
end
|
297
|
+
alias attributes attribute_values
|
298
|
+
|
299
|
+
#
|
300
|
+
# Returns list of all attributes. Attributes with special characters are returned as String,
|
301
|
+
# rest are returned as a Symbol.
|
302
|
+
#
|
303
|
+
# @return [Array]
|
304
|
+
#
|
305
|
+
# @example
|
306
|
+
# browser.pre(id: 'rspec').attribute_list
|
307
|
+
# #=> [:class, :id]
|
308
|
+
#
|
309
|
+
|
310
|
+
def attribute_list
|
311
|
+
attribute_values.keys
|
312
|
+
end
|
274
313
|
|
275
314
|
#
|
276
315
|
# Sends sequence of keystrokes to element.
|
@@ -372,10 +411,10 @@ module Watir
|
|
372
411
|
def center
|
373
412
|
point = location
|
374
413
|
dimensions = size
|
375
|
-
Selenium::WebDriver::Point.new(point.x + (dimensions['width']/2),
|
376
|
-
point.y + (dimensions['height']/2))
|
414
|
+
Selenium::WebDriver::Point.new(point.x + (dimensions['width'] / 2),
|
415
|
+
point.y + (dimensions['height'] / 2))
|
377
416
|
end
|
378
|
-
|
417
|
+
alias centre center
|
379
418
|
|
380
419
|
#
|
381
420
|
# @api private
|
@@ -386,12 +425,13 @@ module Watir
|
|
386
425
|
end
|
387
426
|
|
388
427
|
#
|
389
|
-
#
|
428
|
+
# Returns underlying Selenium object of the Watir Element
|
429
|
+
#
|
430
|
+
# @return [Selenium::WebDriver::Element]
|
390
431
|
#
|
391
432
|
|
392
433
|
def wd
|
393
|
-
assert_exists
|
394
|
-
return driver if @element.is_a? FramedDriver
|
434
|
+
assert_exists
|
395
435
|
@element
|
396
436
|
end
|
397
437
|
|
@@ -403,15 +443,19 @@ module Watir
|
|
403
443
|
#
|
404
444
|
|
405
445
|
def visible?
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
446
|
+
msg = '#visible? behavior will be changing slightly, consider switching to #present? ' \
|
447
|
+
'(more details: http://watir.com/element-existentialism/)'
|
448
|
+
Watir.logger.warn msg, ids: [:visible_element]
|
449
|
+
displayed = display_check
|
450
|
+
if displayed.nil? && display_check
|
451
|
+
Watir.logger.deprecate 'Checking `#present? == false` to determine a stale element',
|
452
|
+
'`#stale? == true`',
|
453
|
+
reference: 'http://watir.com/staleness-changes',
|
454
|
+
ids: [:stale_visible]
|
455
|
+
end
|
456
|
+
raise unknown_exception if displayed.nil?
|
457
|
+
|
458
|
+
displayed
|
415
459
|
end
|
416
460
|
|
417
461
|
#
|
@@ -434,13 +478,14 @@ module Watir
|
|
434
478
|
#
|
435
479
|
|
436
480
|
def present?
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
481
|
+
displayed = display_check
|
482
|
+
if displayed.nil? && display_check
|
483
|
+
Watir.logger.deprecate 'Checking `#present? == false` to determine a stale element',
|
484
|
+
'`#stale? == true`',
|
485
|
+
reference: 'http://watir.com/staleness-changes',
|
486
|
+
ids: [:stale_present]
|
487
|
+
end
|
488
|
+
displayed
|
444
489
|
rescue UnknownObjectException, UnknownFrameException
|
445
490
|
false
|
446
491
|
end
|
@@ -460,7 +505,7 @@ module Watir
|
|
460
505
|
if property
|
461
506
|
element_call { @element.style property }
|
462
507
|
else
|
463
|
-
attribute_value(
|
508
|
+
attribute_value('style').to_s.strip
|
464
509
|
end
|
465
510
|
end
|
466
511
|
|
@@ -474,16 +519,16 @@ module Watir
|
|
474
519
|
|
475
520
|
def to_subtype
|
476
521
|
tag = tag_name()
|
477
|
-
klass = if tag ==
|
522
|
+
klass = if tag == 'input'
|
478
523
|
case attribute_value(:type)
|
479
|
-
when *Button::VALID_TYPES
|
480
|
-
Button
|
481
524
|
when 'checkbox'
|
482
525
|
CheckBox
|
483
526
|
when 'radio'
|
484
527
|
Radio
|
485
528
|
when 'file'
|
486
529
|
FileField
|
530
|
+
when *Button::VALID_TYPES
|
531
|
+
Button
|
487
532
|
else
|
488
533
|
TextField
|
489
534
|
end
|
@@ -512,22 +557,67 @@ module Watir
|
|
512
557
|
#
|
513
558
|
|
514
559
|
def stale?
|
515
|
-
raise Watir::Exception::Error,
|
516
|
-
|
517
|
-
|
560
|
+
raise Watir::Exception::Error, 'Can not check staleness of unused element' unless @element
|
561
|
+
|
562
|
+
ensure_context
|
563
|
+
stale_in_context?
|
518
564
|
end
|
519
565
|
|
520
566
|
def stale_in_context?
|
521
567
|
@element.enabled? # any wire call will check for staleness
|
522
568
|
false
|
523
569
|
rescue Selenium::WebDriver::Error::ObsoleteElementError
|
524
|
-
|
570
|
+
true
|
525
571
|
end
|
526
572
|
|
527
573
|
def reset!
|
528
574
|
@element = nil
|
529
575
|
end
|
530
576
|
|
577
|
+
#
|
578
|
+
# @api private
|
579
|
+
#
|
580
|
+
|
581
|
+
def locate
|
582
|
+
ensure_context
|
583
|
+
locate_in_context
|
584
|
+
end
|
585
|
+
|
586
|
+
#
|
587
|
+
# @api private
|
588
|
+
#
|
589
|
+
# Returns true if element has been previously located.
|
590
|
+
#
|
591
|
+
# @return [Boolean]
|
592
|
+
#
|
593
|
+
|
594
|
+
def located?
|
595
|
+
!!@element
|
596
|
+
end
|
597
|
+
|
598
|
+
#
|
599
|
+
# @api private
|
600
|
+
#
|
601
|
+
# This is a performance shortcut for ensuring context
|
602
|
+
# Returns true if ensuring context requires relocating the element.
|
603
|
+
#
|
604
|
+
# @return [Boolean]
|
605
|
+
#
|
606
|
+
|
607
|
+
def relocate?
|
608
|
+
located? && stale?
|
609
|
+
end
|
610
|
+
|
611
|
+
#
|
612
|
+
# @api private
|
613
|
+
#
|
614
|
+
|
615
|
+
def selector_string
|
616
|
+
return @selector.inspect if @query_scope.is_a?(Browser)
|
617
|
+
|
618
|
+
"#{@query_scope.selector_string} --> #{@selector.inspect}"
|
619
|
+
end
|
620
|
+
|
531
621
|
protected
|
532
622
|
|
533
623
|
def wait_for_exists
|
@@ -551,7 +641,8 @@ module Watir
|
|
551
641
|
@query_scope.wait_for_present unless @query_scope.is_a? Browser
|
552
642
|
wait_until_present
|
553
643
|
rescue Watir::Wait::TimeoutError
|
554
|
-
msg = "element located, but timed out after #{Watir.default_timeout} seconds,
|
644
|
+
msg = "element located, but timed out after #{Watir.default_timeout} seconds, " \
|
645
|
+
"waiting for #{inspect} to be present"
|
555
646
|
raise unknown_exception, msg
|
556
647
|
end
|
557
648
|
end
|
@@ -560,7 +651,7 @@ module Watir
|
|
560
651
|
return assert_enabled unless Watir.relaxed_locate?
|
561
652
|
|
562
653
|
wait_for_exists
|
563
|
-
return if [Input, Button, Select, Option].none? { |c|
|
654
|
+
return if [Input, Button, Select, Option].none? { |c| is_a? c }
|
564
655
|
|
565
656
|
begin
|
566
657
|
wait_until(&:enabled?)
|
@@ -570,7 +661,6 @@ module Watir
|
|
570
661
|
end
|
571
662
|
|
572
663
|
def wait_for_writable
|
573
|
-
wait_for_exists
|
574
664
|
wait_for_enabled
|
575
665
|
unless Watir.relaxed_locate?
|
576
666
|
raise_writable unless !respond_to?(:readonly?) || !readonly?
|
@@ -579,31 +669,28 @@ module Watir
|
|
579
669
|
begin
|
580
670
|
wait_until { !respond_to?(:readonly?) || !readonly? }
|
581
671
|
rescue Watir::Wait::TimeoutError
|
582
|
-
message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds,
|
672
|
+
message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds, " \
|
673
|
+
"waiting for #{inspect} to not be readonly"
|
583
674
|
raise ObjectReadOnlyException, message
|
584
675
|
end
|
585
676
|
end
|
586
677
|
|
587
|
-
#
|
678
|
+
# Locates if not previously found; does not check for staleness for performance reasons
|
588
679
|
def assert_exists
|
589
|
-
locate unless
|
590
|
-
return if
|
591
|
-
raise unknown_exception, "unable to locate element: #{inspect}"
|
592
|
-
end
|
680
|
+
locate unless located?
|
681
|
+
return if located?
|
593
682
|
|
594
|
-
|
595
|
-
@locator = build_locator
|
596
|
-
@element = @locator.locate
|
683
|
+
raise unknown_exception, "unable to locate element: #{inspect}"
|
597
684
|
end
|
598
685
|
|
599
|
-
def
|
600
|
-
|
601
|
-
|
686
|
+
def ensure_context
|
687
|
+
@query_scope.locate if @query_scope.relocate?
|
688
|
+
@query_scope.switch_to! if @query_scope.is_a?(IFrame)
|
602
689
|
end
|
603
690
|
|
604
|
-
|
605
|
-
|
606
|
-
|
691
|
+
def locate_in_context
|
692
|
+
@locator = build_locator
|
693
|
+
@element = @locator.locate
|
607
694
|
end
|
608
695
|
|
609
696
|
private
|
@@ -613,17 +700,21 @@ module Watir
|
|
613
700
|
end
|
614
701
|
|
615
702
|
def raise_writable
|
616
|
-
message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds,
|
703
|
+
message = "element present and enabled, but timed out after #{Watir.default_timeout} seconds, " \
|
704
|
+
"waiting for #{inspect} to not be readonly"
|
617
705
|
raise ObjectReadOnlyException, message
|
618
706
|
end
|
619
707
|
|
620
708
|
def raise_disabled
|
621
|
-
message = "element present, but timed out after #{Watir.default_timeout} seconds,
|
709
|
+
message = "element present, but timed out after #{Watir.default_timeout} seconds, " \
|
710
|
+
"waiting for #{inspect} to be enabled"
|
622
711
|
raise ObjectDisabledException, message
|
623
712
|
end
|
624
713
|
|
625
714
|
def raise_present
|
626
|
-
|
715
|
+
message = "element located, but timed out after #{Watir.default_timeout} seconds, " \
|
716
|
+
"waiting for #{inspect} to be present"
|
717
|
+
raise unknown_exception, message
|
627
718
|
end
|
628
719
|
|
629
720
|
def element_class
|
@@ -635,76 +726,88 @@ module Watir
|
|
635
726
|
end
|
636
727
|
|
637
728
|
def assert_enabled
|
638
|
-
unless element_call { @element.enabled? }
|
639
|
-
raise ObjectDisabledException, "object is disabled #{inspect}"
|
640
|
-
end
|
729
|
+
raise ObjectDisabledException, "object is disabled #{inspect}" unless element_call { @element.enabled? }
|
641
730
|
end
|
642
731
|
|
643
732
|
def assert_is_element(obj)
|
644
|
-
unless obj.
|
645
|
-
raise TypeError, "execpted Watir::Element, got #{obj.inspect}:#{obj.class}"
|
646
|
-
end
|
733
|
+
raise TypeError, "execpted Watir::Element, got #{obj.inspect}:#{obj.class}" unless obj.is_a? Watir::Element
|
647
734
|
end
|
648
735
|
|
736
|
+
# Removes duplication in #present? & #visible? and makes setting deprecation notice easier
|
737
|
+
def display_check
|
738
|
+
assert_exists
|
739
|
+
@element.displayed?
|
740
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
741
|
+
reset!
|
742
|
+
nil
|
743
|
+
end
|
744
|
+
|
745
|
+
# TODO: - this will get addressed with Watir::Executor implementation
|
746
|
+
# rubocop:disable Metrics/AbcSize
|
747
|
+
# rubocop:disable Metrics/MethodLength
|
748
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
749
|
+
# rubocop:disable Metrics/CyclomaticComplexity:
|
649
750
|
def element_call(precondition = nil, &block)
|
650
751
|
caller = caller_locations(1, 1)[0].label
|
651
752
|
already_locked = Wait.timer.locked?
|
652
|
-
unless already_locked
|
653
|
-
Wait.timer = Wait::Timer.new(timeout: Watir.default_timeout)
|
654
|
-
end
|
753
|
+
Wait.timer = Wait::Timer.new(timeout: Watir.default_timeout) unless already_locked
|
655
754
|
|
656
755
|
begin
|
657
|
-
check_condition(precondition)
|
756
|
+
check_condition(precondition, caller)
|
658
757
|
Watir.logger.info "-> `Executing #{inspect}##{caller}`"
|
659
758
|
yield
|
660
759
|
rescue unknown_exception => ex
|
661
|
-
if precondition.nil?
|
662
|
-
element_call(:wait_for_exists, &block)
|
663
|
-
end
|
760
|
+
element_call(:wait_for_exists, &block) if precondition.nil?
|
664
761
|
msg = ex.message
|
665
|
-
msg +=
|
762
|
+
msg += '; Maybe look in an iframe?' if @query_scope.iframe.exists?
|
666
763
|
custom_attributes = @locator.nil? ? [] : @locator.selector_builder.custom_attributes
|
667
|
-
|
764
|
+
unless custom_attributes.empty?
|
765
|
+
msg += "; Watir treated #{custom_attributes} as a non-HTML compliant attribute, ensure that was intended"
|
766
|
+
end
|
668
767
|
raise unknown_exception, msg
|
669
768
|
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
670
|
-
@query_scope.ensure_context
|
671
769
|
reset!
|
672
770
|
retry
|
673
771
|
rescue Selenium::WebDriver::Error::ElementNotVisibleError, Selenium::WebDriver::Error::ElementNotInteractableError
|
674
|
-
raise_present unless Wait.timer.remaining_time
|
772
|
+
raise_present unless Wait.timer.remaining_time.positive?
|
675
773
|
raise_present unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
|
676
774
|
retry
|
677
775
|
rescue Selenium::WebDriver::Error::InvalidElementStateError
|
678
|
-
raise_disabled unless Wait.timer.remaining_time
|
776
|
+
raise_disabled unless Wait.timer.remaining_time.positive?
|
679
777
|
raise_disabled unless %i[wait_for_present wait_for_enabled wait_for_writable].include?(precondition)
|
680
778
|
retry
|
681
779
|
rescue Selenium::WebDriver::Error::NoSuchWindowError
|
682
|
-
raise Exception::NoMatchingWindowFoundException,
|
780
|
+
raise Exception::NoMatchingWindowFoundException, 'browser window was closed'
|
683
781
|
ensure
|
684
782
|
Watir.logger.info "<- `Completed #{inspect}##{caller}`"
|
685
783
|
Wait.timer.reset! unless already_locked
|
686
784
|
end
|
687
785
|
end
|
786
|
+
# rubocop:enable Metrics/AbcSize
|
787
|
+
# rubocop:enable Metrics/MethodLength
|
788
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
789
|
+
# rubocop:enable Metrics/CyclomaticComplexity:
|
688
790
|
|
689
|
-
def check_condition(condition)
|
690
|
-
Watir.logger.info "<- `Verifying precondition #{inspect}##{condition}`"
|
791
|
+
def check_condition(condition, caller)
|
792
|
+
Watir.logger.info "<- `Verifying precondition #{inspect}##{condition} for #{caller}`"
|
691
793
|
begin
|
692
794
|
condition.nil? ? assert_exists : send(condition)
|
693
795
|
Watir.logger.info "<- `Verified precondition #{inspect}##{condition || 'assert_exists'}`"
|
694
796
|
rescue unknown_exception
|
695
797
|
raise unless condition.nil?
|
798
|
+
|
696
799
|
Watir.logger.info "<- `Unable to satisfy precondition #{inspect}##{condition}`"
|
697
|
-
check_condition(:wait_for_exists)
|
800
|
+
check_condition(:wait_for_exists, caller)
|
698
801
|
end
|
699
802
|
end
|
700
803
|
|
701
804
|
def method_missing(meth, *args, &blk)
|
702
805
|
method = meth.to_s
|
703
806
|
if method =~ Locators::Element::SelectorBuilder::WILDCARD_ATTRIBUTE
|
704
|
-
attribute_value(
|
807
|
+
attribute_value(meth, *args)
|
705
808
|
elsif UserEditable.instance_methods(false).include?(meth) && content_editable?
|
706
809
|
@content_editable = true
|
707
|
-
|
810
|
+
extend UserEditable
|
708
811
|
send(meth, *args, &blk)
|
709
812
|
else
|
710
813
|
super
|
@@ -712,8 +815,7 @@ module Watir
|
|
712
815
|
end
|
713
816
|
|
714
817
|
def respond_to_missing?(meth, *)
|
715
|
-
Locators::Element::SelectorBuilder::WILDCARD_ATTRIBUTE
|
818
|
+
meth.to_s =~ Locators::Element::SelectorBuilder::WILDCARD_ATTRIBUTE || super
|
716
819
|
end
|
717
|
-
|
718
820
|
end # Element
|
719
821
|
end # Watir
|